Files
pn-new-crm/06-MASTER-FEATURE-SPEC.md
Matt 67d7e6e3d5
Some checks failed
Build & Push Docker Images / build-and-push (push) Has been cancelled
Build & Push Docker Images / deploy (push) Has been cancelled
Build & Push Docker Images / lint (push) Has been cancelled
Initial commit: Port Nimara CRM (Layers 0-4)
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>
2026-03-26 11:52:51 +01:00

42 KiB
Raw Blame History

Port Nimara CRM — Master Feature Specification (V1)

Compiled: 2026-03-11 Status: Final — all features confirmed for V1 (single release, no phased rollout) Constraint: "There is no v1 or v2. It's ONLY v1." — Every feature listed here ships in the one and only build.


Table of Contents

  1. Client Management
  2. Interest Management
  3. Berth Management
  4. EOI & Document Signing
  5. Expenses & Invoicing
  6. File Management
  7. Email System
  8. Dashboard & Analytics
  9. Reminders & Google Calendar Integration
  10. Notification Center
  11. Search & Filtering
  12. Admin Panel
  13. Audit System
  14. Multi-Port Tenancy
  15. Authentication & Authorization
  16. Public API & Website Integration
  17. AI-Assisted Features
  18. Data Import/Export Center
  19. Webhooks
  20. Scheduled Reports
  21. System Monitoring & Alerts
  22. Client Portal
  23. UX & Quality of Life

1. Client Management

Clients are the anchor records in the system. A client is a person or entity interested in one or more berths.

1.1 Client Record

  • Core fields: Full name, company/entity name (optional), nationality
  • Multi-contact support: Each client can have multiple contact entries, each with:
    • Channel: email, phone, WhatsApp, other
    • Value: the actual address/number
    • Label: primary, secondary, work, personal, broker, assistant
    • A client can have multiple entries per channel (e.g., two phone numbers, three emails)
  • Proxy/representative support: A client record can be marked as a proxy. Fields for:
    • Proxy type: broker, representative, family member, legal counsel, other
    • Actual owner name (if known — may be learned later)
    • Relationship notes
  • Vessel details: Yacht name, length, width, draft (imperial + metric), berth size desired
  • Communication preferences: Preferred contact method, preferred language, timezone
  • Tags/labels: Color-coded, user-defined tags (VIP, Broker-referred, Returning client, etc.)
  • Source tracking: How the client was acquired (website registration, manual entry, referral, broker)
  • Internal notes: Freeform timestamped notes thread (see Section 1.3)
  • Activity timeline: Chronological feed of all events (see Section 1.4)
  • Files: Client-grouped file storage (see Section 6)
  • Relationship mapping: Links between clients (referral chains, broker → client, family connections)

1.2 Duplicate Detection & Merging

  • Auto-merge on website registration: When a website registration comes in with an email matching an existing client, the system automatically creates a new Interest under the existing client record (not a new client).
  • Fuzzy match alerts: When a new client is created (manually or via website) and fuzzy matching detects potential duplicates (similar name + phone, similar name + address), the system creates a merge alert for manual review.
  • Manual merge tool: Select two client records → preview side-by-side → choose which fields to keep from each → merge into one record. All interests, files, notes, and timeline entries transfer to the surviving record. The merged-away record becomes a redirect entry in the audit log.
  • Merge rules: Same email = auto-merge (new interest). Everything else = alert for manual decision.

1.3 Internal Notes / Comments

  • Freeform timestamped notes on each client record
  • Any user can add notes
  • Notes are permanent (editable by author within 15 minutes, then locked)
  • Supports @mentions of other CRM users
  • Notes appear in the activity timeline

1.4 Activity Timeline

  • Chronological feed on each client record showing every event:
    • Status changes (on any linked interest)
    • Emails sent/received
    • EOIs generated, sent, signed
    • Documents uploaded/signed
    • Berths linked/unlinked
    • Notes added
    • Files uploaded
    • Invoices created
    • Reminders created/completed
    • Manual edits to any field (from audit log)
  • Filterable by event type
  • Pulled from the audit log — no separate storage needed

1.5 Client Relationship Mapping

  • Visual/list view of relationships between clients
  • Relationship types: referred by, broker for, family member of, same vessel, custom
  • When viewing a client, related clients are shown with relationship context
  • Helps salesperson identify referral networks and broker portfolios

2. Interest Management

An Interest represents a client's interest in a specific berth (or general interest with no berth assigned yet).

