API — Supporting Endpoints
The remaining endpoint groups: search, quota, inquiries, messaging, notifications, profiles, reports, dashboard, taxonomy, admin, and public routes.
Search & discovery
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /search | requireAuth | ?q=&tab=products|sellers&state=&district=&trustTier=&hasActiveLeads=&minResponseRate=&page=&limit=. Postgres trigram (or Meilisearch when configured). |
| GET | /quota/today | requireAuth | All 3 axes (used/limit) + IST resetsAt. |
| GET | /tile-counts/:side | requireAuth | side = buy|sell → { browse, myEngagements, inquiries, myLeads }. |
| GET | /engagement-counts | requireAuth | Sidebar leaf badge counts. |
Inquiries (pre-engagement threads)
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /inquiries | requireActiveUser | Threads (unread first); ?archived=true. |
| POST | /inquiries | requireActiveUser | { productId, body } — find-or-create by (productId, senderId). |
| POST | /inquiries/:id/messages | requireActiveUser | Append. |
| POST | /inquiries/:id/read | requireActiveUser | Mark received as read. |
| POST | /inquiries/:id/{archive,unarchive} | requireActiveUser | Per-participant archive. |
Messaging (deal threads)
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /messaging/threads | requireActiveUser | All deal threads. |
| GET | /messaging/threads/:id | membership | Thread + last 50 messages. |
| POST | /messaging/threads/:id/messages | membership | Send — gated on ACCEPTED (422 MESSAGING_LOCKED otherwise). Inquiry threads bypass the gate. |
| PATCH | /messaging/threads/:id/read | membership | Mark received as read (idempotent even when locked). |
Notifications & nudges
| Method | Path | Notes |
|---|---|---|
| GET | /notifications | ?read=true|false&page=&limit= |
| PATCH | /notifications/:id/read | Mark one read |
| PATCH | /notifications/read-all | Mark all read |
| GET | /profile/score | Trust score breakdown + tier |
| POST | /profile/nudges/snooze | { hours?: number } (default 24) |
| PATCH | /profile/nudges/preferences | Per-type opt-out toggles |
Profiles, farms & warehouses
| Method | Path | Notes |
|---|---|---|
| GET / PUT | /farmer/profile | Own farmer profile (upsert) |
| GET / POST / PATCH / DELETE | /farmer/farms[/:id] | Farm CRUD (requireRole('farmer') + ownership) |
| POST / DELETE | /farmer/farms/:id/photos[/:photoId] | Farm photos |
| GET / PUT | /trader/profile | Own trader profile |
| GET / POST / PATCH / DELETE | /trader/warehouses[/:id] | Warehouse CRUD (requireRole('trader') + ownership) |
| POST / DELETE | /trader/warehouses/:id/photos[/:photoId] | Warehouse photos |
| GET | /users/:userId | Public profile card |
Reports (owner-only)
| Method | Path | Notes |
|---|---|---|
| GET | /reports/pnl | Period P&L summary + bucketed trend |
| GET | /reports/transactions | Paginated sales + purchases; direction + product filter |
| GET | /reports/export | CSV / XLS (dependency-free SpreadsheetML) / PDF (audit-hash footer). 5000-row cap → RANGE_TOO_LARGE |
All report endpoints scope to req.user.id; there is no admin or shared view. Realised P&L is read live (cost basis) with a fixed sale-price snapshot.
Dashboard, taxonomy, lookups
| Method | Path | Notes |
|---|---|---|
| GET | /dashboard | 4 tiles + weather |
| GET | /taxonomy/tree | Full taxonomy tree (admins see PENDING; nodes carry hsnCode/gstRate) |
Admin (/admin/*, authorize('admin'))
Selected endpoints — the authoritative source is apps/api/src/routes/admin.routes.ts.
| Method | Path | Notes |
|---|---|---|
| GET | /admin/stats | Platform counts |
| GET | /admin/users | Filters: role, kycStatus, membershipNumber |
| PATCH | /admin/users/:userId/kyc | Set KYC status (self-edit 403) |
| PATCH | /admin/users/:userId/membership | ACTIVE needs a future date; BASIC forces null |
| POST | /admin/users/:userId/sub-admin | { grant } — sub-admins get grievance routes only |
| GET | /admin/users/:userId/search-history | DPDP audit-gated (reason ≥10; writes an audit log) |
| GET | /admin/orders + POST /admin/orders/backfill | Deals dashboard + V1 rescue |
| GET/POST/PATCH/DELETE | /admin/{group-affiliations,makhana-varieties,crops}[/:id] | Lookup CRUD |
| PATCH / POST | /admin/taxonomy/nodes[/:nodeId] | Edit / create nodes (name, icon, GST bracket) |
| GET / POST | /admin/taxonomy/suggestions[/:id/approve|reject] | Suggestion queue |
| POST | /admin/retention-purge | { retentionYears? } — the only hard-delete path |
Public (no auth)
| Method | Path | Notes |
|---|---|---|
| GET | /public/home | Hero stats + makhana variety list |
| GET | /public/states, /public/districts/:stateCode | Location dropdowns |
| GET | /public/{group-affiliations,makhana-varieties,crops} | Lookup lists |
| POST | /public/contact | Contact form |
| GET | /api/v1/health | Health check (DB + Redis probe) |
