Files
carmanagement/api-routes.md
T
Administrator 65394f6436 project design
2026-04-30 18:28:05 +00:00

499 lines
24 KiB
Markdown

# API Routes Inventory — RentFlow (Complete)
Base URL: `https://api.rentflow.com/api/v1`
## Middleware Legend
- 🔒 `requireCompanyAuth` — valid Clerk JWT (Employee)
- 🏢 `requireTenant` — attaches `req.company` + `req.companyId` + `req.employee`
- 💳 `requireSubscription` — blocks SUSPENDED/PENDING companies
- 🎫 `requireRenterAuth` — valid Renter JWT
- 🔑 `requireApiKey` — company public API key in `x-api-key` header
- 👑 `requireAdmin` — RentFlow super-admin role
> **Tenant isolation rule:** Every 🏢 route must use `where: { companyId: req.companyId }` in every query.
---
## Auth — Company Employees
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/auth/company/signup` | — | Create Clerk user + Company + AmanPay/PayPal customer |
| POST | `/auth/company/verify-email` | — | Verify email token |
*(Clerk handles login/logout/session refresh on the frontend)*
---
## Auth — Renters
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/auth/renter/signup` | — | Create renter account |
| POST | `/auth/renter/login` | — | Email + password → JWT |
| POST | `/auth/renter/logout` | 🎫 | Invalidate token |
| POST | `/auth/renter/verify-email` | — | Email verification token |
| POST | `/auth/renter/forgot-password` | — | Send reset email |
| POST | `/auth/renter/reset-password` | — | Reset with token |
| GET | `/auth/renter/me` | 🎫 | Get renter profile |
| PATCH | `/auth/renter/me` | 🎫 | Update profile (name, phone, locale, currency) |
| POST | `/auth/renter/me/fcm-token` | 🎫 | Register FCM push token |
---
## Subscriptions (AmanPay/PayPal subscription — RentFlow collects)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/subscriptions/plans` | — | List plans + prices (public) |
| GET | `/subscriptions/me` | 🔒🏢 | Current subscription |
| POST | `/subscriptions/checkout` | 🔒🏢 | Create AmanPay/PayPal Checkout session |
| POST | `/subscriptions/portal` | 🔒🏢 | Open AmanPay/PayPal Customer Portal |
| GET | `/subscriptions/invoices` | 🔒🏢💳 | Invoice history |
| POST | `/subscriptions/webhook` | — (sig) | AmanPay/PayPal subscription webhook |
---
## Companies
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/companies/me` | 🔒🏢 | Company profile |
| PATCH | `/companies/me` | 🔒🏢💳 | Update profile |
| GET | `/companies/me/brand` | 🔒🏢 | Brand settings |
| PATCH | `/companies/me/brand` | 🔒🏢💳 | Update branding |
| POST | `/companies/me/brand/logo` | 🔒🏢💳 | Upload logo |
| POST | `/companies/me/brand/hero` | 🔒🏢💳 | Upload hero image |
| POST | `/companies/me/brand/subdomain/check` | 🔒🏢💳 | Check subdomain availability |
| POST | `/companies/me/brand/custom-domain` | 🔒🏢💳 | Add custom domain (Pro) |
| GET | `/companies/me/brand/custom-domain/status` | 🔒🏢💳 | Domain verification status |
| DELETE | `/companies/me/brand/custom-domain` | 🔒🏢💳 | Remove custom domain |
| GET | `/companies/me/api-key` | 🔒🏢💳 | Get public API key |
| POST | `/companies/me/api-key/regenerate` | 🔒🏢💳 | Regenerate API key |
| GET | `/companies/me/stripe-connect` | 🔒🏢💳 | Connect status |
| POST | `/companies/me/stripe-connect` | 🔒🏢💳 | Start Connect OAuth |
| POST | `/companies/me/stripe-connect/webhook` | — (sig) | Connect events |
---
## Team
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/team` | 🔒🏢💳 | List employees |
| POST | `/team/invite` | 🔒🏢💳 | Invite by email |
| PATCH | `/team/:id/role` | 🔒🏢💳 | Change role |
| DELETE | `/team/:id` | 🔒🏢💳 | Remove employee |
---
## Vehicles (Company fleet — strictly isolated)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/vehicles` | 🔒🏢💳 | List `?status=&category=&published=` |
| POST | `/vehicles` | 🔒🏢💳 | Add vehicle (checks plan limit) |
| GET | `/vehicles/:id` | 🔒🏢💳 | Detail (validates companyId) |
| PATCH | `/vehicles/:id` | 🔒🏢💳 | Update |
| DELETE | `/vehicles/:id` | 🔒🏢💳 | Archive |
| POST | `/vehicles/:id/photos` | 🔒🏢💳 | Upload photos (Cloudinary) |
| DELETE | `/vehicles/:id/photos/:idx` | 🔒🏢💳 | Remove photo |
| PATCH | `/vehicles/:id/publish` | 🔒🏢💳 | Toggle published |
| GET | `/vehicles/:id/availability` | 🔒🏢💳 | `?startDate=&endDate=` |
| GET | `/vehicles/:id/reservations` | 🔒🏢💳 | Reservation history |
| GET | `/vehicles/:id/maintenance` | 🔒🏢💳 | Maintenance log |
| POST | `/vehicles/:id/maintenance` | 🔒🏢💳 | Add maintenance entry |
---
## Offers (Company promotional offers)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/offers` | 🔒🏢💳 | List all offers `?active=&public=` |
| POST | `/offers` | 🔒🏢💳 | Create offer |
| GET | `/offers/:id` | 🔒🏢💳 | Offer detail |
| PATCH | `/offers/:id` | 🔒🏢💳 | Update offer |
| DELETE | `/offers/:id` | 🔒🏢💳 | Delete offer |
| POST | `/offers/:id/activate` | 🔒🏢💳 | Activate offer |
| POST | `/offers/:id/deactivate` | 🔒🏢💳 | Deactivate offer |
| POST | `/offers/:id/feature` | 🔒🏢💳 | Toggle featured (plan-gated) |
| GET | `/offers/:id/stats` | 🔒🏢💳 | Redemption stats, revenue impact |
---
## Reservations (Company view — includes all sources)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/reservations` | 🔒🏢💳 | List `?status=&vehicleId=&source=&startDate=&endDate=` |
| POST | `/reservations` | 🔒🏢💳 | Create (dashboard) |
| GET | `/reservations/:id` | 🔒🏢💳 | Detail |
| PATCH | `/reservations/:id` | 🔒🏢💳 | Update |
| POST | `/reservations/:id/confirm` | 🔒🏢💳 | Confirm + charge |
| POST | `/reservations/:id/checkin` | 🔒🏢💳 | Check in `{ mileage }` |
| POST | `/reservations/:id/checkout` | 🔒🏢💳 | Check out + complete `{ mileage }` |
| POST | `/reservations/:id/cancel` | 🔒🏢💳 | Cancel `{ reason }` |
| POST | `/reservations/:id/no-show` | 🔒🏢💳 | Mark no-show |
| POST | `/reservations/:id/reply-review` | 🔒🏢💳 | Reply to renter review |
---
## Customers (Company CRM)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/customers` | 🔒🏢💳 | List `?q=&flagged=` |
| POST | `/customers` | 🔒🏢💳 | Create |
| GET | `/customers/:id` | 🔒🏢💳 | Detail + reservation history |
| PATCH | `/customers/:id` | 🔒🏢💳 | Update |
| POST | `/customers/:id/flag` | 🔒🏢💳 | Flag `{ reason }` |
| DELETE | `/customers/:id/flag` | 🔒🏢💳 | Remove flag |
---
## Payments (AmanPay/PayPal rental — rental revenue)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/payments` | 🔒🏢💳 | List payments |
| GET | `/payments/:id` | 🔒🏢💳 | Payment detail |
| POST | `/payments/:id/refund` | 🔒🏢💳 | Issue refund |
| POST | `/payments/webhook` | — (sig) | AmanPay/PayPal rental webhook |
---
## Analytics
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/analytics/summary` | 🔒🏢💳 | KPIs `?period=7d|30d|90d` |
| GET | `/analytics/revenue` | 🔒🏢💳 | Revenue time series |
| GET | `/analytics/vehicles` | 🔒🏢💳 | Per-vehicle performance |
| GET | `/analytics/utilization` | 🔒🏢💳 | Fleet utilization |
| GET | `/analytics/offers` | 🔒🏢💳 | Offer performance + redemptions |
| GET | `/analytics/sources` | 🔒🏢💳 | Booking source breakdown |
---
## Notifications — Company
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/notifications/company` | 🔒🏢💳 | In-app notification log `?unread=true` |
| POST | `/notifications/company/:id/read` | 🔒🏢💳 | Mark as read |
| POST | `/notifications/company/read-all` | 🔒🏢💳 | Mark all read |
| GET | `/notifications/company/preferences` | 🔒🏢💳 | Get notification preferences |
| PATCH | `/notifications/company/preferences` | 🔒🏢💳 | Update preferences per type+channel |
---
## Notifications — Renter
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/notifications/renter` | 🎫 | Renter in-app notifications |
| POST | `/notifications/renter/:id/read` | 🎫 | Mark as read |
| POST | `/notifications/renter/read-all` | 🎫 | Mark all read |
| GET | `/notifications/renter/preferences` | 🎫 | Get preferences |
| PATCH | `/notifications/renter/preferences` | 🎫 | Update preferences |
---
## Renter — Marketplace Actions
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/renter/reservations` | 🎫 | All reservations (cross-company) |
| GET | `/renter/reservations/:id` | 🎫 | Reservation detail |
| POST | `/renter/reservations/:id/cancel` | 🎫 | Cancel `{ reason }` |
| GET | `/renter/saved-companies` | 🎫 | Saved companies |
| POST | `/renter/saved-companies/:slug` | 🎫 | Save company |
| DELETE | `/renter/saved-companies/:slug` | 🎫 | Unsave company |
| POST | `/renter/reviews` | 🎫 | Submit review (completed reservation only) |
| GET | `/renter/reviews` | 🎫 | Renter's review history |
---
## Global Marketplace API (public, optional renter auth)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/marketplace/offers` | opt 🎫 | Featured + recent offers across all companies |
| GET | `/marketplace/companies` | opt 🎫 | Company list `?city=&rating=&hasOffer=` |
| GET | `/marketplace/search` | opt 🎫 | Search vehicles `?city=&startDate=&endDate=&category=&maxPrice=` |
| GET | `/marketplace/[slug]` | opt 🎫 | Company marketplace profile |
| GET | `/marketplace/[slug]/vehicles` | opt 🎫 | Published vehicles (no internal fields) |
| GET | `/marketplace/[slug]/offers` | opt 🎫 | Active public offers |
| POST | `/marketplace/[slug]/book` | opt 🎫 | Book (renter auth preferred, guest allowed) |
| GET | `/marketplace/[slug]/reviews` | opt 🎫 | Company reviews |
| POST | `/marketplace/offers/:code/validate` | opt 🎫 | Validate promo code |
---
## Company Public Site API (slug-resolved, no user auth)
> Used by SSR pages on `{slug}.rentflow.com`. Never subscription-gated.
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/site/:slug/brand` | 🔑 | Branding for SSR |
| GET | `/site/:slug/vehicles` | 🔑 | Published vehicles |
| GET | `/site/:slug/vehicles/:id` | 🔑 | Vehicle detail + availability |
| GET | `/site/:slug/offers` | 🔑 | Active offers |
| POST | `/site/:slug/availability` | 🔑 | Date range availability check |
| POST | `/site/:slug/book` | 🔑 | Create booking + payment |
| POST | `/site/:slug/book/validate-code` | 🔑 | Validate promo code |
| GET | `/site/:slug/booking/:id` | 🔑 | Booking status (confirmation page) |
| POST | `/site/:slug/contact` | 🔑 | Contact form → email to company |
---
## Admin (RentFlow internal)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/admin/companies` | 👑 | All companies |
| GET | `/admin/companies/:id` | 👑 | Company detail + subscription |
| PATCH | `/admin/companies/:id/status` | 👑 | Force status |
| GET | `/admin/offers/featured` | 👑 | All featured offers |
| GET | `/admin/metrics` | 👑 | Platform MRR, churn, signups |
| GET | `/admin/notifications/stats` | 👑 | Delivery rates per channel |
---
## Standard Response Formats
```json
// Success
{ "data": { ... } }
// Paginated
{ "data": [...], "total": 47, "page": 1, "pageSize": 20, "totalPages": 3 }
// Error
{ "error": "vehicle_not_found", "message": "Vehicle not found or access denied", "statusCode": 404 }
// Subscription error
{ "error": "subscription_suspended", "message": "...", "statusCode": 402, "billingUrl": "https://..." }
```
## Common Query Params
`page`, `pageSize` (max 100), `sortBy`, `sortOrder` (asc|desc), `q` (search)
---
## Payment Routes — AmanPay + PayPal
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/payments/amanpay-webhook` | — (HMAC sig) | AmanPay event webhook (subscriptions + rentals) |
| POST | `/payments/paypal/create-order` | 🔒🏢 or 🎫 | Create PayPal order (subscription or rental) |
| POST | `/payments/paypal/capture` | 🔒🏢 or 🎫 | Capture PayPal order after approval |
| POST | `/payments/paypal/refund` | 🔒🏢💳 | Refund PayPal capture |
| GET | `/payments` | 🔒🏢💳 | Payment history (AmanPay + PayPal combined) |
| GET | `/payments/:id` | 🔒🏢💳 | Payment detail |
| POST | `/payments/:id/refund` | 🔒🏢💳 | Refund (AmanPay or PayPal auto-detected) |
---
## Documents — Contracts & Invoices (On-Demand PDF Generation)
> **Design rule:** PDFs are NEVER stored. Every request hits the DB, assembles data, renders PDF via `@react-pdf/renderer`, and streams the result. Reference numbers (`contractNumber`, `invoiceNumber`) ARE stored in the DB and assigned once via atomic transaction.
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/documents/reservations/:id/contract` | 🔒🏢💳 | Generate + stream contract PDF. `?download=true` forces file download vs inline view. |
| GET | `/documents/reservations/:id/invoice` | 🔒🏢💳 | Generate + stream invoice PDF. |
| POST | `/documents/reservations/:id/send` | 🔒🏢💳 | Generate + email PDF(s) as attachment. Body: `{ type: "contract"|"invoice"|"both", email?: string }` |
| GET | `/documents/settings` | 🔒🏢💳 | Get company's contract settings (terms, prefixes, tax config) |
| PATCH | `/documents/settings` | 🔒🏢💳 | Update contract settings. Sequence counters are protected from API reset. |
| GET | `/documents/settings/preview-contract` | 🔒🏢💳 | Preview contract PDF with sample data (for settings page preview) |
| GET | `/documents/settings/preview-invoice` | 🔒🏢💳 | Preview invoice PDF with sample data |
| GET | `/renter/reservations/:id/contract` | 🎫 | Renter downloads their own contract (renterId must match) |
| GET | `/renter/reservations/:id/invoice` | 🎫 | Renter downloads their own invoice |
---
## Damage Inspections
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/reservations/:id/inspections` | 🔒🏢💳 | Create check-in or check-out inspection (with damage points) |
| GET | `/reservations/:id/inspections` | 🔒🏢💳 | Get both inspections (checkin + checkout) |
| GET | `/reservations/:id/inspections/checkin` | 🔒🏢💳 | Check-in inspection detail |
| GET | `/reservations/:id/inspections/checkout` | 🔒🏢💳 | Check-out inspection detail |
---
## Billing (per-reservation line items)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/reservations/:id/billing` | 🔒🏢💳 | Get full itemized billing breakdown (JSON — for invoice preview) |
| PATCH | `/reservations/:id/billing` | 🔒🏢💳 | Add damage charges and extras to reservation |
---
## Accounting Reports
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/accounting/settings` | 🔒🏢💳 | Get company accounting settings |
| PATCH | `/accounting/settings` | 🔒🏢💳 | Update accounting settings (period, accountant, taxes, fuel policy) |
| GET | `/accounting/report` | 🔒🏢💳 | Get accounting report as JSON `?period=MONTHLY&from=&to=` |
| GET | `/accounting/report/pdf` | 🔒🏢💳 | Stream accounting report PDF |
| GET | `/accounting/report/csv` | 🔒🏢💳 | Stream CSV file |
| POST | `/accounting/report/send` | 🔒🏢💳 | Email report to accountant `{ period, from, to, format }` |
| GET | `/accounting/report/periods` | 🔒🏢💳 | List available periods with labels and date ranges |
---
## Admin Panel Routes (admin.rentflow.com → api.rentflow.com/admin)
> All require admin JWT. Role hierarchy: VIEWER < FINANCE < SUPPORT < ADMIN < SUPER_ADMIN
### Admin Auth
| Method | Path | Role | Description |
|--------|------|------|-------------|
| POST | `/admin/auth/login` | — | Login `{ email, password, totpCode? }` |
| POST | `/admin/auth/logout` | VIEWER | Invalidate token |
| GET | `/admin/auth/me` | VIEWER | Current admin profile |
| PATCH | `/admin/auth/me` | VIEWER | Update name/password |
| POST | `/admin/auth/2fa/setup` | VIEWER | Generate TOTP secret + QR code |
| POST | `/admin/auth/2fa/verify` | VIEWER | Verify and enable 2FA |
### Admin User Management (SUPER_ADMIN only)
| Method | Path | Role | Description |
|--------|------|------|-------------|
| GET | `/admin/users` | SUPER_ADMIN | List admin users |
| POST | `/admin/users` | SUPER_ADMIN | Create admin user |
| PATCH | `/admin/users/:id` | SUPER_ADMIN | Edit name, role |
| POST | `/admin/users/:id/deactivate` | SUPER_ADMIN | Deactivate admin |
| POST | `/admin/users/:id/reset-password` | SUPER_ADMIN | Force password reset |
| PATCH | `/admin/users/:id/permissions` | SUPER_ADMIN | Override permissions |
### Company Management (SUPPORT+)
| Method | Path | Role | Description |
|--------|------|------|-------------|
| GET | `/admin/companies` | SUPPORT | List all companies |
| POST | `/admin/companies` | SUPPORT | Create company |
| GET | `/admin/companies/:id` | SUPPORT | Company detail |
| PATCH | `/admin/companies/:id` | SUPPORT | Edit company |
| POST | `/admin/companies/:id/suspend` | SUPPORT | Suspend `{ reason }` |
| POST | `/admin/companies/:id/reactivate` | SUPPORT | Reactivate |
| DELETE | `/admin/companies/:id` | ADMIN | Delete company |
| PATCH | `/admin/companies/:id/subscription` | SUPPORT | Override subscription |
| POST | `/admin/companies/:id/invoices/:invoiceId/mark-paid` | ADMIN | Manual mark paid |
### Company Staff Management (SUPPORT+)
| Method | Path | Role | Description |
|--------|------|------|-------------|
| GET | `/admin/companies/:id/employees` | SUPPORT | List employees |
| POST | `/admin/companies/:id/employees` | SUPPORT | Add employee |
| GET | `/admin/companies/:id/employees/:empId` | SUPPORT | Employee detail |
| PATCH | `/admin/companies/:id/employees/:empId` | SUPPORT | Edit employee |
| PATCH | `/admin/companies/:id/employees/:empId/role` | SUPPORT | Change role |
| POST | `/admin/companies/:id/employees/:empId/deactivate` | SUPPORT | Deactivate |
| POST | `/admin/companies/:id/employees/:empId/reactivate` | SUPPORT | Reactivate |
| POST | `/admin/companies/:id/employees/:empId/reset-password` | SUPPORT | Send reset |
| POST | `/admin/companies/:id/employees/:empId/impersonate` | ADMIN | Generate impersonation token |
### Renters, Metrics, Audit
| Method | Path | Role | Description |
|--------|------|------|-------------|
| GET | `/admin/renters` | SUPPORT | List renters |
| PATCH | `/admin/renters/:id` | SUPPORT | Update renter |
| POST | `/admin/renters/:id/block` | SUPPORT | Block `{ reason }` |
| POST | `/admin/renters/:id/unblock` | SUPPORT | Unblock |
| GET | `/admin/metrics` | FINANCE | Platform KPIs |
| GET | `/admin/metrics/subscriptions` | FINANCE | Plan breakdown |
| GET | `/admin/audit-logs` | ADMIN | Paginated audit log |
| GET | `/admin/audit-logs/export` | ADMIN | CSV export |
---
## Advanced Features — New Routes
### Damage Reports
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/reservations/:id/damage-reports` | 🔒🏢💳 | Get check-in + check-out damage reports |
| POST | `/reservations/:id/damage-reports` | 🔒🏢💳 | Save damage report. Body: `{ type: "CHECKIN"|"CHECKOUT", damages: DamageZone[], fuelLevel, mileage, photos[], inspectedBy, customerSignedAt, customerName }` |
| PATCH | `/reservations/:id/damage-reports/:type` | 🔒🏢💳 | Update a damage report (before finalizing) |
### Insurance Policies (Company configuration)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/insurance-policies` | 🔒🏢💳 | List company's insurance policies |
| POST | `/insurance-policies` | 🔒🏢💳 | Create policy |
| PATCH | `/insurance-policies/:id` | 🔒🏢💳 | Update policy |
| DELETE | `/insurance-policies/:id` | 🔒🏢💳 | Deactivate policy |
| GET | `/reservations/:id/insurances` | 🔒🏢💳 | Insurance selections for a reservation |
| POST | `/reservations/:id/insurances` | 🔒🏢💳 | Apply insurance(s) to reservation. Body: `{ policyIds: string[] }` |
### Additional Drivers
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/reservations/:id/additional-drivers` | 🔒🏢💳 | List additional drivers |
| POST | `/reservations/:id/additional-drivers` | 🔒🏢💳 | Add additional driver. Body: `{ firstName, lastName, driverLicense, licenseExpiry, dateOfBirth, ... }` |
| PATCH | `/reservations/:id/additional-drivers/:did` | 🔒🏢💳 | Update driver info |
| DELETE | `/reservations/:id/additional-drivers/:did` | 🔒🏢💳 | Remove additional driver |
| POST | `/reservations/:id/additional-drivers/:did/approve-license` | 🔒🏢💳 (OWNER/MANAGER) | Approve flagged license. Body: `{ decision: "APPROVE"|"DENY", note }` |
### Driver License Validation
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/customers/:id/validate-license` | 🔒🏢💳 | Validate license expiry + flag if <3 months. Returns `{ status, daysUntilExpiry, requiresApproval }` |
| POST | `/customers/:id/approve-license` | 🔒🏢💳 (OWNER/MANAGER) | Approve or deny flagged license. Body: `{ decision: "APPROVE"|"DENY", note }` |
### Pricing Rules
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/pricing-rules` | 🔒🏢💳 | List company's pricing rules |
| POST | `/pricing-rules` | 🔒🏢💳 | Create rule (age surcharge, license discount, etc.) |
| PATCH | `/pricing-rules/:id` | 🔒🏢💳 | Update rule |
| DELETE | `/pricing-rules/:id` | 🔒🏢💳 | Deactivate rule |
| POST | `/pricing-rules/preview` | 🔒🏢💳 | Preview rules applied to a hypothetical booking. Body: `{ customerId, additionalDrivers, dailyRate, totalDays }` |
### Financial Reporting (Accountant Export)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/reports/financial` | 🔒🏢💳 | Financial report. `?period=WEEK|MONTH|YEAR&startDate=&endDate=&format=JSON|CSV` |
| GET | `/reports/financial/summary` | 🔒🏢💳 | Aggregate totals only (for dashboard KPIs) |
### Admin Panel Routes
Base path: `/api/v1/admin/` — requires `requireAdminAuth` middleware (separate JWT from company auth)
| Method | Path | Role | Description |
|--------|------|------|-------------|
| POST | `/admin/auth/login` | — | Admin login |
| GET | `/admin/auth/me` | Any | Admin profile |
| GET | `/admin/companies` | Any | All companies `?q=&status=&plan=` |
| POST | `/admin/companies` | ADMIN+ | Create company |
| GET | `/admin/companies/:id` | Any | Full company detail |
| PATCH | `/admin/companies/:id` | ADMIN+ | Edit company profile |
| PATCH | `/admin/companies/:id/status` | ADMIN+ | Change status |
| PATCH | `/admin/companies/:id/plan` | ADMIN+ | Change plan (bypasses payment) |
| DELETE | `/admin/companies/:id` | SUPER_ADMIN | Hard delete |
| POST | `/admin/companies/:id/impersonate` | ADMIN+ | Get 30-min impersonation token |
| GET | `/admin/companies/:id/employees` | Any | List employees |
| POST | `/admin/companies/:id/employees` | ADMIN+ | Add employee |
| PATCH | `/admin/companies/:id/employees/:eid` | ADMIN+ | Edit employee |
| PATCH | `/admin/companies/:id/employees/:eid/role` | ADMIN+ | Change role |
| DELETE | `/admin/companies/:id/employees/:eid` | ADMIN+ | Deactivate |
| POST | `/admin/companies/:id/employees/:eid/reset-password` | ADMIN+ | Trigger reset email |
| GET | `/admin/metrics` | Any | Platform MRR, churn, signups |
| GET | `/admin/admins` | SUPER_ADMIN | List admin users |
| POST | `/admin/admins` | SUPER_ADMIN | Create admin |
| PATCH | `/admin/admins/:id/role` | SUPER_ADMIN | Change admin role |
| DELETE | `/admin/admins/:id` | SUPER_ADMIN | Deactivate admin |
| GET | `/admin/audit-log` | SUPER_ADMIN | Audit log `?adminId=&targetType=&startDate=&endDate=` |