Files
motovaultpro/backend/src/features/admin
2025-12-22 18:20:25 -06:00
..
2025-12-22 18:20:25 -06:00
2025-12-21 19:56:52 -06:00
2025-11-05 19:04:06 -06:00
2025-11-05 19:04:06 -06:00

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

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

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

Phase 2: Admin Management APIs

Will provide:

  • /api/admin/admins - List all admins (GET)
  • /api/admin/admins - Add admin (POST)
  • /api/admin/admins/:auth0Sub/revoke - Revoke admin (PATCH)
  • /api/admin/admins/:auth0Sub/reinstate - Reinstate admin (PATCH)
  • /api/admin/audit-logs - View audit trail (GET)

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:

// 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)

npm test -- features/admin/tests/unit

Tests:

  • Admin guard authorization logic
  • Admin service business rules
  • Repository error handling

Integration tests (with database)

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:

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