Add technical check history

A car's mandatory roadworthiness inspections — przegląd techniczny, MOT,
TÜV — had nowhere to live. Log them behind Service history, which this
mirrors minus the odometer: an inspection falls due on a date whatever
the mileage reads.

The cycle is legal rather than mechanical, and it is not constant — a new
car's first check falls due years later than its third. So the car's
technical_check_interval_days only prefills the next date, and any check
overrides it with the valid-until printed on its own certificate. A
failed check derives no next date at all: reading one off a failure would
stamp a reassuring "valid until" on a car that just flunked.

The next-due date and its status are derived on every read rather than
stored, for the same reason documents are — a stored verdict goes stale
as the date passes. The response carries the same expiry shape documents
use, so the web app reuses the existing badge rather than growing a
second one.

Each check records result, cost, station and notes, and holds the
certificate as its single attachment on the same terms as every other
record.

Needs `node scripts/setup-pocketbase.mjs` to create technical_checks and
add the interval to cars. The reformatting in records.go is gofmt
realigning the car struct around a longer field name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tajniak81
2026-07-17 11:54:26 +02:00
co-authored by Claude Opus 4.8
parent 03738f08dc
commit 21c99ad762
11 changed files with 713 additions and 81 deletions
+11
View File
@@ -135,6 +135,16 @@ export const api = {
request(`/service-records/${id}`, { method: "PATCH", body: JSON.stringify(body) }),
deleteService: (id) => request(`/service-records/${id}`, { method: "DELETE" }),
// Technical checks — roadworthiness inspections. nextCheckDate and the expiry
// assessment are derived server-side from the certificate's valid-until date,
// falling back to the car's interval.
listCarTechnicalChecks: (carId) => request(`/cars/${carId}/technical-checks`),
createTechnicalCheck: (body) =>
request("/technical-checks", { method: "POST", body: JSON.stringify(body) }),
updateTechnicalCheck: (id, body) =>
request(`/technical-checks/${id}`, { method: "PATCH", body: JSON.stringify(body) }),
deleteTechnicalCheck: (id) => request(`/technical-checks/${id}`, { method: "DELETE" }),
// Parts
listCarParts: (carId) => request(`/cars/${carId}/parts`),
createPart: (body) => request("/parts", { method: "POST", body: JSON.stringify(body) }),
@@ -170,6 +180,7 @@ export const api = {
files: {
documents: attachment("/car-documents"),
services: attachment("/service-records"),
technical: attachment("/technical-checks"),
maintenance: attachment("/maintenance"),
fuel: attachment("/fuel-entries"),
parts: attachment("/parts"),