docs(auth,users,devices,progress,matching): Beam batch 8 — WO5 backfill complete
14 endpoints backfilled: devices pending/approve/reject; users
password/profile/profile-delete self-service (admin variants in prose);
admin list_users + update_user_max_devices; progress history; book
matching; new password-rules doc.
Gate fix: authLabel missed JWT middleware written inline as
createJWTMiddleware(cfg) (uppercase 'JWT') — reported auth 'none' for
/api/auth self-service routes and would have for any wrapper-inlined
group. Labeled 'JWTMiddleware' + fallthrough 'jwt' case.
Claude registry: 12 entries. Drift fixed by gate: list_users on-device —
handler returns raw []database.Users (bare array, full model incl.
password_hash — real leak the API emits; pinned + documented; earlier
draft had invented {users,total,limit,offset} wrapper). max-devices
response is {message} only. books/match is GET /api/books/match
{matches, action}. progress history sessions = ReadingHistory rows
(pgtype fields). make test 9/9.
This commit is contained in:
1 parent
2c56ae4b9d
commit
cc5677eb17
13 files changed
+233
-75
No files matched your search
@@ -659,4 +659,71 @@ var Schemas = map[string]Schema{
|
||||
"watching_libraries": [""], "total_watching": 0
|
||||
}`),
|
||||
},
|
||||
|
||||
// --- Beam batch 8: devices remaining + auth remainder ---
|
||||
"GET /api/devices/pending": {
|
||||
// Device registrations live in an in-memory map; both key spellings
|
||||
// are emitted for compatibility.
|
||||
Response: json.RawMessage(`{
|
||||
"registrations": [], "pending_registrations": [], "total": 0
|
||||
}`),
|
||||
},
|
||||
"GET /api/devices/approve/:registration_id": {
|
||||
// Already-approved variant omits registration_id. Credentials ride
|
||||
// the registration map polled elsewhere — NOT this JSON body.
|
||||
Response: json.RawMessage(`{
|
||||
"message": "", "device_name": "", "device_type": "",
|
||||
"registration_id": "", "approved": false
|
||||
}`),
|
||||
},
|
||||
"POST /api/devices/reject/:registration_id": {
|
||||
Response: json.RawMessage(`{"message": ""}`),
|
||||
},
|
||||
"POST /api/auth/users": {
|
||||
Request: handlers.RegisterRequest{},
|
||||
Response: json.RawMessage(`{
|
||||
"id": "", "email": "", "username": "", "role": "",
|
||||
"timezone": "", "created_at": null
|
||||
}`),
|
||||
},
|
||||
"GET /api/auth/users": {
|
||||
Response: []database.Users{},
|
||||
},
|
||||
"PUT /api/auth/users/:id/max-devices": {
|
||||
Request: handlers.UpdateUserMaxDevicesRequest{},
|
||||
Response: json.RawMessage(`{"message": ""}`),
|
||||
},
|
||||
"PUT /api/auth/password": {
|
||||
// Self-change (jwt). Admin variant PUT /auth/password/:id documented
|
||||
// in prose; handler is shared (admin mode skips current_password).
|
||||
Request: json.RawMessage(`{
|
||||
"current_password": "", "new_password": "", "confirm_password": ""
|
||||
}`),
|
||||
Response: json.RawMessage(`{"message": ""}`),
|
||||
},
|
||||
"PUT /api/auth/profile": {
|
||||
// Shared with admin variant (PUT /auth/profile/:id).
|
||||
Request: handlers.AdminUpdateUserRequest{},
|
||||
Response: json.RawMessage(`{"message": ""}`),
|
||||
},
|
||||
"DELETE /api/auth/profile": {
|
||||
// Self-delete; admin variant DELETE /auth/profile/:id (reassignment
|
||||
// of admin-owned assets to another admin before cascade).
|
||||
Response: json.RawMessage(`{"message": ""}`),
|
||||
},
|
||||
"GET /api/progress/:id/history": {
|
||||
// id is MEDIA ITEM id; sessions are ReadingHistory rows.
|
||||
Response: json.RawMessage(`{
|
||||
"media_item_id": "", "sessions": [], "count": 0
|
||||
}`),
|
||||
},
|
||||
"GET /api/books/match": {
|
||||
Response: services.BookQueryResponse{},
|
||||
},
|
||||
"GET /api/auth/password-rules": {
|
||||
Response: json.RawMessage(`{
|
||||
"min_length": 8, "require_upper": true, "require_lower": true,
|
||||
"require_number": true, "require_special": true
|
||||
}`),
|
||||
},
|
||||
}
|
||||
Reference in new issue
Block a user