diff --git a/docs/ADMIN.md b/docs/ADMIN.md deleted file mode 100644 index 3b24847..0000000 --- a/docs/ADMIN.md +++ /dev/null @@ -1,600 +0,0 @@ -# Admin Feature Documentation - -Complete reference for the admin role management, authorization, and cross-tenant oversight capabilities in MotoVaultPro. - -## Overview - -The admin feature provides role-based access control for system administrators to manage: -- Admin user accounts (create, revoke, reinstate) -- Vehicle catalog data (makes, models, years, trims, engines) -- Gas stations and user favorites -- Complete audit trail of all admin actions - -## Architecture - -### Backend Feature Capsule - -Location: `backend/src/features/admin/` - -Structure: -``` -admin/ -├── api/ -│ ├── admin.controller.ts - HTTP handlers for admin management -│ ├── admin.routes.ts - Route registration -│ ├── admin.validation.ts - Input validation schemas -│ ├── catalog.controller.ts - Vehicle catalog handlers -│ └── stations.controller.ts - Station oversight handlers -├── domain/ -│ ├── admin.types.ts - TypeScript type definitions -│ ├── admin.service.ts - Admin user management logic -│ ├── vehicle-catalog.service.ts - Catalog CRUD logic -│ └── station-oversight.service.ts - Station management logic -├── data/ -│ └── admin.repository.ts - Database access layer -├── migrations/ -│ ├── 001_create_admin_users.sql - Admin tables and seed -│ └── 002_create_platform_change_log.sql - Catalog audit log -└── tests/ - ├── unit/ - Service and guard tests - ├── integration/ - Full API endpoint tests - └── fixtures/ - Test data -``` - -### Core Plugins - -- **auth.plugin.ts**: Enhanced with `request.userContext` containing `userId`, `email`, `isAdmin`, `adminRecord` -- **admin-guard.plugin.ts**: `fastify.requireAdmin` preHandler that checks `admin_users` table and enforces 403 on non-admins - -### Frontend Feature - -Location: `frontend/src/features/admin/` - -Structure: -``` -admin/ -├── types/admin.types.ts - TypeScript types (mirroring backend) -├── api/admin.api.ts - API client functions -├── hooks/ -│ ├── useAdminAccess.ts - Verify admin status -│ ├── useAdmins.ts - Admin user management -│ ├── useCatalog.ts - Vehicle catalog -│ └── useStationOverview.ts - Station management -├── pages/ -│ ├── AdminUsersPage.tsx - Desktop user management -│ ├── AdminCatalogPage.tsx - Desktop catalog management -│ └── AdminStationsPage.tsx - Desktop station management -├── mobile/ -│ ├── AdminUsersMobileScreen.tsx - Mobile user management -│ ├── AdminCatalogMobileScreen.tsx - Mobile catalog management -│ └── AdminStationsMobileScreen.tsx - Mobile station management -└── __tests__/ - Component and hook 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 -); -``` - -**Indexes:** -- `auth0_sub` (PRIMARY KEY) - OAuth ID from Auth0 -- `email` - For admin lookups by email -- `created_at` - For audit trails -- `revoked_at` - For active admin queries - -### 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 -); -``` - -**Actions logged:** -- CREATE - New admin or resource created -- UPDATE - Resource updated -- DELETE - Resource deleted -- REVOKE - Admin access revoked -- REINSTATE - Admin access restored -- VIEW - Data accessed (for sensitive operations) - -### platform_change_log table - -```sql -CREATE TABLE platform_change_log ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - change_type VARCHAR(50) NOT NULL, - resource_type VARCHAR(100) NOT NULL, - resource_id VARCHAR(255), - old_value JSONB, - new_value JSONB, - changed_by VARCHAR(255) NOT NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -); -``` - -**Resource types:** -- makes, models, years, trims, engines -- stations -- users - -## API Reference - -### Phase 2: Admin Management - -#### List all admins -``` -GET /api/admin/admins -Authorization: Bearer -Guard: fastify.requireAdmin - -Response (200): -{ - "total": 2, - "admins": [ - { - "auth0Sub": "auth0|admin1", - "email": "admin@motovaultpro.com", - "role": "admin", - "createdAt": "2024-01-01T00:00:00Z", - "createdBy": "system", - "revokedAt": null, - "updatedAt": "2024-01-01T00:00:00Z" - } - ] -} -``` - -#### Create admin -``` -POST /api/admin/admins -Authorization: Bearer -Guard: fastify.requireAdmin -Content-Type: application/json - -Request: -{ - "email": "newadmin@example.com", - "role": "admin" -} - -Response (201): -{ - "auth0Sub": "auth0|newadmin", - "email": "newadmin@example.com", - "role": "admin", - "createdAt": "2024-01-15T10:30:00Z", - "createdBy": "auth0|existing", - "revokedAt": null, - "updatedAt": "2024-01-15T10:30:00Z" -} - -Audit log entry: -{ - "actor_admin_id": "auth0|existing", - "target_admin_id": "auth0|newadmin", - "action": "CREATE", - "resource_type": "admin_user", - "resource_id": "newadmin@example.com", - "context": { "email": "newadmin@example.com", "role": "admin" } -} -``` - -#### Revoke admin -``` -PATCH /api/admin/admins/:auth0Sub/revoke -Authorization: Bearer -Guard: fastify.requireAdmin - -Response (200): -{ - "auth0Sub": "auth0|toadmin", - "email": "admin@motovaultpro.com", - "role": "admin", - "createdAt": "2024-01-01T00:00:00Z", - "createdBy": "system", - "revokedAt": "2024-01-15T10:35:00Z", - "updatedAt": "2024-01-15T10:35:00Z" -} - -Errors: -- 400 Bad Request - Last active admin (cannot revoke) -- 403 Forbidden - Not an admin -- 404 Not Found - Admin not found -``` - -#### Reinstate admin -``` -PATCH /api/admin/admins/:auth0Sub/reinstate -Authorization: Bearer -Guard: fastify.requireAdmin - -Response (200): -{ - "auth0Sub": "auth0|toadmin", - "email": "admin@motovaultpro.com", - "role": "admin", - "createdAt": "2024-01-01T00:00:00Z", - "createdBy": "system", - "revokedAt": null, - "updatedAt": "2024-01-15T10:40:00Z" -} -``` - -#### Audit logs -``` -GET /api/admin/audit-logs?limit=100&offset=0 -Authorization: Bearer -Guard: fastify.requireAdmin - -Response (200): -{ - "total": 150, - "logs": [ - { - "id": "550e8400-e29b-41d4-a716-446655440000", - "actor_admin_id": "auth0|admin1", - "target_admin_id": "auth0|admin2", - "action": "CREATE", - "resource_type": "admin_user", - "resource_id": "admin2@motovaultpro.com", - "context": { "email": "admin2@motovaultpro.com", "role": "admin" }, - "created_at": "2024-01-15T10:30:00Z" - } - ] -} -``` - -### Phase 3: Catalog CRUD - -All catalog endpoints follow RESTful patterns: - -``` -GET /api/admin/catalog/{resource} - List all -GET /api/admin/catalog/{parent}/{parentId}/{resource} - List by parent -POST /api/admin/catalog/{resource} - Create -PUT /api/admin/catalog/{resource}/:id - Update -DELETE /api/admin/catalog/{resource}/:id - Delete -``` - -**Resources:** makes, models, years, trims, engines - -**Example: Get all makes** -``` -GET /api/admin/catalog/makes -Guard: fastify.requireAdmin - -Response (200): -{ - "total": 42, - "makes": [ - { "id": "1", "name": "Toyota", "createdAt": "...", "updatedAt": "..." }, - { "id": "2", "name": "Honda", "createdAt": "...", "updatedAt": "..." } - ] -} -``` - -**Cache invalidation:** All mutations invalidate `platform:*` Redis keys - -**Audit trail:** All mutations recorded in `platform_change_log` with old and new values - -### Phase 4: Station Oversight - -#### List all stations -``` -GET /api/admin/stations?limit=100&offset=0&search=query -Guard: fastify.requireAdmin - -Response (200): -{ - "total": 1250, - "stations": [ - { - "id": "station-1", - "placeId": "ChIJxxx", - "name": "Shell Station Downtown", - "address": "123 Main St", - "latitude": 40.7128, - "longitude": -74.0060, - "createdAt": "...", - "deletedAt": null - } - ] -} -``` - -#### Create station -``` -POST /api/admin/stations -Guard: fastify.requireAdmin -Content-Type: application/json - -Request: -{ - "placeId": "ChIJxxx", - "name": "New Station", - "address": "456 Oak Ave", - "latitude": 40.7580, - "longitude": -73.9855 -} - -Response (201): Station object with all fields - -Cache invalidation: -- mvp:stations:* - All station caches -- mvp:stations:search:* - Search result caches -``` - -#### Delete station (soft or hard) -``` -DELETE /api/admin/stations/:stationId?force=false -Guard: fastify.requireAdmin - -Query parameters: -- force=false (default) - Soft delete (set deleted_at) -- force=true - Hard delete (permanent removal) - -Response (204 No Content) -``` - -#### User station management -``` -GET /api/admin/users/:userId/stations -Guard: fastify.requireAdmin - -Response (200): -{ - "userId": "auth0|user123", - "stations": [...] -} -``` - -## Authorization Rules - -### Admin Guard - -The `fastify.requireAdmin` preHandler enforces: - -1. **JWT validation** - User must be authenticated -2. **Admin check** - User must exist in `admin_users` table -3. **Active status** - User's `revoked_at` must be NULL -4. **Error response** - Returns 403 Forbidden with message "Admin access required" - -### Last Admin Protection - -The system maintains at least one active admin: -- Cannot revoke the last active admin (returns 400 Bad Request) -- Prevents system lockout -- Enforced in `AdminService.revokeAdmin()` - -### Audit Trail - -All admin actions logged: -- Actor admin ID (who performed action) -- Target admin ID (who was affected, if applicable) -- Action type (CREATE, UPDATE, DELETE, REVOKE, REINSTATE) -- Resource type and ID -- Context (relevant data, like old/new values) -- Timestamp - -## Security Considerations - -### Input Validation - -All inputs validated using Zod schemas: -- Email format and uniqueness -- Role enum validation -- Required field presence -- Type checking - -### Parameterized Queries - -All database operations use parameterized queries: -```typescript -// Good - Parameterized -const result = await pool.query( - 'SELECT * FROM admin_users WHERE email = $1', - [email] -); - -// Bad - SQL concatenation (never done) -const result = await pool.query( - `SELECT * FROM admin_users WHERE email = '${email}'` -); -``` - -### Transaction Support - -Catalog mutations wrapped in transactions: -```sql -BEGIN; --- INSERT/UPDATE/DELETE operations -COMMIT; -- or ROLLBACK on error -``` - -### Cache Invalidation - -Prevents stale data: -- All catalog mutations invalidate `platform:*` keys -- All station mutations invalidate `mvp:stations:*` keys -- User station mutations invalidate `mvp:stations:saved:{userId}` - -## Deployment - -### Prerequisites - -1. **Database migrations** - Run all migrations before deploying -2. **Initial admin** - First admin seeded automatically in migration -3. **Auth0 configuration** - Admin user must exist in Auth0 - -### Deployment Steps - -```bash -# 1. Build containers -make rebuild - -# 2. Run migrations (automatically on startup) -docker compose exec mvp-backend npm run migrate - -# 3. Verify admin user created -docker compose exec mvp-backend npm run verify-admin - -# 4. Check backend health -curl https://motovaultpro.com/api/health - -# 5. Verify frontend build -curl https://motovaultpro.com -``` - -### Rollback - -If issues occur: - -```bash -# Revoke problematic admin -docker compose exec mvp-backend npm run admin:revoke admin@motovaultpro.com - -# Reinstate previous admin -docker compose exec mvp-backend npm run admin:reinstate - -# Downgrade admin feature (keep data) -docker compose down -git checkout previous-version -make rebuild -make start -``` - -## Testing - -### Backend Unit Tests - -Location: `backend/src/features/admin/tests/unit/` - -```bash -npm test -- features/admin/tests/unit -``` - -Tests: -- Admin guard authorization logic -- Admin service business rules -- Repository error handling -- Last admin protection - -### Backend Integration Tests - -Location: `backend/src/features/admin/tests/integration/` - -```bash -npm test -- features/admin/tests/integration -``` - -Tests: -- Full API endpoints -- Database persistence -- Audit logging -- Admin guard in request context -- CRUD operations -- Cache invalidation -- Permission enforcement - -### Frontend Tests - -Location: `frontend/src/features/admin/__tests__/` - -```bash -docker compose exec mvp-frontend npm test -``` - -Tests: -- useAdminAccess hook (loading, admin, non-admin, error states) -- Admin page rendering -- Admin route guards -- Navigation - -### E2E Testing - -1. **Desktop workflow** - - Navigate to `/garage/settings` - - Verify "Admin Console" card visible (if admin) - - Click "User Management" - - Verify admin list loads - - Try to create new admin (if permitted) - -2. **Mobile workflow** - - Open app on mobile viewport (375px) - - Navigate to settings - - Verify admin section visible (if admin) - - Tap "Users" button - - Verify admin list loads - -## Monitoring & Troubleshooting - -### Common Issues - -**Issue: "Admin access required" (403 Forbidden)** -- Verify user in `admin_users` table -- Check `revoked_at` is NULL -- Verify JWT token valid -- Check Auth0 configuration - -**Issue: Stale catalog data** -- Verify Redis is running -- Check cache invalidation logs -- Manually flush: `redis-cli DEL 'mvp:platform:*'` - -**Issue: Audit log not recording** -- Check `admin_audit_logs` table exists -- Verify migrations ran -- Check database connection - -### Logs - -View admin-related logs: - -```bash -# Backend logs -make logs | grep -i admin - -# Check specific action -docker compose exec mvp-backend psql -U postgres -d motovaultpro \ - -c "SELECT * FROM admin_audit_logs WHERE action = 'CREATE' ORDER BY created_at DESC LIMIT 10;" - -# Check revoked admins -docker compose exec mvp-backend psql -U postgres -d motovaultpro \ - -c "SELECT email, revoked_at FROM admin_users WHERE revoked_at IS NOT NULL;" -``` - -## Next Steps - -### Planned Enhancements - -1. **Role-based permissions** - Extend from binary admin to granular roles (admin, catalog_editor, station_manager) -2. **2FA for admins** - Enhanced security with two-factor authentication -3. **Admin impersonation** - Test user issues as admin without changing password -4. **Bulk operations** - Import/export catalog data -5. **Advanced analytics** - Admin activity dashboards - -## References - -- Backend feature: `backend/src/features/admin/README.md` -- Frontend feature: `frontend/src/features/admin/` (see individual files) -- Architecture: `docs/PLATFORM-SERVICES.md` -- Testing: `docs/TESTING.md` diff --git a/docs/AUDIT.md b/docs/AUDIT.md index 72b4213..c101259 100644 --- a/docs/AUDIT.md +++ b/docs/AUDIT.md @@ -12,7 +12,7 @@ ### 1.1 High-Level Assessment -**MotoVaultPro** is an Australian automotive vehicle management platform built on a modern 5-container Docker architecture. The application demonstrates solid architectural foundations with proper authentication, modular feature design, and production-ready deployment configuration. +**MotoVaultPro** is an automotive vehicle management platform built on a modern 5-container Docker architecture. The application demonstrates solid architectural foundations with proper authentication, modular feature design, and production-ready deployment configuration. ### 1.2 Key Findings Summary diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index 56d8943..4af9023 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -10,7 +10,6 @@ | `DATABASE-SCHEMA.md` | Database table definitions | Schema changes, data modeling | | `DATABASE-MIGRATION.md` | Migration procedures | Running or writing migrations | | `VEHICLES-API.md` | Vehicles API specification | Vehicle-related API work | -| `ADMIN.md` | Admin feature documentation | Admin role management, catalog CRUD | | `TESTING.md` | Testing strategy and commands | Writing or running tests | | `E2E-TESTING.md` | End-to-end testing guide | Cypress E2E test setup | | `SECURITY.md` | Security guidelines | Security considerations | @@ -19,7 +18,6 @@ | `AUDIT.md` | Audit documentation | Security audits, compliance | | `MVP-COLOR-SCHEME.md` | Color scheme reference | UI styling decisions | | `UX-DEBUGGING.md` | UX debugging techniques | Debugging UI issues | -| `PROMPTS.md` | AI prompt templates | AI-assisted development | ## Subdirectories diff --git a/docs/PROMPTS.md b/docs/PROMPTS.md deleted file mode 100644 index 4fd21ff..0000000 --- a/docs/PROMPTS.md +++ /dev/null @@ -1,111 +0,0 @@ -*** CRITICAL ***: Never read this file. Stop and move on. - - -*** PLANNING PROMPT *** -- Prompt into a thinking model -brainstorming a detailed specification -iteratively ask me questions -comprehensive spec.md - containing requirements, architecture decisions, data models, and even a testing strategy. This spec forms the foundation for development. - -- Prompt into a thinking model -- generate a project plan -- break into bite-sized tasks and milestones - - -- generate a structured “prompt plan” file that contains a sequence of prompts for each task - - -*** ROLE *** -You are a senior software engineer specializsing in NodeJS, Typescript, front end and back end development. You will be delegating tasks to the platform-agent, feature-agent, first-frontend-agent and quality-agent when appropriate. - -*** ACTION *** -- Make no assumptions. -- Ask clarifying questions. -- Ultrathink - -*** CONTEXT *** -- This is a modern web app for managing a vehicle fleet. It has both a desktop and mobile versions of the site that both need to maintain feature parity. It's currently deployed via docker compose but in the future will be deployed via k8s. -- Read README.md CLAUDE.md and AI-INDEX.md and follow relevant instructions to understand this code repository in the context of this change. - -*** CHANGES TO IMPLEMENT *** -- Research this code base and ask iterative questions to compile a complete plan. -- We will pair troubleshoot this. Tell me what logs and things to run and I will -- There is current a Dark / Light theme option for this application -- There is logic somewhere in the code that detects the operating systems' theme and uses that. Remove this. -- Default to the - - - -*** ROLE *** -- You are a senior DevOps SRE with expert knowledge of Python, Ansible, GitHub and GitLab pipelines. - -*** ACTION *** -- Make no assumptions. -- Ask clarifying questions. -- Ultrathink -- Debug why staging and production websites dont' match even though the docker image ID's match -- Analysis needs to be done on the CI/CD pipeline - -*** CONTEXT *** -- Read README.md CLAUDE.md and AI-INDEX.md and follow relevant instructions to understand this code repository in the context of this change. -- The staging site runs on staging.motovaultpro.com and production runs on motovaultpro.com -- These sites are local so use an MCP that will work with local sites to gather a snapshot. -- Example: Staging has the correct title in About Us "Built by enthusiasts. Made for your collection." -- Exaxmple: Production has the old title in About us "Overall, our goal is to meet each individual's needs with quality, passion, and professionalism." - -*** ACTION - CHANGES TO IMPLEMENT *** -- Research this code base and ask iterative questions to compile a complete plan. -- We will pair plan this. Ask me for options for various levels of redundancy and automation - - - -*** ROLE *** -- You are a senior DBA with expert knowledge in Postgres SQL. - -*** ACTION *** -- Make no assumptions. -- Ask clarifying questions. -- Ultrathink -- You will be implementing an ETL process that takes a export of the NHTSA vPIC database in Postgres and transforming it for use in this application. - -*** CONTEXT *** -- This is a modern web app for managing a vehicle fleet. It has both a desktop and mobile versions of the site that both need to maintain feature parity. It's currently deployed via docker compose but in the future will be deployed via k8s. -- Read README.md CLAUDE.md and AI-INDEX.md and follow relevant instructions to understand this code repository in the context of this change. -- There is an existing database import process in this directory. This process works and should not be changed. -- The source database from the NHTSA vPIC dataset is located in the @vpic-source directory -- Deep research needs to be conducted on how to execute this ETL process. -- The source database is designed for VIN decoding only. -- Example VIN: 2025 Honda Civic Hybrid - 2HGFE4F88SH315466 -- Example VIN: 2023 GMC Sierra 1500 AT4x - 3GTUUFEL6PG140748 -- Example VIN: 2017 Chevrolet Corvette Z06 - 1G1YU3D64H5602799 - -*** CHANGES TO IMPLEMENT *** -- Research this code base and ask iterative questions to compile a complete plan. -- generate a project plan -- break into bite-sized tasks and milestones - - - - - -*** ROLE *** -- You are a expert frontend developer specializing in advanced techniques using Tailwind and React frameworks. - -*** ACTION *** -- Make no assumptions. -- Ask clarifying questions. -- Ultrathink -- You will be making changes to email templates of this application. - -*** CONTEXT *** -- This is a modern web app for managing a vehicle fleet. It has both a desktop and mobile versions of the site that both need to maintain feature parity. It's currently deployed via docker compose but in the future will be deployed via k8s. -- Read README.md CLAUDE.md and AI-INDEX.md and follow relevant instructions to understand this code repository in the context of this change. -- Start your research at this route https://motovaultpro.com/garage/settings/admin/email-templates -- The email templates are currently plain text. -- The templates need to be improved with colors and the company logo -- The company log should be base64 encoded in the email so end users don't need to download anything. -- The theme should match the website light theme -- A screenshot showing the colors is attached - -*** CHANGES TO IMPLEMENT *** -- Research this code base and ask iterative questions to compile a complete plan. \ No newline at end of file diff --git a/docs/changes/BULK-DELETE-ENDPOINT-DOCS.md b/docs/changes/BULK-DELETE-ENDPOINT-DOCS.md deleted file mode 100644 index 60f66b8..0000000 --- a/docs/changes/BULK-DELETE-ENDPOINT-DOCS.md +++ /dev/null @@ -1,227 +0,0 @@ -# Bulk Catalog Delete Endpoint Documentation - -## Overview -Generic bulk delete endpoint for catalog entities (makes, models, years, trims, engines) in the admin panel. - -## Endpoint -``` -DELETE /api/admin/catalog/{entity}/bulk-delete -``` - -## Path Parameters -- `entity`: Entity type - one of: `makes`, `models`, `years`, `trims`, `engines` - -## Request Body -```json -{ - "ids": [1, 2, 3, 4, 5] -} -``` - -### Validation Rules -- IDs must be an array of positive integers -- At least 1 ID required -- Maximum 100 IDs per batch -- All IDs must be valid integers (not strings or floats) - -## Response Codes -- `204 No Content`: All deletions succeeded (no response body) -- `207 Multi-Status`: Some deletions failed (includes response body with details) -- `400 Bad Request`: Invalid entity type or invalid request body -- `401 Unauthorized`: Missing or invalid authentication -- `500 Internal Server Error`: Unexpected server error - -## Response Body (207 Multi-Status only) -```json -{ - "deleted": [1, 3, 5], - "failed": [ - { - "id": 2, - "error": "Make 2 not found" - }, - { - "id": 4, - "error": "Cannot delete make with existing models" - } - ] -} -``` - -## Cascade Behavior -The endpoint uses existing single-delete methods which have the following behavior: - -### Makes -- **Blocks deletion** if models exist under the make -- Error: "Cannot delete make with existing models" -- **Solution**: Delete all dependent models first - -### Models -- **Blocks deletion** if years exist under the model -- Error: "Cannot delete model with existing years" -- **Solution**: Delete all dependent years first - -### Years -- **Blocks deletion** if trims exist under the year -- Error: "Cannot delete year with existing trims" -- **Solution**: Delete all dependent trims first - -### Trims -- **Blocks deletion** if engines exist under the trim -- Error: "Cannot delete trim with existing engines" -- **Solution**: Delete all dependent engines first - -### Engines -- **No cascade restrictions** (leaf entity in hierarchy) - -## Deletion Order for Hierarchy -To delete an entire make and all its dependencies: -1. Delete engines first -2. Delete trims -3. Delete years -4. Delete models -5. Delete make last - -## Examples - -### Example 1: Delete Multiple Engines (Success) -```bash -DELETE /api/admin/catalog/engines/bulk-delete -{ - "ids": [101, 102, 103] -} - -Response: 204 No Content -``` - -### Example 2: Delete Multiple Makes (Partial Failure) -```bash -DELETE /api/admin/catalog/makes/bulk-delete -{ - "ids": [1, 2, 3] -} - -Response: 207 Multi-Status -{ - "deleted": [3], - "failed": [ - { - "id": 1, - "error": "Cannot delete make with existing models" - }, - { - "id": 2, - "error": "Make 2 not found" - } - ] -} -``` - -### Example 3: Invalid Entity Type -```bash -DELETE /api/admin/catalog/invalid/bulk-delete -{ - "ids": [1, 2, 3] -} - -Response: 400 Bad Request -{ - "error": "Invalid entity type", - "message": "Entity must be one of: makes, models, years, trims, engines" -} -``` - -### Example 4: Invalid IDs -```bash -DELETE /api/admin/catalog/makes/bulk-delete -{ - "ids": ["abc", "def"] -} - -Response: 400 Bad Request -{ - "error": "Invalid IDs", - "message": "All IDs must be positive integers" -} -``` - -## Implementation Details - -### Files Modified -1. `/backend/src/features/admin/api/admin.routes.ts` (line 209-212) - - Added route: `DELETE /admin/catalog/:entity/bulk-delete` - - Requires admin authentication - -2. `/backend/src/features/admin/api/catalog.controller.ts` (line 542-638) - - Added method: `bulkDeleteCatalogEntity()` - - Maps entity type to appropriate delete method - - Processes deletions sequentially - - Collects successes and failures - -3. `/backend/src/features/admin/api/admin.validation.ts` (line 43-49, 57-58) - - Added `catalogEntitySchema`: Validates entity type - - Added `bulkDeleteCatalogSchema`: Validates request body - - Exported types: `CatalogEntity`, `BulkDeleteCatalogInput` - -4. `/backend/src/features/admin/domain/admin.types.ts` (line 97-103) - - Added `BulkDeleteCatalogResponse` interface - -### Continue-on-Failure Pattern -The endpoint uses a continue-on-failure pattern: -- One deletion failure does NOT stop the batch -- All deletions are attempted -- Successes and failures are tracked separately -- Final response includes both lists - -### Transaction Behavior -- Each individual deletion runs in its own transaction (via service layer) -- If one delete fails, it doesn't affect others -- No rollback of previously successful deletions - -## Testing - -### Manual Testing with cURL -```bash -# Test valid request (requires auth token) -curl -X DELETE "http://localhost/api/admin/catalog/makes/bulk-delete" \ - -H "Authorization: Bearer YOUR_TOKEN_HERE" \ - -H "Content-Type: application/json" \ - -d '{"ids": [1, 2, 3]}' - -# Test invalid entity type -curl -X DELETE "http://localhost/api/admin/catalog/invalid/bulk-delete" \ - -H "Content-Type: application/json" \ - -d '{"ids": [1, 2, 3]}' - -# Test empty IDs -curl -X DELETE "http://localhost/api/admin/catalog/makes/bulk-delete" \ - -H "Content-Type: application/json" \ - -d '{"ids": []}' -``` - -### Expected Audit Log Behavior -Each successful deletion creates a platform change log entry: -- `changeType`: "DELETE" -- `resourceType`: Entity type (makes, models, years, trims, engines) -- `resourceId`: ID of deleted entity -- `changedBy`: Actor's user ID -- `oldValue`: Entity data before deletion -- `newValue`: null - -## Security -- Endpoint requires admin authentication (via `fastify.requireAdmin`) -- Actor ID is logged for all operations -- All deletions are audited in platform_change_log table - -## Performance Considerations -- Deletions are processed sequentially (not in parallel) -- Each deletion queries the database separately -- Cache invalidation occurs after each successful deletion -- For large batches (50+ items), consider breaking into smaller batches - -## Future Enhancements -Potential improvements: -1. Add cascade delete option to automatically delete dependent entities -2. Add dry-run mode to preview what would be deleted -3. Add batch size optimization for better performance -4. Add progress tracking for long-running batches diff --git a/docs/changes/COMMUNITY-STATIONS-FEATURE.md b/docs/changes/COMMUNITY-STATIONS-FEATURE.md deleted file mode 100644 index 164113a..0000000 --- a/docs/changes/COMMUNITY-STATIONS-FEATURE.md +++ /dev/null @@ -1,339 +0,0 @@ -# Community Gas Stations Feature - Implementation Complete - -## Executive Summary - -The Community Gas Stations feature has been fully implemented as a complete backend feature capsule for MotoVaultPro. This feature allows users to submit 93 octane gas station locations that require admin approval before becoming publicly visible. The implementation follows the modular monolith architecture with self-contained feature capsules. - -## Files Created - -### Domain Layer (Business Logic) - -1. **`backend/src/features/stations/domain/community-stations.types.ts`** - - Complete TypeScript type definitions - - Interfaces for CommunityStation, submission body, review body, filters - - Supports all business requirements - -2. **`backend/src/features/stations/domain/community-stations.service.ts`** - - Complete business logic layer - - Methods: submitStation, getMySubmissions, withdrawSubmission, getApprovedStations, getApprovedNearby, getPendingReview, reviewStation - - Redis caching with 5-minute TTL for approved stations and nearby searches - - Proper error handling and validation - - User ownership checks on sensitive operations - -### Data Access Layer - -3. **`backend/src/features/stations/data/community-stations.repository.ts`** - - Repository pattern with parameterized SQL queries (no string concatenation) - - Methods: submitStation, getStationById, getUserSubmissions, getApprovedStations, getNearbyApprovedStations, getPendingStations, getAllStationsWithFilters, reviewStation, deleteStation - - Proper row mapping to domain types - - All queries use prepared statements for security - -### API Layer - -4. **`backend/src/features/stations/api/community-stations.controller.ts`** - - Complete HTTP request handler class - - Methods for all user and admin endpoints - - Proper error handling with meaningful error codes - - Request validation delegation to schemas - - Audit logging for admin actions - -5. **`backend/src/features/stations/api/community-stations.validation.ts`** - - Zod validation schemas for all requests - - SubmitCommunityStationSchema, ReviewStationSchema, FiltersSchema, NearbySchema - - Type-safe input validation - - Clear error messages for validation failures - -6. **`backend/src/features/stations/api/community-stations.routes.ts`** - - Fastify plugin for route registration - - User routes: POST /api/stations/community, GET /api/stations/community/mine, DELETE /api/stations/community/:id, GET /api/stations/community/approved, POST /api/stations/community/nearby - - Admin routes integrated into admin.routes.ts - - Proper authentication and authorization guards - -### Testing - -7. **`backend/src/features/stations/tests/unit/community-stations.service.test.ts`** - - 40+ test cases covering service layer - - Tests for all service methods - - Cache invalidation testing - - Error condition testing - - User ownership validation tests - -8. **`backend/src/features/stations/tests/integration/community-stations.api.test.ts`** - - Integration tests for complete API workflows - - Tests for HTTP endpoints - - Database interaction verification - - Authentication and authorization tests - - Error response validation - -### Documentation - -9. **`backend/src/features/stations/COMMUNITY-STATIONS.md`** - - Complete feature documentation - - API endpoint specifications with examples - - Database schema documentation - - Validation rules - - Caching strategy - - Error codes - - Development notes - -## Integration Points - -### App Registration -- **File**: `backend/src/app.ts` -- **Changes**: Added import and registration of communityStationsRoutes -- **Status**: Complete - -### Admin Routes Integration -- **File**: `backend/src/features/admin/api/admin.routes.ts` -- **Changes**: - - Added CommunityStationsController import - - Instantiated controller in route handler - - Added 3 admin endpoints for community station management - - Integrated into Phase 5 of admin operations -- **Status**: Complete - -### Stations Feature Index -- **File**: `backend/src/features/stations/index.ts` -- **Changes**: - - Exported CommunityStationsService - - Exported all community station types - - Exported route definitions -- **Status**: Complete - -### Database -- **File**: `backend/src/features/stations/migrations/004_create_community_stations.sql` -- **Status**: Already exists, no changes needed -- **Includes**: - - community_stations table with all required columns - - Indexes for common queries - - Trigger for updated_at timestamp - -## API Endpoints Implemented - -### User Endpoints (JWT Required) - -| Method | Path | Purpose | -|--------|------|---------| -| POST | /api/stations/community | Submit new station | -| GET | /api/stations/community/mine | Get user's submissions | -| DELETE | /api/stations/community/:id | Withdraw pending submission | -| GET | /api/stations/community/approved | List approved stations | -| POST | /api/stations/community/nearby | Find nearby approved stations | - -### Admin Endpoints (Admin Role Required) - -| Method | Path | Purpose | -|--------|------|---------| -| GET | /api/admin/community-stations | List all submissions with filters | -| GET | /api/admin/community-stations/pending | Get pending review queue | -| PATCH | /api/admin/community-stations/:id/review | Approve or reject submission | - -## Key Features - -- **User Submission**: Users can submit gas station locations with optional fuel details -- **Admin Approval Workflow**: Submissions start as "pending" and require admin review -- **Public Listing**: Approved stations are visible to all authenticated users -- **Location Search**: Find approved stations near specific coordinates -- **User Withdrawal**: Users can withdraw their own pending submissions -- **Audit Logging**: All admin actions are logged with context -- **Caching**: Redis caching for approved stations and location-based searches -- **Validation**: Comprehensive input validation using Zod -- **Error Handling**: Meaningful error messages and proper HTTP status codes -- **User Ownership**: All user operations validate ownership of their submissions -- **Type Safety**: Full TypeScript support with strict typing - -## Quality Metrics - -### Type Safety -- ✅ Zero TypeScript errors -- ✅ Strict type checking enabled -- ✅ Full type definitions for all features - -### Linting -- ✅ No errors from new code -- ✅ Follows existing code style -- ✅ ESLint compliant - -### Testing -- ✅ Unit tests for service layer (40+ tests) -- ✅ Integration tests for API endpoints -- ✅ Error condition coverage -- ✅ Authorization/authentication testing - -### Documentation -- ✅ Feature documentation complete -- ✅ API specifications with examples -- ✅ Database schema documented -- ✅ Validation rules documented -- ✅ Development notes included - -## Architecture Compliance - -### Modular Monolith Pattern -- ✅ Feature fully contained in `backend/src/features/stations/` -- ✅ Repository pattern for data access -- ✅ Service layer for business logic -- ✅ Controller layer for HTTP handling -- ✅ No direct database access from controllers -- ✅ No business logic in controllers - -### Security -- ✅ JWT authentication required for all user endpoints -- ✅ Admin role required for admin endpoints -- ✅ User ownership validation on sensitive operations -- ✅ Parameterized SQL queries (no string concatenation) -- ✅ Input validation on all requests -- ✅ Meaningful error messages without exposing internals - -### Performance -- ✅ Redis caching for frequently accessed data -- ✅ Proper database indexes on common query fields -- ✅ Location-based search with distance calculation -- ✅ Pagination support for large result sets -- ✅ Efficient cache invalidation strategy - -## Database Indexes - -The migration creates indexes for: -- `status` - For filtering by submission status -- `latitude, longitude` - For location-based searches -- `submitted_by` - For user-specific queries -- `created_at DESC` - For sorting by submission time - -## Caching Strategy - -- **Approved Stations List**: 5-minute TTL, cache key includes pagination params -- **Nearby Stations**: 5-minute TTL, cache key includes coordinates and radius -- **Invalidation**: Caches cleared on new submissions and admin reviews -- **Pattern**: `mvp:community-stations:*` for cache keys - -## Error Handling - -| Status | Code | Use Case | -|--------|------|----------| -| 201 | Created | Successful submission | -| 204 | No Content | Successful deletion/withdrawal | -| 400 | Bad Request | Validation error or invalid operation | -| 401 | Unauthorized | Missing authentication | -| 403 | Forbidden | Missing admin role | -| 404 | Not Found | Station not found | -| 500 | Server Error | Unexpected error | - -## Next Steps - -### For Frontend Integration - -1. **User Submission Flow** - - Use `POST /api/stations/community` endpoint - - Provide validation feedback from schema errors - - Show success/error messages - -2. **View Submissions** - - Use `GET /api/stations/community/mine` with pagination - - Display station status (pending/approved/rejected) - - Show rejection reasons if applicable - - Provide withdrawal option for pending submissions - -3. **Discover Stations** - - Use `GET /api/stations/community/approved` for list view - - Use `POST /api/stations/community/nearby` for map view - - Display station details and user-added notes - -### For Admin Integration - -1. **Review Queue** - - Use `GET /api/admin/community-stations/pending` to get submissions - - Display station details and user notes - - Provide approve/reject interface - -2. **Review Submission** - - Use `PATCH /api/admin/community-stations/:id/review` - - For approval: send `{status: "approved"}` - - For rejection: send `{status: "rejected", rejectionReason: "..."}` - - Handle success/error responses - -3. **Filter Submissions** - - Use `GET /api/admin/community-stations?status=approved` etc. - - Support filtering by status and submitter - - Pagination support for large result sets - -## Testing Commands - -```bash -# Run unit tests -npm test -- features/stations/tests/unit/community-stations.service.test.ts - -# Run integration tests -npm test -- features/stations/tests/integration/community-stations.api.test.ts - -# Type check -npm run type-check - -# Lint -npm run lint - -# Build for production -npm run build -``` - -## Docker Deployment - -The feature is fully integrated into the existing Docker setup: - -```bash -# Rebuild containers after code changes -make rebuild - -# Run tests in container -make test - -# Check logs -make logs -``` - -## Feature Completeness Checklist - -- ✅ User can submit gas stations -- ✅ Submissions require admin approval -- ✅ Approved stations are publicly visible -- ✅ User can withdraw pending submissions -- ✅ User can find nearby approved stations -- ✅ Admin can review pending submissions -- ✅ Admin can approve or reject with reason -- ✅ All operations are audited -- ✅ Proper error handling -- ✅ Input validation -- ✅ User ownership validation -- ✅ Caching for performance -- ✅ Database indexes for query optimization -- ✅ Complete API documentation -- ✅ Unit and integration tests -- ✅ Type safety with TypeScript -- ✅ Follows modular monolith pattern -- ✅ Zero linting errors -- ✅ Zero type errors -- ✅ Ready for production deployment - -## File Summary - -| File | Lines | Purpose | -|------|-------|---------| -| community-stations.types.ts | 56 | Type definitions | -| community-stations.service.ts | 125 | Business logic | -| community-stations.repository.ts | 283 | Data access | -| community-stations.controller.ts | 226 | HTTP handlers | -| community-stations.validation.ts | 58 | Input schemas | -| community-stations.routes.ts | 65 | Route definitions | -| community-stations.service.test.ts | 242 | Service tests | -| community-stations.api.test.ts | 292 | Integration tests | -| COMMUNITY-STATIONS.md | 390 | Feature documentation | -| **Total** | **1,737** | **Complete feature** | - -## Handoff Status - -The feature is complete and ready for: -- ✅ Frontend team for mobile and desktop integration -- ✅ Quality Assurance for validation testing -- ✅ Production deployment with existing infrastructure - -All code has been tested, linted, type-checked, and documented according to MotoVaultPro standards. diff --git a/docs/changes/COMMUNITY-STATIONS-FILES.md b/docs/changes/COMMUNITY-STATIONS-FILES.md deleted file mode 100644 index 6af0b3b..0000000 --- a/docs/changes/COMMUNITY-STATIONS-FILES.md +++ /dev/null @@ -1,177 +0,0 @@ -# Community Gas Stations - All Files Created - -Complete list of all files created for the community gas stations feature with full mobile + desktop implementation. - -## User Features - Stations Module - -### Types (1) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/types/community-stations.types.ts` - -### API Client (1) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/api/community-stations.api.ts` - -### Hooks (2) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/hooks/useCommunityStations.ts` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/hooks/index-community.ts` - -### Components (4) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/CommunityStationCard.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/SubmitStationForm.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/CommunityStationsList.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/index-community.ts` - -### Pages & Screens (2) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/pages/CommunityStationsPage.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/mobile/CommunityStationsMobileScreen.tsx` - -### Tests (3) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/api/community-stations.api.test.ts` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/hooks/useCommunityStations.test.ts` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/components/CommunityStationCard.test.tsx` - -### Documentation (1) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/COMMUNITY-STATIONS-README.md` - -## Admin Features - Admin Module - -### Components (2) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/components/CommunityStationReviewCard.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/components/CommunityStationReviewQueue.tsx` - -### Pages & Screens (2) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/pages/AdminCommunityStationsPage.tsx` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/mobile/AdminCommunityStationsMobileScreen.tsx` - -## Documentation - -### Implementation Summary (2) -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/COMMUNITY-STATIONS-IMPLEMENTATION.md` -- `/Users/egullickson/Documents/Technology/coding/motovaultpro/COMMUNITY-STATIONS-FILES.md` (this file) - -## Total Files - -18 source files + 2 documentation files = **20 total files created** - -## File Organization - -``` -frontend/src/features/ -├── stations/ -│ ├── types/ -│ │ └── community-stations.types.ts (1 file) -│ ├── api/ -│ │ └── community-stations.api.ts (1 file) -│ ├── hooks/ -│ │ ├── useCommunityStations.ts (1 file) -│ │ └── index-community.ts (1 file) -│ ├── components/ -│ │ ├── CommunityStationCard.tsx (1 file) -│ │ ├── SubmitStationForm.tsx (1 file) -│ │ ├── CommunityStationsList.tsx (1 file) -│ │ └── index-community.ts (1 file) -│ ├── pages/ -│ │ └── CommunityStationsPage.tsx (1 file) -│ ├── mobile/ -│ │ └── CommunityStationsMobileScreen.tsx (1 file) -│ ├── __tests__/ -│ │ ├── api/ -│ │ │ └── community-stations.api.test.ts (1 file) -│ │ ├── hooks/ -│ │ │ └── useCommunityStations.test.ts (1 file) -│ │ └── components/ -│ │ └── CommunityStationCard.test.tsx (1 file) -│ └── COMMUNITY-STATIONS-README.md (1 file) -│ -└── admin/ - ├── components/ - │ ├── CommunityStationReviewCard.tsx (1 file) - │ └── CommunityStationReviewQueue.tsx (1 file) - ├── pages/ - │ └── AdminCommunityStationsPage.tsx (1 file) - └── mobile/ - └── AdminCommunityStationsMobileScreen.tsx (1 file) -``` - -## Quick Links to Key Files - -### User Interface -- Desktop: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/pages/CommunityStationsPage.tsx` -- Mobile: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/mobile/CommunityStationsMobileScreen.tsx` -- Form: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/SubmitStationForm.tsx` - -### Admin Interface -- Desktop: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/pages/AdminCommunityStationsPage.tsx` -- Mobile: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/mobile/AdminCommunityStationsMobileScreen.tsx` -- Review Card: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/components/CommunityStationReviewCard.tsx` - -### Data & API -- Types: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/types/community-stations.types.ts` -- API: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/api/community-stations.api.ts` -- Hooks: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/hooks/useCommunityStations.ts` - -### Tests -- API Tests: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/api/community-stations.api.test.ts` -- Hook Tests: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/hooks/useCommunityStations.test.ts` -- Component Tests: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/__tests__/components/CommunityStationCard.test.tsx` - -### Documentation -- Feature Guide: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/COMMUNITY-STATIONS-README.md` -- Implementation Summary: `/Users/egullickson/Documents/Technology/coding/motovaultpro/COMMUNITY-STATIONS-IMPLEMENTATION.md` - -## Features Implemented - -### User Features -- Submit 93 octane gas station with geolocation -- Browse approved community stations -- View personal submissions with status -- Browse nearby approved stations -- Withdraw pending submissions -- Full form validation - -### Admin Features -- Review pending submissions -- Approve/reject with reasons -- Bulk operations support -- Filter by status -- View statistics -- Complete audit trail - -### Quality Assurance -- TypeScript strict mode -- React Query integration -- Zod validation -- Comprehensive error handling -- Loading states -- 100% mobile + desktop parity -- Unit tests -- API mocking tests - -## Mobile + Desktop Validation - -All components tested and validated for: -- Mobile viewport (320px - 599px) -- Tablet viewport (600px - 1023px) -- Desktop viewport (1024px+) -- Touch interaction (44px+ targets) -- Keyboard navigation -- Form inputs -- Pagination -- Modal dialogs -- Tab navigation - -## Build Status - -✅ All files created successfully -✅ TypeScript compilation passes -✅ No linting errors -✅ Container builds successfully -✅ Frontend serving at https://admin.motovaultpro.com - -## Next Steps - -1. Implement backend API endpoints -2. Integrate routes into App.tsx -3. Update navigation menus -4. Run full test suite -5. Validate on mobile/desktop devices -6. Deploy and monitor diff --git a/docs/changes/COMMUNITY-STATIONS-IMPLEMENTATION.md b/docs/changes/COMMUNITY-STATIONS-IMPLEMENTATION.md deleted file mode 100644 index 84bb6c3..0000000 --- a/docs/changes/COMMUNITY-STATIONS-IMPLEMENTATION.md +++ /dev/null @@ -1,333 +0,0 @@ -# Community Gas Stations Feature - Implementation Complete - -## Overview - -Complete implementation of the community gas station feature for MotoVaultPro with full mobile + desktop parity. Users can submit 93 octane gas stations for admin approval, and admins can review submissions in a workflow. - -## Implementation Status - -All components, hooks, pages, and screens have been implemented and tested. - -## Files Created - -### Types (1 file) -1. **frontend/src/features/stations/types/community-stations.types.ts** - - CommunityStation - Main entity - - SubmitStationData - Form submission data - - ReviewDecision - Admin review decision - - CommunityStationsListResponse - Paginated list response - -### API Client (1 file) -2. **frontend/src/features/stations/api/community-stations.api.ts** - - User endpoints: submit, getMySubmissions, withdrawSubmission, getApprovedStations, getApprovedNearby - - Admin endpoints: getAllSubmissions, getPendingSubmissions, reviewStation, bulkReviewStations - -### React Query Hooks (1 file) -3. **frontend/src/features/stations/hooks/useCommunityStations.ts** - - useSubmitStation() - Submit new station - - useMySubmissions() - Fetch user submissions - - useWithdrawSubmission() - Withdraw submission - - useApprovedStations() - Fetch approved stations - - useApprovedNearbyStations() - Fetch nearby approved stations - - useAllCommunitySubmissions() - Admin: all submissions - - usePendingSubmissions() - Admin: pending submissions - - useReviewStation() - Admin: review submission - - useBulkReviewStations() - Admin: bulk review - -### User Components (3 files) -4. **frontend/src/features/stations/components/CommunityStationCard.tsx** - - Display individual community station with status, details, and actions - - Admin and user views with appropriate buttons - - Rejection reason dialog for admins - - Mobile-friendly with 44px+ touch targets - -5. **frontend/src/features/stations/components/SubmitStationForm.tsx** - - React Hook Form with Zod validation - - Geolocation integration - - Address, location, 93 octane details, price, notes - - Mobile-first responsive layout - - Loading and error states - -6. **frontend/src/features/stations/components/CommunityStationsList.tsx** - - Grid list of stations (1 col mobile, 2+ cols desktop) - - Pagination support - - Loading, error, and empty states - - Works for both user and admin views - -### User Pages (2 files) -7. **frontend/src/features/stations/pages/CommunityStationsPage.tsx** - - Desktop page with tab navigation: Browse All, My Submissions, Near Me - - Submit dialog for new stations - - Integrates map view for nearby stations - - Responsive to mobile via media queries - -8. **frontend/src/features/stations/mobile/CommunityStationsMobileScreen.tsx** - - Mobile-optimized with bottom tab navigation: Browse, Submit, My Submissions - - Full-screen submit form - - Pull-to-refresh support (structure prepared) - - Touch-friendly spacing and buttons - -### Admin Components (2 files) -9. **frontend/src/features/admin/components/CommunityStationReviewCard.tsx** - - Individual station review card for admins - - Approve/reject buttons with actions - - Rejection reason dialog - - Station details, coordinates, notes, metadata - - 44px+ touch targets - -10. **frontend/src/features/admin/components/CommunityStationReviewQueue.tsx** - - Queue of pending submissions for review - - Grid layout (1 col mobile, 2+ cols desktop) - - Pagination support - - Loading, error, and empty states - -### Admin Pages (2 files) -11. **frontend/src/features/admin/pages/AdminCommunityStationsPage.tsx** - - Desktop admin page with Pending and All submissions tabs - - Status filter dropdown for all submissions - - Review actions (approve/reject) - - Statistics dashboard - - Responsive to mobile - -12. **frontend/src/features/admin/mobile/AdminCommunityStationsMobileScreen.tsx** - - Mobile admin interface with bottom tabs - - Status filter for all submissions tab - - Admin access control - - Touch-friendly review workflow - -### Tests (3 files) -13. **frontend/src/features/stations/__tests__/components/CommunityStationCard.test.tsx** - - Rendering tests for station details - - User interaction tests - - Mobile viewport tests - - Admin/user view tests - -14. **frontend/src/features/stations/__tests__/hooks/useCommunityStations.test.ts** - - React Query hook tests - - Mutation and query tests - - Mock API responses - - Error handling tests - -15. **frontend/src/features/stations/__tests__/api/community-stations.api.test.ts** - - API client tests - - Successful and error requests - - Parameter validation - - Admin endpoint tests - -### Exports and Documentation (2 files) -16. **frontend/src/features/stations/hooks/index-community.ts** - - Export all community stations hooks - -17. **frontend/src/features/stations/components/index-community.ts** - - Export all community stations components - -18. **frontend/src/features/stations/COMMUNITY-STATIONS-README.md** - - Complete feature documentation - - API endpoints - - Hook usage examples - - Component props - - Testing instructions - - Integration guide - -## Key Features Implemented - -### User Features -- Submit new 93 octane gas stations with: - - Station name, address, city/state/zip - - Brand (optional) - - 93 octane availability and ethanol-free options - - Price per gallon (optional) - - Additional notes (optional) - - Geolocation support (use current location button) - - Form validation with Zod - -- Browse community submissions: - - All approved stations (paginated) - - Personal submissions with status - - Nearby stations (with geolocation) - - Station details with rejection reasons (if rejected) - - Withdraw pending submissions - -- View submission status: - - Pending (under review) - - Approved (publicly visible) - - Rejected (with reason) - -### Admin Features -- Review pending submissions: - - Card-based review interface - - Full station details and notes - - Approve or reject with optional reason - - Bulk operations - -- Manage submissions: - - View all submissions with filtering - - Filter by status (pending, approved, rejected) - - Quick statistics dashboard - - Pagination support - -### Mobile + Desktop Parity -- 100% feature parity between mobile and desktop -- Responsive components using MUI breakpoints -- Touch-friendly (44px+ buttons) -- Bottom tab navigation on mobile -- Modal dialogs for forms -- Optimized form inputs for mobile keyboards -- Full-screen forms on mobile - -### Quality Assurance -- TypeScript strict mode -- Zod validation -- React Query for data management -- Comprehensive error handling -- Loading states with skeletons -- Toast notifications -- Accessibility (ARIA labels) -- Unit and integration tests - -## Technical Stack - -- React 18 with TypeScript -- Material-UI (MUI) components -- React Hook Form + Zod validation -- React Query (TanStack Query) -- Axios for API calls -- Jest + React Testing Library -- Tailwind CSS for utilities - -## Mobile Responsiveness - -### Touch Targets -- All interactive elements: 44px × 44px minimum -- Button padding and spacing -- Icon button sizing -- Checkbox and form input heights - -### Responsive Breakpoints -- Mobile: 320px - 599px (1 column grid) -- Tablet: 600px - 1023px (2 column grid) -- Desktop: 1024px+ (3+ column grid) - -### Mobile Optimizations -- Full-width forms -- Bottom tab navigation -- Vertical scrolling (no horizontal) -- Large touch targets -- Appropriate keyboard types (email, tel, number) -- No hover-only interactions -- Dialog forms go full-screen - -## Backend API Requirements - -The following endpoints must be implemented in the backend: - -### User Endpoints -``` -POST /api/stations/community/submit -GET /api/stations/community/mine -DELETE /api/stations/community/:id -GET /api/stations/community/approved?page=0&limit=50 -POST /api/stations/community/nearby -``` - -### Admin Endpoints -``` -GET /api/stations/community/admin/submissions?status=&page=0&limit=50 -GET /api/stations/community/admin/pending?page=0&limit=50 -PATCH /api/stations/community/admin/:id/review -POST /api/stations/community/admin/bulk-review -``` - -## Integration Steps - -1. **Update App.tsx routing** - ```tsx - import { CommunityStationsPage } from './features/stations/pages/CommunityStationsPage'; - import { CommunityStationsMobileScreen } from './features/stations/mobile/CommunityStationsMobileScreen'; - import { AdminCommunityStationsPage } from './features/admin/pages/AdminCommunityStationsPage'; - import { AdminCommunityStationsMobileScreen } from './features/admin/mobile/AdminCommunityStationsMobileScreen'; - - // Add routes - } /> - } /> - } /> - } /> - ``` - -2. **Update navigation menus** - - Add "Community Stations" to main navigation - - Add "Community Station Reviews" to admin navigation - -3. **Backend API implementation** - - Implement all endpoints listed above - - Add community_stations table migrations - - Add approval workflow logic - - Add admin authorization checks - -4. **Testing** - ```bash - npm test -- features/stations/community - npm test -- features/admin/community - ``` - -## Files Summary - -Total Files Created: 18 - -- Types: 1 -- API: 1 -- Hooks: 1 -- User Components: 3 -- User Pages: 2 -- Admin Components: 2 -- Admin Pages: 2 -- Tests: 3 -- Exports/Documentation: 3 - -## Build Status - -✅ Frontend builds successfully -✅ No TypeScript errors -✅ No ESLint warnings -✅ All components export correctly -✅ Tests compile without errors - -## Testing Checklist - -- [ ] Run component tests: `npm test -- features/stations/community` -- [ ] Run API tests: `npm test -- features/stations/community/api` -- [ ] Run hook tests: `npm test -- features/stations/community/hooks` -- [ ] Test mobile viewport (320px width) -- [ ] Test desktop viewport (1920px width) -- [ ] Test form submission and validation -- [ ] Test admin approval workflow -- [ ] Test error states and edge cases -- [ ] Test loading states -- [ ] Test geolocation integration -- [ ] Test pagination -- [ ] Test status filtering - -## Documentation - -Comprehensive documentation included in: -- `/frontend/src/features/stations/COMMUNITY-STATIONS-README.md` - -Features documented: -- Component props and usage -- Hook usage and examples -- API endpoints -- Type definitions -- Integration guide -- Testing instructions -- Mobile considerations -- Future enhancements - -## Next Steps - -1. Implement backend API endpoints -2. Test all features in containerized environment -3. Validate mobile + desktop on physical devices -4. Add routes to navigation menus -5. Configure database migrations -6. Run full test suite -7. Deploy and monitor diff --git a/docs/changes/COMMUNITY-STATIONS-INTEGRATION-GUIDE.md b/docs/changes/COMMUNITY-STATIONS-INTEGRATION-GUIDE.md deleted file mode 100644 index 90efce8..0000000 --- a/docs/changes/COMMUNITY-STATIONS-INTEGRATION-GUIDE.md +++ /dev/null @@ -1,310 +0,0 @@ -# Community Gas Stations - Integration Guide - -Quick reference for integrating the community gas stations feature into MotoVaultPro. - -## 1. Add Routes to App.tsx - -Add these imports at the top of your main App.tsx or routing file: - -```typescript -import { CommunityStationsPage } from './features/stations/pages/CommunityStationsPage'; -import { CommunityStationsMobileScreen } from './features/stations/mobile/CommunityStationsMobileScreen'; -import { AdminCommunityStationsPage } from './features/admin/pages/AdminCommunityStationsPage'; -import { AdminCommunityStationsMobileScreen } from './features/admin/mobile/AdminCommunityStationsMobileScreen'; -``` - -Add these routes in your route configuration: - -```typescript -// User routes -} /> -} /> - -// Admin routes -} /> -} /> -``` - -## 2. Update Navigation - -### User Navigation -Add link to Community Stations: -```tsx - - Community Stations - -``` - -### Admin Navigation -Add link to Admin Community Stations: -```tsx - - Community Station Reviews - -``` - -## 3. Backend API Implementation - -### Required Endpoints - -Implement these endpoints in your backend API: - -#### User Endpoints -``` -POST /api/stations/community/submit - Body: SubmitStationData - Response: CommunityStation - -GET /api/stations/community/mine - Response: CommunityStation[] - -DELETE /api/stations/community/:id - Response: 204 No Content - -GET /api/stations/community/approved?page=0&limit=50 - Response: { stations: CommunityStation[], total: number, page: number, limit: number } - -POST /api/stations/community/nearby - Body: { latitude, longitude, radiusMeters } - Response: CommunityStation[] -``` - -#### Admin Endpoints -``` -GET /api/stations/community/admin/submissions?status=&page=0&limit=50 - Response: CommunityStationsListResponse - -GET /api/stations/community/admin/pending?page=0&limit=50 - Response: CommunityStationsListResponse - -PATCH /api/stations/community/admin/:id/review - Body: { status: 'approved' | 'rejected', rejectionReason?: string } - Response: CommunityStation - -POST /api/stations/community/admin/bulk-review - Body: { ids: string[], status: 'approved' | 'rejected', rejectionReason?: string } - Response: CommunityStation[] -``` - -### Database Schema - -The backend should have migrations for the `community_stations` table: - -```sql -CREATE TABLE community_stations ( - id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - submitted_by VARCHAR(255) NOT NULL, - name VARCHAR(200) NOT NULL, - address TEXT NOT NULL, - city VARCHAR(100), - state VARCHAR(50), - zip_code VARCHAR(20), - latitude DECIMAL(10, 8) NOT NULL, - longitude DECIMAL(11, 8) NOT NULL, - brand VARCHAR(100), - has_93_octane BOOLEAN DEFAULT true, - has_93_octane_ethanol_free BOOLEAN DEFAULT false, - price_93 DECIMAL(5, 3), - notes TEXT, - status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'rejected')), - reviewed_by VARCHAR(255), - reviewed_at TIMESTAMP WITH TIME ZONE, - rejection_reason TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -); - -CREATE INDEX idx_community_stations_status ON community_stations(status); -CREATE INDEX idx_community_stations_submitted_by ON community_stations(submitted_by); -CREATE INDEX idx_community_stations_location ON community_stations(latitude, longitude); -CREATE INDEX idx_community_stations_created_at ON community_stations(created_at DESC); -``` - -## 4. Environment Variables - -No additional environment variables required. The API client uses the existing `VITE_API_BASE_URL`. - -## 5. Testing - -### Run Component Tests -```bash -npm test -- features/stations/community -npm test -- features/admin/community -``` - -### Test Mobile Viewport -```bash -# Open DevTools and set viewport to 375x667 (mobile) -# Test on: Browse, Submit, My Submissions tabs -# Verify: Form submission, withdrawal, pagination -``` - -### Test Desktop Viewport -```bash -# Open on 1920x1080 (desktop) -# Test on: Browse All, My Submissions, Near Me tabs -# Verify: Submit dialog, status filtering, nearby stations -``` - -## 6. Manual Testing Checklist - -### User Features -- [ ] Navigate to /stations/community -- [ ] Submit new station with geolocation -- [ ] Submit station with manual coordinates -- [ ] Submit station with all optional fields -- [ ] View approved stations -- [ ] View personal submissions -- [ ] Withdraw pending submission -- [ ] View rejected submission with reason -- [ ] Browse nearby approved stations -- [ ] Test pagination -- [ ] Test form validation (missing fields) -- [ ] Test location permission denied -- [ ] Test on mobile viewport -- [ ] Test on desktop viewport -- [ ] Test tab switching - -### Admin Features -- [ ] Navigate to /admin/community-stations -- [ ] View pending submissions -- [ ] Approve submission -- [ ] Reject submission with reason -- [ ] Filter submissions by status -- [ ] View all submissions -- [ ] View approval statistics -- [ ] Test pagination -- [ ] Test on mobile viewport -- [ ] Test on desktop viewport -- [ ] Test tab switching -- [ ] Verify admin-only access - -## 7. Deployment - -### Prerequisites -1. Backend API endpoints implemented -2. Database migrations applied -3. Admin role configured in authentication -4. Test on staging environment - -### Deployment Steps -1. Merge to main branch -2. Run full test suite -3. Build and deploy frontend -4. Verify routes are accessible -5. Monitor logs for errors -6. Test on mobile and desktop - -## 8. Monitoring - -### Key Metrics -- Form submission success rate -- Approval/rejection ratio -- Pending submissions count -- Error rate on API endpoints -- Mobile vs desktop usage - -### Common Issues - -**Form submission fails** -- Check backend API endpoints are implemented -- Verify JWT authentication is working -- Check CORS settings - -**Geolocation not working** -- Check browser permissions -- Test on HTTPS only (required for geolocation) -- Verify GPS access on mobile device - -**Admin endpoints return 403** -- Verify user has admin role -- Check authentication token is valid -- Check admin authorization middleware - -**Images/photos not loading** -- Verify station photo API endpoints -- Check CloudFront/CDN cache -- Check CORS headers - -## 9. Performance Optimization - -### Implemented -- React Query caching -- Lazy loading of routes -- Code splitting -- Image optimization - -### Optional Enhancements -- Implement infinite scroll for stations list -- Add offline support with service workers -- Implement map tile caching -- Add predictive prefetching - -## 10. Security Considerations - -### Already Implemented -- JWT authentication on all endpoints -- User-scoped data isolation -- Admin role-based access control -- Form validation (Zod) -- Input sanitization via axios - -### Verify -- SQL injection prevention (parameterized queries) -- XSS prevention (React's built-in escaping) -- CSRF token validation -- Rate limiting on API endpoints -- Admin operations audit logging - -## Quick Troubleshooting - -### Components not rendering -1. Check routes are added to App.tsx -2. Verify imports are correct -3. Check browser console for errors -4. Verify React Query is initialized - -### API calls failing -1. Check backend endpoints are implemented -2. Verify base URL is correct (VITE_API_BASE_URL) -3. Check authentication token is included -4. Verify CORS headers - -### Tests failing -1. Mock API responses correctly -2. Use React Query's test utilities -3. Check for missing wait() calls -4. Verify Zod schema matches types - -### Mobile layout broken -1. Check viewport settings -2. Verify MUI breakpoints are used -3. Check responsive classes -4. Test on actual mobile device - -## Support - -For detailed documentation, see: -- `/frontend/src/features/stations/COMMUNITY-STATIONS-README.md` -- `/COMMUNITY-STATIONS-IMPLEMENTATION.md` -- `/COMMUNITY-STATIONS-FILES.md` - -## File References - -All absolute paths to files: - -### User Features -- Desktop Page: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/pages/CommunityStationsPage.tsx` -- Mobile Screen: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/mobile/CommunityStationsMobileScreen.tsx` -- Submit Form: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/SubmitStationForm.tsx` -- Station Card: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/components/CommunityStationCard.tsx` -- Hooks: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/hooks/useCommunityStations.ts` - -### Admin Features -- Desktop Page: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/pages/AdminCommunityStationsPage.tsx` -- Mobile Screen: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/mobile/AdminCommunityStationsMobileScreen.tsx` -- Review Card: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/admin/components/CommunityStationReviewCard.tsx` - -### API & Types -- API Client: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/api/community-stations.api.ts` -- Types: `/Users/egullickson/Documents/Technology/coding/motovaultpro/frontend/src/features/stations/types/community-stations.types.ts` diff --git a/docs/changes/DARK-THEME-PLAN.md b/docs/changes/DARK-THEME-PLAN.md deleted file mode 100644 index e805c46..0000000 --- a/docs/changes/DARK-THEME-PLAN.md +++ /dev/null @@ -1,448 +0,0 @@ -from pathlib import Path - -md = """# MotoVaultPro Homepage Dark Theme Update (Logo-Compatible) - -## Goal -Update the **public marketing homepage** to a **dark theme** so the **new logo (with a black background)** feels native and intentional. - -## Constraints (DO NOT VIOLATE) -- **Do not modify the logo image files** (no transparency edits, no recolors). -- The logo background **must remain dark/black**. -- Keep the existing page structure (nav → hero → welcome → about → features grid → CTA strip → footer). -- Only adjust styling/theme + minor hero layout to place the logo cleanly. - -## Source of Truth (what this doc is based on) -The current homepage markup is Tailwind-based and includes these notable class patterns: -- Root container: `min-h-screen bg-white` -- Nav: `bg-white shadow-md sticky top-0` -- Section backgrounds: `bg-white`, `bg-gray-100`, `bg-gray-50` -- Feature cards: `bg-white p-6` + `text-gray-900` + `text-gray-600` -- Footer: `bg-gray-900` -- Primary color already matches **Rosso Mugello** (primary-500 = `#7A212A`) - -This doc provides **exact class changes and snippets** to implement in the **React/Tailwind** source (not the built HTML). - ---- - -## Assets - -### Logo files (must remain unchanged) -Place these in the frontend **public** folder so they can be used without bundler imports: - -- `frontend/public/branding/motovaultpro-title.png` -- `frontend/public/branding/motovaultpro-logo-only.png` - -(If your repo structure differs, keep the same `/branding/...` URL path equivalent.) - -Usage: -- Hero: `/branding/motovaultpro-title.png` -- Nav: `/branding/motovaultpro-logo-only.png` - ---- - -## Design Tokens (from MVP color scheme) -Use these colors (hex values) directly in Tailwind arbitrary values or via Tailwind config. -- **Nero Daytona**: `#231F1C` (page base) -- **Bianco Avus**: `#F2F3F6` (primary text on dark) -- **Grigio Titanio**: `#A8B8C0` (secondary text on dark) -- **Canna Di Fucile**: `#7E8792` (muted borders/icons) -- **Rosso Mugello (Primary)**: `#7A212A` (primary CTA; already `primary-500`) - -### Quick token aliases (recommended) -If you can edit `tailwind.config.*`, add: -- `nero: "#231F1C"` -- `avus: "#F2F3F6"` -- `titanio: "#A8B8C0"` -- `canna: "#7E8792"` - -If you prefer no config changes, use arbitrary values like `bg-[#231F1C]`. - ---- - -## Implementation Plan (Step-by-step) - -### 0) Locate the homepage components -In the repo, find the marketing homepage by searching for one of these: -- `hero-carousel` -- `slick-dots` -- `MOTOVAULTPRO` -- `Thank you for your interest in MotoVaultPro` -- `What We Offer` -- `min-h-screen bg-white` -- `bg-gray-50` + `Our Features` - -Common file names in React projects: -- `LandingPage.tsx`, `HomePage.tsx`, `MarketingHome.tsx`, `PublicHome.tsx` -- Components: `HeroCarousel.tsx`, `Navbar.tsx`, `FeaturesSection.tsx` - ---- - -## 1) Root container: switch to dark base - -**Before** -```tsx -
-After - -Always show details -
- - -Notes: - -This makes all default text inherit Bianco Avus. - -Any sections that used gray text must be updated (see below). - -2) Nav: dark surface + logo-only -Nav container - -Before - -Always show details -