Files
content-factory/tasks/014-assets-and-media-library.md
T

4.3 KiB

Task 014: Assets And Media Library

Development description: Implement asset specifications, generated or uploaded asset records, object-storage file handling, approval/rejection, replacement, and a media library view.

Implementation Details

  • Backend endpoints:
    • POST /api/articles/{article_id}/assets/generate-specs
    • GET /api/articles/{article_id}/assets
    • PATCH /api/articles/{article_id}/assets/{asset_id}
    • POST /api/articles/{article_id}/assets/{asset_id}/approve
    • Upload/replacement endpoint for asset files.
  • Asset types:
    • Hero image.
    • Inline diagram.
    • Table.
    • Flowchart.
    • Comparison matrix.
    • Architecture diagram.
    • Inline image.
  • Asset record fields:
    • Title.
    • Type.
    • Prompt or diagram/table code.
    • File URL/object key.
    • Alt text.
    • Caption.
    • Status.
    • Linked section/article.
  • Frontend:
    • Asset review page.
    • Media library.
    • Replacement upload.
    • Approval/rejection controls.

Public Interface

  • Editor reviews generated asset specs.
  • Editor approves, rejects, or replaces assets.
  • Approved assets are included in draft/publish bundle.

Acceptance Criteria

  • TDD pre-requirement: before implementation, write one failing public API test for approving an asset and seeing it become available to the article; proceed one asset behavior at a time and record evidence in Result.
  • Asset specs are generated and linked to article or section.
  • File uploads store objects in object storage and persist object keys.
  • Asset approval writes workflow event.
  • Rejected assets are excluded from publish bundle.
  • Replacement preserves audit history.
  • Media library lists article assets with status, type, title, preview/file link, alt text, and caption.
  • Draft preview uses approved asset references where available.

Verification

  • Run asset API tests.
  • Run object-storage upload integration tests.
  • Run frontend media library tests.
  • Run smoke flow approving and replacing an asset.

Result

  • Status: Implementation completed, acceptance criteria closed.
  • TDD plan:
    1. Keep RED pre-requirement test that calls approve API and asserts asset visibility in article context.
    2. Expand integration tests to cover full assets lifecycle: specs generation, upload, approve/reject, replacement audit, and draft-facing inclusion/exclusion behavior.
    3. Implement API contracts + persistence + routes + object storage integration.
    4. Add frontend media library model/UI and draft preview asset reference resolution.
  • Red evidence:
    • Initial pre-requirement failure: POST /api/articles/{article_id}/assets/{asset_id}/approve returned 404 Not Found.
    • During implementation hardening: transient runtime bug NameError: name 'approved' is not defined in approve_asset (fixed), confirmed by rerun to green.
  • Green evidence:
    • Backend assets suite now green with 7 integration tests, including:
      • specs linked to sections,
      • upload persists object_key and writes object file,
      • approval writes workflow event,
      • rejected asset excluded from assembled draft publish-facing data,
      • replacement keeps full audit history.
    • Draft assembly and parallel production suites remain green after assets integration.
    • Frontend media-library model tests and typecheck are green.
  • Refactor notes:
    • Added dedicated assets application module and routes.
    • Extended object storage adapter with put_bytes.
    • Added persistent asset_revisions history table and API-visible history payload.
    • Updated shared OpenAPI contracts and generated TS types.
  • Verification output:
    • PYTHONPATH=/private/tmp/pupline-backend-deps python3 -m unittest apps/backend/tests/integration/test_assets_media_library_public_api.py
      • Ran 7 tests ... OK
    • PYTHONPATH=/private/tmp/pupline-backend-deps python3 -m unittest apps/backend/tests/integration/test_draft_assembly_public_api.py
      • Ran 5 tests ... OK
    • PYTHONPATH=/private/tmp/pupline-backend-deps python3 -m unittest apps/backend/tests/integration/test_parallel_production_public_api.py
      • Ran 6 tests ... OK
    • node apps/frontend/tests/article_assets.model.test.mjs
      • OK (exit code 0)
    • node apps/frontend/tests/draft_editor.model.test.mjs
      • OK (exit code 0)
    • pnpm --dir apps/frontend typecheck
      • tsc --noEmit completed successfully.