Add attachments to service, maintenance, fuel and parts records
Documents already carried a single optional file: upload, download, detach,
access-checked on every request and proxied through this server, so PocketBase's
files are never public URLs. Service records, workshop visits, refills and
catalog parts all want the same thing — a receipt, an invoice, a photo of the
box — so extend it to them.
Rather than copy the document handlers four more times, lift them into one
shared layer. Every attachable collection has a car relation and a file field,
which is what lets a single set of handlers authorize and serve all of them. An
upload finishes by delegating to the collection's own GET handler, so the
response carries the full record — derived fields and all — exactly as a re-read
would. The web side gets the same treatment: one picker component and one
upload-after-save helper behind all five forms. Net effect is five features for
about the cost of the one that was already there.
Alongside:
- parts gain a notes field
- Reminders moves behind Parts catalog in the car detail tabs
- the changed-part labels spell out in full ("Oil & Oil filter" rather than
"Oil & filter"), and the form and table now agree
The PocketBase schema must be migrated before the new attachments work:
scripts/setup-pocketbase.mjs adds the file fields and parts.notes. It is
additive and safe to re-run.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e64c89a564
commit
07192f1238
@@ -72,9 +72,12 @@
|
||||
// GET /api/car-documents POST /api/car-documents
|
||||
// GET /api/car-documents/{id} PATCH /api/car-documents/{id}
|
||||
// DELETE /api/car-documents/{id}
|
||||
// POST /api/car-documents/{id}/file
|
||||
// GET /api/car-documents/{id}/file
|
||||
// DELETE /api/car-documents/{id}/file
|
||||
//
|
||||
// # attachments — one optional file per record, same three verbs everywhere.
|
||||
// # {records} is car-documents | service-records | maintenance | fuel-entries | parts
|
||||
// POST /api/{records}/{id}/file
|
||||
// GET /api/{records}/{id}/file
|
||||
// DELETE /api/{records}/{id}/file
|
||||
//
|
||||
// # reminders (stored + auto-derived from documents and service records)
|
||||
// GET /api/cars/{id}/reminders
|
||||
@@ -283,9 +286,6 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.HandleFunc("GET /api/car-documents/{id}", s.getDocument)
|
||||
mux.HandleFunc("PATCH /api/car-documents/{id}", s.updateDocument)
|
||||
mux.HandleFunc("DELETE /api/car-documents/{id}", s.deleteDocument)
|
||||
mux.HandleFunc("POST /api/car-documents/{id}/file", s.handleUploadDocumentFile)
|
||||
mux.HandleFunc("GET /api/car-documents/{id}/file", s.handleGetDocumentFile)
|
||||
mux.HandleFunc("DELETE /api/car-documents/{id}/file", s.handleDeleteDocumentFile)
|
||||
|
||||
// Reminders.
|
||||
mux.HandleFunc("GET /api/reminders", s.listReminders)
|
||||
@@ -295,6 +295,15 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.HandleFunc("DELETE /api/reminders/{id}", s.deleteReminder)
|
||||
mux.HandleFunc("POST /api/reminders/{id}/complete", s.handleCompleteReminder)
|
||||
|
||||
// Attachments — one optional file per record, on identical terms for every
|
||||
// collection that takes one (see attachments.go). The GET handler passed
|
||||
// alongside is what renders the record after an upload.
|
||||
s.attachmentRoutes(mux, "/api/car-documents", colDocuments, s.getDocument)
|
||||
s.attachmentRoutes(mux, "/api/service-records", colServices, s.getServiceRecord)
|
||||
s.attachmentRoutes(mux, "/api/maintenance", colMaintenance, s.getMaintenance)
|
||||
s.attachmentRoutes(mux, "/api/fuel-entries", colFuel, s.getFuelEntry)
|
||||
s.attachmentRoutes(mux, "/api/parts", colParts, s.getPart)
|
||||
|
||||
return s.withMiddleware(mux)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user