Files
alla-allaos-fullstack/docs/implementation/task-i-storage-artifact-lifecycle.md
phaichayon 0a484e0b45 task-i
2026-06-16 17:01:29 +07:00

4.2 KiB

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