2.1 Interest Record

  • Link to client: Every interest belongs to one client. One client can have multiple interests.
  • Link to berth: Optional — interests can exist without a berth assignment (general inquiry)
  • Pipeline stage: Open → Details Sent → In Communication → Visited → Signed EOI and NDA → 10% Deposit → Contract → Completed
  • Stage flexibility: All stages are manually overridable. The system never forces a workflow. Salesperson can skip stages, move backwards, or manually set any status at any time.
  • Automated convenience: Berth status transitions use a configurable rules engine (auto, suggest via toast prompt, or off — admin-configurable per trigger action). Pipeline stage auto-advances on key events (e.g., EOI send) but can always be manually overridden.
  • Lead category: General Interest, Specific Qualified Interest, Hot Lead, etc.
  • Source: Website, manual, referral, broker
  • EOI tracking: EOI status, Documenso document ID, signing links, signature timestamps
  • Contract tracking: Contract status, deposit status, reservation agreement status
  • Milestone tracking: Berth info sent, contract sent, deposit received, contract executed
  • Date tracking: Date added, last contacted, last status change, all milestone dates
  • Internal notes: Separate from client notes — interest-specific notes thread
  • Activity timeline: Interest-specific timeline (subset of client timeline filtered to this interest)

2.2 UI Presentation

  • Single interest: When a client has one interest, the client and interest details display inline as one unified view.
  • Multiple interests: When a client has multiple interests, each interest appears as an expandable section within the client view. Client details at the top, interests below as tabs or accordions.
  • Interest list view: Standalone list of all interests across all clients, filterable by pipeline stage, berth, date range, salesperson, source, tags.

2.3 Pipeline View

  • Kanban board view of interests grouped by pipeline stage
  • Drag-and-drop to move between stages (with confirmation for significant stage changes)
  • Card shows: client name, berth (if assigned), days in stage, next action due
  • Filterable by berth area, date range, salesperson

2.4 Waiting List

  • When a berth is sold/contracted, other clients interested in it can be placed on a waiting list
  • Waiting list tracks: position, date added, priority (normal/high), notification preference
  • If a deal falls through and the berth becomes available again, the system alerts everyone on the waiting list in order
  • Waiting list visible on the berth detail view

3. Berth Management

3.1 Berth Record

All fields from the existing berths CSV, organized:

  • Identity: Mooring Number, Area, Status (Available / Under Offer / Sold)
  • Dimensions (imperial + metric): Length, Width, Draft, Nominal Boat Size
  • Water: Water Depth, Water Depth Is Minimum (flag)
  • Infrastructure: Side Pontoon, Power Capacity, Voltage, Mooring Type, Cleat Type, Cleat Capacity, Bollard Type, Bollard Capacity, Access
  • Commercial: Price, Bow Facing
  • Map data: SVG path coordinates, x, y, transform, fontSize (for interactive berth map)
  • Status control: Manual override always available. Automatic transitions governed by configurable rules engine (see BR-001 in Business Rules). status_last_modified_at tracked.
  • Berth Approved: Approval flag
  • Tenure: Tenure type (permanent / fixed-term), term length (years), start date, expiration date
  • Linked interests: All interests assigned to this berth
  • Waiting list: Ordered list of clients waiting for this berth
  • Maintenance log: See Section 3.5

3.2 Berth Display — Three-Panel Layout

  • Left panel — Smart list: Berths grouped by status (Under Offer first, then Available, then Sold). Within each group, sorted by area then mooring number. Each list item shows: mooring number, area, status, nominal size, price. Clicking selects and opens detail panel.
  • Right panel — Detail view: Full berth specs in collapsible sections (dimensions, infrastructure, commercial, linked interests, waiting list, maintenance log, files). All info at a glance with ability to expand sections for detail.
  • Top/toggleable — Interactive map: Same berth map as the website, color-coded by status (green = available, orange = under offer, red = sold). Clicking a berth on the map selects it in the list and opens its detail. Collapsible to maximize list/detail space.

3.3 Berth Recommendation Engine

  • Input: client's vessel dimensions (length, width, draft) + desired amenities
  • Matching logic: find berths where berth dimensions accommodate the vessel with appropriate clearance, then rank by amenity match (power, access, mooring type, etc.)
  • Uses all available berth data for matching — no need to ask for more from the client
  • Results shown as a ranked list with match score and reasons
  • Salesperson can assign recommended berths to the interest with one click

3.4 Berth Comparison View

  • Select 2-3 berths for side-by-side comparison
  • Shows: dimensions, price, amenities, availability, infrastructure specs
  • Exportable as a PDF to send to the client
  • Accessible from the berth list or from within an interest record

3.5 Berth Maintenance Log

  • Per-berth log of maintenance, repairs, and inspections
  • Fields: date, description, cost, photos (stored in MinIO), responsible party, category (routine, repair, inspection, upgrade)
  • Important for a luxury marina — berth condition matters for sales

3.6 Berth Availability Calendar — CUT FROM V1 (Post-V1)

