# Admin Feature Self-contained feature capsule for MotoVaultPro admin role and access control management. ## Architecture ``` admin/ ├── api/ │ ├── admin.controller.ts # HTTP request handlers │ └── admin.routes.ts # Route registration ├── domain/ │ ├── admin.types.ts # TypeScript interfaces │ └── admin.service.ts # Business logic ├── data/ │ └── admin.repository.ts # Database access (parameterized queries) ├── migrations/ │ └── 001_create_admin_users.sql # Database schema └── tests/ ├── unit/ # Service/guard tests └── integration/ # API endpoint tests ``` ## Database Schema ### admin_users table ```sql CREATE TABLE admin_users ( auth0_sub VARCHAR(255) PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, role VARCHAR(50) NOT NULL DEFAULT 'admin', created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, created_by VARCHAR(255) NOT NULL, revoked_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` ### admin_audit_logs table ```sql CREATE TABLE admin_audit_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), actor_admin_id VARCHAR(255) NOT NULL, target_admin_id VARCHAR(255), action VARCHAR(100) NOT NULL, resource_type VARCHAR(100), resource_id VARCHAR(255), context JSONB, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` ## Usage ### Phase 1: Access Control Foundations Provides: - `AdminRepository` - Database access with parameterized queries - `AdminService` - Business logic for admin operations - `admin-guard` plugin - Authorization enforcement (decorator on Fastify) - `request.userContext` - Enhanced with `isAdmin`, `adminRecord` ### Admin Dashboard Stats Provides admin dashboard statistics: - `GET /api/admin/stats` - Get total users and vehicles counts **Response:** ```json { "totalUsers": 150, "totalVehicles": 287 } ``` ### User Management APIs Provides: - `GET /api/admin/users` - List all users with pagination/filters - `GET /api/admin/users/:auth0Sub` - Get single user details - `GET /api/admin/users/:auth0Sub/vehicles` - Get user's vehicles (admin view) - `PATCH /api/admin/users/:auth0Sub/tier` - Update subscription tier - `PATCH /api/admin/users/:auth0Sub/deactivate` - Deactivate user - `PATCH /api/admin/users/:auth0Sub/reactivate` - Reactivate user - `PATCH /api/admin/users/:auth0Sub/profile` - Update user profile - `PATCH /api/admin/users/:auth0Sub/promote` - Promote to admin - `DELETE /api/admin/users/:auth0Sub` - Hard delete user (GDPR) **User Vehicles Endpoint:** ``` GET /api/admin/users/:auth0Sub/vehicles ``` Returns minimal vehicle data for privacy (Year/Make/Model only): ```json { "vehicles": [ { "year": 2022, "make": "Toyota", "model": "Camry" }, { "year": 2020, "make": "Honda", "model": "Civic" } ] } ``` ### Admin Management APIs Provides: - `GET /api/admin/admins` - List all admins - `POST /api/admin/admins` - Add admin - `PATCH /api/admin/admins/:auth0Sub/revoke` - Revoke admin - `PATCH /api/admin/admins/:auth0Sub/reinstate` - Reinstate admin - `GET /api/admin/audit-logs` - View audit trail ### Phase 3: Platform Catalog CRUD (COMPLETED) Provides complete CRUD operations for platform vehicle catalog data: **Makes:** - `GET /api/admin/catalog/makes` - List all makes - `POST /api/admin/catalog/makes` - Create new make - `PUT /api/admin/catalog/makes/:makeId` - Update make - `DELETE /api/admin/catalog/makes/:makeId` - Delete make **Models:** - `GET /api/admin/catalog/makes/:makeId/models` - List models for a make - `POST /api/admin/catalog/models` - Create new model - `PUT /api/admin/catalog/models/:modelId` - Update model - `DELETE /api/admin/catalog/models/:modelId` - Delete model **Years:** - `GET /api/admin/catalog/models/:modelId/years` - List years for a model - `POST /api/admin/catalog/years` - Create new year - `PUT /api/admin/catalog/years/:yearId` - Update year - `DELETE /api/admin/catalog/years/:yearId` - Delete year **Trims:** - `GET /api/admin/catalog/years/:yearId/trims` - List trims for a year - `POST /api/admin/catalog/trims` - Create new trim - `PUT /api/admin/catalog/trims/:trimId` - Update trim - `DELETE /api/admin/catalog/trims/:trimId` - Delete trim **Engines:** - `GET /api/admin/catalog/trims/:trimId/engines` - List engines for a trim - `POST /api/admin/catalog/engines` - Create new engine - `PUT /api/admin/catalog/engines/:engineId` - Update engine - `DELETE /api/admin/catalog/engines/:engineId` - Delete engine **Change Logs:** - `GET /api/admin/catalog/change-logs?limit=100&offset=0` - Retrieve platform catalog change history **Features:** - All mutations wrapped in database transactions - Automatic cache invalidation (platform:* keys) - Complete audit trail in platform_change_log table - Referential integrity validation (prevents orphan deletions) - requireAdmin guard on all endpoints ### Phase 4: Station Oversight Provides: - `GET /api/admin/stations` - List all stations globally with pagination and search - `POST /api/admin/stations` - Create new station - `PUT /api/admin/stations/:stationId` - Update station details - `DELETE /api/admin/stations/:stationId` - Delete station (soft delete by default, ?force=true for hard delete) - `GET /api/admin/users/:userId/stations` - List user's saved stations - `DELETE /api/admin/users/:userId/stations/:stationId` - Remove user's saved station (soft delete by default, ?force=true for hard delete) All station mutations invalidate related Redis caches and log audit trails. ## Extending the Feature ### Adding a new admin endpoint 1. Add handler method to `AdminController` 2. Register route in `admin.routes.ts` with `app.requireAdmin` guard 3. Add service method if business logic needed 4. Add repository method for database operations Example: ```typescript // In admin.routes.ts fastify.get('/admin/users', { preHandler: [fastify.requireAdmin] }, adminController.getUsers.bind(adminController)); // In AdminController async getUsers(request: FastifyRequest, reply: FastifyReply) { const actorId = request.userContext?.userId; const users = await this.adminService.getAllUsers(); return reply.code(200).send(users); } // Audit logging await this.adminService.logAuditAction(actorId, 'VIEW', null, 'users'); ``` ## Security Considerations 1. **Admin Guard**: All admin endpoints require `preHandler: [fastify.requireAdmin]` 2. **Parameterized Queries**: All database operations use parameterized queries (no SQL concatenation) 3. **Audit Logging**: All sensitive actions logged with actor, target, action, and context 4. **Last Admin Protection**: Cannot revoke the last active admin 5. **Soft Deletes**: Admins are soft-deleted (revoked_at), never hard-deleted ## Testing ### Unit tests (no database) ```bash npm test -- features/admin/tests/unit ``` Tests: - Admin guard authorization logic - Admin service business rules - Repository error handling ### Integration tests (with database) ```bash npm test -- features/admin/tests/integration ``` Tests: - Full API endpoints - Database persistence - Audit logging - Admin guard in request context ## Migrations Run migrations during container startup: ```bash docker compose exec mvp-backend npm run migrate ``` Initial seed: First admin user is seeded in migration with: - `auth0_sub`: `system|bootstrap` - `email`: `admin@motovaultpro.com` - `role`: `admin`