# 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`

### 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:

```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`
