Appearance
Document Service API
Baseline Endpoints
POST /v1/media-assetsGET /v1/media-assetsGET /v1/media-assets/{id}GET /v1/media-assets/{id}/contentPOST /v1/storage/presigned-uploadPOST /v1/storage/media-assetsGET /v1/storage/media-assets/{id}GET /v1/storage/media-assets/{id}/contentGET /v1/storage/objects/content?storageKey=...GET /healthzGET /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_keyis required.content_typeis required and must parse as a media type.size_bytesmust be greater than or equal to0.bucketdefaults tohoctapaz-local.organization_idandowner_user_idcan be supplied by JSON or theX-Organization-IdandX-User-Idheaders.
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, optionalpurpose. X-Organization-Idsupplies the tenant scope while auth/tenant middleware is still pending.- Allowed MIME types and upload limits follow legacy
StorageService.validateUpload: default max50MB,classroom-videomax500MB. - 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_ENDPOINTorS3_ENDPOINTis 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:9902and reads internally fromhttp://minio:9000. scripts/test/storage-e2e.shverifies signed PUT plus content read against MinIO/S3-compatible storage.scripts/test/storage-media-parity-smoke.shcompares 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-uploadand/storage/media-assetscompatibility 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
MediaAssetinstead 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-servicethrough this service boundary. - Add parity fixtures for legacy
sharpoutputs on real imported formula/image assets. - Execute
scripts/test/storage-media-parity-smoke.shagainst representative imported image/formula assets before default route promotion.