Deferred: This feature is lowest priority and not needed for V1 launch. Tenure data, expiry dates, and expiry notification checks remain in the schema and background jobs — only the Gantt-style visualization UI is deferred.

  • Timeline/Gantt-style view showing berth occupancy over time
  • For fixed-term tenure berths: shows contract period and approaching expirations
  • Flags upcoming expirations (configurable warning period, e.g., 6 months before)
  • Integrates with waiting list — when a term is approaching expiry, alerts waiting list clients
  • For permanent berths: shows as permanently occupied (no expiry)

4. EOI & Document Signing

4.1 EOI Generation

  • Prerequisites for generation: Client name, email, yacht name, length × width × draft, at least one linked berth
  • Generation blocked if: Manual/uploaded EOI documents already exist on the interest (unless overridden)
  • Process: Generate EOI PDF from template (@pdfme) → create Documenso document → assign 3 signers (client, developer, sales/approver) in sequential order → store signing URLs on interest record
  • Auto-status: Sets EOI Status = "Waiting for Signatures" and advances pipeline stage to "EOI and NDA Sent"

4.2 Signature Tracking

  • Webhook-driven: Documenso webhooks notify on each signature event
  • Deduplication: Signature hash + in-memory lock prevents double processing
  • Notification chain: Client signs → notify developer. Developer signs → notify sales. All sign → download completed PDF → email all parties → store in MinIO
  • Fallback polling: Every 6 hours, poll Documenso API for interests with pending signatures (rare safety net — primary mechanism is instant Documenso webhooks)
  • Reminders: Time-gated reminders (configurable send windows), per-interest toggle, system-wide cooldown

4.3 Manual Upload

  • Upload pre-signed documents directly, bypassing Documenso entirely
  • Immediately sets EOI Status = "Signed" and advances pipeline to "Signed EOI and NDA"
  • Used when client signs physical documents or has their own signing process

4.4 Generic Document Signing

  • Not just EOIs — any document can be uploaded and sent through Documenso for signing
  • Contracts, NDAs, reservation agreements, custom documents
  • Same tracking infrastructure as EOIs: webhook events, status tracking, signed PDF storage
  • Document type is tagged (EOI, contract, NDA, other) for filtering and organization

4.5 Pre-filled Data Collection Forms

  • Branded, web-accessible forms that the salesperson can send to clients
  • Pre-filled with known data from the client/interest record
  • Client fills in missing fields, corrects existing data
  • On submission, data flows back into the CRM and updates the relevant records
  • Form link is generated per-client with a secure token
  • Used for: EOI data collection, supplemental information gathering, general intake

4.6 Document Templates

  • Reusable templates for standard correspondence and documents beyond EOIs/contracts
  • Template types: welcome letters, berth handover checklists, acknowledgment letters, standard correspondence, custom
  • Merge fields: client name, berth details, dates, amounts, and any other CRM data auto-filled into the template
  • Admin creates and manages templates in the admin panel
  • Users generate documents from templates by selecting a template and a client/interest/berth — merge fields auto-populate
  • Generated documents can be: downloaded as PDF, sent via email, sent for signing via Documenso, or stored in the client's file folder
  • Template editor: TipTap rich text editor with merge field insertion (dropdown to pick field, inserted as {{client.full_name}} style tokens via custom TipTap extension)

4.7 Record PDF Export

  • One-click PDF export of any individual record view
  • Client summary PDF: client details, contact info, vessel details, linked interests with status, recent activity, files list
  • Berth spec sheet PDF: all berth specifications, dimensions, infrastructure, pricing, current status, linked interests
  • Interest summary PDF: client info, berth info, pipeline stage, EOI status, milestones, notes, timeline
  • Invoice PDF: already covered in Section 5.2
  • Useful for: meetings, offline reference, sharing with parent company, printing
  • Export button available on every record detail view
  • Styled with port branding (logo, colors) from port settings

5. Expenses & Invoicing

5.1 Expense Management

  • CRUD: Create, read, update, delete expenses
  • Fields: Establishment name, amount, currency, payment method, category, payer, date/time, description/contents, receipt image(s)
  • Receipt scanner integration: Standalone PWA at /scan (see Section 17.2). Mobile-first tool where user takes a photo of a receipt, AI extracts: establishment name, amount, currency, date, line items. Handles currency conversion (ECD local currency, USD primary business currency, EUR/GBP from international clients). Can be added to Apple home screen as a dedicated app.
  • Multi-currency: Expenses can be in any currency. System stores original currency + amount and converted USD equivalent. Exchange rates from Frankfurter API with local cache fallback.
  • Payment tracking: Payment status, date, method, reference, notes
  • Filtering: By date range, payer, category, payment status, currency
  • Export: CSV export, PDF export with receipt images. Groupable by category, payer, date range, invoice.
  • Parent company export: Dedicated export format bundling expenses with receipt images for parent company reporting. Includes EUR subtotal + 5% processing fee calculation.

