fix: harden API, DB schema, and CLI safety
- Add 'reminder' to glyph CHECK constraint (was accepted by parser but
rejected by DB)
- Default serve bind to 127.0.0.1, add --host flag for LAN access
- Validate card_data as JSON in Store.Create/Update/Promote
- Return pagination envelope {data,total,limit,offset} from list endpoint
- Append absorb breadcrumb to source entity before soft-delete
- Add Levenshtein fuzzy match to catch command typos before routing to add
- Replace DDL string-matching migrations with versioned schema_version table
- Update web UI and API tests for envelope response format
This commit is contained in:
@@ -102,6 +102,15 @@ func listEntities(store *db.Store) http.HandlerFunc {
|
||||
}
|
||||
p.Offset = offset
|
||||
}
|
||||
if p.Limit <= 0 {
|
||||
p.Limit = 50
|
||||
}
|
||||
|
||||
total, err := store.Count(p)
|
||||
if err != nil {
|
||||
writeInternalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
entities, err := store.List(p)
|
||||
if err != nil {
|
||||
@@ -109,11 +118,16 @@ func listEntities(store *db.Store) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
resp := make([]EntityResponse, len(entities))
|
||||
items := make([]EntityResponse, len(entities))
|
||||
for i, e := range entities {
|
||||
resp[i] = entityToResponse(e)
|
||||
items[i] = entityToResponse(e)
|
||||
}
|
||||
writeJSON(w, http.StatusOK, resp)
|
||||
writeJSON(w, http.StatusOK, map[string]any{
|
||||
"data": items,
|
||||
"total": total,
|
||||
"limit": p.Limit,
|
||||
"offset": p.Offset,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +175,10 @@ func createEntity(store *db.Store) http.HandlerFunc {
|
||||
}
|
||||
|
||||
if err := store.Create(e); err != nil {
|
||||
if err == db.ErrInvalidCardData {
|
||||
writeError(w, http.StatusBadRequest, "invalid_card_data", "card_data must be valid JSON")
|
||||
return
|
||||
}
|
||||
writeInternalError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -227,6 +245,10 @@ func updateEntity(store *db.Store) http.HandlerFunc {
|
||||
writeError(w, http.StatusNotFound, "not_found", "no entity with id "+id)
|
||||
return
|
||||
}
|
||||
if err == db.ErrInvalidCardData {
|
||||
writeError(w, http.StatusBadRequest, "invalid_card_data", "card_data must be valid JSON")
|
||||
return
|
||||
}
|
||||
writeInternalError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -291,6 +313,10 @@ func promoteEntity(store *db.Store) http.HandlerFunc {
|
||||
writeError(w, http.StatusBadRequest, "invalid_promote", "entity is already crystallized")
|
||||
return
|
||||
}
|
||||
if err == db.ErrInvalidCardData {
|
||||
writeError(w, http.StatusBadRequest, "invalid_card_data", "card_data must be valid JSON")
|
||||
return
|
||||
}
|
||||
writeInternalError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user