diff --git a/API Server/internal/api/homechargers.go b/API Server/internal/api/homechargers.go index 2fc0d9f..9617328 100644 --- a/API Server/internal/api/homechargers.go +++ b/API Server/internal/api/homechargers.go @@ -79,11 +79,25 @@ func (s *Server) listHomeChargers(w http.ResponseWriter, r *http.Request) { writeError(w, http.StatusUnauthorized, "not authenticated") return } - res, err := s.pb.List(r.Context(), colHomeChargers, url.Values{ - "filter": {fmt.Sprintf("owner='%s'", me)}, - "sort": {"created"}, - "perPage": {"200"}, - }) + query := func(sort string) url.Values { + q := url.Values{ + "filter": {fmt.Sprintf("owner='%s'", me)}, + "perPage": {"200"}, + } + if sort != "" { + q.Set("sort", sort) + } + return q + } + res, err := s.pb.List(r.Context(), colHomeChargers, query("created")) + if err != nil { + // A collection created before `created` was declared does not have the + // field, and PocketBase rejects the whole query over an unknown sort. The + // order is a nicety; the list is not, so ask again without it rather than + // show the owner an error about a field they cannot see. The bootstrap + // adds the field on the next boot, and the sorted query then wins. + res, err = s.pb.List(r.Context(), colHomeChargers, query("")) + } if err != nil { writePBError(w, err) return diff --git a/API Server/internal/bootstrap/schema.go b/API Server/internal/bootstrap/schema.go index b43d524..86f03ab 100644 --- a/API Server/internal/bootstrap/schema.go +++ b/API Server/internal/bootstrap/schema.go @@ -219,6 +219,11 @@ var collectionsSchema = map[string][]fieldDef{ // Owner. Non-cascading, like a car's: deleting a user must not silently // wipe the records they own. fRelation("owner", "users", false, false), + // A charger carries no date of its own, so the import order is the only + // order there is to list them in. PocketBase adds no created field to a + // collection defined through the API, so it is declared here like the + // audit trail's. + fAutodate("created", true, false), }, // Custom fields layered onto the built-in "users" auth collection. "users": { diff --git a/API Server/scripts/setup-pocketbase.mjs b/API Server/scripts/setup-pocketbase.mjs index 1c6d7c2..3f396ea 100644 --- a/API Server/scripts/setup-pocketbase.mjs +++ b/API Server/scripts/setup-pocketbase.mjs @@ -457,6 +457,10 @@ const DESIRED = { F.text("provider_charger_id"), // Owner. Non-cascading, like a car's: deleting a user must not wipe their records. F.relation("owner", "users", false, false), + // A charger carries no date of its own, so the import order is the only order + // there is to list them in. PocketBase adds no created field to a collection + // defined through the API, so it is declared here like the audit trail's. + F.autodate("created", true, false), ], // Server-wide settings as a single record, keyed "global". Today it holds // pluginSettings: the top (L1) layer of the integration cascade — every