5.2 Invoice System

  • Full invoicing: Not just expense grouping — proper invoice generation with configurable billing target
  • Auto-numbering: INV-YYYYMM-### format
  • Invoice fields: Invoice number, client/company name, billing email, billing address, due date, payment terms, currency, line items, subtotal, fees/discounts, total
  • Payment terms: Immediate, Net 10, Net 15, Net 30, Net 45, Net 60
  • Discount rules: 2% discount for Net 10 terms (configurable)
  • PDF generation: Professional invoice PDF with line items, totals, payment instructions
  • Payment tracking: Status (draft, sent, paid, overdue, cancelled), payment date, method, reference
  • Expense linking: Invoices can be created from grouped expenses, with bidirectional linking maintained
  • Email integration: Send invoices via email directly from CRM
  • Overdue alerts: Configurable alerts when invoices pass their due date

6. File Management

6.1 Storage Structure

MinIO (S3-compatible) with client-grouped folder structure:

/clients/{client_id}/
  ├── eoi/           # EOI documents (generated + signed)
  ├── contracts/     # Contracts, NDAs, reservation agreements
  ├── images/        # Client/vessel photos
  ├── receipts/      # Expense receipts
  ├── correspondence/ # Email attachments, letters
  └── misc/          # Anything else

6.2 File Operations

  • Upload (drag-and-drop, multi-file), download, preview (PDF, images), rename, delete
  • Folder management: create, rename, delete folders
  • File metadata stored in PostgreSQL: filename, path, size, MIME type, uploaded by, upload date, client_id, category
  • Presigned URLs for secure downloads

6.3 Migration from Existing Storage

  • Current S3 files are not organized by client
  • AI-assisted migration script to: scan all existing files → identify which client they belong to (from filenames, metadata, content) → reorganize into the new client-grouped structure
  • Runs as a one-time migration job with manual review for uncertain matches

6.4 File Audit

  • All file operations (upload, download, delete, rename, move) logged in the audit system
  • File access history visible per file

7. Email System

Priority level: Deprioritized. Built but not a focus area. Salesperson uses personal email/WhatsApp for client communication. CRM handles system-generated emails only as the primary use case.

7.1 System-Generated Email (Primary)

  • Sent via Nodemailer → Poste.io SMTP (noreply@portnimara.com)
  • Templates: password set/reset, EOI signature reminders, form links, follow-up reminders, invoice delivery, system alerts, waiting list notifications
  • MJML template files with variable substitution (not inline HTML strings)
  • Queued via BullMQ for reliable delivery

7.2 User Mailbox (Secondary — Nice to Have)

  • Per-user SMTP/IMAP connection with provider presets (Google Workspace, Outlook, Custom)
  • Compose and send emails from within CRM
  • Email thread viewer showing conversation history
  • Sent/received emails linked to client records and visible in activity timeline
  • Credentials stored encrypted in PostgreSQL (not in-memory)

8. Dashboard & Analytics

8.1 Main Dashboard (Home Screen)

  • Pipeline overview: interest count and value by stage, visual funnel
  • Conversion rates: interest → EOI → contract → completed (with trend lines)
  • Berth occupancy: available vs under offer vs sold (pie/donut chart), by area
  • Revenue: pipeline value (weighted by stage probability), realized revenue
  • Recent activity: last 10 actions across the system
  • Upcoming reminders: next 5 due CRM reminders + upcoming Google Calendar events for the current user
  • Overdue items: unsigned EOIs, overdue invoices, overdue reminders

8.2 Revenue Forecasting

  • Weighted pipeline value by stage (configurable probability per stage)
  • Best case / likely case / worst case scenarios
  • Trend over time (monthly/quarterly)
  • Breakdown by area, berth type, client source

8.3 Berth Analytics

  • Occupancy rates over time
  • Average time from interest to signed contract
  • Most popular berth areas/sizes
  • Price distribution analysis
  • Waiting list depth per berth

8.4 Expense Analytics

  • Monthly expense trends by category
  • Payer breakdown
  • Currency distribution
  • Budget vs actual (if budget targets are configured)

8.5 Port Comparison (Super Admin)

  • Side-by-side metrics across ports (future — when multi-port is active)
  • Unified pipeline view
  • Cross-port revenue summary

9. Reminders & Google Calendar Integration

CRM-native reminders with optional Google Calendar sync. The salesperson can create reminders/follow-ups that live inside the CRM, and optionally push them to their connected Google Calendar. No full calendar built into the CRM — the display shows CRM reminders alongside synced Google Calendar events in a unified list.

