Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM, PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source files covering clients, berths, interests/pipeline, documents/EOI, expenses/invoices, email, notifications, dashboard, admin, and client portal. CI/CD via Gitea Actions with Docker builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
41 KiB
41 KiB
Port Nimara CRM — API Endpoint Catalog
Compiled: 2026-03-11
Pattern: REST with Zod validation, JSON responses
Auth: Better Auth session cookies (internal), API key (webhooks), none (public)
Docs: OpenAPI/Swagger auto-generated at /api-docs for public endpoints
Conventions
- All endpoints prefixed with
/api/ - Port context from
X-Port-Idheader or session (middleware extracts and validates) - Standard response shape:
{ data, meta?, error? } - Pagination:
?page=1&limit=25→ response includesmeta: { total, page, limit, pages } - Sorting:
?sort=field&order=asc|desc - Filtering:
?field=valueor?field[op]=value(e.g.,?status=available,?created_at[gte]=2025-01-01) - All write endpoints return the created/updated entity
- All delete endpoints return
{ success: true } - Error shape:
{ error: { code, message, details? } } - HTTP status codes: 200 (success), 201 (created), 400 (validation), 401 (unauthorized), 403 (forbidden), 404 (not found), 409 (conflict), 500 (server error)
1. Public API (No Auth)
Served to the website and external consumers. OpenAPI documented.
| Method | Path | Description |
|---|---|---|
| GET | /api/public/berths |
List all berths with status and map data for website berth map |
| GET | /api/public/berths/:id |
Single berth details for website detail view |
| POST | /api/public/interests |
Website interest registration form submission |
| POST | /api/public/forms/:token |
Pre-filled data collection form submission |
| GET | /api/public/forms/:token |
Get form template + prefilled data for rendering |
Rate limited. CORS configured for allowed origins.
2. Authentication
| Method | Path | Description |
|---|---|---|
| POST | /api/auth/login |
Email + password login → session cookie |
| POST | /api/auth/logout |
Destroy session |
| GET | /api/auth/session |
Get current session (user info, port access, permissions) |
| POST | /api/auth/password/set |
Set password from email link (token + new password) |
| POST | /api/auth/password/reset-request |
Request password reset email |
| POST | /api/auth/password/reset |
Reset password from email link (token + new password) |
3. Clients
| Method | Path | Description |
|---|---|---|
| GET | /api/clients |
List clients (paginated, filterable, sortable) |
| POST | /api/clients |
Create client |
| GET | /api/clients/:id |
Get client with contacts, tags, interest count |
| PATCH | /api/clients/:id |
Update client fields |
| DELETE | /api/clients/:id |
Soft delete (archive) client |
| POST | /api/clients/:id/restore |
Restore archived client |
| GET | /api/clients/:id/interests |
List all interests for this client |
| GET | /api/clients/:id/timeline |
Activity timeline for this client |
| GET | /api/clients/:id/files |
Files belonging to this client |
| GET | /api/clients/:id/notes |
Notes on this client |
| POST | /api/clients/:id/notes |
Add note to client |
| PATCH | /api/clients/:id/notes/:noteId |
Edit note (within 15-min window) |
| GET | /api/clients/:id/relationships |
Client relationships |
| POST | /api/clients/:id/relationships |
Create relationship between clients |
| DELETE | /api/clients/:id/relationships/:relId |
Remove relationship |
| POST | /api/clients/merge |
Merge two clients (body: { surviving_id, merged_id, field_choices }) |
| GET | /api/clients/duplicates |
List pending duplicate alerts |
| POST | /api/clients/duplicates/:id/dismiss |
Dismiss a duplicate alert |
Client Contacts
| Method | Path | Description |
|---|---|---|
| GET | /api/clients/:id/contacts |
List contact entries |
| POST | /api/clients/:id/contacts |
Add contact entry |
| PATCH | /api/clients/:id/contacts/:contactId |
Update contact entry |
| DELETE | /api/clients/:id/contacts/:contactId |
Delete contact entry |
Client Tags
| Method | Path | Description |
|---|---|---|
| POST | /api/clients/:id/tags |
Add tag(s) to client |
| DELETE | /api/clients/:id/tags/:tagId |
Remove tag from client |
4. Interests
| Method | Path | Description |
|---|---|---|
| GET | /api/interests |
List all interests (paginated, filterable by stage, berth, client, source, tags) |
| POST | /api/interests |
Create interest (linked to client) |
| GET | /api/interests/:id |
Get interest detail with client, berth, documents, milestones |
| PATCH | /api/interests/:id |
Update interest fields |
| DELETE | /api/interests/:id |
Soft delete (archive) interest |
| POST | /api/interests/:id/restore |
Restore archived interest |
| PATCH | /api/interests/:id/stage |
Change pipeline stage (with validation and auto-actions) |
| POST | /api/interests/:id/berth |
Link berth to interest (auto-updates berth status) |
| DELETE | /api/interests/:id/berth |
Unlink berth from interest (conditionally resets berth status) |
| GET | /api/interests/:id/recommendations |
Get berth recommendations for this interest |
| POST | /api/interests/:id/recommendations/generate |
Generate AI berth recommendations |
| POST | /api/interests/:id/recommendations |
Add manual berth recommendation |
| GET | /api/interests/:id/timeline |
Activity timeline for this interest |
| GET | /api/interests/:id/notes |
Notes on this interest |
| POST | /api/interests/:id/notes |
Add note to interest |
| PATCH | /api/interests/:id/notes/:noteId |
Edit note (within 15-min window) |
| GET | /api/interests/:id/documents |
Documents linked to this interest |
Interest Tags
| Method | Path | Description |
|---|---|---|
| POST | /api/interests/:id/tags |
Add tag(s) to interest |
| DELETE | /api/interests/:id/tags/:tagId |
Remove tag from interest |
5. Berths
| Method | Path | Description |
|---|---|---|
| GET | /api/berths |
List berths (paginated, filterable by status, area, availability) |
| GET | /api/berths/:id |
Get berth detail with linked interests, waiting list, maintenance log |
| PATCH | /api/berths/:id |
Update berth fields |
| GET | /api/berths/:id/map-data |
Get map rendering data |
| PATCH | /api/berths/:id/map-data |
Update map rendering data |
| GET | /api/berths/:id/interests |
List interests linked to this berth |
| GET | /api/berths/:id/waiting-list |
Get waiting list for this berth |
| POST | /api/berths/:id/waiting-list |
Add client to waiting list |
| PATCH | /api/berths/:id/waiting-list/:entryId |
Update waiting list entry (position, priority) |
| DELETE | /api/berths/:id/waiting-list/:entryId |
Remove from waiting list |
| GET | /api/berths/:id/maintenance |
List maintenance log entries |
| POST | /api/berths/:id/maintenance |
Add maintenance log entry |
| PATCH | /api/berths/:id/maintenance/:logId |
Update maintenance entry |
| DELETE | /api/berths/:id/maintenance/:logId |
Delete maintenance entry |
| POST | /api/berths/:id/maintenance/:logId/photos |
Upload photos to maintenance log entry |
| DELETE | /api/berths/:id/maintenance/:logId/photos/:photoId |
Remove photo from maintenance log |
| GET | /api/berths/compare |
Compare berths (query: ?ids=id1,id2,id3) |
| POST | /api/berths/compare/export |
Export comparison as PDF |
/api/berths/availability-calendar |
CUT FROM V1 — Timeline view data deferred to post-V1 | |
| POST | /api/berths/import |
AI-assisted berth spec import (upload file) |
| GET | /api/berths/import/:jobId |
Check import job status / get preview |
| POST | /api/berths/import/:jobId/confirm |
Confirm and commit spec import |
Berth Tags
| Method | Path | Description |
|---|---|---|
| POST | /api/berths/:id/tags |
Add tag(s) to berth |
| DELETE | /api/berths/:id/tags/:tagId |
Remove tag from berth |
6. Documents & Signing
| Method | Path | Description |
|---|---|---|
| GET | /api/documents |
List documents (filterable by type, status, client, interest) |
| POST | /api/documents |
Create document record |
| GET | /api/documents/:id |
Get document detail with signers and events |
| PATCH | /api/documents/:id |
Update document |
| DELETE | /api/documents/:id |
Delete document |
| POST | /api/documents/:id/send |
Send document for signing via Documenso |
| POST | /api/documents/:id/upload-signed |
Upload manually signed document |
| POST | /api/documents/:id/remind |
Send signing reminder |
| GET | /api/documents/:id/signers |
List signers and their status |
| GET | /api/documents/:id/events |
List signature events |
| POST | /api/documents/generate-eoi |
Generate EOI from interest (auto-creates document + sends to Documenso) |
| POST | /api/webhooks/documenso |
Documenso webhook receiver (signature events) |
Document Templates
| Method | Path | Description |
|---|---|---|
| GET | /api/document-templates |
List document templates (filterable by type, active status) |
| POST | /api/document-templates |
Create document template |
| GET | /api/document-templates/:id |
Get template detail with merge field definitions |
| PATCH | /api/document-templates/:id |
Update template |
| DELETE | /api/document-templates/:id |
Delete template |
| GET | /api/document-templates/merge-fields |
List all available merge fields by source (client, interest, berth, port) |
| POST | /api/document-templates/:id/generate |
Generate document from template (body: { clientId?, interestId?, berthId? }) — resolves merge fields, returns PDF |
| POST | /api/document-templates/:id/generate-and-send |
Generate + email to client |
| POST | /api/document-templates/:id/generate-and-sign |
Generate + send for Documenso signing |
Record PDF Export
| Method | Path | Description |
|---|---|---|
| POST | /api/clients/:id/export-pdf |
Export client summary as branded PDF |
| POST | /api/berths/:id/export-pdf |
Export berth spec sheet as branded PDF |
| POST | /api/interests/:id/export-pdf |
Export interest summary as branded PDF |
7. Expenses
| Method | Path | Description |
|---|---|---|
| GET | /api/expenses |
List expenses (paginated, filterable by date, category, payer, status) |
| POST | /api/expenses |
Create expense |
| GET | /api/expenses/:id |
Get expense detail |
| PATCH | /api/expenses/:id |
Update expense |
| DELETE | /api/expenses/:id |
Soft delete expense |
| POST | /api/expenses/scan-receipt |
Upload receipt image → AI extraction → return parsed data |
| POST | /api/expenses/export/csv |
Export filtered expenses as CSV |
| POST | /api/expenses/export/pdf |
Export filtered expenses as PDF with receipt images |
| POST | /api/expenses/export/parent-company |
Parent company export (expenses + receipts + EUR subtotal + 5% fee) |
8. Invoices
| Method | Path | Description |
|---|---|---|
| GET | /api/invoices |
List invoices (paginated, filterable by status, date, client) |
| POST | /api/invoices |
Create invoice (from line items or from grouped expenses) |
| GET | /api/invoices/:id |
Get invoice detail with line items and linked expenses |
| PATCH | /api/invoices/:id |
Update invoice |
| DELETE | /api/invoices/:id |
Soft delete invoice |
| POST | /api/invoices/:id/send |
Send invoice via email |
| POST | /api/invoices/:id/generate-pdf |
Generate/regenerate invoice PDF |
| PATCH | /api/invoices/:id/payment |
Record payment against invoice |
| GET | /api/invoices/:id/line-items |
List line items |
| POST | /api/invoices/:id/line-items |
Add line item |
| PATCH | /api/invoices/:id/line-items/:itemId |
Update line item |
| DELETE | /api/invoices/:id/line-items/:itemId |
Delete line item |
9. Files
| Method | Path | Description |
|---|---|---|
| GET | /api/files |
List files (filterable by client, category, type) |
| POST | /api/files/upload |
Upload file(s) to MinIO + create metadata |
| GET | /api/files/:id |
Get file metadata |
| GET | /api/files/:id/download |
Get presigned download URL |
| GET | /api/files/:id/preview |
Get presigned preview URL (for PDFs/images) |
| PATCH | /api/files/:id |
Update file metadata (rename, recategorize) |
| DELETE | /api/files/:id |
Delete file (removes from MinIO + metadata) |
| POST | /api/files/folders |
Create folder |
| PATCH | /api/files/folders/:path |
Rename folder |
| DELETE | /api/files/folders/:path |
Delete folder |
10. Email
| Method | Path | Description |
|---|---|---|
| GET | /api/email/accounts |
List user's email accounts |
| POST | /api/email/accounts |
Configure email account (SMTP/IMAP) |
| PATCH | /api/email/accounts/:id |
Update email account settings |
| DELETE | /api/email/accounts/:id |
Remove email account |
| POST | /api/email/accounts/:id/test |
Test SMTP/IMAP connection |
| GET | /api/email/threads |
List email threads (filterable by client) |
| GET | /api/email/threads/:id |
Get thread with all messages |
| POST | /api/email/send |
Compose and send email |
| POST | /api/email/sync |
Trigger manual email sync |
11. Reminders
| Method | Path | Description |
|---|---|---|
| GET | /api/reminders |
List reminders (filterable by status, assignee, due date, priority, linked entity) |
| POST | /api/reminders |
Create reminder (optional: sync_to_calendar: true to push to Google Calendar) |
| GET | /api/reminders/:id |
Get reminder detail |
| PATCH | /api/reminders/:id |
Update reminder (updates Google Calendar event if synced) |
| DELETE | /api/reminders/:id |
Delete reminder (removes Google Calendar event if synced) |
| POST | /api/reminders/:id/complete |
Mark reminder as completed |
| POST | /api/reminders/:id/snooze |
Snooze reminder (body: { snooze_until }) |
| POST | /api/reminders/:id/dismiss |
Dismiss reminder |
| GET | /api/reminders/my |
Current user's reminders |
| GET | /api/reminders/overdue |
Overdue reminders |
| GET | /api/reminders/upcoming |
Unified upcoming view: CRM reminders + Google Calendar events (next 14 days) |
11b. Google Calendar Integration
| Method | Path | Description |
|---|---|---|
| GET | /api/calendar/auth-url |
Get Google OAuth 2.0 authorization URL |
| GET | /api/calendar/callback |
OAuth callback — exchange code for tokens, store encrypted |
| GET | /api/calendar/status |
Current user's calendar connection status (connected, calendar name, last sync) |
| GET | /api/calendar/calendars |
List user's available Google Calendars (for calendar selection) |
| PATCH | /api/calendar/settings |
Update calendar settings (selected calendar_id, sync_enabled) |
| POST | /api/calendar/disconnect |
Disconnect Google Calendar (revoke token, clear cache) |
| POST | /api/calendar/sync |
Trigger sync of Google Calendar events (called manually, on login, or on navigation to calendar-displaying pages if stale > 5 min) |
12. Notifications
| Method | Path | Description |
|---|---|---|
| GET | /api/notifications |
List notifications for current user (paginated) |
| GET | /api/notifications/unread-count |
Get unread notification count |
| PATCH | /api/notifications/:id/read |
Mark notification as read |
| POST | /api/notifications/mark-all-read |
Mark all as read |
| GET | /api/notifications/preferences |
Get notification preferences |
| PATCH | /api/notifications/preferences |
Update notification preferences |
13. Dashboard & Analytics
| Method | Path | Description |
|---|---|---|
| GET | /api/dashboard |
Main dashboard data (pipeline, occupancy, revenue, recent activity, upcoming reminders + calendar events, overdue items) |
| GET | /api/analytics/pipeline |
Pipeline analytics (counts/values by stage, conversion rates) |
| GET | /api/analytics/revenue |
Revenue analytics (forecast, trends, breakdown) |
| GET | /api/analytics/berths |
Berth analytics (occupancy, popularity, time-to-close) |
| GET | /api/analytics/expenses |
Expense analytics (trends, categories, budgets) |
14. Search
| Method | Path | Description |
|---|---|---|
| GET | /api/search |
Global search across all entity types (query: ?q=search+term) |
| GET | /api/search/recent |
Recent searches for current user |
15. Tags
| Method | Path | Description |
|---|---|---|
| GET | /api/tags |
List all tags for current port |
| POST | /api/tags |
Create tag |
| PATCH | /api/tags/:id |
Update tag (name, color) |
| DELETE | /api/tags/:id |
Delete tag |
16. Saved Views
| Method | Path | Description |
|---|---|---|
| GET | /api/saved-views |
List saved views for current user (filterable by entity type) |
| POST | /api/saved-views |
Create saved view |
| PATCH | /api/saved-views/:id |
Update saved view |
| DELETE | /api/saved-views/:id |
Delete saved view |
17. Scratchpad
| Method | Path | Description |
|---|---|---|
| GET | /api/scratchpad |
List current user's scratchpad notes |
| POST | /api/scratchpad |
Create scratchpad note |
| PATCH | /api/scratchpad/:id |
Update note content |
| DELETE | /api/scratchpad/:id |
Delete note |
| POST | /api/scratchpad/:id/link |
Link note to a client record |
18. Import/Export
| Method | Path | Description |
|---|---|---|
| POST | /api/import/upload |
Upload CSV/Excel for import (returns column mapping preview) |
| POST | /api/import/preview |
Preview import with column mapping applied |
| POST | /api/import/execute |
Execute import |
| GET | /api/import/history |
List past imports |
| POST | /api/export/:entityType |
Export entity list as CSV/Excel (body: filters, columns) |
19. Admin — User Management
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/users |
List all users |
| POST | /api/admin/users |
Create user (sends "set password" email) |
| GET | /api/admin/users/:id |
Get user detail with port assignments |
| PATCH | /api/admin/users/:id |
Update user (activate/deactivate, update profile) |
| POST | /api/admin/users/:id/reset-password |
Send password reset email |
| GET | /api/admin/users/:id/activity |
User's recent activity |
20. Admin — Roles
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/roles |
List all roles |
| POST | /api/admin/roles |
Create role |
| GET | /api/admin/roles/:id |
Get role detail with permissions |
| PATCH | /api/admin/roles/:id |
Update role |
| DELETE | /api/admin/roles/:id |
Delete role (blocked if users assigned) |
| GET | /api/admin/roles/:id/overrides |
List per-port overrides for this role |
| POST | /api/admin/roles/:id/overrides |
Create per-port override |
| PATCH | /api/admin/roles/:id/overrides/:portId |
Update per-port override |
| DELETE | /api/admin/roles/:id/overrides/:portId |
Remove per-port override |
21. Admin — Ports
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/ports |
List all ports |
| POST | /api/admin/ports |
Create port |
| GET | /api/admin/ports/:id |
Get port detail |
| PATCH | /api/admin/ports/:id |
Update port settings |
| POST | /api/admin/ports/:id/assign-user |
Assign user to port with role |
| DELETE | /api/admin/ports/:id/users/:userId |
Remove user from port |
22. Admin — Audit Log
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/audit-logs |
List audit log entries (paginated, filterable by user, entity, action, date) |
| GET | /api/admin/audit-logs/:id |
Get audit log entry detail (before/after values) |
| POST | /api/admin/audit-logs/:id/revert |
Revert a specific change (super admin only) |
| POST | /api/admin/audit-logs/export |
Export audit logs as CSV |
23. Admin — System
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/settings |
Get all system settings |
| PATCH | /api/admin/settings |
Update system settings |
| GET | /api/admin/settings/:portId |
Get port-specific settings |
| PATCH | /api/admin/settings/:portId |
Update port-specific settings |
| GET | /api/admin/health |
System health check (all services) |
| POST | /api/admin/backup |
Trigger manual database backup |
| GET | /api/admin/backups |
List available backups |
| GET | /api/admin/backups/:id/download |
Download backup file |
| POST | /api/admin/backups/:id/restore |
Restore from backup (super admin only) |
24. Admin — Webhooks
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/webhooks |
List webhook configurations |
| POST | /api/admin/webhooks |
Create webhook |
| GET | /api/admin/webhooks/:id |
Get webhook detail |
| PATCH | /api/admin/webhooks/:id |
Update webhook |
| DELETE | /api/admin/webhooks/:id |
Delete webhook |
| GET | /api/admin/webhooks/:id/deliveries |
List delivery log for this webhook |
| POST | /api/admin/webhooks/:id/test |
Send test webhook payload |
25. Admin — Scheduled Reports
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/reports |
List scheduled reports |
| POST | /api/admin/reports |
Create scheduled report |
| GET | /api/admin/reports/:id |
Get report detail |
| PATCH | /api/admin/reports/:id |
Update report schedule/config |
| DELETE | /api/admin/reports/:id |
Delete scheduled report |
| POST | /api/admin/reports/:id/run |
Manually trigger report generation |
26. Admin — Custom Fields
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/custom-fields |
List custom field definitions (filterable by entity type) |
| POST | /api/admin/custom-fields |
Create custom field definition |
| PATCH | /api/admin/custom-fields/:id |
Update custom field definition |
| DELETE | /api/admin/custom-fields/:id |
Delete custom field definition |
27. Admin — Forms
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/forms |
List form templates |
| POST | /api/admin/forms |
Create form template |
| GET | /api/admin/forms/:id |
Get form template detail |
| PATCH | /api/admin/forms/:id |
Update form template |
| DELETE | /api/admin/forms/:id |
Delete form template |
| GET | /api/admin/forms/:id/submissions |
List submissions for this form |
| POST | /api/admin/forms/:id/expire/:submissionId |
Manually expire a form submission link |
| POST | /api/admin/forms/:id/regenerate |
Regenerate form link for a client/interest |
28. Admin — Monitoring
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/jobs |
BullMQ job dashboard data (queues, counts, failed) |
| GET | /api/admin/jobs/:queueName |
Jobs in a specific queue |
| POST | /api/admin/jobs/:queueName/:jobId/retry |
Retry a failed job |
| DELETE | /api/admin/jobs/:queueName/:jobId |
Delete a job |
| GET | /api/admin/alerts |
Active system alerts |
| PATCH | /api/admin/alerts/:id/acknowledge |
Acknowledge an alert |
29. Currency
| Method | Path | Description |
|---|---|---|
| GET | /api/currency/rates |
Get current exchange rates |
| POST | /api/currency/rates/refresh |
Force refresh exchange rates from Frankfurter API |
| POST | /api/currency/convert |
Convert amount between currencies |
| PATCH | /api/currency/rates/:pair |
Manually override an exchange rate |
30. Bulk Operations
| Method | Path | Description |
|---|---|---|
| POST | /api/bulk/status-change |
Bulk status change (body: { entity_type, ids, new_status }) |
| POST | /api/bulk/tag |
Bulk tag assignment (body: { entity_type, ids, tag_ids }) |
| POST | /api/bulk/export |
Bulk export (body: { entity_type, ids, format }) |
| POST | /api/bulk/delete |
Bulk soft delete (body: { entity_type, ids }) |
Endpoint Count Summary
| Section | Endpoints |
|---|---|
| Public API | 5 |
| Authentication | 6 |
| Clients | 22 |
| Interests | 19 |
| Berths | 22 |
| Documents | 12 |
| Document Templates | 9 |
| Record PDF Export | 3 |
| Expenses | 9 |
| Invoices | 12 |
| Files | 10 |
| 9 | |
| Reminders | 11 |
| Google Calendar | 7 |
| Notifications | 6 |
| Dashboard & Analytics | 5 |
| Search | 2 |
| Tags | 4 |
| Saved Views | 4 |
| Scratchpad | 5 |
| Import/Export | 5 |
| Admin — Users | 6 |
| Admin — Roles | 9 |
| Admin — Ports | 6 |
| Admin — Audit | 4 |
| Admin — System | 9 |
| Admin — Webhooks | 7 |
| Admin — Reports | 6 |
| Admin — Custom Fields | 4 |
| Admin — Forms | 6 |
| Admin — Monitoring | 6 |
| Currency | 4 |
| Bulk Operations | 4 |
| TOTAL | ~256 endpoints |