# Task H - PDF Generation and Approved Document Persistence

## Files Added

- `src/features/foundation/pdf-generator/server/service.ts`
- `src/app/api/crm/quotations/[id]/pdf-preview/route.ts`
- `src/app/api/crm/quotations/[id]/pdf-download/route.ts`
- `src/app/api/crm/quotations/[id]/approved-pdf/route.ts`
- `drizzle/0007_luxuriant_malice.sql`

## Files Modified

- `package.json`
- `package-lock.json`
- `src/components/icons.tsx`
- `src/db/schema.ts`
- `src/lib/auth/rbac.ts`
- `src/features/crm/quotations/api/types.ts`
- `src/features/crm/quotations/server/service.ts`
- `src/features/crm/quotations/document/types.ts`
- `src/features/crm/quotations/document/server/service.ts`
- `src/features/foundation/approval/server/service.ts`
- `src/app/dashboard/crm/quotations/[id]/page.tsx`
- `src/features/crm/quotations/components/quotation-detail.tsx`
- `src/features/crm/enquiries/components/enquiry-form-sheet.tsx`
- `src/features/crm/enquiries/schemas/enquiry.schema.ts`
- `src/features/crm/quotations/schemas/quotation.schema.ts`
- `docs/implementation/technical-debt.md`

## PDF Generator Added

- Added production server-side `pdfme` generation in `src/features/foundation/pdf-generator/server/service.ts`.
- Installed:
  - `@pdfme/common`
  - `@pdfme/generator`
  - `@pdfme/schemas`
- Implemented:
  - `generatePdfFromTemplate()`
  - `generateQuotationPdf()`
  - `generateQuotationPreviewPdf()`
  - `generateApprovedQuotationPdf()`
  - `getStoredApprovedQuotationPdf()`

## API Routes Added

- `GET /api/crm/quotations/[id]/pdf-preview`
- `GET /api/crm/quotations/[id]/pdf-download`
- `GET /api/crm/quotations/[id]/approved-pdf`
- `POST /api/crm/quotations/[id]/approved-pdf`

Behavior:

- preview returns inline PDF from current quotation state
- download returns attachment PDF from current quotation state
- approved-pdf POST generates, persists, audits, and returns the approved PDF
- approved-pdf GET streams the already stored approved artifact

## UI Actions Added

Quotation detail now supports:

- `Preview PDF`
- `Download PDF`
- `Generate Approved PDF`
- `View Approved PDF`

The detail page also now displays:

- `Approved At`
- `Approved Template Version`

## Approved Snapshot Persistence

Added quotation persistence fields:

- `approvedAt`
- `approvedPdfUrl`
- `approvedSnapshot`
- `approvedTemplateVersionId`

Approved snapshot now stores:

- quotation id
- approved timestamp
- normalized document data
- template version id
- mapped template input
- generated timestamp
- generated by user id

## Attachment Metadata Integration

After generating an approved PDF:

- a local file is written under `public/generated/quotations/<organizationId>/`
- quotation attachment metadata is created or updated with:
  - `fileName`
  - `originalFileName`
  - `filePath`
  - `fileSize`
  - `fileType = application/pdf`
  - `description = Approved quotation PDF`
  - `uploadedBy`
  - `uploadedAt`

## Permission Added

- `crm.quotation.pdf.preview`
- `crm.quotation.pdf.download`
- `crm.quotation.pdf.generate_approved`

## Audit Integration

Required audit was added for approved PDF generation with:

- `entityType = crm_quotation_pdf_generate_approved`
- `action = generate_approved`

Preview and download remain unaudited by design.

## Remaining Risks

- Current `pdfme` generation uses a font fallback normalization step because the provided templates reference `cordia/cordiaBold`, while direct TTC-based rendering did not behave reliably with table layout generation.
- Approved PDF storage uses local filesystem placeholder output under `public/generated/...`, not external object storage.
- The environment used during implementation had no quotation rows available in the database, so full quotation-specific end-to-end smoke testing through a live record could not be completed here.

## Task I Readiness

Task H leaves the repo ready for:

- auto-generate approved PDF after final approval
- object-storage abstraction
- signed download / retention policy
- immutable approved artifact lifecycle rules
- richer template version publish controls
