Skip to content

Document Service API

Baseline Endpoints

  • POST /v1/media-assets
  • GET /v1/media-assets
  • GET /v1/media-assets/{id}
  • GET /v1/media-assets/{id}/content
  • POST /v1/storage/presigned-upload
  • POST /v1/storage/media-assets
  • GET /v1/storage/media-assets/{id}
  • GET /v1/storage/media-assets/{id}/content
  • GET /v1/storage/objects/content?storageKey=...
  • GET /healthz
  • GET /readyz

Current Behavior

The current implementation owns media asset metadata for the new Go platform and signs direct browser uploads to S3-compatible storage.

POST /v1/media-assets accepts JSON metadata for an object that already exists or will exist in MinIO/S3-compatible storage:

  • object_key is required.
  • content_type is required and must parse as a media type.
  • size_bytes must be greater than or equal to 0.
  • bucket defaults to hoctapaz-local.
  • organization_id and owner_user_id can be supplied by JSON or the X-Organization-Id and X-User-Id headers.

The service uses hoctapaz_document_db.media_assets when DATABASE_URL is reachable. It falls back to an in-memory store for local skeleton runs.

POST /v1/storage/presigned-upload mirrors the legacy request contract:

  • Request JSON: fileName, mimeType, size, optional purpose.
  • X-Organization-Id supplies the tenant scope while auth/tenant middleware is still pending.
  • Allowed MIME types and upload limits follow legacy StorageService.validateUpload: default max 50MB, classroom-video max 500MB.
  • Response JSON: bucket, storageKey, uploadUrl, publicUrl, expiresIn.
  • Storage key format follows legacy: {organizationId}/{purpose}/{timestamp}-{safeFileName}.

POST /v1/storage/media-assets accepts the legacy frontend payload (fileName, storageKey, mimeType, size, optional checksum, purpose, url) and returns camelCase media asset fields for compatibility.

GET /v1/storage/media-assets/{id}/content streams object bytes from the configured object store and sets Content-Type, Content-Length, and Cache-Control.

For image content, variant=formula trims white background and returns PNG. variant=trim trims white background, adds 8px white padding, and returns PNG. If the image cannot be decoded by the Go stdlib image decoders, the service falls back to the original object bytes and content type.

GET /v1/storage/objects/content?storageKey=... streams object bytes by storage key for internal compatibility adapters such as DOCX Fast create-job migration. When X-Organization-Id is present, the storage key must be equal to that organization id or start with {organizationId}/. This keeps docx-import-service on the document-service API boundary instead of reading document metadata or object storage internals directly.

Runtime storage selection:

  • If MINIO_ENDPOINT or S3_ENDPOINT is set, the service uses the S3-compatible adapter.
  • If no S3/MinIO endpoint is configured, tests and local skeleton runs use an in-memory object store.
  • Docker Compose config signs upload URLs against http://localhost:9902 and reads internally from http://minio:9000.
  • scripts/test/storage-e2e.sh verifies signed PUT plus content read against MinIO/S3-compatible storage.
  • scripts/test/storage-media-parity-smoke.sh compares a real legacy media asset content response with native document-service content in read-only mode. It supports direct native asset-id reads, direct storage-key reads for pre-backfill object parity, and gateway native-route reads.

Legacy Evidence

  • Legacy import/editor media parity relies on /storage/presigned-upload and /storage/media-assets compatibility surfaces.
  • DOCX Fast temp drafts and imported images use shared object storage paths such as system/docx-fast-temp-drafts/<token>.json.
  • Real DOCX import validation expects extracted images to map back into MediaAsset instead of being silently dropped.

Pending Compatibility Work

  • Gateway cutover can use deploy/gateway/routes.storage-native-example.json; default routing remains legacy until quota/variant parity is approved.
  • Materialize DOCX extracted images from docx-import-service through this service boundary.
  • Add parity fixtures for legacy sharp outputs on real imported formula/image assets.
  • Execute scripts/test/storage-media-parity-smoke.sh against representative imported image/formula assets before default route promotion.

Go-platform documentation is generated from repository Markdown.