refractor code,
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user