Files
carmanagement/docs/project-design/API_REFACTOR_TASK_LIST.md
T
2026-05-21 14:18:36 -04:00

12 KiB

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:

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

  • API test runner added
  • shared error middleware added
  • shared validation helpers added
  • shared response helpers added
  • customers module extracted
  • vehicles module extracted
  • companies module extracted
  • reservations module extracted
  • marketplace module extracted
  • site module extracted
  • upload validation standardized
  • 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