docs(media-items): Work Order 3 batch 3a — reader-adjacent CRUD (11 endpoints)

New frontmatter'd docs with real shapes (sqlc models pinned directly):
- bookmarks: get/create/update/delete (sync-aware rows: dedup_key,
  last_modified_*, tombstones; delete is 204)
- review: upsert (empty string DELETES the review) / get (200 with
  {review:null} when absent) / delete
- get single note + highlight (full sqlc row shapes)
- annotation history: restore (POST, kind via query or body) and purge
  (DELETE, kind via required query; permanent)

Gate hardening forced by this batch:
- required-field walk now guards non-struct Request types (RawMessage pins)
- update_media_bookmark needed a full example block (no cross-reference
  shortcuts — the gate checks every doc standalone)
This commit is contained in:
John O'Keefe committed 2026-10-24 15:03:36 -04:00
1 parent 85cdaf7196
commit ed0ce5d077
13 files changed
+545 -4

No files matched your search

+10 -4
View File
@@ -231,9 +231,15 @@ func validateRequestExample(t *testing.T, doc *APIDoc, schema Schema) {
}
// Staleness guard: required fields must be present in the example.
for _, field := range requiredJSONFields(reflect.TypeOf(schema.Request)) {
if !jsonHasKey(doc.ExampleRequest, field) {
t.Errorf("%s: example-request missing required field %q", doc.RelPath, field)
rt := reflect.TypeOf(schema.Request)
for rt != nil && rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt != nil && rt.Kind() == reflect.Struct {
for _, field := range requiredJSONFields(rt) {
if !jsonHasKey(doc.ExampleRequest, field) {
t.Errorf("%s: example-request missing required field %q", doc.RelPath, field)
}
}
}
}
@@ -283,7 +289,7 @@ func validateResponseExample(t *testing.T, doc *APIDoc, schema Schema) {
}
// requiredJSONFields lists json field names of struct type whose validate tag
// marks them required.
// marks them required. Callers must pass a struct kind.
func requiredJSONFields(rt reflect.Type) []string {
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()