refractor code,

This commit is contained in:
root
2026-05-21 12:35:49 -04:00
parent e74681e810
commit f009ca10c6
158 changed files with 215801 additions and 5884 deletions
@@ -0,0 +1,458 @@
# API Refactor Task List
This document turns the current API refactor direction into a concrete task list for this repo.
Scope:
- modularize route and service structure
- strengthen validation boundaries
- add meaningful API test coverage
Non-goals:
- rewrite the API framework
- switch ORM or database
- redesign product behavior
## Current State
Main pressure points in the current API:
- large route files with mixed concerns:
- `apps/api/src/routes/reservations.ts`
- `apps/api/src/routes/site.ts`
- `apps/api/src/routes/marketplace.ts`
- `apps/api/src/routes/admin.ts`
- business logic split inconsistently between `routes/` and `services/`
- no real API test runner wired in `apps/api/package.json`
- ad hoc request parsing and response/error shaping across route files
- direct Prisma access from route handlers in many domains
## Target Structure
Target layout after refactor:
```text
apps/api/src/
modules/
customers/
customer.routes.ts
customer.schemas.ts
customer.service.ts
customer.repo.ts
customer.presenter.ts
customer.test.ts
vehicles/
companies/
reservations/
marketplace/
site/
http/
errors/
middleware/
respond/
validate/
lib/
services/
```
Rules for the target shape:
- route files parse input, call services, and return responses only
- services own business rules and transaction boundaries
- repos own Prisma access
- schemas own `params`, `query`, and `body` validation
- presenters own response DTO shaping
## Phase 1: Foundation
### 1.1 Add API test tooling
Tasks:
- add `vitest` to the repo
- add `supertest` for HTTP integration tests
- add API test scripts to:
- `apps/api/package.json`
- root `package.json`
- add a basic test config under `apps/api`
- decide on test DB bootstrap using existing Docker test stack in `docker-compose.test.yml`
Acceptance criteria:
- `npm run test --workspace @rentaldrivego/api` exists
- one smoke test can boot the Express app and hit `/health`
- one authenticated test can hit a protected route
### 1.2 Centralize HTTP errors
Tasks:
- create `apps/api/src/http/errors/`
- add app error classes:
- `AppError`
- `ValidationError`
- `NotFoundError`
- `ConflictError`
- `ForbiddenError`
- `UnauthorizedError`
- add a single Express error middleware
- register it in `apps/api/src/index.ts`
Acceptance criteria:
- route files stop hand-shaping most error JSON
- thrown app errors become consistent `{ error, message, statusCode }` responses
### 1.3 Centralize request parsing helpers
Tasks:
- create `apps/api/src/http/validate/`
- add helpers for:
- `parseBody`
- `parseQuery`
- `parseParams`
- standardize `zod` parse error mapping to `400`
Acceptance criteria:
- new/updated route files no longer call `schema.parse(req.body)` inline repeatedly
- validation failures follow one shared response shape
### 1.4 Centralize response helpers
Tasks:
- create `apps/api/src/http/respond/`
- add helpers for:
- `ok`
- `created`
- `noContent`
- use the same success envelope conventions across refactored modules
Acceptance criteria:
- refactored routes send responses through shared helpers
## Phase 2: First Safe Module Extractions
Goal:
- refactor smaller route files first to establish patterns before touching reservation flows
### 2.1 Customers module
Files in scope:
- `apps/api/src/routes/customers.ts`
- `apps/api/src/services/licenseValidationService.ts`
- customer-related Prisma access
Tasks:
- create:
- `modules/customers/customer.routes.ts`
- `modules/customers/customer.schemas.ts`
- `modules/customers/customer.service.ts`
- `modules/customers/customer.repo.ts`
- `modules/customers/customer.presenter.ts`
- move all Prisma reads/writes out of the route file
- move license image upload orchestration into the service
- standardize customer DTO output
Tests to add:
- list customers
- create customer
- update customer
- validate license
- approve license
- upload license image
Acceptance criteria:
- `routes/customers.ts` becomes a thin delegator or is replaced by module route registration
- no direct Prisma calls remain in the customer route layer
### 2.2 Vehicles module
Files in scope:
- `apps/api/src/routes/vehicles.ts`
- `apps/api/src/services/vehicleAvailabilityService.ts`
- `apps/api/src/lib/storage.ts`
Tasks:
- extract module files for vehicles
- isolate upload/photo operations from route code
- isolate availability query logic from route formatting
- create presenter functions for dashboard-facing vehicle responses
Tests to add:
- create vehicle
- update vehicle
- upload photos
- delete photo
- availability check
Acceptance criteria:
- vehicle upload and availability logic are both service-owned
### 2.3 Companies module
Files in scope:
- `apps/api/src/routes/companies.ts`
Tasks:
- extract company brand/profile subdomain flows into a module
- isolate brand asset upload logic
- separate subdomain availability checks from route code
Tests to add:
- get company profile
- update company profile
- upload logo
- upload hero image
- subdomain check
Acceptance criteria:
- no upload/storage branching remains in the route handler
## Phase 3: High-Value Reservation Refactor
This is the biggest and highest-risk slice.
### 3.1 Split reservations into sub-services
Files in scope:
- `apps/api/src/routes/reservations.ts`
- `apps/api/src/services/additionalDriverService.ts`
- `apps/api/src/services/insuranceService.ts`
- `apps/api/src/services/pricingRuleService.ts`
- `apps/api/src/services/licenseValidationService.ts`
- `apps/api/src/services/invoicePdfService.ts`
Target internal split:
- `reservation.service.ts`
- `reservation.lifecycle.service.ts`
- `reservation.pricing.service.ts`
- `reservation.insurance.service.ts`
- `reservation.additional-driver.service.ts`
- `reservation.document.service.ts`
- `reservation.inspection.service.ts`
- `reservation.presenter.ts`
- `reservation.repo.ts`
Tasks:
- extract create/update/confirm/check-in/check-out/close flows into dedicated service methods
- move `serializeReservationForDashboard` into a presenter
- move document number generation out of route code
- keep Prisma transactions in the service layer only
- remove route-local helper sprawl from `reservations.ts`
Tests to add:
- create reservation success
- create reservation conflict
- confirm reservation
- check-in reservation
- check-out reservation
- close reservation
- add additional driver requiring approval
- pricing rule application
- insurance application
Acceptance criteria:
- reservation route file becomes orchestration-only
- all state transitions are covered by integration tests
## Phase 4: Public-Surface Modules
These routes should move after internal domains are stabilized.
### 4.1 Marketplace module
Files in scope:
- `apps/api/src/routes/marketplace.ts`
Tasks:
- extract search/filter/offer validation into module files
- unify database-unavailable handling
- separate presenter logic from business logic
Tests to add:
- list cities
- search vehicles
- fetch vehicle details
- validate offer / promo path
### 4.2 Site module
Files in scope:
- `apps/api/src/routes/site.ts`
Tasks:
- extract public company site flows
- isolate booking flow for public site reservations
- unify maintenance-mode / database-unavailable behavior
Tests to add:
- fetch site brand
- fetch public vehicle list
- availability check
- create booking request
- payment-init guard paths
Acceptance criteria:
- public route handlers become small and deterministic
## Phase 5: Cross-Cutting Cleanup
### 5.1 Authentication and role boundaries
Files in scope:
- `apps/api/src/middleware/requireCompanyAuth.ts`
- `apps/api/src/middleware/requireRenterAuth.ts`
- `apps/api/src/middleware/requireAdminAuth.ts`
- `apps/api/src/middleware/requireRole.ts`
- `apps/api/src/middleware/requireTenant.ts`
- `apps/api/src/middleware/requireSubscription.ts`
Tasks:
- standardize auth failure responses
- document what request context each middleware guarantees
- remove duplicate assumptions in route files
Acceptance criteria:
- auth and permission expectations are explicit and shared
### 5.2 Upload policy standardization
Files in scope:
- `apps/api/src/routes/vehicles.ts`
- `apps/api/src/routes/companies.ts`
- `apps/api/src/routes/customers.ts`
- `apps/api/src/lib/storage.ts`
- `docker-compose.production.yml`
- `docker-compose.dev.yml`
Tasks:
- create shared upload policy helpers for image uploads
- standardize max file size, mime validation, and error responses
- centralize folder path rules for stored uploads
- keep runtime uploads out of the API source tree and out of the image filesystem
- require all uploaded files to be written to the configured storage root mounted from a Docker volume
- verify the API serves uploads from the volume-backed storage root only
- document the storage contract clearly:
- app code may generate URLs and read/write through the storage abstraction
- Docker volumes own persistence
- rebuilds and redeploys must not delete uploaded files
Acceptance criteria:
- upload endpoints share one validation policy
- uploaded files are not stored inside `apps/api/src`, `apps/api/dist`, or any other API-local runtime path
- production uploads persist in the named Docker volume mounted into the API container
- dev Docker uploads persist in the dev named Docker volume mounted into the API container
- storage behavior is environment-configured through the storage root, not hardcoded to an app-relative folder
### 5.3 Remove route-local DTO drift
Tasks:
- define presenter functions for each major domain
- stop returning raw Prisma records where API shape is intended to be stable
Acceptance criteria:
- DTO shape changes are isolated to presenters
## Testing Plan
### Priority 0: smoke coverage
Add first:
- `/health`
- authenticated customer list
- authenticated vehicle list
- reservation create
- site availability
### Priority 1: critical business flows
Add next:
- reservation state changes
- uploads
- payments init guards
- license approval paths
### Priority 2: regression coverage
Add later:
- analytics
- notifications
- admin routes
- subscriptions
### Test types
Use:
- unit tests for pure business logic
- integration tests for route + middleware + DB behavior
- a few contract-style tests for public endpoints
Avoid:
- brittle snapshots
- tests that assert Prisma internal shapes directly unless repo-level persistence behavior is the actual concern
## Suggested Execution Order
1. add test tooling and smoke tests
2. add shared error middleware and validation helpers
3. refactor customers
4. refactor vehicles
5. refactor companies
6. refactor reservations in slices
7. refactor marketplace
8. refactor site
9. refactor admin, notifications, analytics, subscriptions, payments
## Deliverables Checklist
- [x] API test runner added
- [x] shared error middleware added
- [x] shared validation helpers added
- [x] shared response helpers added
- [x] customers module extracted
- [x] vehicles module extracted
- [x] companies module extracted
- [x] reservations module extracted
- [x] marketplace module extracted
- [x] site module extracted
- [ ] upload validation standardized
- [x] auth/role middleware behavior documented
- [ ] critical booking flows covered by integration tests
## Status Update
Completed in the workspace:
- phases 1 through 5 are implemented
- the originally listed phase 9 domains are modularized, and the remaining route surface was also cleared for:
- `team`
- `offers`
- `notifications`
- `analytics`
- `subscriptions`
- `payments`
- `admin`
- `auth.*`
- `webhooks`
- `apps/api/src/routes/` has been cleared and route registration now points at module routers
- shared HTTP helpers are in place under:
- `apps/api/src/http/errors/`
- `apps/api/src/http/validate/`
- `apps/api/src/http/respond/`
- the Docker-backed API integration workflow is wired and passing
Current automated integration coverage includes:
- health
- customers
- vehicles
- reservations
- payments
- subscriptions
- notifications
- admin
Still intentionally open:
- upload policy standardization from section `5.2`
- any remaining Priority 1 integration gaps not yet covered by the current suite, especially upload and license-approval paths if they are still required as dedicated HTTP flows
## Completion Criteria
The refactor is considered successful when:
- route files are thin and mostly declarative
- business rules live in services, not route handlers
- Prisma access lives in repos or well-defined service boundaries
- request validation is explicit for `params`, `query`, and `body`
- core booking, customer, and upload flows have automated coverage
- API error and success envelopes are consistent across modules