task-i
This commit is contained in:
155
docs/implementation/task-i-storage-artifact-lifecycle.md
Normal file
155
docs/implementation/task-i-storage-artifact-lifecycle.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user