Skip to content
Docs

Command palette

Jump to a page or search the docs.

Changelog

Vehicle documents

How a car's private documents are filed from the template's uploads, listed by type with their status, opened through a five-minute signed link, and how a due date becomes a reminder.

Markdown

What it does

A vehicle document (RF15, US18) is a file in the Organization's private storage filed among one car's documents with a kind (registration, title, insurance, tax, purchase_invoice, loan_agreement, warranty, inspection, receipt, other), a title and an optional due date. The bytes travel by the template's direct upload (Documents and uploads): uploads.prepare, one signed PUT or S3 multipart above 16 MiB, uploads.complete. There is no second storage path.

  • Filing checks that the car and the uploaded file belong to the Active Organization. The client generates the id, so a replay answers the first filing (RNF04).
  • A due date is a reminder (basis date, titled like the document, reminder.document_id), written in the same transaction. Changing the date moves it and reopens it if it was done; clearing the date or deleting the document deletes it. These reminders are alerts, not services: reminder.list (M-Manutencao, the M-Veiculo next service) leaves them out.
  • A document is mutable (kind, title, due date) and deletable, unless it is the receipt of an expense or a service (receiptOf): that record keeps its proof (CONFLICT). Deleting a document leaves the uploaded file in Files.
  • Opening one asks vehicleDocument.url, a presigned GET of its key that expires after 300 seconds (RNF05).
ProcedureFailures
vehicleDocument.list { vehicleId, limit ≤ 100 } (newest first)INPUT_VALIDATION, NOT_FOUND (car)
vehicleDocument.create { id, vehicleId, fileId, kind, title, dueOn? }INPUT_VALIDATION, NOT_FOUND (car, file), CONFLICT (id taken)
vehicleDocument.update { id, kind?, title?, dueOn? } (dueOn: null clears)INPUT_VALIDATION, NOT_FOUND
vehicleDocument.delete { id }NOT_FOUND, CONFLICT (a receipt)
vehicleDocument.url { id }NOT_FOUND

All are for Members of the Organization; a non-Member gets FORBIDDEN.

In the app

M-Documentos (features/vehicle-document/vehicle-document.screen.tsx, route /documents?vehicleId=) opens from M-Veiculo's Documents pill and segment. The segmented All | Garage | Insurance | Taxes filters the two-column grid (Garage is every kind but insurance and tax; one column at the largest text sizes). The status line and the chip's tint come from vehicle-document.model.ts: expired or due within 30 days is warning, a registration or inspection in force is "valid" in positive, another due date "expires …", and without one a title is "on file", a tax "paid", the rest "private" (text2). A card opens a sheet: a photo shows from its signed link, a PDF opens in the in-app browser, then edit or delete (confirmed). "Add document" and ⋯ open the form (vehicle-document.form.screen.tsx): a photo from the library or a PDF from Files (expo-document-picker), the type, the name (the type's by default) and the due date. The file uploads once per pick, so a retry after a failed filing reuses it. autofolio://dev/M-Documentos opens the seeded M3's six documents.

Data and isolation

vehicle_document and reminder have row-level security by Active Organization, and composite foreign keys keep a document on its car and its file in its Organization; uploaded_file keys are CHECKed under orgs/<organizationId>/. The tests prove another Organization gets NOT_FOUND on every procedure and that every signed key is under the caller's prefix (RNF06). No audit_log event is written; titles and file names never go to logs.

Key files

Edit on GitHubDocumentation is in English.

We use essential cookies to make our app work. With your consent, we also use optional cookies to improve your experience. Read our Cookie Policy and Privacy Policy.