addon-object-storage-minio-s3
Add-on: Object Storage (MinIO/S3)
Use this skill when the project needs durable storage for:
- original uploaded PDFs
- derived markdown/page artifacts
- JSONL artifacts
- report exports
Local dev uses MinIO; production can switch to AWS S3 (or any S3-compatible store) without changing calling code.
Inputs
Collect:
S3_BUCKET: defaultdocuments.S3_REGION: defaultus-east-1(ignored by MinIO but kept for portability).S3_ENDPOINT_URL: for MinIO, typicallyhttp://minio:9000inside compose.
Key Layout (Deterministic)
Use stable keys:
documents/raw/{document_id}.pdfdocuments/markdown/{document_id}.mddocuments/pages/{document_id}/page-{page_number}.mddocuments/jsonl/{document_id}.jsonldocuments/reports/{document_id}.jsondocuments/reports/{document_id}.md(optional)
Integration Workflow (Python)
- Add dependencies:
uv add boto3
- Add a small storage module:
src/{{PY_MODULE}}/storage/
s3.py
s3.py should expose:
put_object_bytes(bucket, key, data, content_type) -> Noneget_object_bytes(bucket, key) -> bytespresign_get_url(bucket, key, expires_seconds) -> str(optional)ensure_bucket(bucket) -> None(used by bootstrap/init)
- Configure via env vars (API + worker share this):
S3_ENDPOINT_URL(set for MinIO)S3_BUCKETAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_REGION(optional)
docker-compose MinIO (Local Dev)
Add a minio service with:
- ports
9000(S3 API) and9001(console) - root creds from env
- a persistent volume
Add a one-shot bucket init step (preferred):
- container runs MinIO client (
mc) to createS3_BUCKETif missing - treat this as idempotent
Guardrails
- Never store PDFs or artifacts solely on local disk in prod paths; always go through object storage abstraction.
- Always persist the
storage_key/object key in Postgres rows so any artifact is reproducible. - Use content-type metadata consistently (
application/pdf,text/markdown,application/json). - Avoid embedding secrets in code or docker-compose; use env vars.
Decision Justification Rule
- Every non-trivial decision must include a concrete justification.
- Capture the alternatives considered and why they were rejected.
- State tradeoffs and residual risks for the chosen option.
- If justification is missing, treat the task as incomplete and surface it as a blocker.
More from ajrlewis/ai-skills
architect-python-uv-fastapi-sqlalchemy
Use when scaffolding production-ready FastAPI services with uv, SQLAlchemy, Alembic, Postgres, Docker, and CI gates.
11addon-rag-ingestion-pipeline
Use when adding multi-format RAG ingest, chunk, embed, and retrieval pipelines; pair with architect-python-uv-batch or architect-python-uv-fastapi-sqlalchemy.
11addon-docling-legal-chunk-embed
Use when you need legal PDF to markdown extraction plus clause chunking and embedding prep; pair with addon-rag-ingestion-pipeline and architect-python-uv-batch.
10addon-llm-ancient-greek-translation
Use when adding Koine or Attic Greek translation to Next.js content flows; pair with ui-editorial-writing-surface and addon-nostr-nip23-longform.
10architect-python-uv-batch
Use when scaffolding production-ready Python uv batch or worker projects with Docker required by default.
10addon-human-pr-review-gate
Use when agent-generated code must pass a human PR review gate with trusted checks and merge blocks; pair with addon-decision-justification-ledger and architect-stack-selector.
9