Conformance checklist
Use these lists to review an implementation. Each item links to the page with the full rule. Items marked SHOULD are recommended but not needed for interoperability.
Server
Section titled “Server”Discovery and authentication
Section titled “Discovery and authentication”-
GET /lve/v1/infoanswers without authentication withprotocol: "lve-sync",versionscontaining1,server,auth,features, andlicenseonly when a licence is configured. Discovery -
POST /lve/v1/auth/tokenand/orPOST /lve/v1/auth/pairissue a bearer token bound todevice.idand answertoken,user.id(string),user.name,inventory.id,inventory.name. Authentication - Signing in again with the same user and device id replaces the previous token.
- Pairing codes work once, expire, and are compared without case, spaces and dashes. Two concurrent redemptions of one code cannot both succeed.
- Sign-in endpoints are rate-limited and answer
429withtoo_many_requests. -
DELETE /lve/v1/auth/tokenrevokes only the token of the request and answers204. - Every authenticated endpoint answers
401withunauthenticatedfor a missing or revoked token. -
inventory.idnever changes while devices are connected.
- Accepts up to 500 changes; refuses more with
422too_many_changeswithout storing anything. Push - Answers exactly one result per change at the same index, echoing
idandentityas sent. - Rejects malformed envelopes with
invalid_change, deletes of movements withimmutable, invalid payloads of known types withinvalid_payload, changes to locked templates withlocked. - Never rejects a change because of stock, references or duplicate numbers.
- Applies mutable records only when the stamp is greater than the stored one (byte-wise, upper case), tombstones included; answers
ignoredotherwise. Merge rules - Applies a movement only when its id is new; answers
ignoredotherwise. - Stores and relays unknown entity types and unknown fields unchanged; keeps
{}as an object. - Compares ids case-insensitively.
- Stores each change atomically; a failure does not leave a change half stored, and a rejected change does not affect the others.
- Serialises the merge decision per record, so concurrent pushes of one record cannot both apply out of order.
- Without cursor returns the current version of every record, tombstones included, paged, ending with a cursor that covers every change applied since the first page. Pull
- With cursor returns every applied change after it, in application order, including the caller's own.
- Never lets a reader see a later log position before an earlier one is committed.
- Honours
limit(1 to 1000, default 500) and setshas_moreexactly when changes were held back. - Always returns a cursor, also on an empty page.
- Answers a cursor it did not issue with
400invalid_cursor.
Attachments and number ranges
Section titled “Attachments and number ranges”-
PUTverifies the SHA-256 of the body against the path (422hash_mismatch), limits the size to 20 MiB (413payload_too_large), answers201when stored and200when already present. Attachments -
HEADanswers200or404;GETreturns the bytes with the stored content type. - Keeps every attachment that a current record version references.
- If
number_rangesis announced: hands out every number once across all devices, consecutive within a response, restarting each calendar year in the business time zone. Number ranges
General
Section titled “General”- Answers errors as
{"error": {"code", "message"}}with the codes of Errors, localised byAccept-Language(de,en) and named inContent-Language. - Uses HTTPS when reachable from the internet. Security
- Writes its own changes (administration, migrations, ERP imports) as new versions with greater stamps, node
00000000, appended to the log. Server-side writes - SHOULD keep tombstones and the change log forever, or answer cursors into a compacted range with
invalid_cursor.
Client
Section titled “Client”Records and clock
Section titled “Records and clock”- Keeps a full local copy of the inventory and works without a connection. Records
- Writes ids in upper case, compares them case-insensitively, uses fresh random UUIDs for new records and the fixed ids for the company profile and the two templates.
- Stamps every local write with a hybrid logical clock: 15-digit milliseconds, 4-digit upper-case hex counter, 8-digit upper-case hex node; strictly greater than every stamp issued or observed.
- Observes every received stamp before merging it.
- Merges received changes with the merge rules: greater stamp wins for mutable records, first write wins for movements.
- Never changes or deletes a movement; corrects with counter-bookings.
- Writes whole records; keeps unknown top-level fields of the previous version when writing a new one; sends
nullto clear a field. - Stores and relays unknown entity types.
- Reads payloads leniently: applies documented defaults for missing optional fields; ignores unknown fields and unknown values of open lists.
- Writes strict JSON types: numbers, booleans, RFC 3339 timestamps with seconds and time zone, lowercase SHA-256 hashes.
- Checks
protocolandversionsbefore signing in; verifies the licence if one is sent. Discovery, Licence - Stores the token in secure storage; on
401stops syncing, keeps local data and asks the user to sign in again. - After signing in, drops any old cursor and queues every local record for push.
- Keeps an outbox of local changes in write order; pushes it oldest first in batches of at most 500.
- Uploads every attachment a batch references (that it holds) before pushing the batch.
- Removes
appliedandignoredentries; keepsrejectedentries with their message and lets the user retry or discard them. - Pulls until
has_moreis false, merges each page before persisting its cursor, and starts over oninvalid_cursor. - Downloads missing attachments and verifies their SHA-256.
- Treats
5xx,429and transport errors as temporary and retries later; waits forRetry-After. - Sends
Accept-Language; decides by error codes, never by messages. - Uses HTTPS except in a trusted local network.
Derived state and workflows
Section titled “Derived state and workflows”- Derives stock, serial states, low stock and loan state with the rules of Derived state; never stores them as records.
- Writes one
issuemovement per delivery note line withdelivery_note_id, and the note withmovement_idper item, copies of recipient and article data, signatures and PDF. Delivery notes - Writes one
issuemovement per loan item at handover and onereceiptper returned line withloan_id; writes returns only with both signatures; writes no movement for lost units. Loans - Freezes
termsandpenaltyin the loan at handover. - Numbers documents with device numbering or reserved server numbers; never assumes numbers are unique across devices. Number ranges
- Shows locked templates read-only and does not write them.
- SHOULD apply the device booking checks (stock, serial numbers) before writing movements.
- SHOULD warn before merging local data into a server whose inventory id differs from the previous connection.
- Passes every vector in
test-vectors/that applies to its role.