Add REST API v1 with token-based authentication#443
Open
Conversation
Implements a full REST API with Bearer token authentication using Rails has_secure_token. Endpoints cover all main resources: organizations, clients, projects, tasks, time registrations, users, and reports. Key changes: - Add api_token column to users with unique index - Create Api::V1::BaseController with token auth and JSON error handling - Add API controllers for all resources with proper authorization - Add missing policy methods (index?, show?, create?, etc.) to existing policies for Client, Task, TimeReg, User, and Project - Fix ProjectPolicy scope to not filter by project_accesses for admins - Add comprehensive integration tests (33 tests, all passing) https://claude.ai/code/session_01P3uN3uxLcyQwmeYHGkMdgc
Move all JSON serialization out of controller private methods and into Jbuilder view templates under app/views/api/v1/, following standard Rails MVC conventions. Controllers now only authorize, scope queries, and set instance variables. - Replace Ruby-level group_by in ReportsController with SQL GROUP BY aggregation, eliminating full table loads into memory - Fix OrganizationsController: add missing authorize! calls (security gap) - Add OrganizationPolicy#index? and #show? so the policy actually covers these actions - Remove redundant `to: :index?` from all authorize! calls; ActionPolicy infers the action from the method name - Replace ActiveSupport String#remove with Ruby's delete_prefix for Bearer token extraction - Drop custom pagy_metadata override from BaseController; pagination metadata is now rendered directly in the Jbuilder index view via @pagy - Add `defaults: { format: :json }` to API route namespace so implicit Jbuilder rendering works without explicit render calls - Use render :show for create/update responses (Rails convention) https://claude.ai/code/session_01P3uN3uxLcyQwmeYHGkMdgc
…tokens
Address all issues from the DHH-style code review:
1. Extract toggle_active into TimersController — verb-y actions get
their own resource controller. PATCH /time_regs/:id/timer replaces
PATCH /time_regs/:id/toggle_active.
2. Extract regenerate_token into ApiTokensController — PATCH /api_token
replaces POST /users/regenerate_token. One controller, one action.
3. Add X-Organization-Id header — multi-org users can now specify which
organization context to use per-request. Without the header, falls
back to the user's active organization. Uses singleton method
override on the user instance so all existing policies work without
modification.
4. Replace has_secure_token with on-demand generation — tokens are no
longer auto-generated on User.create. New ensure_api_token! and
regenerate_api_token methods generate tokens only when needed.
5. Move query from projects/show view into controller — the
active_assigned_tasks.includes(:task) query now runs in the
controller (show/create/update), not in the Jbuilder template.
6. Normalize error responses — all error handlers now return
{ errors: [...] } (always an array) instead of mixed error/errors
keys.
All 38 API tests pass (97 assertions, 0 failures).
https://claude.ai/code/session_01P3uN3uxLcyQwmeYHGkMdgc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR introduces a comprehensive REST API v1 for the application with token-based authentication, organization scoping, and full CRUD operations for core resources. The API follows RESTful conventions and integrates with the existing authorization policies.
Changes Made
API Base Infrastructure
Api::V1::BaseControllerwith token-based authentication viaAuthorization: Bearer <token>headerX-Organization-IdheaderAPI Endpoints
GET /api/v1/organizations(index),GET /api/v1/organizations/:id(show)/meendpointAuthentication & Authorization
api_tokencolumn to users table with unique indexensure_api_token!andregenerate_api_tokenmethods on User modelViews & Serialization
Routing
/meroute for current user endpointTesting
api_headersutility for authenticated requestsConfiguration
>= 3.2.2for flexibilityHow to Test
rails test test/controllers/api/v1/to execute all API testsuser.ensure_api_token!Authorization: Bearer <token>X-Organization-Id: <org_id>?per_page=10&page=2?date=2024-01-15or?start_date=...&end_date=...Additional Context
resolve_organizationbefore_action