Product
Phase 1 — CRM Core (+ Phase 1.5 polish)
- Status: ✅ core complete · 🔵 polish ongoing
- Closed: 2026-06-12
Goal
A manual-but-efficient CRM the agency can run on daily: companies, contacts and deals with full CRUD, 360° records with a writable, auto-logged timeline, tasks, appointments, multiple pipelines, fast keyboard navigation, powerful lists, and a real-data dashboard.
Delivered
- Workspace & brand (T-010): Shadcn UI Kit shell, locked Ocean-Breeze brand, self-hosted Satoshi, official logo, custom CRM navigation; server-side auth with a 7-day httpOnly session and a
proxy.tsroute guard. - CRUD (T-011): Companies, Contacts, Deals, Services via server actions (
lib/payload-write.ts), tenant attached on create, toasts, list pages on the sharedDataTable. - 360 + timeline (T-012): contact and deal detail pages with an activity timeline, a "Log activity" dialog, and auto-logged events via Payload
afterChangehooks (stage/owner/lifecycle changes) written in the samereqtransaction (the deadlock fix). Timeline is full-width at the bottom and height-bounded/scrollable; the main column is reserved for the future inbox. - Deal redesign (T-013): primary contact is the anchor; company is derived read-only from the contact; owner + pipeline (Sales/Onboarding/Renewal); linked services (
serviceInterest). - Tasks (T-014): tenant-scoped
taskscollection + global Tasks view (filters, complete, overdue) + a Tasks card on the 360. - Multiple pipelines (T-015): board filter All/Sales/Onboarding/Renewal with per-pipeline counts.
- Command palette + search (T-016): Cmd/Ctrl+K opens a palette that searches contacts/companies/deals live (server-side, tenant-scoped) and navigates to the 360.
- List power (T-017, partial): row selection + bulk delete + faceted filters (lifecycle/stage) + page size, on all four lists.
- Appointments (T-018): tenant-scoped
appointmentscollection + global view (upcoming/past, complete/cancel) + datetime form + a 360 card. - Dashboard (T-019): every default widget wired to real data — win rate, customers, open deals/pipeline value, won revenue, leads-by-source, open tasks, sales pipeline, recent deals.
- Polish (Phase 1.5): owner/assignee defaults to the current user; denser, wider, full-width-select form dialogs (no empty gutters); richer Services (deliveryType, billingType, price, priceUnit) shown on deals and in the catalog.
Data-model additions
New tenant-scoped collections: tasks, appointments. Enriched services (deliveryType, billingType, price, priceUnit). deals.serviceInterest (many-to-many to services) surfaced in the form and the 360.
Key files
apps/crm: components/data-table/, components/crud/ (forms, 360 cards, timeline), lib/payload-write.ts, lib/me.ts, app/dashboard/(auth)/*. apps/cms: collections/{Tasks,Appointments,Services,Deals,Contacts}.ts, hooks/timeline.ts, migrations add_tasks, add_appointments, add_service_fields.
Decisions
Company derived from contact (read-only); UTC in DB; full-width selects (G-07); prod schema via migrations (ADR 0007 / G-24); selects/forms standardised.
GATE
Per-task reports under docs/pm/gate-reports/ (T-014…T-019). Backend verified by real data-layer CRUD with FK joins; routes guarded (307) / protected (403).
Deferred
Saved views + inline editing (T-017b); appointments calendar view + bulk actions; user-configurable pipelines/stages and editable deal cards on the board; surfacing services on the contact 360.