# Task E: Quotation Production Module ## 1. Files Added - `src/app/api/crm/quotations/route.ts` - `src/app/api/crm/quotations/[id]/route.ts` - `src/app/api/crm/quotations/[id]/items/route.ts` - `src/app/api/crm/quotations/[id]/items/[itemId]/route.ts` - `src/app/api/crm/quotations/[id]/customers/route.ts` - `src/app/api/crm/quotations/[id]/topics/route.ts` - `src/app/api/crm/quotations/[id]/followups/route.ts` - `src/app/api/crm/quotations/[id]/attachments/route.ts` - `src/app/api/crm/quotations/[id]/revisions/route.ts` - `src/features/crm/quotations/api/types.ts` - `src/features/crm/quotations/api/service.ts` - `src/features/crm/quotations/api/queries.ts` - `src/features/crm/quotations/api/mutations.ts` - `src/features/crm/quotations/schemas/quotation.schema.ts` - `src/features/crm/quotations/server/service.ts` - `src/features/crm/quotations/components/quotation-status-badge.tsx` - `src/features/crm/quotations/components/quotation-form-sheet.tsx` - `src/features/crm/quotations/components/quotation-cell-action.tsx` - `src/features/crm/quotations/components/quotation-columns.tsx` - `src/features/crm/quotations/components/quotations-table.tsx` - `src/features/crm/quotations/components/quotation-listing.tsx` - `src/features/crm/quotations/components/quotation-detail.tsx` - `drizzle/0004_worthless_ender_wiggin.sql` - `drizzle/meta/0004_snapshot.json` ## 2. Files Modified - `src/app/dashboard/crm/quotations/page.tsx` - `src/app/dashboard/crm/quotations/[id]/page.tsx` - `src/app/dashboard/crm/enquiries/[id]/page.tsx` - `src/app/dashboard/crm/customers/[id]/page.tsx` - `src/features/crm/enquiries/components/enquiry-detail.tsx` - `src/features/crm/customers/components/customer-detail.tsx` - `src/db/schema.ts` - `src/db/seeds/foundation.seed.ts` - `src/lib/auth/rbac.ts` - `src/lib/searchparams.ts` - `drizzle/meta/_journal.json` ## 3. Schema Added - `crm_quotations` - organization-scoped quotation master with document code, customer/contact/enquiry linkage, pricing header, status, revision metadata, and soft-delete columns - `crm_quotation_items` - server-calculated line items under quotation - `crm_quotation_customers` - related parties such as owner, consultant, contractor, and billing - `crm_quotation_topics` - quotation document sections such as scope, exclusions, and payment - `crm_quotation_topic_items` - topic bullet items stored under each section - `crm_quotation_followups` - post-send follow-up timeline under quotation - `crm_quotation_attachments` - metadata-only attachment registry for future file-storage integration ## 4. API Routes Added - `GET /api/crm/quotations` - `POST /api/crm/quotations` - `GET /api/crm/quotations/[id]` - `PATCH /api/crm/quotations/[id]` - `DELETE /api/crm/quotations/[id]` - `GET /api/crm/quotations/[id]/items` - `POST /api/crm/quotations/[id]/items` - `PATCH /api/crm/quotations/[id]/items/[itemId]` - `DELETE /api/crm/quotations/[id]/items/[itemId]` - `GET /api/crm/quotations/[id]/customers` - `POST /api/crm/quotations/[id]/customers` - `PATCH /api/crm/quotations/[id]/customers` - `DELETE /api/crm/quotations/[id]/customers` - `GET /api/crm/quotations/[id]/topics` - `POST /api/crm/quotations/[id]/topics` - `PATCH /api/crm/quotations/[id]/topics` - `DELETE /api/crm/quotations/[id]/topics` - `GET /api/crm/quotations/[id]/followups` - `POST /api/crm/quotations/[id]/followups` - `PATCH /api/crm/quotations/[id]/followups` - `DELETE /api/crm/quotations/[id]/followups` - `GET /api/crm/quotations/[id]/attachments` - `POST /api/crm/quotations/[id]/attachments` - `PATCH /api/crm/quotations/[id]/attachments` - `DELETE /api/crm/quotations/[id]/attachments` - `GET /api/crm/quotations/[id]/revisions` - `POST /api/crm/quotations/[id]/revisions` ## 5. UI Routes Completed - `/dashboard/crm/quotations` - production list with React Query, nuqs filters, create button, edit/view/delete actions - filters: search, status, quotation type, branch, customer, enquiry, hot project - `/dashboard/crm/quotations/[id]` - detail page with tabs: Overview, Items, Customers, Topics, Follow-ups, Attachments, Activity, Approval Placeholder, Document Preview Placeholder - revision chain card with create-revision action - `/dashboard/crm/enquiries/[id]` - related quotations tab now shows real quotation links for the enquiry - `/dashboard/crm/customers/[id]` - related documents tab now shows both enquiries and quotations for the customer ## 6. Permissions Used - `crm.quotation.read` - `crm.quotation.create` - `crm.quotation.update` - `crm.quotation.delete` - `crm.quotation.item.manage` - `crm.quotation.customer.manage` - `crm.quotation.topic.manage` - `crm.quotation.followup.manage` - `crm.quotation.attachment.manage` - `crm.quotation.revision.create` Admin defaults include the full quotation permission set. Regular users inherit read access only unless their membership permissions are extended. ## 7. Audit Integration - quotation create/update/delete writes audit entries with `entityType = crm_quotation` - item create/update/delete writes audit entries with `entityType = crm_quotation_item` - related customer create/update/delete writes audit entries with `entityType = crm_quotation_customer` - topic create/update/delete writes audit entries with `entityType = crm_quotation_topic` - follow-up create/update/delete writes audit entries with `entityType = crm_quotation_followup` - attachment metadata create/update/delete writes audit entries with `entityType = crm_quotation_attachment` - quotation detail activity tab now surfaces all quotation-side audit mutations together ## 8. Document Sequence And Totals - quotation create uses `generateNextDocumentCode({ documentType: 'quotation' })` - revisions also consume the same document sequence and keep `parentQuotationId` linkage - item totals are calculated on the server - quotation subtotal, tax, and total are refreshed from current line items after item mutations ## 9. Enquiry And Customer Integration - quotation create/update validates customer, contact, enquiry, branch, and salesman membership against the active organization - selecting an enquiry in the quotation form auto-fills customer/contact/project context where available - enquiry detail now links to real quotations instead of the old Task D placeholder - customer detail now links to both related enquiries and related quotations ## 10. Remaining Risks - quotation item `taxRate` is stored per line, but current aggregate total refresh still uses quotation-header tax for the final quote summary rather than a mixed per-line tax rollup - attachment handling is metadata-only; there is still no binary upload/storage pipeline - revision creation copies header, items, customers, and topics, but does not snapshot follow-ups or attachments - there are still no database foreign keys between quotation tables and the linked CRM entities; organization scoping is enforced in application logic ## 11. Verification - `npx tsc --noEmit` - `npm run gen`