Files
pn-new-crm/02-FEATURE-INVENTORY.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

156 lines
21 KiB
Markdown

# Port Nimara CRM — Feature Inventory: Keep / Cut / Rethink
**Compiled:** 2026-03-11
Each feature is categorized as **KEEP** (carry forward as-is or with minor cleanup), **RETHINK** (keep the functionality but redesign the implementation), or **CUT** (drop entirely from the rebuild). A rationale is provided for every decision.
---
## 1. Core Domain Features
| Feature | Verdict | Rationale |
| ------------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| Interest CRUD (create, read, update, delete) | **KEEP** | Heart of the CRM. Whitelist filtering and audit logging are good patterns. |
| Interest list with search, filter, sort | **RETHINK** | Keep functionality. Replace unbounded fetch (limit: 1000) with proper cursor-based pagination and server-side search. |
| Interest detail view with tabs | **KEEP** | Core UI pattern. Rebuild with Maritime-only components. |
| Sales Process Level pipeline (8 stages) | **KEEP** | Proven workflow. Model transitions explicitly (state machine) instead of raw field mutation. |
| Frontend auto-promotion (yacht dims → Specific Qualified Interest) | **RETHINK** | Business rule should live server-side only. Currently duplicated in frontend and backend — single source of truth needed. |
| Berth CRUD and specifications | **KEEP** | Essential. Imperial + metric pairs are correct for the marina domain. |
| Berth area/status filtering | **KEEP** | Core navigation pattern for sales team. |
| Berth-to-interest linking/unlinking | **KEEP** | Critical workflow with auto-status rules. Keep the business rules, improve with database-level constraints. |
| Berth auto-status (Available → Under Offer on link) | **KEEP** | Essential business rule. Enforce at database/service layer, not scattered across endpoints. |
| Berth status override mode | **KEEP** | Manual override capability is important for edge cases. |
| Berth recommendations (separate from committed links) | **KEEP** | Useful sales workflow distinction. Implement as proper join table. |
| Duplicate detection (interests) | **RETHINK** | Useful feature. Replace Levenshtein blocking approach with database-level fuzzy matching (pg_trgm). Simplify scoring. |
| Duplicate merging (interests) | **RETHINK** | Keep merge capability. Add preview/dry-run mode. Improve rollback handling (currently fragile). |
| Duplicate detection (expenses) | **KEEP** | Same approach as interests. Rebuild with improved matching. |
## 2. EOI / Signature Features
| Feature | Verdict | Rationale |
| ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| EOI document generation via Documenso | **KEEP** | Critical business process. Consolidate two duplicate ~400-line implementations into single `EOIService`. |
| 3-party sequential signing (Client → Developer → Sales) | **KEEP** | Core legal workflow. Preserve exact signing order and notification chain. |
| EOI signature tracking | **RETHINK** | Keep tracking. Replace 15+ nullable text fields on Interest with dedicated `signature_events` table. |
| Documenso webhook handler | **KEEP** | Deduplication via signature hashing and locking is well-designed. Extract into testable service module. |
| Background notification processing (30s poll) | **RETHINK** | Keep the queued notification pattern. Replace Nitro experimental task with BullMQ job. Reduce to event-driven rather than polling. |
| Fallback signature polling (5-min) | **KEEP** | Important resilience pattern for missed webhooks. Keep as scheduled job. |
| EOI reminder system (morning/afternoon) | **RETHINK** | Currently disabled in production. Re-evaluate need with users. If keeping, implement with proper job queue. |
| Manual EOI upload (bypass Documenso) | **KEEP** | Business need for pre-signed documents. Keep the immediate status promotion. |
| EOI document validation (Documenso sync check) | **RETHINK** | Manual-trigger only. Automate as periodic reconciliation job. |
| EOI delete/cleanup | **KEEP** | Needed for error recovery. Ensure it cleans up all three stores (NocoDB, Documenso, MinIO). |
| Signing link QR codes | **KEEP** | Useful for in-person signing scenarios at the marina. |
| Embedded signing links (iframe-based) | **RETHINK** | Evaluate if direct Documenso links are sufficient vs. embedding in CRM. |
## 3. Email Features
| Feature | Verdict | Rationale |
| ---------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Email composer with HTML signature | **RETHINK** | Keep functionality. Replace raw Nodemailer with transactional email service (Resend/SendGrid) for outbound. Extract HTML templates to template files. |
| Email thread viewer (IMAP sync) | **RETHINK** | Keep functionality. Single IMAP implementation (eliminate duplicate pool/standalone). Move sync to background worker. Store thread metadata in database, not just MinIO JSON. |
| Email attachment support (MinIO storage) | **KEEP** | Works well. Ensure consistent namespace in MinIO. |
| Sales inbox PDF harvesting | **RETHINK** | Keep if actively used. Remove hardcoded credentials. Move to background worker with proper scheduling. |
| Per-user mailbox credential storage | **RETHINK** | Currently in-memory (lost on restart). Move to encrypted database storage or Redis with proper key management. |
| Inline HTML email templates (4+ files) | **CUT** | Replace with proper template system (MJML or html template files with variable substitution). |
| V1 + V2 email fetch endpoints | **CUT** | Consolidate into single implementation. |
## 4. Expense / Invoice Features
| Feature | Verdict | Rationale |
| -------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
| Expense CRUD with receipt upload | **KEEP** | Core operational feature. |
| Expense filtering (date, payer, category, payment) | **KEEP** | Essential for operations team. |
| Expense CSV export | **KEEP** | Business reporting need. Fix EUR subtotal + 5% processing fee logic. |
| Expense PDF export | **KEEP** | Business reporting need. Fix 2% net10 discount logic. |
| Expense mark-paid (single + bulk) | **KEEP** | Essential workflow. |
| Invoice generation from expenses | **RETHINK** | Keep functionality. Replace comma-separated `expense_ids` with proper join table. Add database transaction support. |
| Invoice payment tracking | **KEEP** | Core billing workflow. |
| Invoice PDF generation | **RETHINK** | Keep. Standardize on single PDF library (@pdfme). Move templates external. |
| Orphaned invoice cleanup (admin) | **CUT** | Should be unnecessary with proper relational integrity. Keep a reconciliation check as admin tool. |
| Currency conversion (Frankfurter API) | **KEEP** | Needed for multi-currency expenses. Add proper in-memory caching instead of file-based. |
## 5. File Management Features
| Feature | Verdict | Rationale |
| ------------------------------------------ | ----------- | ----------------------------------------------------------------------- |
| File upload/download via MinIO | **KEEP** | Works well. Move credentials to env vars. |
| File browser with folder management | **KEEP** | Core feature for document access. |
| File rename/delete | **KEEP** | Standard file operations. |
| File preview (presigned URLs) | **KEEP** | Good pattern. |
| Email attachments surfaced in file browser | **KEEP** | Useful cross-reference for sales team. |
| File audit logging | **RETHINK** | Currently only prints to console. Wire up to actual `audit_logs` table. |
## 6. Admin Features
| Feature | Verdict | Rationale |
| ----------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
| Audit log viewer | **KEEP** | Essential compliance feature. Expand coverage to all domains. |
| Alert monitoring system (per-type counters, cooldowns) | **KEEP** | Valuable operational feature. Enhance with dashboard. |
| Reminder settings management | **KEEP** | Needed if reminder system is re-enabled. |
| Alert settings management | **KEEP** | Operational configuration. |
| System health dashboard | **RETHINK** | Currently basic stats. Build proper task execution dashboard. |
| Webhook event monitor | **RETHINK** | Currently in-memory only (lost on restart). Persist to database. |
| Debug endpoints (NocoDB config, OIDC session, connectivity tests) | **CUT** | Security risk. Replace with admin-only health check endpoint. |
| Destructive test endpoints (EOI cleanup, berth connection test) | **CUT** | No place in production. Remove entirely. |
## 7. Auth / Security Features
| Feature | Verdict | Rationale |
| ------------------------------------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Keycloak OIDC SSO | **KEEP** | Works well. Clean up implementation (single composable, remove dev bypass from production). |
| Role-based access (admin/sales/user) | **KEEP** | Correct model for the organization. |
| Session caching with TTL + jitter | **KEEP** | Good performance pattern. |
| Circuit breaker on Keycloak calls | **KEEP** | Important resilience pattern. |
| Dev auth bypass | **RETHINK** | Move to server-only config. Add build-time assertion preventing production use. |
| Internal service auth (x-tag header) | **CUT** | Replace with proper HMAC with rotatable env-var secret. |
| Feature flag system | **RETHINK** | The Vuetify→Maritime migration use case is moot. Keep the pattern (dependency chains, rollout %, user targeting) for future feature rollouts. |
## 8. UI / Frontend Features
| Feature | Verdict | Rationale |
| --------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- |
| Maritime Design System (glassmorphism tokens) | **KEEP** | Distinctive visual identity. Reimplement as Tailwind CSS theme extensions. |
| Vuetify components | **CUT** | Drop entirely. Maritime-only in rebuild. |
| Nuxt UI v3 components | **RETHINK** | Evaluate overlap with Headless UI / Radix Vue. Pick one component library. |
| Dashboard layout (sidebar, mobile nav) | **RETHINK** | Rebuild cleanly with single component system. Current version has ~40% duplicate code for dual-system support. |
| Toast notifications | **KEEP** | Standard UX pattern. |
| PWA (workbox, auto-update, 20s sync) | **RETHINK** | Evaluate if sales team actually needs offline/install. If yes, reduce sync frequency. If no, cut. |
| Chart.js visualizations | **KEEP** | Useful for analytics views. |
## 9. Iframe Embeds
| Feature | Verdict | Rationale |
| ---------------------------- | ----------- | ----------------------------------------------------------------------------------------------- |
| Metabase analytics dashboard | **RETHINK** | Keep as iframe OR build native charts. Custom charts integrate better with CRM design language. |
| NocoDB EOI queue view | **CUT** | Replace with native CRM page. NocoDB views bypass auth and don't match UI. |
| NocoDB berth gallery view | **CUT** | Replace with native CRM berth browser. |
| Webmail iframe | **CUT** | Replace with native email UI (EmailCommunication component already exists). |
| Port Nimara AI | **KEEP** | Separate service, keep as iframe. |
| Site analytics (Umami) | **KEEP** | Read-only, low priority. Keep as iframe. |
| Social media marketing | **KEEP** | Third-party service. Keep as iframe. |
| Client support ticketing | **KEEP** | Separate system. Keep as iframe. |
## 10. Infrastructure / Architecture
| Feature | Verdict | Rationale |
| ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NocoDB as primary database | **CUT** | Replace with PostgreSQL + Drizzle ORM. Gains: transactions, migrations, JOINs, type safety, foreign keys. NocoDB can optionally remain as admin read view. |
| Single Nuxt container deployment | **KEEP** | Simple, effective for team size. Add Redis sidecar for sessions/jobs/caching. |
| Docker + Gitea CI/CD | **RETHINK** | Keep. Add test stage before image publish. |
| Nitro experimental tasks + node-cron | **CUT** | Replace with BullMQ + Redis for proper job tracking, retries, dead letter queues. |
| In-memory state (webhook store, credential cache, IMAP pool) | **CUT** | Replace with Redis for shared state that survives restarts. |
| Console.log-based logging | **CUT** | Replace with structured logger (consola with levels). |
| Hardcoded NocoDB table IDs throughout code | **CUT** | Moot with PostgreSQL migration. If keeping NocoDB: centralize in single config module. |
---
## Summary Counts
| Verdict | Count |
| ----------- | ----- |
| **KEEP** | 38 |
| **RETHINK** | 27 |
| **CUT** | 16 |
The rebuild preserves ~80% of current functionality (keep + rethink) while cutting dead code, security risks, and architectural debt.