# Task I: Storage Abstraction and Approved Artifact Lifecycle

## 1. Files Added

- `src/features/foundation/storage/types.ts`
- `src/features/foundation/storage/service.ts`
- `src/features/foundation/storage/server/local-provider.ts`
- `src/features/foundation/storage/server/s3-provider.ts`
- `src/features/foundation/storage/server/provider.ts`
- `src/features/foundation/storage/server/checksum.ts`
- `src/features/foundation/document-artifact/server/service.ts`
- `src/app/api/crm/document-artifacts/[id]/download/route.ts`
- `drizzle/0009_lazy_shard.sql`
- `drizzle/meta/0009_snapshot.json`

## 2. Files Modified

- `package.json`
- `package-lock.json`
- `src/db/schema.ts`
- `src/lib/auth/rbac.ts`
- `src/features/foundation/pdf-generator/server/service.ts`
- `src/features/foundation/approval/server/service.ts`
- `src/features/crm/quotations/api/types.ts`
- `src/features/crm/quotations/server/service.ts`
- `src/features/crm/quotations/components/quotation-detail.tsx`
- `src/app/api/crm/quotations/[id]/approved-pdf/route.ts`
- `scripts/seed-task-h1-fixture.js`
- `docs/implementation/technical-debt.md`
- `docs/adr/0009-approved-document-storage-lifecycle.md`

## 3. Storage Provider Added

Added a storage foundation under `src/features/foundation/storage/**`.

Providers:

- local provider for development
- S3 / MinIO-compatible provider for production-oriented storage

Configuration supported:

- `STORAGE_PROVIDER`
- `LOCAL_STORAGE_ROOT`
- `S3_ENDPOINT`
- `S3_REGION`
- `S3_BUCKET`
- `S3_ACCESS_KEY_ID`
- `S3_SECRET_ACCESS_KEY`
- `S3_FORCE_PATH_STYLE`

## 4. Artifact Schema Added

Added `crm_document_artifacts` with:

- organization/entity identity
- document and artifact types
- template version reference
- storage provider and storage key
- file metadata
- checksum
- lifecycle status
- generated / locked / voided metadata
- JSON metadata payload

Added `approved_artifact_id` to `crm_quotations`.

## 5. Approved PDF Refactor

Approved quotation PDFs now:

- write through `StorageProvider.putObject()`
- persist checksum via SHA-256
- create a `crm_document_artifacts` row
- lock the artifact after generation
- update quotation `approvedArtifactId`
- keep `approvedPdfUrl` as compatibility reference in `artifact:<artifactId>` form

Rules enforced:

- only approved quotations can generate approved PDF
- locked approved artifacts cannot be overwritten
- existing active approved artifact blocks silent regeneration

## 6. Secure Download Added

Added secure artifact route:

- `GET /api/crm/document-artifacts/[id]/download`

Updated quotation approved-PDF flow so secure reads resolve artifact metadata from the database and fetch bytes through the storage provider instead of treating public file paths as source of truth.

## 7. UI Updated

Quotation detail now shows approved artifact metadata when available:

- file name
- generated by
- generated at
- checksum short form
- locked status badge

It also shows a legacy warning when a quotation still references old `/generated/...` storage without an artifact record.

## 8. Permissions Added

- `crm.document_artifact.read`
- `crm.document_artifact.download`
- `crm.document_artifact.void`

Defaults were added alongside the existing quotation PDF permissions in RBAC role derivation.

## 9. Audit Integration

Artifact service now audits:

- `create`
- `lock`
- `void`
- `download`

Entity type:

- `crm_document_artifact`

## 10. Compatibility Notes

Compatibility behavior now supports:

- `approvedArtifactId` when present
- `approvedPdfUrl = artifact:<artifactId>` during migration
- legacy `/generated/...` approved PDF paths with warning fallback

Task I intentionally does not bulk-migrate legacy files yet.

## 11. Remaining Risks

- artifact void/regeneration still has no admin UI workflow
- legacy approved PDFs still need one-time migration into artifact storage
- signed-URL delivery is not enabled yet; downloads are still server-streamed
- storage-provider health and bucket policy checks are still operational concerns outside the app

## 12. Task J Readiness

Task I leaves the app ready for:

- richer artifact lifecycle tooling
- legacy-file migration command
- object-storage rollout beyond local development
- future secure delivery strategies such as signed URLs

## 13. Verification

- `npx tsc --noEmit`
- `npm run gen`
