# 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.