9.1 CRM Reminders

  • Linked to: a client, an interest, a berth, or standalone
  • Fields: title, note (optional), due date/time, priority (low/medium/high/urgent), assigned to, status (pending/snoozed/completed/dismissed)
  • No recurring reminders — lightweight by design, salesperson creates new reminders as needed
  • Overdue reminders trigger in-app notifications
  • Quick create from any entity detail page (client, interest, berth) — reminder auto-linked to that entity
  • Reminders appear in: dashboard "Upcoming Reminders" widget, entity detail pages (sidebar or tab), notification center when due/overdue

9.2 Follow-up Reminders (Auto-Generated)

  • Configurable per interest record: "remind me to follow up in X days if no activity"
  • Auto-creates a CRM reminder when the inactivity threshold fires
  • Salesperson can snooze (pushes due date forward), dismiss, or complete the reminder
  • System-wide reminder settings in admin panel (send windows, cooldowns)

9.3 Google Calendar Integration

  • Per-user OAuth 2.0 connection via Google Calendar API v3 (googleapis Node.js library)
  • Each CRM user can connect their Google Calendar from Settings → Calendar
  • Scopes: calendar.events (read/write), calendar.readonly, calendar.calendarlist.readonly
  • Encrypted refresh tokens stored in google_calendar_tokens table
  • Calendar selection: On connect, fetch the user's calendar list (via calendarList.list) and let them choose which calendar to sync with (e.g., "Business", "CRM", or their primary). Stored as calendar_id on the token record. Can be changed later in Settings.
  • Push to Calendar: When creating/editing a CRM reminder, toggle "Add to Google Calendar" → creates a Google Calendar event on the selected calendar with title, time, and a link back to the CRM entity
  • Pull from Calendar: Multiple sync triggers ensure freshness:
    1. Background poll: Every 30 minutes for all connected users (BullMQ recurring job)
    2. On login: When a user with a connected calendar logs in, trigger an immediate sync
    3. On navigation: When a user navigates to any page displaying calendar data (dashboard, reminders list, client detail with reminders), trigger a sync if last sync was > 5 minutes ago
    • All sync strategies fetch upcoming events (next 14 days) from the selected calendar into the CRM for display alongside CRM reminders
  • Two-way sync: If a Google Calendar event pushed from CRM is deleted/moved in Google, the next sync updates the CRM reminder accordingly (time change → update due_at, deletion → mark as dismissed)
  • Display: CRM reminders and Google Calendar events shown in a unified "Upcoming" list on the dashboard and entity detail pages. Google Calendar events are visually distinguished (calendar icon badge)
  • Disconnect: User can disconnect Google Calendar at any time. CRM reminders remain unaffected; synced events are removed from display.

10. Notification Center

10.1 In-App Notifications

  • Bell icon in the top navigation bar with unread count badge
  • Notification types:
    • Reminder due / overdue
    • New website registration
    • EOI signature event (signed, completed)
    • New email received (if user mailbox connected)
    • Duplicate client alert
    • Invoice overdue
    • Waiting list notification (berth became available)
    • System alert (job failure, background job error)
    • Follow-up reminder auto-created
    • Berth tenure expiring
  • Each notification: icon, title, description, timestamp, read/unread state, link to relevant record
  • Mark as read individually or bulk "mark all as read"
  • Notification preferences per user: which types to receive, which to suppress

10.2 Delivery Channels

  • In-app notification (always)
  • Email notification (configurable per notification type, sent via Poste.io)
  • Future: push notifications (when mobile app is built)

11. Search & Filtering

  • Single search bar in the top navigation (focus on Cmd+K or Ctrl+K)
  • Searches across: clients, berths, interests, notes, documents, invoices, expenses
  • Fuzzy matching for names and text content
  • Recent searches remembered
  • Results grouped by entity type with quick-jump links

11.2 Saved Filters / Custom Views

  • On any list view (clients, interests, berths, expenses, invoices), users can configure filters and save them as named views
  • Examples: "Available berths in Area A", "Clients with unsigned EOIs", "Overdue invoices"
  • Views are per-user but can be shared with other users
  • Saved views appear as tabs or dropdown on the list page

11.3 Bulk Operations

  • Select multiple records in any list view
  • Available actions: bulk status change, bulk tag assignment, bulk email send, bulk export (CSV/PDF), bulk delete (with confirmation)
  • Operations run as background jobs via BullMQ with progress indicator

12. Admin Panel

12.1 Three Admin Levels

  • Super Admin (Matt): Everything. All configurations, all ports, all settings, system-level operations.
  • Director: Operational admin. User management within their port, port-scoped audit logs, reminder/alert configuration. No system-level settings, no role definitions, no cross-port access (unless assigned).
  • Everyone else: Custom role-based permissions defined by the role builder.

