feat: add API-key authenticated Admin API for users and time logs#63
Conversation
Exposes REST endpoints under /api/admin/{users,timelogs} for external
systems to manage users and time logs, secured via a static Bearer
API key (ADMIN_API_KEY), plus an OpenAPI 3.0 schema at
/openapi/admin-api.json.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ReviewThe PR adds a new API-key-authenticated REST API ( 1. Malformed
|
Malformed ids/userIds previously reached Prisma directly and crashed with an unhandled 500 (Mongo P2023); now validated with a shared ObjectId zod schema and mapped to a clean 400. Also fix adminUpdateTimeLog to null out omitted outTime/notes instead of leaving Prisma's stale values in place when a PUT transitions a log away from DONE/LOCKED. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Addressed both review findings in b73dadb:
Verified manually against the dev DB: malformed ids on all affected routes now 400, and the reopen-to-CURRENTLY_IN scenario now clears |
Summary
/api/admin/usersand/api/admin/timelogs(GET/POST/PUT/DELETE) for external systems to manage users and time logsADMIN_API_KEYenv var), checked with a constant-time comparison; returns 503 if unconfigured, 401 if invalidadminGet/Create/Update/DeleteUser,adminGet/Create/Update/DeleteTimeLog) alongside existing session-based DTO functions, since the API key auth path has no NextAuth sessionpublic/openapi/admin-api.jsondocumenting all endpoints, schemas, and the bearer auth schemeTest plan
npx tsc --noEmitandnpm run buildpasscurl:ADMIN_API_KEYunset → 503POST/GET/PUT/DELETE /api/admin/usersand/api/admin/users/{id}— create, fetch, update, delete, 404 on missing idPOST/GET/PUT/DELETE /api/admin/timelogsand/api/admin/timelogs/{id}— including validation error (DONE without outTime → 400) and query filterspublic/openapi/admin-api.jsonis well-formed JSONNote: found a pre-existing gap where the dev MongoDB doesn't enforce the
email @uniqueindex (duplicate emails succeed) — predates this change and also affects the existing UI create flow; out of scope here.🤖 Generated with Claude Code