Skip to content

Add ApiRequestLog observability stack and migrate User to UUID PK#223

Merged
edimossilva merged 1 commit into
mainfrom
add-api-request-log-and-uuid-user
May 7, 2026
Merged

Add ApiRequestLog observability stack and migrate User to UUID PK#223
edimossilva merged 1 commit into
mainfrom
add-api-request-log-and-uuid-user

Conversation

@edimossilva
Copy link
Copy Markdown
Member

Summary

Backports the request-logging middleware, admin observability dashboards, and generic User improvements (UUID PK, name column) from the plantao backend into this boilerplate. Plantao-specific business code (medical_shifts, locations, chat_messages, domain_events, app_versions, doctor/accountant roles, Firebase auth, paying flag, mobile_platform, etc.) is intentionally not brought over. Existing boilerplate features (GraphQL, Chewy, Schools, HandleFile, demo_pack, oauth pack) are untouched.

What's added

  • Migrations (8): enable pgcrypto, convert users.id and devise_api_tokens to UUID, change versions.item_id to string for PaperTrail compatibility with UUID records, add name to users, create api_request_logs (with deleted_at + response_code).
  • ApiRequestLog model with summary helper; User gains has_many :api_request_logs.
  • ApiRequestLoggerMiddleware records every /api/* request to api_request_logs and resolves the user via the Bearer access token.
  • Admin dashboards under /admin — Administrate CRUD for ApiRequestLog plus six custom dashboards: Daily Overview, Requests Dashboard, Non-2xx API Logs, User Analytics, User Lookup, Request Logs by Payload. Dashboards that originally referenced removed plantao entities have been adapted to track only User and ApiRequestLog data.
  • Routes: new admin resources for the seven dashboards above.
  • Specs: factory + middleware spec + six admin request specs (99 examples, 0 failures), conforming to this repo's stricter RuboCop config.
  • CLAUDE.md: short note on the new middleware + dashboards.

Heads-up: UUID migration is destructive

Migrating users from bigint to UUID truncates devise_api_tokens (existing tokens become invalid) and versions (PaperTrail history is cleared). Any deployment with real data on a fork of this branch will need a coordinated re-auth + acceptance of the lost audit trail.

Test plan

  • bin/rails db:drop db:create db:migrate runs cleanly; db/schema.rb shows users.id, devise_api_tokens.id + resource_owner_id, versions.id as UUID and versions.item_id as string.
  • bundle exec bin/rspec -P './*/**/*_spec.rb' passes without any new regressions.
  • bundle exec rubocop reports no new offenses.
  • Manual smoke: create a user via POST /api/v1/users, sign in via POST /api/v1/tokens, hit GET /api/v1/users with the bearer token, and confirm a corresponding row appears in api_request_logs.
  • Sign in to /admin as admin@email.com / password (after bin/rails db:seed) and click through every nav entry — each dashboard should render without errors.
  • Hit /api/v1/users without a token and verify the resulting 401 shows up under /admin/api_error_logs.

🤖 Generated with Claude Code

Backports the request-logging middleware, admin observability dashboards,
and generic User improvements (UUID PK, name column) from the plantao
backend, leaving plantao-specific business code (medical_shifts, locations,
chat_messages, domain_events, app_versions, doctor/accountant roles,
Firebase) behind. Existing boilerplate features (GraphQL, Chewy, Schools,
HandleFile, demo_pack, oauth pack) are untouched.

- Migrations: enable pgcrypto, convert users.id and devise_api_tokens to
  uuid, change versions.item_id to string for PaperTrail, add name to
  users, create api_request_logs (+ deleted_at, response_code).
- Model: ApiRequestLog with summary helper; User gains has_many
  :api_request_logs.
- Middleware: ApiRequestLoggerMiddleware records every /api/* request to
  api_request_logs and resolves the user via the Bearer token.
- Admin: ApiRequestLog Administrate dashboard plus six dashboards
  (daily_overview, requests_dashboard, request_logs_by_payload,
  api_error_logs, user_analytics, user_lookup) under /admin, with the
  navigation partial wiring them up. Dashboards that originally referenced
  removed plantao entities have been adapted to track only User and
  ApiRequestLog data.
- Routes: new admin resources for the seven dashboards above.
- Specs: factory + middleware spec + six request specs (≥99 examples,
  0 failures), all matching boilerplate's stricter RuboCop config.
- CLAUDE.md: short note on the new middleware + dashboards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edimossilva edimossilva merged commit 0a24a0a into main May 7, 2026
3 checks passed
@edimossilva edimossilva deleted the add-api-request-log-and-uuid-user branch May 7, 2026 20:48
edimossilva added a commit that referenced this pull request May 7, 2026
* Fix UserDashboard id field type after UUID migration

UserDashboard declared id: Field::Number, which calls Float() on the
value. After the users.id migration to uuid in #223, visiting /admin
raised "invalid value for Float(): \"<uuid>\"" before any rows could
render. Switching to Field::String (matching ApiRequestLogDashboard)
lets Administrate render the UUID as plain text.

Verified end-to-end: GET /admin and every dashboard introduced in #223
(/admin/users, /admin/api_request_logs, /admin/daily_overview,
/admin/requests_dashboard, /admin/api_error_logs, /admin/user_analytics,
/admin/user_lookup, /admin/request_logs_by_payload) return 200.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Redirect admins to /admin after sign in

Override after_sign_in_path_for in ApplicationController so that a User
with admin? lands on admin_root_path. Non-admin users continue to use
Devise's default (stored_location_for or root_path via super).

Verified manually: signing in as admin@email.com returns 303 to
http://localhost:3002/admin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant