update documentation
This commit is contained in:
+329
-431
@@ -1,498 +1,396 @@
|
||||
# API Routes Inventory — RentalDriveGo (Complete)
|
||||
# API Architecture and Route Design
|
||||
|
||||
Base URL: `https://api.RentalDriveGo.com/api/v1`
|
||||
This document explains how the API is structured today, how requests move through the stack, and what each route group is responsible for.
|
||||
|
||||
## 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` — RentalDriveGo super-admin role
|
||||
Source of truth for the runtime wiring:
|
||||
|
||||
> **Tenant isolation rule:** Every 🏢 route must use `where: { companyId: req.companyId }` in every query.
|
||||
- `apps/api/src/app.ts`
|
||||
- `apps/api/src/modules/*`
|
||||
- `apps/api/src/middleware/*`
|
||||
- `apps/api/src/swagger/openapi.ts`
|
||||
|
||||
---
|
||||
## Runtime Overview
|
||||
|
||||
## Auth — Company Employees
|
||||
The API is an Express application mounted under `/api/v1` with a few non-versioned utility endpoints:
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| POST | `/auth/company/signup` | — | Create Clerk user + Company + AmanPay/PayPal customer |
|
||||
| POST | `/auth/company/verify-email` | — | Verify email token |
|
||||
- `GET /health` returns process health.
|
||||
- `GET /docs` serves Swagger UI.
|
||||
- `GET /api/v1/openapi.json` returns the generated OpenAPI document.
|
||||
- `/storage/*` serves uploaded assets such as logos, hero images, vehicle photos, and reservation/customer documents.
|
||||
|
||||
*(Clerk handles login/logout/session refresh on the frontend)*
|
||||
The app boot sequence in `apps/api/src/app.ts` is intentionally ordered:
|
||||
|
||||
---
|
||||
1. CORS is applied first.
|
||||
2. storage guards are applied before static serving so private customer license files are never anonymously retrievable.
|
||||
3. Swagger UI is mounted before Helmet so the UI assets are not blocked by CSP.
|
||||
4. webhook routes that require raw payload handling are mounted before `express.json()`.
|
||||
5. Helmet, request logging, JSON parsing, and the module routers are mounted.
|
||||
6. the centralized error middleware converts validation, Prisma, and application errors into consistent JSON responses.
|
||||
|
||||
## Auth — Renters
|
||||
## Request Lifecycle
|
||||
|
||||
| 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 |
|
||||
Most internal company routes follow the same pattern:
|
||||
|
||||
---
|
||||
1. Express router receives the request.
|
||||
2. Zod schemas validate `req.params`, `req.query`, and `req.body` through `parseParams`, `parseQuery`, and `parseBody`.
|
||||
3. auth middleware resolves the caller identity.
|
||||
4. tenant middleware resolves the company record.
|
||||
5. subscription middleware blocks suspended or pending companies where required.
|
||||
6. role middleware enforces employee or admin permissions.
|
||||
7. the route handler calls a service function.
|
||||
8. the service applies business rules and calls a repo or Prisma directly.
|
||||
9. a presenter may normalize the payload for frontend consumption.
|
||||
10. `ok()` or `created()` wraps successful responses in `{ "data": ... }`.
|
||||
|
||||
## Subscriptions (AmanPay/PayPal subscription — RentalDriveGo collects)
|
||||
Common exceptions:
|
||||
|
||||
| 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 |
|
||||
- `GET /health` and `GET /api/v1/docs` return raw JSON, not the `{ data }` envelope.
|
||||
- webhook endpoints return minimal receipt payloads.
|
||||
- some public endpoints return graceful fallback responses if the database is unavailable.
|
||||
|
||||
---
|
||||
## Security and Access Model
|
||||
|
||||
## Companies
|
||||
There are four main access patterns.
|
||||
|
||||
| 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 |
|
||||
### Employee JWT
|
||||
|
||||
---
|
||||
`requireCompanyAuth` validates a Bearer token with `type === "employee"`, loads the employee, and attaches:
|
||||
|
||||
## Team
|
||||
- `req.employee`
|
||||
- `req.company`
|
||||
- `req.companyId`
|
||||
|
||||
| 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 |
|
||||
This is the default for dashboard/company management routes.
|
||||
|
||||
---
|
||||
### Tenant Resolution
|
||||
|
||||
## Vehicles (Company fleet — strictly isolated)
|
||||
`requireTenant` reloads the company from `req.companyId` and guarantees the tenant context exists. Company-scoped modules then query by `companyId`.
|
||||
|
||||
| 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 |
|
||||
### Subscription Guard
|
||||
|
||||
---
|
||||
`requireSubscription` blocks company routes when the company status is `PENDING` or `SUSPENDED`. Public site and marketplace routes are intentionally not behind this guard.
|
||||
|
||||
## Offers (Company promotional offers)
|
||||
### Role-Based Access Control
|
||||
|
||||
| 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 |
|
||||
Employee roles are hierarchical:
|
||||
|
||||
---
|
||||
- `OWNER`
|
||||
- `MANAGER`
|
||||
- `AGENT`
|
||||
|
||||
## Reservations (Company view — includes all sources)
|
||||
Admin roles are hierarchical:
|
||||
|
||||
| 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 |
|
||||
- `SUPER_ADMIN`
|
||||
- `ADMIN`
|
||||
- `SUPPORT`
|
||||
- `FINANCE`
|
||||
- `VIEWER`
|
||||
|
||||
---
|
||||
### Renter JWT
|
||||
|
||||
## Customers (Company CRM)
|
||||
`requireRenterAuth` validates a Bearer token with `type === "renter"` and attaches `req.renterId`.
|
||||
|
||||
| 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 |
|
||||
`optionalRenterAuth` is used on marketplace routes so public reads still work without a token.
|
||||
|
||||
---
|
||||
### API Key
|
||||
|
||||
## Payments (AmanPay/PayPal rental — rental revenue)
|
||||
`requireApiKey` accepts a company public API key in `x-api-key`. This is the low-friction integration path for public company-site style calls.
|
||||
|
||||
| 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 |
|
||||
## Implementation Pattern
|
||||
|
||||
---
|
||||
The API codebase is organized per module. The most common pattern is:
|
||||
|
||||
## Analytics
|
||||
- `*.routes.ts`: route definitions and middleware composition
|
||||
- `*.schemas.ts`: Zod input validation
|
||||
- `*.service.ts`: business rules and orchestration
|
||||
- `*.repo.ts`: Prisma access helpers
|
||||
- `*.presenter.ts`: response shaping
|
||||
|
||||
| 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 |
|
||||
The `vehicles` module is representative:
|
||||
|
||||
---
|
||||
- `vehicle.routes.ts` mounts auth, tenant, and subscription guards once for the router.
|
||||
- route handlers validate input and call service functions.
|
||||
- `vehicle.service.ts` contains business rules such as publish-state normalization and availability calculation.
|
||||
- `vehicle.repo.ts` owns the Prisma queries and enforces tenant filters in reads.
|
||||
- `vehicle.presenter.ts` shapes the response returned to clients.
|
||||
|
||||
## Notifications — Company
|
||||
Some modules split specialized workflows into additional services instead of one large file. The reservations module is the clearest example:
|
||||
|
||||
| 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 |
|
||||
- `reservation.service.ts` handles CRUD and list behavior
|
||||
- `reservation.lifecycle.service.ts` handles confirm/checkin/checkout/close/extend/cancel transitions
|
||||
- `reservation.inspection.service.ts` handles pickup/dropoff inspections
|
||||
- `reservation.additional-driver.service.ts` handles approval workflows
|
||||
- `reservation.photo.service.ts` handles pickup/dropoff photo uploads
|
||||
- `reservation.document.service.ts` generates contract and billing payloads
|
||||
|
||||
---
|
||||
## Route Groups
|
||||
|
||||
## Notifications — Renter
|
||||
The table below describes the current route groups mounted in `app.ts`.
|
||||
|
||||
| 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 |
|
||||
| Base path | Access | Purpose | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `/health` | Public | Process health | Non-versioned utility endpoint |
|
||||
| `/docs` | Public | Swagger UI | Backed by `openapi.ts` |
|
||||
| `/api/v1/openapi.json` | Public | OpenAPI JSON | Generated from Zod schemas and manual path entries |
|
||||
| `/api/v1/auth/company` | Public | Company signup | `complete-signup` and `verify-email` now return disabled errors |
|
||||
| `/api/v1/auth/employee` | Public plus employee JWT | Employee login, password reset, profile, language | Dashboard/staff authentication path |
|
||||
| `/api/v1/auth/renter` | Renter JWT for profile routes | Renter profile and push token | `signup` and `login` are currently disabled in this codebase |
|
||||
| `/api/v1/admin` | Admin JWT | Platform operations | Includes company admin, billing, subscriptions, pricing, audit, and admin-user management |
|
||||
| `/api/v1/marketplace` | Public, optional renter JWT | Marketplace discovery and reservation intake | Designed for discovery and lead capture across companies |
|
||||
| `/api/v1/site` | Public | White-label company site APIs | Drives each company-branded booking site |
|
||||
| `/api/v1/subscriptions` | Mixed | Plan listing, webhooks, subscription lifecycle | Public, webhook, and authenticated sub-routers share the same prefix |
|
||||
| `/api/v1/vehicles` | Employee JWT + tenant + subscription | Fleet management | Includes photos, status, calendar blocks, maintenance, and availability |
|
||||
| `/api/v1/reservations` | Employee JWT + tenant + subscription | Reservation operations | Central booking lifecycle for internal staff |
|
||||
| `/api/v1/team` | Employee JWT + tenant + subscription | Employee/team management | Owner-controlled invite, role, activation, removal |
|
||||
| `/api/v1/customers` | Employee JWT + tenant + subscription | Company CRM and license handling | Includes protected license-image retrieval and approval flows |
|
||||
| `/api/v1/offers` | Employee JWT + tenant + subscription | Promotional offers | Company marketing and promo codes |
|
||||
| `/api/v1/analytics` | Employee JWT + tenant + subscription | Dashboard metrics and reports | Includes summary, dashboard, source, and report routes |
|
||||
| `/api/v1/notifications` | Employee or renter JWT depending on route | Notification inbox and preferences | Separate company and renter surfaces |
|
||||
| `/api/v1/companies` | Employee JWT + tenant + subscription | Company profile and settings | Brand, domains, contract settings, insurance policies, pricing rules, accounting, API key |
|
||||
| `/api/v1/payments` | Mixed | Rental payment webhooks and company payment actions | Webhooks are public; operational routes are company-authenticated |
|
||||
| `/api/v1/reviews` | Employee JWT + tenant + subscription | Review moderation | Company-side review visibility and replies |
|
||||
| `/api/v1/complaints` | Employee JWT + tenant + subscription | Complaint handling | Internal complaint tracking |
|
||||
| `/api/v1/webhooks` | Public | External webhook receivers | Currently includes `/clerk` placeholder |
|
||||
|
||||
---
|
||||
## Functional Breakdown by Module
|
||||
|
||||
## Renter — Marketplace Actions
|
||||
### Company and employee onboarding
|
||||
|
||||
| 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 |
|
||||
- `POST /api/v1/auth/company/signup` creates the company tenant, owner employee, default subscription state, and related baseline records in one transaction.
|
||||
- The signup flow generates a unique company slug, hashes the owner password, starts a 90-day trial window, and sends account-created notifications.
|
||||
- Employee auth supports login, forgot-password, reset-password, profile read, and language updates.
|
||||
|
||||
---
|
||||
### Company profile and business configuration
|
||||
|
||||
## Global Marketplace API (public, optional renter auth)
|
||||
The `companies` module owns tenant-level settings:
|
||||
|
||||
| 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 identity
|
||||
- brand settings and asset upload
|
||||
- subdomain/custom-domain configuration
|
||||
- contract settings used by rental documents
|
||||
- insurance policies
|
||||
- pricing rules
|
||||
- accounting settings
|
||||
- public API key generation/regeneration
|
||||
|
||||
---
|
||||
This module is where most long-lived company configuration lives.
|
||||
|
||||
## Company Public Site API (slug-resolved, no user auth)
|
||||
### Fleet management
|
||||
|
||||
> Used by SSR pages on `{slug}.RentalDriveGo.com`. Never subscription-gated.
|
||||
The `vehicles` module handles:
|
||||
|
||||
| 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 |
|
||||
- CRUD for vehicles
|
||||
- publish/unpublish
|
||||
- explicit status updates
|
||||
- photo upload and deletion
|
||||
- availability checks
|
||||
- monthly vehicle calendar events
|
||||
- manual calendar blocks
|
||||
- maintenance logs
|
||||
|
||||
---
|
||||
Uploads are persisted through the storage service, then surfaced under `/storage/*`.
|
||||
|
||||
## Admin (RentalDriveGo internal)
|
||||
### Reservations and rental workflow
|
||||
|
||||
| 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 |
|
||||
The reservation aggregate is the center of the operational API.
|
||||
|
||||
---
|
||||
Important transitions:
|
||||
|
||||
## Standard Response Formats
|
||||
1. create draft reservation
|
||||
2. confirm reservation after license checks
|
||||
3. check in and move the reservation to `ACTIVE`
|
||||
4. check out and mark the reservation `COMPLETED`
|
||||
5. close the reservation operationally after post-rental tasks are done
|
||||
|
||||
The lifecycle service also handles:
|
||||
|
||||
- extensions with conflict checks
|
||||
- cancellations
|
||||
- vehicle status synchronization
|
||||
- review token generation
|
||||
- review request email dispatch on close
|
||||
|
||||
The reservations module also owns:
|
||||
|
||||
- contract and billing payload generation
|
||||
- pickup/dropoff inspections
|
||||
- additional-driver approval
|
||||
- pickup/dropoff photo upload
|
||||
|
||||
### Customer CRM and license compliance
|
||||
|
||||
Customers are company-scoped CRM records, even when a renter identity also exists. The `customers` module supports:
|
||||
|
||||
- customer CRUD
|
||||
- flag/unflag flows
|
||||
- license image upload and protected retrieval
|
||||
- license validation and manager approval
|
||||
|
||||
This is intentionally separate from renter identity because one renter may interact with multiple companies while each company still needs its own operational customer record.
|
||||
|
||||
### Marketplace and public site
|
||||
|
||||
The public surface is split in two modules on purpose.
|
||||
|
||||
`marketplace` is the cross-company discovery layer:
|
||||
|
||||
- featured/public offers
|
||||
- marketplace cities
|
||||
- listed companies
|
||||
- vehicle search
|
||||
- marketplace reservation intake
|
||||
- review submission by token
|
||||
- company public pages under `/:slug`
|
||||
|
||||
`site` is the white-label company booking API:
|
||||
|
||||
- company brand payload
|
||||
- published vehicle catalog
|
||||
- booking options
|
||||
- date-range availability
|
||||
- promo validation
|
||||
- booking creation
|
||||
- payment initialization
|
||||
- booking lookup
|
||||
- company contact form
|
||||
|
||||
Both modules deliberately include graceful degradation paths when the database is unavailable so public pages can fail softer than internal operations.
|
||||
|
||||
### Payments
|
||||
|
||||
Rental payments are company-side operational payments, distinct from SaaS subscription billing.
|
||||
|
||||
The `payments` module handles:
|
||||
|
||||
- AmanPay and PayPal rental webhooks
|
||||
- listing payments by company or reservation
|
||||
- initializing online charges
|
||||
- capturing PayPal orders
|
||||
- recording manual payments
|
||||
- refunding successful online payments
|
||||
|
||||
Payment success updates both the payment record and the reservation paid amount.
|
||||
|
||||
### Subscriptions and SaaS billing
|
||||
|
||||
The `subscriptions` module owns the platform billing lifecycle:
|
||||
|
||||
- public plan/provider/feature listing
|
||||
- company subscription read endpoints
|
||||
- trial start
|
||||
- checkout
|
||||
- plan changes
|
||||
- cancellation/resume/reactivation
|
||||
- provider webhooks
|
||||
- admin overrides
|
||||
|
||||
It also exposes background-job style functions for:
|
||||
|
||||
- trial expiration
|
||||
- payment-pending timeout
|
||||
- past-due timeout
|
||||
- suspension timeout
|
||||
- period-end cancellation
|
||||
|
||||
### Notifications
|
||||
|
||||
Notifications are multi-channel and multi-audience:
|
||||
|
||||
- company inbox
|
||||
- renter inbox
|
||||
- unread counts
|
||||
- preferences per type and channel
|
||||
- notification history
|
||||
|
||||
Templates and preference records live in the database; delivery orchestration lives in `services/notificationService.ts`.
|
||||
|
||||
### Admin surface
|
||||
|
||||
The admin router is broad because it covers platform operations across multiple domains:
|
||||
|
||||
- admin authentication and 2FA
|
||||
- company listing, inspection, status changes, deletion, impersonation
|
||||
- renter blocking/unblocking
|
||||
- platform metrics
|
||||
- notification inspection
|
||||
- audit log access
|
||||
- admin-user and permission management
|
||||
- billing account and billing invoice operations
|
||||
- pricing config, plan features, and promotions
|
||||
- subscription overrides and extensions
|
||||
- marketplace homepage configuration
|
||||
|
||||
This is the only route group allowed to work across tenants.
|
||||
|
||||
## Important Workflow Examples
|
||||
|
||||
### 1. Company signup
|
||||
|
||||
`POST /api/v1/auth/company/signup`
|
||||
|
||||
- validates the payload with Zod
|
||||
- checks for duplicate company and owner email addresses
|
||||
- generates a unique slug
|
||||
- hashes the owner password
|
||||
- creates the tenant, owner employee, and initial subscription state in one transaction
|
||||
- sends localized account-created notifications
|
||||
|
||||
### 2. Public booking from a company site
|
||||
|
||||
`POST /api/v1/site/:slug/book`
|
||||
|
||||
- resolves the company from the slug
|
||||
- verifies vehicle availability for the requested date range
|
||||
- upserts the company-scoped customer record
|
||||
- computes total days and base rental price
|
||||
- applies promo code discount if present
|
||||
- applies pricing rules
|
||||
- stores a draft reservation
|
||||
- attaches reservation insurance snapshots and additional-driver snapshots
|
||||
- triggers license validation flags
|
||||
|
||||
Payment is then started with `POST /api/v1/site/:slug/booking/:id/pay`.
|
||||
|
||||
### 3. Reservation lifecycle after booking
|
||||
|
||||
- reservation starts in `DRAFT`
|
||||
- staff confirms it after license compliance checks
|
||||
- vehicle status moves to `RESERVED`
|
||||
- checkin moves reservation to `ACTIVE` and vehicle to `RENTED`
|
||||
- checkout moves reservation to `COMPLETED`, records mileage, and generates a review token
|
||||
- close marks the operational workflow complete and can send the review request email
|
||||
|
||||
## Error Handling and Response Shape
|
||||
|
||||
The API standardizes error handling in `http/errors/errorMiddleware.ts`.
|
||||
|
||||
Special handling exists for:
|
||||
|
||||
- Zod validation errors -> `400 validation_error`
|
||||
- Prisma `P2025` -> `404 not_found`
|
||||
- Prisma `P2002` -> `409 conflict`
|
||||
- custom `AppError` subclasses -> explicit status and machine-readable code
|
||||
|
||||
Successful route handlers usually return:
|
||||
|
||||
```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://..." }
|
||||
{
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Query Params
|
||||
`page`, `pageSize` (max 100), `sortBy`, `sortOrder` (asc|desc), `q` (search)
|
||||
Common deviations:
|
||||
|
||||
---
|
||||
- `/health`
|
||||
- `/api/v1/docs`
|
||||
- webhook receipt payloads
|
||||
- file downloads such as admin invoice PDFs
|
||||
|
||||
## Payment Routes — AmanPay + PayPal
|
||||
## Documentation Artifacts
|
||||
|
||||
| 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) |
|
||||
There are two documentation layers in the codebase:
|
||||
|
||||
---
|
||||
1. runtime API docs from Swagger/OpenAPI at `/docs` and `/api/v1/openapi.json`
|
||||
2. this markdown document, which explains design decisions, route grouping, and request flow
|
||||
|
||||
## 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.RentalDriveGo.com → api.RentalDriveGo.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=` |
|
||||
The OpenAPI file is useful for request/response contracts, but it is not yet a perfect mirror of every newer route. This document should be updated together with `app.ts`, route files, and the OpenAPI generator whenever route groups change.
|
||||
|
||||
Reference in New Issue
Block a user