electric-horses-infra/docs/adr/README.md
Benjamin Weinlich 09925f7eda docs(adr): add ADR-0007 on OIDC avatar data-URL gotcha
When a new user logs in via Authentik OIDC for the first time,
Forgejo tries to fetch the 'picture' claim as an avatar — but
Authentik delivers a 'data:image/svg+xml;base64,...' URL that
Forgejo can't store. Result: DB has an avatar hash but no file,
so /avatars/<hash> returns 404, the <img> is in broken state,
and the activity page's canvas renderer crashes with
'drawImage on broken state'.

Fix (per user, after first login):
  UPDATE "user" SET avatar = '', use_custom_avatar = false
  WHERE lower_name = '<name>';

Triggers Forgejo's default identicon generation, which works.

This commit:
- Adds ADR-0007 with full root cause + three rejected alternatives
- Updates docs/adr/README.md index
- Extends stacks/forgejo/Agent.md 'Known Gotchas' with the fix
- Appends the fix to docs/runbooks/forgejo-admin-recovery.md

Applied for user 'bw' already on 2026-04-12.

Refs OP#1119
2026-04-12 04:47:25 +02:00

2.4 KiB

Architecture Decision Records

Dieses Verzeichnis enthält ADRs — kurze Markdown-Dokumente die einzelne Architektur-Entscheidungen festhalten. Das Pattern kommt von Michael Nygard und ist gemeinsamer Standard in vielen Open-Source-Projekten.

Warum ADRs?

  • Warum, nicht Wie: Der Code ändert sich. Die Intention soll bleiben. Eine ADR erklärt warum etwas so gebaut wurde — in einem halben Jahr weiß niemand mehr sonst.
  • Referenz für AI-Sessions: Wenn die AI morgen eine Änderung vorschlägt, die eine bestehende Entscheidung umkehrt, soll sie das bewusst tun und neue ADR schreiben, nicht versehentlich.
  • Audit-Trail: Jede ADR hat Status, Datum und Entscheider. Das ist Compliance-ready.

Format

Jede ADR folgt grob diesem Schema:

# ADR-NNNN: <Titel>
Status: Proposed | Accepted | Superseded by ADR-NNNN | Deprecated
Datum: YYYY-MM-DD
Entscheider: <Name>
Phase: <OpenProject Phase oder Sprint>

## Kontext
Was war das Problem? Welche Optionen standen zur Wahl?

## Entscheidung
Was wurde gewählt?

## Begründung
Warum genau diese Option? Welche Prinzipien waren leitend?

## Konsequenzen
- **Positiv:** Was gewinnen wir?
- **Negativ/Trade-off:** Was geben wir auf?

## Alternativen
Was wurde verworfen und warum?

Nummerierung

Fortlaufend NNNN beginnend bei 0001. Niemals alte ADRs ändern — superseden via neue ADR mit Verweis. Die Historie ist die Wahrheit.

Aktuelle ADRs (alle aus M7.1 — Forgejo Deployment)

# Titel Status
0001 Forgejo statt Gitea Accepted
0002 Forgejo auf ai-apps, nicht separate VM Accepted
0003 Natives OIDC statt ForwardAuth Accepted
0004 Subdomain code.sdda.eu Accepted
0005 Volume-Mount auf /data Accepted (Lesson Learned)
0006 Silent SSO via OAuth2-Initiate-Launch-URL Accepted (Lesson Learned)
0007 OIDC-Avatar als data-URL bricht Canvas-Renderer Accepted (Lesson Learned)

Vorlage für neue ADRs

Copy-and-paste Startpunkt:

# ADR-NNNN: <Titel>

**Status:** Proposed
**Datum:** YYYY-MM-DD
**Entscheider:** <Name>
**Phase:** <OpenProject>

## Kontext

## Entscheidung

## Begründung

## Konsequenzen

### Positiv

### Negativ / Trade-off

## Alternativen

## Referenzen