12.2 User Management

  • Create user accounts (admin creates, system sends "set password" email)
  • Assign users to ports with specific roles
  • Deactivate/reactivate user accounts
  • View user activity (last login, actions performed)
  • Password reset (send reset email)

12.3 Role Builder

  • Define roles with granular permissions
  • Permission categories: clients (view, create, edit, delete), interests (view, create, edit, delete, change stage), berths (view, edit), expenses (view, create, edit, delete, export), invoices (view, create, edit, delete, send), files (view, upload, delete), email (view, send), admin (user management, audit log, settings), reports (view, export)
  • Global roles (apply to all ports by default)
  • Per-port role overrides (tweak a global role for a specific port)
  • Role assignment: user → port → role

12.4 Port Management

  • Create, edit, deactivate ports
  • Port settings: name, slug, branding (logo, colors), default currency, timezone
  • Port-specific configurations (reminder schedules, alert thresholds)
  • Onboarding wizard for new ports: step-by-step setup of port details → berth import → user creation → role assignment → branding

12.5 System Configuration

  • Email settings (Poste.io SMTP config, template management)
  • Documenso connection settings
  • MinIO connection settings
  • Currency settings (primary currency, exchange rate refresh schedule)
  • Backup settings (schedule, retention policy)
  • Webhook configuration (see Section 19)

13. Audit System

13.1 Deep Audit Log

  • Every data change across every entity type logged
  • Fields: timestamp, user, action (create/update/delete), entity type, entity ID, field changed, old value, new value, IP address, port context
  • Searchable by: user, entity type, entity ID, date range, action type
  • Filterable and exportable (CSV)

13.2 Undo Capability

  • Super admin can revert specific changes from the audit log
  • Revert creates a new audit log entry ("Reverted change X by user Y")
  • Undo available for: field value changes, status changes, berth assignments
  • Undo NOT available for: file deletions (files already removed from storage), sent emails, signed documents
  • Confirmation required before any undo operation

13.3 Audit Views

  • System-wide audit log (super admin only)
  • Port-scoped audit log (director level)
  • Per-record audit trail (visible on each client/interest/berth detail view)
  • Per-user audit trail (what actions did this user take)

14. Multi-Port Tenancy

14.1 Data Isolation

  • Every core table has a port_id foreign key
  • Every query scoped to current port context
  • Super admin can view/query across all ports
  • No data leakage between ports for regular users

14.2 Port Switcher & Single-Port Mode

  • Single-port mode: When only one port is active (SELECT count(*) FROM ports WHERE is_active = true = 1), ALL multi-port UI is hidden:
    • Port switcher dropdown hidden
    • "Port" column hidden in admin tables (users, berths, interests, etc.)
    • Port selection step hidden in entity creation forms
    • Port-scoped filter dropdowns hidden from list views
    • Port context set automatically behind the scenes (no user interaction needed)
    • Admin settings that are "per-port" still work — they just apply to the only port
  • Multi-port mode: When 2+ active ports exist, full multi-port UI appears:
    • Users assigned to multiple ports see a port switcher in the navigation
    • Switching ports changes all data context — lists, dashboards, search results
    • Current port indicated in the navigation
    • Port columns and filters visible throughout the app
  • Transition: If a super admin creates a second port, multi-port UI automatically appears on next page load for all users. No restart or setting toggle needed — purely derived from active port count.

14.3 Global vs. Per-Port

  • Global roles: defined once, available at all ports
  • Per-port role overrides: customize a global role for a specific port
  • Global settings: system-wide defaults
  • Per-port settings: override any global setting at the port level
  • New ports inherit all global configurations automatically

15. Authentication & Authorization

15.1 Better Auth Integration

  • Integrated login page matching CRM styling (no redirect to external auth service)
  • Password hashing (argon2/bcrypt)
  • Session cookies (httpOnly, secure, CSRF-protected)
  • Login/logout flows

15.2 Account Lifecycle

  1. Super admin creates user account in CRM admin panel
  2. Admin assigns user to port(s) with role(s)
  3. System sends "Set your password" email via Poste.io
  4. User clicks link, sets password, can log in
  5. Password reset follows same email flow

15.3 Authorization Flow

  1. User logs in → Better Auth validates credentials → session created
  2. App checks user_port_roles → which ports?
  3. Multiple ports → port switcher
  4. Every API request includes current port context
  5. Every DB query scoped to current port
  6. Permission check: user's role at current port → check against permissions (with port override if exists)
  7. Super admin bypasses all port scoping

15.4 Future: 2FA

  • Better Auth TOTP plugin available for future implementation
  • Not required for V1 but architecture supports it

16. Public API & Website Integration

