shinkan-jinkendo/.cursor/rules/access-layer.mdc
Lars abee6171df
Some checks failed
Deploy Development / deploy (push) Successful in 37s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 6s
Test Suite / playwright-tests (push) Failing after 34s
feat: enhance access layer governance and visibility checks
- Added new documentation references for access layer governance in CLAUDE.md, including multi-tenancy and endpoint audit guidelines.
- Updated ACCESS_LAYER_AND_GOVERNANCE_PLAN.md to include cursor and heuristic checks for access layer compliance.
- Enhanced ACCESS_LAYER_ENDPOINT_AUDIT.md to clarify endpoint visibility and governance requirements, including exemptions for certain routers.
- Introduced library_content_visible_to_profile function in club_tenancy.py to streamline visibility checks for library content.
- Updated exercise progression graphs router to utilize the new visibility function, improving access control.
- Bumped application version to 0.8.27 and updated changelog to reflect these changes.
2026-05-05 22:09:25 +02:00

37 lines
1.8 KiB
Plaintext

---
description: Mandanten & Governance — TenantContext, Sichtbarkeit, keine Schnellpfade
globs: backend/routers/*.py
alwaysApply: false
---
# Zugriffsschicht (Shinkan)
Vor neuen oder geänderten Endpoints in `backend/routers/` kurz prüfen:
1. **Pflichtlektüre** (bei inhaltsbezogenen APIs): `.claude/docs/technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md` und `.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md`.
2. **Auth**: kein geschützter Endpoint ohne `Depends(require_auth)` bzw. eingebettet in `Depends(get_tenant_context)` (der holt die Session bereits).
3. **Verein / Sichtbarkeit** (`visibility`, `club_id`, Mitglieder-Inhalte):
`tenant: TenantContext = Depends(get_tenant_context)` verwenden; Profile-ID aus `tenant.profile_id`, Rolle aus `tenant.global_role`.
4. **Bibliothekslisten** (Übungen, Vorlagen, Rahmenprogramme, Progressionsgraphen, gleiche Semantik): Filter über `library_content_visibility_sql(...)` bzw. gleiche Leseregel wie bestehende Module — nicht „alle Zeilen aus SELECT“.
5. **Schreiben mit Governance**: bei `visibility`/`club_id`-Änderungen `assert_valid_governance_visibility`; bei `club` ohne `club_id` im Body → `tenant.effective_club_id` oder klare 400-Hinweise (wie bei Übungen).
6. **Ausnahmen** nur mit kurzem Kommentar im Code: `# ACCESS_LAYER exempt: …` und Eintrag im Audit oder in `backend/scripts/check_access_layer_hints.py` (EXEMPT-Liste).
7. **Nach Merge**: eine Zeile `.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md` anpassen, wenn sich Tenant oder Governance ändert.
```python
# ❌ Schnellpfad: nur Session, obwohl Vereinsdaten betroffen
@router.get("/foo")
def foo(session=Depends(require_auth)):
...
# ✅ Konsistent zu clubs/exercises/planning
@router.get("/foo")
def foo(tenant: TenantContext = Depends(get_tenant_context)):
...
```