REQ-20260625: General document store for MIME-typed uploads
Date: 2026-06-25
Requestor: the implementation partner (on behalf of the CTN platform)
Priority: High
Status: Submitted
Request Summary
Section titled “Request Summary”A general, reusable capability to store MIME-typed documents (mostly PDF, also scanned images) with their upload metadata, addressable by a stable UUID so that various platform entities can reference them. The first consumer is the onboarding flow (a requestor uploading proof supporting an Onboarding Request), but the store itself must not be onboarding-specific.
Business Context
Section titled “Business Context”Business Driver
Section titled “Business Driver”Participants and applicants must be able to supply supporting documents — registry extracts proving a business-register identifier, a signed acceptance of the consortium contract conditions, and (later) periodic re-validation uploads. The platform needs one trustworthy place to keep these, with provenance (who uploaded, when) and a business-validity (expiry) marker, rather than a per-feature bolt-on.
Stakeholders Affected
Section titled “Stakeholders Affected”- Primary: prospective participants / requestors (upload proof); association back-office admins (review proof).
- Secondary: future organization admins (
OrgAdminRole); future automated re-validation; any later entity that needs to attach documents.
Business Impact
Section titled “Business Impact”- If Implemented: documents become first-class, referenceable, auditable; the onboarding verification flow and future re-validation gain a shared foundation.
- If Not Implemented: each feature invents its own file handling, with inconsistent metadata, provenance and access control.
Technical Requirements
Section titled “Technical Requirements”Functional Requirements
Section titled “Functional Requirements”- Store a MIME-typed document and return a stable UUID identity.
- Persist upload metadata: MIME type, file name, size, business kind (Document Type), optional business-validity expiry, and uploader/timestamps.
- Read a stored document’s bytes and metadata back, API-mediated only.
- Let other entities reference a document by its UUID (the referrer holds the link).
- Govern, per Document Type, whether an expiry date is forbidden / optional / required.
Non-Functional Requirements
Section titled “Non-Functional Requirements”- Performance: metadata listing must not load byte payloads.
- Security: only authenticated users may upload; read restricted to the uploader and association admins; no direct/presigned object access — everything via the API; the design must not preclude later serving user content from an isolated origin.
- Scalability: the byte-storage backend must be swappable (Postgres now, an object store such as MinIO/S3 later) without changing the document model or its references.
- Reliability: stored documents are write-once; corrections are new documents (admins may correct expiry and document type in place).
Integration Requirements
Section titled “Integration Requirements”- Keycloak-issued identities for uploader provenance (
sub) and role checks. - The onboarding flow as first consumer (delegating upload to the document service).
Current State Analysis
Section titled “Current State Analysis”Existing Capabilities
Section titled “Existing Capabilities”- Quarkus + PostgreSQL + Keycloak stack (ADR-00002); JPA entities on
MetaEntity(created/updated by/at, soft-delete); Liquibase owns schema (TDR-0001). - Established SPI-seam pattern (onboarding provider, claim-verification provider).
- Multipart upload precedent (
BulkImportResource). Verificationprecedent for an entity that hangs off an Onboarding Request via a bare id and later relates to a Participant.
Gaps Identified
Section titled “Gaps Identified”- No document/blob storage of any kind.
- No object store in the preferred stack (Postgres only).
- No concept of a stored file’s identity, metadata, or expiry.
Impact on Current Architecture
Section titled “Impact on Current Architecture”- Adds a new core service + entity + a storage SPI; extends ADR-00002’s Postgres-only stack with a seam that anticipates an object store later.
Proposed Approach
Section titled “Proposed Approach”See ADR-00021. In short: a decoupled DocumentService over document + document_blob tables; bytes behind an ObjectStorageProvider SPI with a Postgres-first implementation; referrers hold the document_id.
Success Criteria
Section titled “Success Criteria”Acceptance Criteria
Section titled “Acceptance Criteria”- Storing a document returns a UUID; metadata persisted; bytes round-trip via the Postgres
ObjectStorageProvider. - Per-Document-Type expiry policy enforced at store time.
- MIME allow-list and per-MIME size cap enforced.
- Metadata reads do not load byte payloads.
- Read authorized only for uploader and association admin.
Related Documents
Section titled “Related Documents”Status History
Section titled “Status History”| Date | Status | Reviewer | Notes |
|---|---|---|---|
| 2026-06-25 | Submitted | the implementation partner | Initial submission, drives ADR-00021 |
In samenwerking met