16.1 Public Berth API

  • GET /api/public/berths — returns all berths with status and map data for the website berth map
  • GET /api/public/berths/:id — single berth details for the website detail view
  • No authentication required
  • OpenAPI/Swagger documentation at /api-docs

16.2 Interest Registration

  • POST /api/public/interests — website form submits new interest registrations
  • Triggers: duplicate detection check, notification to salesperson, auto-assign to pipeline stage "Open"
  • Rate limited to prevent abuse

16.3 Form Submission

  • POST /api/public/forms/:token — pre-filled data collection form submissions from clients
  • Token-authenticated (one-time or time-limited tokens per form link)

17. AI-Assisted Features

17.1 Berth Spec Sheet Import

  • Upload PDF or Excel spec sheet for a berth or batch of berths
  • AI interprets the document: identifies columns/fields, maps to database schema, handles varying formats
  • Preview screen shows AI's interpretation for human review before committing
  • Supports: different column orders, missing columns, unit variations, format differences between marina providers

17.2 Receipt Scanner (Standalone PWA)

  • Standalone PWA route: Available at /scan (short, easy-to-remember URL). Also accessible via /expenses/scan which redirects.
  • PWA manifest: display: "standalone", custom icon, "Port Nimara Scanner" name — when added to Apple home screen (or Android), opens as a standalone app with no browser chrome
  • Service worker: Caches the scanner UI shell for instant load. If offline, photos are queued locally and uploaded when connectivity returns (offline queueing with IndexedDB).
  • Minimal UI: Camera viewfinder → capture → AI processing spinner → review extracted data → save. No sidebar, no navigation — just the scanner flow. "Back to CRM" link for returning to the full app.
  • AI extraction: Extracts establishment name, total amount, currency, date, line items (if readable)
  • Currency conversion: Detects currency from receipt, converts to USD at current exchange rate
  • User reviews and confirms/corrects extracted data before saving as expense
  • Auth: Requires login (session cookie). If not logged in, redirects to a minimal login page then back to /scan.
  • Easy access: Team can bookmark crm.portnimara.dev/scan or add to home screen — works like a dedicated receipt scanning app

17.3 Berth Recommendation Engine

  • Input: client's vessel dimensions + amenity preferences
  • Uses all available berth data for matching
  • Ranking factors: dimensional fit (with clearance margins), power/voltage match, access type preference, mooring type, water depth adequacy, price range
  • Returns ranked list with match score and match reasons per berth

17.4 S3 File Migration

  • One-time AI-assisted reorganization of existing MinIO files
  • Scans existing files → identifies client association (from filenames, metadata, content) → proposes new location in client-grouped structure
  • Manual review for uncertain matches before executing moves

18. Data Import/Export Center

18.1 Import

  • CSV/Excel import for: clients, interests, berths, expenses
  • Column mapping interface: upload file → map source columns to CRM fields → preview → import
  • Validation on import: required fields, data types, duplicate detection
  • Import history log

18.2 Export

  • Export any entity list to CSV or Excel
  • Configurable columns: choose which fields to include
  • Filtered export: apply current list filters before exporting
  • Scheduled exports (see Section 20)

18.3 Migration Tools

  • NocoDB → PostgreSQL migration: extract all data from NocoDB tables, transform to new schema, seed PostgreSQL, verify, decommission NocoDB
  • Runs as a managed process with progress tracking and rollback capability

19. Webhooks

19.1 Outbound Webhooks

  • Admin-configurable: "when X happens, POST to this URL"
  • Available events: new client, new interest, interest stage change, EOI signed, EOI completed, berth status change, invoice created, invoice paid, expense created, new website registration
  • Webhook management: create, edit, delete, enable/disable, view delivery logs
  • Retry logic: 3 attempts with exponential backoff, then dead letter
  • Payload includes: event type, timestamp, full entity data, port context
  • Signature verification: HMAC signing for webhook payloads

19.2 Use Cases

  • Connect CRM to Zapier, n8n, or custom integrations
  • Notify external systems of pipeline changes
  • Trigger website updates beyond the berth map
  • Future: connect to accounting software, property management systems

20. Scheduled Reports

20.1 Report Configuration

  • Admin creates report schedules: what report, what frequency, who receives it
  • Report types: pipeline summary, expense summary, berth occupancy, activity log, overdue items, revenue forecast
  • Frequency: daily, weekly, monthly, or custom cron
  • Delivery: email (PDF attachment) via Poste.io
  • Recipients: any CRM user or external email address

20.2 Report Content

  • Each report type has a template
  • Reports generated as PDF
  • Include relevant charts, tables, and summary statistics
  • Date range automatically set based on frequency (e.g., weekly report covers last 7 days)

21. System Monitoring & Alerts

