docs: update group concept

This commit is contained in:
Simon 2026-01-19 11:53:14 +01:00
parent 1d1f3b16b1
commit 1c7c56130d
Signed by: simon
GPG key ID: 40E7A58C4AA1EDB2

View file

@ -117,10 +117,10 @@ CREATE TABLE groups (
description TEXT,
inserted_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
CONSTRAINT groups_name_unique UNIQUE (name)
CONSTRAINT groups_name_unique UNIQUE (LOWER(name))
);
CREATE INDEX groups_name_index ON groups(name);
CREATE INDEX groups_name_index ON groups(LOWER(name));
```
**Attributes:**
@ -130,7 +130,7 @@ CREATE INDEX groups_name_index ON groups(name);
- `inserted_at` / `updated_at` - Timestamps
**Constraints:**
- `name` must be unique
- `name` must be unique (case-insensitive, using LOWER(name))
- `name` cannot be null
- `name` max length: 100 characters
- `description` max length: 500 characters
@ -194,7 +194,7 @@ end
- `destroy` - Delete group (with confirmation)
**Validations:**
- `name` required, unique, max 100 chars
- `name` required, unique (case-insensitive), max 100 chars
- `description` optional, max 500 chars
#### `Mv.Membership.MemberGroup`
@ -319,7 +319,7 @@ end
- Display group badges for each member
- Badge shows group name
- Multiple badges if member in multiple groups
- Click badge to filter by that group
- *(Optional)* Click badge to filter by that group (enhanced UX, can be added later)
**Filtering:**
- Dropdown/select to filter by group
@ -374,7 +374,11 @@ end
</span>
```
**Clickable Group Badge (for filtering):**
**Clickable Group Badge (for filtering) - Optional:**
**Note:** This is an optional enhancement. The dropdown filter provides the same functionality. The clickable badge improves UX by showing the active filter visually and allowing quick removal.
**Estimated effort:** 1.5-2.5 hours
```heex
<button
@ -712,13 +716,13 @@ Das MVP umfasst die **grundlegenden Funktionen**, die notwendig sind, um Gruppen
7. ✅ Nach Gruppen filtern
8. ✅ Nach Gruppen sortieren
9. ✅ Gruppen in Mitgliederdetail anzeigen
10. ✅ Gruppen in Mitgliedersuche (automatisch via search_vector)
**Nicht im MVP:**
- ❌ Hierarchische Gruppen
- ❌ Rollen/Positionen in Gruppen
- ❌ Erweiterte Gruppenattribute (Datum, Status, etc.)
- ❌ Gruppen-spezifische Berechtigungen
- ❌ Gruppen in Mitgliedersuche (kann später kommen)
### Fachliche Einheiten (Vertikale Slices)
@ -846,11 +850,9 @@ Das MVP umfasst die **grundlegenden Funktionen**, die notwendig sind, um Gruppen
- ✅ Einheit 3: Gruppen-Verwaltungs-UI
- ✅ Einheit 4: Gruppen in Mitgliederübersicht
- ✅ Einheit 5: Gruppen in Mitgliederdetail
- ✅ Einheit 6: Gruppen in Mitgliedersuche (automatisch via search_vector)
- ✅ Einheit 7: Berechtigungen
**Optional für MVP (kann später kommen):**
- ⏸️ Einheit 6: Gruppen in Mitgliedersuche (kann in Phase 2 kommen)
**Total MVP Estimation:** 13-15h
### Implementierungsreihenfolge
@ -947,11 +949,13 @@ Jede fachliche Einheit kann als **separates Issue** umgesetzt werden:
3. Group filter dropdown
4. Group sorting
5. URL query param persistence
6. *(Optional)* Clickable group badges for filtering (enhanced UX)
**Deliverables:**
- Groups visible in member overview
- Filter by group
- Filter by group (via dropdown)
- Sort by group
- *(Optional)* Clickable badges for quick filtering
**Estimation:** 2-3h
@ -1046,12 +1050,14 @@ Jede fachliche Einheit kann als **separates Issue** umgesetzt werden:
- Group filter dropdown
- Group sorting
- URL persistence
- *(Optional)* Clickable group badges for filtering
**Acceptance Criteria:**
- Groups visible in member overview
- Can filter by group
- Can filter by group (via dropdown)
- Can sort by group
- Filter persists in URL
- *(Optional)* Can filter by clicking group badge
### Issue 4: Member Detail - Groups Display
**Type:** Frontend
@ -1069,13 +1075,16 @@ Jede fachliche Einheit kann als **separates Issue** umgesetzt werden:
**Type:** Backend
**Estimation:** 2h
**Tasks:**
- Update search vector trigger
- Extend fuzzy search
- Test search
- Update search vector trigger to include group names
- Extend fuzzy search to search group names
- Test search functionality
**Acceptance Criteria:**
- Group names searchable in member search
- Group names searchable in member search (automatic via search_vector)
- Search finds members by group name
- Search vector updates automatically when member-group associations change
**Note:** This is part of MVP as group names are automatically included in full-text search once the search_vector trigger is updated.
### Issue 6: Authorization
**Type:** Backend/Frontend
@ -1132,11 +1141,12 @@ defmodule Mv.Membership.GroupTest do
assert %{name: ["has already been taken"]} = errors_on(changeset)
end
test "name uniqueness is case-sensitive" do
test "name uniqueness is case-insensitive" do
Group.create!(%{name: "Vorstand"})
attrs = %{name: "VORSTAND"}
# For MVP: case-sensitive uniqueness
assert {:ok, _} = Group.create(attrs)
# Name uniqueness should be case-insensitive
assert {:error, changeset} = Group.create(attrs)
assert %{name: ["has already been taken"]} = errors_on(changeset)
end
test "allows description to be nil" do
@ -1458,8 +1468,8 @@ create table(:groups, primary_key: false) do
add :updated_at, :utc_datetime_usec, null: false
end
create unique_index(:groups, [:name])
create index(:groups, [:name])
create unique_index(:groups, [fragment("LOWER(name)")], name: :groups_name_unique)
create index(:groups, [fragment("LOWER(name)")], name: :groups_name_index)
```
**Migration 2: Create member_groups join table**