# Roles and Permissions - Implementation Record (MVP)

**Status:** ✅ Implemented (2026-01-08, PR #346, closes #345)
**Related:** [Overview](./roles-and-permissions-overview.md) · [Architecture](./roles-and-permissions-architecture.md)

> Historical record of how the MVP (Phase 1) of the hardcoded Roles & Permissions
> system was built. The architecture document is the canonical design reference;
> the DB migration/rollback steps and the "What's NOT in MVP" boundary now live in
> its [Migration Strategy](./roles-and-permissions-architecture.md#migration-strategy)
> section.

## How the MVP was built

The MVP shipped as **PR #346 (closes #345)** across four week-sized sprints, built
test-first (TDD) with the work split into 15 issues:

- **Sprint 1 — Foundation:** `Role` Ash resource + `users.role_id` FK (#1); hardcoded
  `PermissionSets` module with the 4 sets `own_data`/`read_only`/`normal_user`/`admin` (#2);
  Role CRUD admin LiveViews (#3).
- **Sprint 2 — Policies:** `HasPermission` custom Ash policy check (#6); resource policies
  for Member (#7), User (#8), CustomFieldValue (#9), CustomField (#10); page-permission
  router plug (#11). Issues #7–#11 ran in parallel after #6.
- **Sprint 3 — Special cases & seeds:** linked-member email validation (#12); role seed
  data + default-role assignment (#13).
- **Sprint 4 — UI & integration:** `MvWeb.Authorization` UI helper (`can?/3`,
  `can_access_page?/2`) (#14); admin role-management UI (#15); applying UI authorization
  to existing LiveViews + navbar (#16); per-role integration journey tests (#17).

The 5 seeded roles map to permission sets as: Mitglied → own_data (system role),
Vorstand → read_only, Kassenwart → normal_user, Buchhaltung → read_only, Admin → admin.

Issues #4, #5, #18 (DB-backed permission tables and ETS cache) were intentionally
**not** built — see "What's NOT in MVP" in the architecture document.

## Scope, migration & rollback

For the MVP scope boundary, the DB migration (create `roles`, add `users.role_id`),
the seed step, and the two-tier rollback plan (`mix ecto.rollback` → code revert), see
[Architecture › Migration Strategy](./roles-and-permissions-architecture.md#migration-strategy).
