Files
familienarchiv/.specify/features/_example/adr-001-avatars-reuse-archive-bucket.md
Marcel fdc3e4ffa9 feat(sdd): add .specify scaffold — constitution, AGENTS, personas, templates, example, RTM
Introduces the SDD root: a v1.0.0 constitution and machine-readable AGENTS.md
grounded in the project's real conventions; six EARS-aware persona spec-review
checklists that cross-reference .claude/personas/; feature-spec/ADR/threat-model/
api-contract templates; a fully worked _example feature; a living RTM; and an
adrs/ pointer that reuses the existing docs/adr/ archive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 12:55:26 +02:00

2.5 KiB

ADR-001 (feature-local) — Avatars reuse the archive bucket under an avatars/ prefix

Status: Accepted Date: 2026-06-13 Issue: # (profile picture upload)

Feature-local ADR. This decision is scoped to the avatar feature and lives with its spec. A decision with project-wide reach is promoted to the permanent archive at docs/adr/ with the next free number. (For the worked example, it stays local.)

Context

Avatars are small binary objects keyed per user. The project already runs MinIO with a single archive bucket and a FileService abstraction used by document uploads. We must decide where avatar bytes live without adding operational surface that the self-hosted Compose deployment has to learn about.

Decision

Store each avatar in the existing archive bucket under the deterministic key avatars/{userId}, written and read through the existing FileService. No new bucket, no new env var, no new Compose service or bucket-bootstrap step.

Alternatives Considered

Option Pros Cons Reason rejected
Reuse archive bucket, avatars/ prefix No infra change; reuses FileService; idempotent overwrite Mixes avatars with documents in one bucket Chosen — least operational cost; prefix keeps them logically separate
Dedicated avatars bucket Clean separation; independent lifecycle/policy New bucket + bootstrap step + env var + Compose idempotency test Operational overhead not justified for small, low-value objects
Store bytes in PostgreSQL (bytea) One datastore; transactional with the row Bloats the DB and backups; streaming images via JPA is awkward Wrong tool; MinIO already exists for blobs
External CDN / object store Offloads bandwidth New third-party dependency + secret + ADR; conflicts with self-hosted goal Contradicts the self-hosted infrastructure stance

Consequences

  • No deployment change ships with this feature — only a Flyway column and code.
  • Avatars and documents share a bucket; any future per-object lifecycle policy must filter by the avatars/ prefix.
  • The deterministic key (avatars/{userId}, no random suffix) makes replace an overwrite, so there is no orphan-cleanup obligation (REQ-001).
  • If avatars later need independent retention or a public CDN, this ADR is superseded by a project-wide ADR in docs/adr/.

References