Demo app, collections/features CRUD, QR codes, docs
CI / test (push) Successful in 4s

Demo app (web/):
- Collections: select, rename, remove (x button per row), delete
- Features: add point (lon/lat validation), remove, list in selected collection
- QR codes for pk (private) and pb (public) keys
- Restore public key from private key
- 409 Conflict handled for already-registered login
- Title: Momswap Geo Backend Use-Cases Test

Backend:
- PATCH /v1/collections/{id} for rename
- DELETE /v1/collections/{id}
- Clearer lon/lat validation errors (-180..180, -90..90)

Client:
- updateCollection, deleteCollection, derivePublicKey

Docs:
- docs/frontend-development.md (demo app, local dev)
- README links to all docs

Made-with: Cursor
This commit is contained in:
2026-03-01 13:41:54 +00:00
parent ceeac1a1ee
commit ef3957b618
15 changed files with 512 additions and 26 deletions
+38
View File
@@ -35,6 +35,8 @@ func (a *API) Routes() http.Handler {
mux.HandleFunc("POST /v1/collections", a.createCollection)
mux.HandleFunc("GET /v1/collections", a.listCollections)
mux.HandleFunc("PATCH /v1/collections/{id}", a.updateCollection)
mux.HandleFunc("DELETE /v1/collections/{id}", a.deleteCollection)
mux.HandleFunc("POST /v1/collections/{id}/features", a.createFeature)
mux.HandleFunc("GET /v1/collections/{id}/features", a.listFeatures)
mux.HandleFunc("DELETE /v1/features/{id}", a.deleteFeature)
@@ -272,6 +274,42 @@ func (a *API) listCollections(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]interface{}{"collections": a.service.ListCollections(user)})
}
func (a *API) updateCollection(w http.ResponseWriter, r *http.Request) {
user, err := a.authUser(r)
if err != nil {
writeErr(w, err)
return
}
collectionID := r.PathValue("id")
var req struct {
Name string `json:"name"`
}
if err := readJSON(r, &req); err != nil {
writeErr(w, app.ErrBadRequest)
return
}
collection, err := a.service.UpdateCollection(user, collectionID, req.Name)
if err != nil {
writeErr(w, err)
return
}
writeJSON(w, http.StatusOK, collection)
}
func (a *API) deleteCollection(w http.ResponseWriter, r *http.Request) {
user, err := a.authUser(r)
if err != nil {
writeErr(w, err)
return
}
collectionID := r.PathValue("id")
if err := a.service.DeleteCollection(user, collectionID); err != nil {
writeErr(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (a *API) createFeature(w http.ResponseWriter, r *http.Request) {
user, err := a.authUser(r)
if err != nil {