156 lines
6.9 KiB
Markdown
156 lines
6.9 KiB
Markdown
# Task EP.1.5 Timeline Projection Foundation - 2026-07-13
|
|
|
|
## Scope
|
|
|
|
- introduced first production CRM Business Projection: Timeline
|
|
- added `crm_timeline_projection` materialized read model schema
|
|
- added Timeline event builder and Activity event mapping
|
|
- added Timeline projection consumer contract and active CRM registration
|
|
- added Timeline list/query storage service
|
|
- added Timeline rebuild and legacy adapter contracts
|
|
- added reusable Timeline UI components
|
|
- added optional Activity detail Timeline integration seam
|
|
- preserved Activity, Audit Log, Approval History, follow-up APIs, Dashboard, Reports, Notifications, and current detail-page behavior
|
|
|
|
## Review Summary
|
|
|
|
Reviewed before and during implementation:
|
|
|
|
- `AGENTS.md`
|
|
- `plans/task-ep.1.5.md`
|
|
- `LAYOUT.md`
|
|
- `docs/standards/engineering-constitution.md`
|
|
- `docs/standards/project-foundations.md`
|
|
- `docs/standards/architecture-rules.md`
|
|
- `docs/standards/ui-ux-rules.md`
|
|
- `docs/business/relationship-sales-workspace-blueprint-v1.md`
|
|
- `docs/security/crm-authorization-boundaries.md`
|
|
- `docs/implementation/task-ep1.4-projection-foundation-delivery-reliability-2026-07-13.md`
|
|
- `docs/implementation/task-ep1.4.1-transactional-outbox-activation-worker-runtime-2026-07-13.md`
|
|
- existing Activity business event adapter
|
|
- existing Projection Runtime and Worker
|
|
- existing CRM detail/audit UI patterns
|
|
|
|
## Implementation Summary
|
|
|
|
### Timeline Schema
|
|
|
|
Added table:
|
|
|
|
- `crm_timeline_projection`
|
|
|
|
Generated migration:
|
|
|
|
- `drizzle/0005_freezing_wendigo.sql`
|
|
|
|
The table stores organization-scoped, rebuildable read-model rows with entity references, event provenance, visibility metadata, display fields, and projection version. It has indexes for event id/version idempotency, organization chronology, customer chronology, and activity/event lookup.
|
|
|
|
### Timeline Builder
|
|
|
|
Added:
|
|
|
|
- `src/features/crm/timeline/server/builder.ts`
|
|
|
|
Builder maps Business Events into business-readable Timeline items. Initial active mappings cover Activity lifecycle events:
|
|
|
|
- `activity.created`
|
|
- `activity.assigned`
|
|
- `activity.reassigned`
|
|
- `activity.started`
|
|
- `activity.rescheduled`
|
|
- `activity.completed`
|
|
- `activity.cancelled`
|
|
- `activity.deleted`
|
|
|
|
Generic mapping is available for registered future CRM events until their business copy is specialized.
|
|
|
|
### Timeline Consumer
|
|
|
|
Added:
|
|
|
|
- `src/features/crm/timeline/server/consumer.ts`
|
|
- `src/features/crm/timeline/server/registration.ts`
|
|
|
|
The consumer builds a Timeline item and persists it with idempotent `eventId + sourceProjectionVersion` storage. Foundation default consumers remain safe skeletons; CRM worker startup can opt into `CRM_TIMELINE_PROJECTION_CONSUMERS` for the active Timeline projection set.
|
|
|
|
### Timeline Storage And Query Contract
|
|
|
|
Added:
|
|
|
|
- `src/features/crm/timeline/api/types.ts`
|
|
- `src/features/crm/timeline/server/service.ts`
|
|
|
|
Supported filters include organization, customer, lead, opportunity, quotation, activity, event, category, actor, search, date range, and cursor/limit contract. Timeline remains read-only.
|
|
|
|
### Legacy Adapter And Rebuild Contracts
|
|
|
|
Added:
|
|
|
|
- `src/features/crm/timeline/server/legacy-adapters.ts`
|
|
- `src/features/crm/timeline/server/rebuild.ts`
|
|
|
|
Legacy adapters are explicitly read-only rebuild inputs for lead follow-up, opportunity follow-up, quotation follow-up, activity, approval, and audit history. No data migration was introduced.
|
|
|
|
### Timeline UI
|
|
|
|
Added:
|
|
|
|
- `src/features/crm/timeline/components/timeline-list.tsx`
|
|
|
|
Components:
|
|
|
|
- `TimelineList`
|
|
- `TimelineCard`
|
|
- `TimelineEmpty`
|
|
- `TimelineSkeleton`
|
|
|
|
The UI follows the existing dashboard card language, uses deterministic shared date formatting, shadcn primitives, and app icon registry. It preserves a calm enterprise density while adding a clear vertical chronology.
|
|
|
|
### Workspace Integration
|
|
|
|
Added an optional `timelineItems` prop to Activity detail. Existing callers are unaffected; when supplied, Activity detail renders an additive Timeline card below the existing Activity detail card.
|
|
|
|
## Security Notes
|
|
|
|
- Timeline rows are organization-scoped.
|
|
- Timeline visibility stores product type, pricing sensitivity, and internal-only flags.
|
|
- Pricing-sensitive/internal-only event payloads continue to rely on source event minimization.
|
|
- Timeline query service is storage-ready; route/API exposure must still apply CRM resolved access, branch/product scope, ownership, and pricing visibility before becoming public.
|
|
- Timeline never mutates source domains and does not replace Audit Log.
|
|
|
|
## Delivery Matrix
|
|
|
|
Initial production path:
|
|
|
|
| Business Event | Timeline Item | Workspace | Consumer | Projection |
|
|
| --- | --- | --- | --- | --- |
|
|
| `activity.created` | Activity created | Customer / Lead / Opportunity / Quotation / Activity | `timeline.projection.consumer` | `crm_timeline_projection` |
|
|
| `activity.completed` | Activity completed | Customer / Lead / Opportunity / Quotation / Activity | `timeline.projection.consumer` | `crm_timeline_projection` |
|
|
| `activity.cancelled` | Activity cancelled | Customer / Lead / Opportunity / Quotation / Activity | `timeline.projection.consumer` | `crm_timeline_projection` |
|
|
|
|
Additional Activity events are supported in code and documented in the builder mapping.
|
|
|
|
## UX Review
|
|
|
|
- Layout: follows `LAYOUT.md` detail-card and timeline entry patterns.
|
|
- Density: Timeline cards stay compact, scannable, and fit existing CRM dashboard surfaces.
|
|
- Accessibility: items use semantic `article`, `time`, non-color badges, and text labels.
|
|
- Loading/empty states: `TimelineSkeleton` and `TimelineEmpty` included.
|
|
- Dark mode: tone classes include dark-mode variants.
|
|
- Date rendering: uses `src/lib/date-format.ts`.
|
|
|
|
## Verification
|
|
|
|
- `npm run typecheck`
|
|
- `node --disable-warning=ExperimentalWarning --disable-warning=MODULE_TYPELESS_PACKAGE_JSON --experimental-strip-types --test src/features/foundation/business-events/*.test.ts src/features/foundation/projections/*.test.ts src/features/crm/activities/server/business-events.test.ts src/features/crm/timeline/server/*.test.ts`
|
|
- `npx oxlint src/features/crm/timeline src/features/foundation/projections/registry.ts src/features/foundation/projections/consumers.ts src/features/foundation/projections/server/store.ts src/features/crm/activities/components/activity-detail.tsx src/db/schema.ts`
|
|
- `npm run db:generate`
|
|
|
|
## Residual Risks / Follow-up
|
|
|
|
- Public Timeline route handlers and server-side CRM resolved-access filtering remain future work before exposing Timeline broadly.
|
|
- Customer, Lead, Opportunity, and Quotation detail pages are not yet wired to fetch Timeline data; Activity detail has a backward-compatible render seam.
|
|
- Approval, quotation, opportunity, customer, and PO event mappings have generic fallback support but need specialized business copy when those domains publish durable events.
|
|
- Legacy adapters are contract-only in this slice; source-query rebuild implementation should be expanded as each workspace adopts Timeline.
|
|
- EP.1.6 Calendar can reuse the same projection runtime and Activity event delivery path.
|