21.1 Alert Monitoring Dashboard

  • Per-type failure counters for background jobs (email, signature polling, backups, etc.)
  • Cooldown system: don't spam admin with repeated alerts for the same issue
  • Health check indicators for all services: PostgreSQL, Redis, MinIO, Documenso, Poste.io, Socket.io
  • BullMQ job dashboard: queue sizes, failed jobs, processing times, dead letter queue

21.2 Admin Notifications

  • System alerts → notification center + email to super admin
  • Configurable thresholds: "alert me if more than X failures in Y minutes"
  • Alert categories: service down, job failure, backup failure, disk space, unusual activity

21.3 System Backup & Restore

  • Automated nightly PostgreSQL backup via pg_dump → stored in MinIO
  • Manual backup trigger from admin panel
  • Backup download from admin panel
  • Restore interface for super admin (upload backup → preview → restore)
  • Backup retention policy (configurable: keep last N days/weeks)

22. Client Portal

Status: Build but deprioritize. Include in V1 but at the bottom of the implementation order.

  • Separate lightweight view for clients to log in
  • Client sees: their berth details, outstanding documents to sign, invoice history, uploaded files
  • Reduces back-and-forth with salesperson for status checks
  • Authentication: separate from CRM auth (client accounts created/managed from CRM side)
  • Read-only except for: document signing, form submissions, file uploads requested by salesperson

23. UX & Quality of Life

23.1 Mobile-Responsive Design

  • Full CRM usable on tablet and phone
  • Receipt scanner is mobile-primary
  • Responsive layouts using Tailwind breakpoints
  • Touch-friendly interaction targets

23.2 Dark Mode

  • Toggle in user settings
  • Tailwind dark mode classes
  • Persists per user

23.3 Quick Notes / Scratchpad

  • Personal scratchpad per user, not tied to any record
  • For jotting notes during calls before associating with a client
  • Notes can be dragged/moved onto a client record later
  • Persists between sessions

23.4 Tags / Labels System

  • Color-coded tags applicable to any entity (clients, interests, berths)
  • User-defined: create, rename, delete, change color
  • Filterable in all list views
  • Port-scoped (each port has its own tag set)

23.5 Archiving

  • Archive completed/lost/expired records instead of deleting
  • Archived records move out of active views
  • Searchable and restorable from archive
  • Separate "Archive" view in each section

23.6 Multi-Currency Price Book

  • Berth prices displayed in USD (primary)
  • Configurable exchange rates for display purposes (EUR, GBP, ECD)
  • Auto-update rates from Frankfurter API or manually set by admin
  • When viewing a berth, see price in all configured currencies
  • Useful for international clients

23.7 Audit Export for Parent Company

  • Dedicated "parent company report" generator
  • Bundles: expenses with receipts, revenue summary, occupancy stats, activity summary
  • Configurable: choose what sections to include
  • One-click generation as a downloadable PDF/ZIP package

Appendix A: Feature Count Summary

Category Feature Count
Client Management 5 features
Interest Management 4 features
Berth Management 6 features
EOI & Document Signing 7 features
Expenses & Invoicing 2 features
File Management 4 features
Email System 2 features
Dashboard & Analytics 5 features
Reminders & Calendar 3 features
Notification Center 2 features
Search & Filtering 3 features
Admin Panel 5 features
Audit System 3 features
Multi-Port Tenancy 3 features
Auth & Authorization 4 features
Public API 3 features
AI-Assisted 4 features
Import/Export 3 features
Webhooks 1 feature
Scheduled Reports 2 features
System Monitoring 3 features
Client Portal 1 feature (deprioritized)
UX & Quality of Life 7 features
TOTAL ~82 features

Appendix B: Decisions Log

Key decisions made during feature review interviews:

  1. NocoDB dropped entirely — PostgreSQL is sole database
  2. Keycloak dropped entirely — Better Auth integrated into Next.js
  3. Client and Interest are separate entities (client is anchor, interest tracks per-berth pipeline)
  4. System never forces a workflow — all pipeline stages manually overridable
  5. Email deprioritized — salesperson uses personal email/WhatsApp, CRM handles system-generated only
  6. WhatsApp integration not possible — salesperson uses personal account
  7. Receipt scanner (existing mobile tool) integrated into CRM expense flow
  8. File storage reorganized by client with AI-assisted migration of existing files
  9. Three admin levels: super admin (Matt), director (operational admin), everyone else (role-based)
  10. Duplicate detection: same-email auto-merges, fuzzy matches alert for manual review
  11. "No v1 or v2" — everything ships in one build
  12. Client portal built but deprioritized in implementation order
  13. Keyboard shortcuts cut from scope
  14. Berth tenure tracking: permanent and fixed-term (typically 5-year) with expiration monitoring
  15. Marina is in Anguilla — ECD local currency, USD primary business currency