ADR-0077: Formats and sizes, checked by artifactr's own code¶
Status: Accepted Date: 2026-10-17 Deciders: Alex Nodeland
Context¶
The subset has formats, date, date-time, email and uri, and limits in bytes. Pydantic checks an email only through email-validator, a third-party dependency lattice RFC-0005 excludes. portalr validates the same subset in TypeScript before it sends, so each check must be one it can repeat exactly.
Decision¶
- Each format is a pattern of artifactr.ui's own, JavaScript-compatible, its digits and spaces spelled out as JavaScript reads them and each matching the whole text: a
dateis an RFC 3339 full date on the calendar; adate-timeis RFC 3339 with seconds and an offset (T, andZor±hh:mm), so a browser'sdatetime-localvalue is converted before it is sent;TandZin either case; anemailis a local part of up to 64 characters without whitespace or@,@, and a domain of two or more dotted ASCII labels, at most 254 characters in all; auriis a link a person may follow,http://,https://ormailto:in either case, and no whitespace. multipleOfis artifactr.ui's own check too: a value is a multiple whenvalue / multipleOfis a whole number, exactly or to within a billionth of the quotient, which floats need and Pydantic's integer constraint can't take; a quotient too large for a float is no multiple.- Every number, in a schema, a value or a dashboard, is within ±(2⁵³ − 1) (
MAX_NUMBER), JavaScript'sNumber.MAX_SAFE_INTEGER, bounds included, so both sides read it as written and no check overflows. - Every limit is measured as the UTF-8 bytes of compact JSON (
json_size): no spaces after separators, non-ASCII characters as they are, keys in their order, as JavaScript'sJSON.stringifywrites it.
Options considered¶
| Option | For | Against |
|---|---|---|
| Small checks of our own (chosen) | No dependency; the TypeScript side repeats them | An address valid by RFC 5321 with quoting or an IP literal is refused; an internationalised domain must be sent as punycode |
email-validator through Pydantic |
Thorough | A third-party validator, and checks the browser can't repeat |
Consequences¶
- Easier: both sides agree on every vector.
- Harder: a
uriof another scheme,ftp:orurn:, is refused;javascript:anddata:must be.