Reference app behaviour
This page collects how the reference implementations behave where it matters for interoperability. Items marked deviation are cases where an implementation does not follow this specification; they are listed so that other implementations can work around them until they are fixed.
Reference app: reading records
Section titled “Reference app: reading records”- Payloads are decoded leniently with the documented defaults. A record is not shown when a required field is missing or any known field has a value of the wrong type. Required fields per entity are marked required or server in the entity reference.
- Dates must be RFC 3339 with seconds and a time zone; fractional seconds are ignored.
2026-10-12or2026-10-12T08:15Zmake the record invisible. - Numbers must be JSON numbers and booleans JSON booleans; numeric strings make the record invisible.
- A movement whose article is unknown is kept but does not count towards stock and is not shown until the article arrives.
- Unknown
columnsvalues in templates are dropped; unknown signature roles are not shown; unknown recipient kinds read ascustomer, unknown or missingborrower_kindasemployee.
Reference app: writing records
Section titled “Reference app: writing records”- Optional fields without value are left out of the payload rather than written as
null. - When it writes a new version, the app keeps the top-level keys of the previous version that it does not know itself (it finds them by decoding and encoding the previous version). Known fields it leaves out are cleared. Unknown nested keys (inside items, returns, signatures) are lost when the app rewrites a record.
- Dates are written in UTC with whole seconds.
- Ids are written in upper case; stamps in upper case.
- Writes
created_aton articles, locations and recipients when it creates them. - Writes
items[].barcodeon delivery notes. - Does not read or write
document_template.numbering.next; the device counter lives on the device. - Delivery note
titleis printed as written;{number},{date}and{recipient}are replaced only inintro,closingandfooter.
Reference app: sync
Section titled “Reference app: sync”- Syncs one round at a time: at start, 1.5 seconds after local changes, every 60 seconds and when the network returns.
- Reads
infoon every round, also while paused, to pick up licence changes. - Does not read
authorfeatures; offers both sign-in methods and requests number reservations whenever the delivery note template is in server mode, ignoring failures. - Matches push results to changes by position;
results[].idandresults[].entitymay benull. - Stores the message (or, without one, the reason) of a rejected change and stops sending it until the user retries or discards it.
- Persists the pull cursor after every merged page. On
invalid_cursorit forgets the cursor and starts over with a full pull in the same round. - Downloads missing attachments after the pull; failed downloads are retried in the next round.
- Uploads only attachments it holds, before each push batch.
- Uses request timeouts of 15 seconds (start of response) and 120 seconds (whole request).
- Does not compare
inventory.idwith an earlier connection.
Reference app: derived values and documents
Section titled “Reference app: derived values and documents”- Stock rows with an absolute value up to 0.0005 are hidden; quantity comparisons use a tolerance of 0.0005.
- Serial numbers are matched case-insensitively, for stock as well as for the outstanding serials of a loan.
- Overdue days are computed in the device's time zone.
- Loans are numbered on the device (
UE-{YYYY}-{DEV}-{SEQ:4}); there is no server number range for loans. - Device numbering appends the counter when the format has no
{SEQ}and replaces only the first{SEQ}.
Reference app: iCloud
Section titled “Reference app: iCloud”- Builds the CloudKit record from the current version of a record, not from the outbox entry. A saved version acknowledges every queued entry of that record with the same or an older stamp, so a record written twice before the next iCloud sync does not stay pending.
- Does not enforce locked templates on other iCloud devices (there is no server); a locked template is only shown read-only.
Reference server
Section titled “Reference server”- Validates payloads with Laravel rules that accept looser forms than clients read: numeric strings,
"0"/"1"booleans, any date PHP can parse. Writers must not rely on this. - Rejects unknown values of closed sets (template
columns, movementtype, returncondition), which readers would ignore. - Does not check the location fields per movement type, references between records, the due date of external loans, or signatures.
- Formats reserved numbers without
{DEV}support and without appending a counter when{SEQ}is missing; restarts the counter every calendar year regardless of the format. - Applies the template lock to any
document_templatewhose stored version haslocked: true, not only to the loan template. - Accepts any numeric cursor of up to 18 digits, also beyond the end of its log.
- Rate-limits only the sign-in endpoints.
- Accepts any attachment content type.
- Projects articles (with prices and accessories), locations, recipients, movements, delivery notes, loans and serial numbers into its read model for the admin panel;
lve:project --freshrebuilds it.