WIP: Update docs #349

Draft
moritz wants to merge 2 commits from docs/update into main
12 changed files with 325 additions and 3679 deletions
Showing only changes of commit 6a9229c54f - Show all commits

View file

@ -107,6 +107,11 @@ lib/
│ ├── membership/ # Domain-specific logic │ ├── membership/ # Domain-specific logic
│ │ └── member/ │ │ └── member/
│ │ └── validations/ │ │ └── validations/
│ ├── membership_fees/ # Membership fee business logic
│ │ ├── cycle_generator.ex # Cycle generation algorithm
│ │ └── calendar_cycles.ex # Calendar cycle calculations
│ ├── helpers.ex # Shared helper functions (ash_actor_opts)
│ ├── constants.ex # Application constants (member_fields, custom_field_prefix)
│ ├── application.ex # OTP application │ ├── application.ex # OTP application
│ ├── mailer.ex # Email mailer │ ├── mailer.ex # Email mailer
│ ├── release.ex # Release tasks │ ├── release.ex # Release tasks
@ -127,6 +132,11 @@ lib/
│ │ ├── error_html.ex │ │ ├── error_html.ex
│ │ ├── error_json.ex │ │ ├── error_json.ex
│ │ └── page_html/ │ │ └── page_html/
│ ├── helpers/ # Web layer helper modules
│ │ ├── member_helpers.ex # Member display utilities
│ │ ├── membership_fee_helpers.ex # Membership fee formatting
│ │ ├── date_formatter.ex # Date formatting utilities
│ │ └── field_type_formatter.ex # Field type display formatting
│ ├── live/ # LiveView modules │ ├── live/ # LiveView modules
│ │ ├── components/ # LiveView-specific components │ │ ├── components/ # LiveView-specific components
│ │ │ ├── search_bar_component.ex │ │ │ ├── search_bar_component.ex
@ -143,7 +153,7 @@ lib/
│ ├── auth_overrides.ex # AshAuthentication overrides │ ├── auth_overrides.ex # AshAuthentication overrides
│ ├── endpoint.ex # Phoenix endpoint │ ├── endpoint.ex # Phoenix endpoint
│ ├── gettext.ex # I18n configuration │ ├── gettext.ex # I18n configuration
│ ├── live_helpers.ex # LiveView helpers │ ├── live_helpers.ex # LiveView lifecycle hooks and helpers
│ ├── live_user_auth.ex # LiveView authentication │ ├── live_user_auth.ex # LiveView authentication
│ ├── router.ex # Application router │ ├── router.ex # Application router
│ └── telemetry.ex # Telemetry configuration │ └── telemetry.ex # Telemetry configuration
@ -192,7 +202,7 @@ test/
**Module Naming:** **Module Naming:**
- **Modules:** Use `PascalCase` with full namespace (e.g., `Mv.Accounts.User`) - **Modules:** Use `PascalCase` with full namespace (e.g., `Mv.Accounts.User`)
- **Domains:** Top-level domains are `Mv.Accounts` and `Mv.Membership` - **Domains:** Top-level domains are `Mv.Accounts`, `Mv.Membership`, `Mv.MembershipFees`, and `Mv.Authorization`
- **Resources:** Resource modules should be singular nouns (e.g., `Member`, not `Members`) - **Resources:** Resource modules should be singular nouns (e.g., `Member`, not `Members`)
- **Context functions:** Use `snake_case` and verb-first naming (e.g., `create_user`, `list_members`) - **Context functions:** Use `snake_case` and verb-first naming (e.g., `create_user`, `list_members`)

View file

@ -189,8 +189,9 @@ The `OIDC_REDIRECT_URI` is auto-generated as `https://{DOMAIN}/auth/user/rauthy/
- **Auth:** AshAuthentication (OIDC + password) - **Auth:** AshAuthentication (OIDC + password)
**Code Structure:** **Code Structure:**
- `lib/accounts/` & `lib/membership/` — Ash resources and domains - `lib/accounts/` & `lib/membership/` & `lib/membership_fees/` & `lib/mv/authorization/` — Ash resources and domains
- `lib/mv_web/` — Phoenix controllers, LiveViews, components - `lib/mv_web/` — Phoenix controllers, LiveViews, components
- `lib/mv/` — Shared helpers and business logic
- `assets/` — Tailwind, JavaScript, static files - `assets/` — Tailwind, JavaScript, static files
📚 **Full tech stack details:** See [`CODE_GUIDELINES.md`](CODE_GUIDELINES.md) 📚 **Full tech stack details:** See [`CODE_GUIDELINES.md`](CODE_GUIDELINES.md)

View file

@ -187,7 +187,6 @@ Settings (1) → MembershipFeeType (0..1)
- `email` (B-tree) - Exact email lookups - `email` (B-tree) - Exact email lookups
- `last_name` (B-tree) - Name sorting - `last_name` (B-tree) - Name sorting
- `join_date` (B-tree) - Date filtering - `join_date` (B-tree) - Date filtering
- `paid` (partial B-tree) - Payment status queries
**custom_field_values:** **custom_field_values:**
- `member_id` - Member custom field value lookups - `member_id` - Member custom field value lookups
@ -214,14 +213,14 @@ Settings (1) → MembershipFeeType (0..1)
### Weighted Fields ### Weighted Fields
- **Weight A (highest):** first_name, last_name - **Weight A (highest):** first_name, last_name
- **Weight B:** email, notes - **Weight B:** email, notes
- **Weight C:** phone_number, city, street, house_number, postal_code, custom_field_values - **Weight C:** city, street, house_number, postal_code, custom_field_values
- **Weight D (lowest):** join_date, exit_date - **Weight D (lowest):** join_date, exit_date
### Custom Field Values in Search ### Custom Field Values in Search
Custom field values are automatically included in the search vector: Custom field values are automatically included in the search vector:
- All custom field values (string, integer, boolean, date, email) are aggregated and added to the search vector - All custom field values (string, integer, boolean, date, email) are aggregated and added to the search vector
- Values are converted to text format for indexing - Values are converted to text format for indexing
- Custom field values receive weight 'C' (same as phone_number, city, etc.) - Custom field values receive weight 'C' (same as city, etc.)
- The search vector is automatically updated when custom field values are created, updated, or deleted via database triggers - The search vector is automatically updated when custom field values are created, updated, or deleted via database triggers
### Usage Example ### Usage Example
@ -377,7 +376,7 @@ priv/repo/migrations/
**High Frequency:** **High Frequency:**
- Member search (uses GIN index on search_vector) - Member search (uses GIN index on search_vector)
- Member list with filters (uses indexes on join_date, paid) - Member list with filters (uses indexes on join_date, membership_fee_type_id)
- User authentication (uses unique index on email/oidc_id) - User authentication (uses unique index on email/oidc_id)
- CustomFieldValue lookups by member (uses index on member_id) - CustomFieldValue lookups by member (uses index on member_id)
@ -396,7 +395,7 @@ priv/repo/migrations/
1. **Use indexes:** All critical query paths have indexes 1. **Use indexes:** All critical query paths have indexes
2. **Preload relationships:** Use Ash's `load` to avoid N+1 2. **Preload relationships:** Use Ash's `load` to avoid N+1
3. **Pagination:** Use keyset pagination (configured by default) 3. **Pagination:** Use keyset pagination (configured by default)
4. **Partial indexes:** `members.paid` index only non-NULL values 4. **GIN indexes:** Full-text search and fuzzy search on multiple fields
5. **Search optimization:** Full-text search via tsvector, not LIKE 5. **Search optimization:** Full-text search via tsvector, not LIKE
## Visualization ## Visualization

View file

@ -121,11 +121,9 @@ Table tokens {
Table members { Table members {
id uuid [pk, not null, default: `uuid_generate_v7()`, note: 'UUIDv7 primary key (sortable by creation time)'] id uuid [pk, not null, default: `uuid_generate_v7()`, note: 'UUIDv7 primary key (sortable by creation time)']
first_name text [not null, note: 'Member first name (min length: 1)'] first_name text [null, note: 'Member first name (min length: 1 if present)']
last_name text [not null, note: 'Member last name (min length: 1)'] last_name text [null, note: 'Member last name (min length: 1 if present)']
email text [not null, unique, note: 'Member email address (5-254 chars, validated)'] email text [not null, unique, note: 'Member email address (5-254 chars, validated)']
paid boolean [null, note: 'Payment status flag']
phone_number text [null, note: 'Contact phone number (format: +?[0-9\- ]{6,20})']
join_date date [null, note: 'Date when member joined club (cannot be in future)'] join_date date [null, note: 'Date when member joined club (cannot be in future)']
exit_date date [null, note: 'Date when member left club (must be after join_date)'] exit_date date [null, note: 'Date when member left club (must be after join_date)']
notes text [null, note: 'Additional notes about member'] notes text [null, note: 'Additional notes about member']
@ -149,7 +147,6 @@ Table members {
email [name: 'members_email_idx', note: 'B-tree index for exact lookups'] email [name: 'members_email_idx', note: 'B-tree index for exact lookups']
last_name [name: 'members_last_name_idx', note: 'B-tree index for name sorting'] last_name [name: 'members_last_name_idx', note: 'B-tree index for name sorting']
join_date [name: 'members_join_date_idx', note: 'B-tree index for date filters'] join_date [name: 'members_join_date_idx', note: 'B-tree index for date filters']
(paid) [name: 'members_paid_idx', type: btree, note: 'Partial index WHERE paid IS NOT NULL']
membership_fee_type_id [name: 'members_membership_fee_type_id_index', note: 'B-tree index for fee type lookups'] membership_fee_type_id [name: 'members_membership_fee_type_id_index', note: 'B-tree index for fee type lookups']
} }
@ -158,8 +155,8 @@ Table members {
Core entity for membership management containing: Core entity for membership management containing:
- Personal information (name, email) - Personal information (name, email)
- Contact details (phone, address) - Contact details (address)
- Membership status (join/exit dates, payment status) - Membership status (join/exit dates, membership fee cycles)
- Additional notes - Additional notes
**Email Synchronization:** **Email Synchronization:**
@ -187,12 +184,11 @@ Table members {
- 1:N with membership_fee_cycles - billing history - 1:N with membership_fee_cycles - billing history
**Validation Rules:** **Validation Rules:**
- first_name, last_name: min 1 character - first_name, last_name: optional, but if present min 1 character
- email: 5-254 characters, valid email format - email: 5-254 characters, valid email format (required)
- join_date: cannot be in future - join_date: cannot be in future
- exit_date: must be after join_date (if both present) - exit_date: must be after join_date (if both present)
- phone_number: matches pattern ^\+?[0-9\- ]{6,20}$ - postal_code: exactly 5 digits (if present)
- postal_code: exactly 5 digits
''' '''
} }

View file

@ -68,7 +68,7 @@ mix phx.new mv --no-ecto --no-mailer
**Key decisions:** **Key decisions:**
- **Elixir 1.18.3 + OTP 27**: Latest stable versions for performance - **Elixir 1.18.3 + OTP 27**: Latest stable versions for performance
- **Ash Framework 3.0**: Declarative resource layer, reduces boilerplate - **Ash Framework 3.0**: Declarative resource layer, reduces boilerplate
- **Phoenix LiveView 1.1**: Real-time UI without JavaScript complexity - **Phoenix LiveView 1.1.0-rc.3**: Real-time UI without JavaScript complexity
- **Tailwind CSS 4.0**: Utility-first styling with custom build - **Tailwind CSS 4.0**: Utility-first styling with custom build
- **PostgreSQL 17**: Advanced features (full-text search, JSONB, citext) - **PostgreSQL 17**: Advanced features (full-text search, JSONB, citext)
- **Bandit**: Modern HTTP server, better than Cowboy for LiveView - **Bandit**: Modern HTTP server, better than Cowboy for LiveView
@ -80,14 +80,15 @@ mix phx.new mv --no-ecto --no-mailer
**Versions pinned in `.tool-versions`:** **Versions pinned in `.tool-versions`:**
- Elixir 1.18.3-otp-27 - Elixir 1.18.3-otp-27
- Erlang 27.3.4 - Erlang 27.3.4
- Just 1.43.0 - Just 1.46.0
#### 4. Database Setup #### 4. Database Setup
**PostgreSQL Extensions:** **PostgreSQL Extensions:**
```sql ```sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generation CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generation (via uuid_generate_v7 function)
CREATE EXTENSION IF NOT EXISTS "citext"; -- Case-insensitive text CREATE EXTENSION IF NOT EXISTS "citext"; -- Case-insensitive text
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- Trigram-based fuzzy search
``` ```
**Migration Strategy:** **Migration Strategy:**
@ -468,7 +469,7 @@ end
- **Tailwind:** Utility-first, no custom CSS - **Tailwind:** Utility-first, no custom CSS
- **DaisyUI:** Pre-built components, consistent design - **DaisyUI:** Pre-built components, consistent design
- **Heroicons:** Icon library, inline SVG - **Heroicons:** Icon library, inline SVG
- **Phoenix LiveView:** Server-rendered, minimal JavaScript - **Phoenix LiveView 1.1.0-rc.3:** Server-rendered, minimal JavaScript
**Trade-offs:** **Trade-offs:**
- Larger HTML (utility classes) - Larger HTML (utility classes)
@ -598,14 +599,33 @@ end
#### Database Migrations #### Database Migrations
**Key migrations in chronological order:** **Key migrations in chronological order (26 total):**
1. `20250528163901_initial_migration.exs` - Core tables (members, custom_field_values, custom_fields) 1. `20250421101957_initialize_extensions_1.exs` - PostgreSQL extensions (uuid-ossp, citext, pg_trgm)
2. `20250617090641_member_fields.exs` - Member attributes expansion 2. `20250528163901_initial_migration.exs` - Core tables (members, custom_field_values, custom_fields - originally property_types/properties)
3. `20250620110850_add_accounts_domain.exs` - Users & tokens tables 3. `20250617090641_member_fields.exs` - Member attributes expansion
4. `20250912085235_AddSearchVectorToMembers.exs` - Full-text search (tsvector + GIN index) 4. `20250617132424_member_delete.exs` - Member deletion constraints
5. `20250926164519_member_relation.exs` - User-Member link (optional 1:1) 5. `20250620110849_add_accounts_domain_extensions.exs` - Accounts domain extensions
6. `20251001141005_add_trigram_to_members.exs` - Fuzzy search (pg_trgm + 6 GIN trigram indexes) 6. `20250620110850_add_accounts_domain.exs` - Users & tokens tables
7. `20251016130855_add_constraints_for_user_member_and_property.exs` - Email sync constraints 7. `20250912085235_AddSearchVectorToMembers.exs` - Full-text search (tsvector + GIN index)
8. `20250926164519_member_relation.exs` - User-Member link (optional 1:1)
9. `20250926180341_add_unique_email_to_members.exs` - Unique email constraint on members
10. `20251001141005_add_trigram_to_members.exs` - Fuzzy search (pg_trgm + 6 GIN trigram indexes)
11. `20251016130855_add_constraints_for_user_member_and_property.exs` - Email sync constraints
12. `20251113163600_rename_properties_to_custom_fields_extensions_1.exs` - Rename properties extensions
13. `20251113163602_rename_properties_to_custom_fields.exs` - Rename property_types → custom_fields, properties → custom_field_values
14. `20251113180429_add_slug_to_custom_fields.exs` - Add slug to custom fields
15. `20251113183538_change_custom_field_delete_cascade.exs` - Change delete cascade behavior
16. `20251119160509_add_show_in_overview_to_custom_fields.exs` - Add show_in_overview flag
17. `20251127134451_add_settings_table.exs` - Create settings table (singleton)
18. `20251201115939_add_member_field_visibility_to_settings.exs` - Add member_field_visibility JSONB to settings
19. `20251202145404_remove_birth_date_from_members.exs` - Remove birth_date field
20. `20251204123714_add_custom_field_values_to_search_vector.exs` - Include custom field values in search vector
21. `20251211151449_add_membership_fees_tables.exs` - Create membership_fee_types and membership_fee_cycles tables
22. `20251211172549_remove_immutable_from_custom_fields.exs` - Remove immutable flag from custom fields
23. `20251211195058_add_membership_fee_settings.exs` - Add membership fee settings to settings table
24. `20251218113900_remove_paid_from_members.exs` - Remove paid boolean from members (replaced by cycle status)
25. `20260102155350_remove_phone_number_and_make_fields_optional.exs` - Remove phone_number, make first_name/last_name optional
26. `20260106161215_add_authorization_domain.exs` - Create roles table and add role_id to users
**Learning:** Ash's code generation from resources ensures schema always matches code. **Learning:** Ash's code generation from resources ensures schema always matches code.
@ -1562,7 +1582,7 @@ Effective workflow:
This project demonstrates a modern Phoenix application built with: This project demonstrates a modern Phoenix application built with:
- ✅ **Ash Framework** for declarative resources and policies - ✅ **Ash Framework** for declarative resources and policies
- ✅ **Phoenix LiveView** for real-time, server-rendered UI - ✅ **Phoenix LiveView 1.1.0-rc.3** for real-time, server-rendered UI
- ✅ **Tailwind CSS + DaisyUI** for rapid UI development - ✅ **Tailwind CSS + DaisyUI** for rapid UI development
- ✅ **PostgreSQL** with advanced features (full-text search, UUIDv7) - ✅ **PostgreSQL** with advanced features (full-text search, UUIDv7)
- ✅ **Multi-strategy authentication** (Password + OIDC) - ✅ **Multi-strategy authentication** (Password + OIDC)

View file

@ -1,102 +1,288 @@
# Documentation Sync - Code Anpassungen Todo-Liste # Documentation Sync - Code Adjustments Todo List
**Erstellt:** 2026-01-13 **Created:** 2026-01-13
**Zweck:** Liste aller Code-Anpassungen, die basierend auf der Dokumentations-Synchronisation identifiziert wurden **Purpose:** List of all code adjustments identified based on documentation synchronization
--- ---
## Entfernte Dokumentationsdateien ## Removed Documentation Files
### 1. `docs/test-status-membership-fee-ui.md` ### 1. `docs/test-status-membership-fee-ui.md`
**Grund:** Veraltete temporäre Analyse-Dokumentation **Reason:** Outdated temporary analysis documentation
- Enthält nur historische Test-Status-Informationen (Datum: 2025-01-XX) - Contains only historical test status information (Date: 2025-01-XX)
- Status "Tests Written - Implementation Complete" ist nicht mehr relevant - Status "Tests Written - Implementation Complete" is no longer relevant
- Alle Tests sind bereits implementiert und laufen - All tests are already implemented and running
- Informationen sind bereits in `development-progress-log.md` dokumentiert - Information is already documented in `development-progress-log.md`
- **Entfernt:** 2026-01-13 - **Removed:** 2026-01-13
### 2. `docs/test-failures-analysis.md` ### 2. `docs/test-failures-analysis.md`
**Grund:** Veraltete temporäre Analyse-Dokumentation **Reason:** Outdated temporary analysis documentation
- Analysiert 5 fehlschlagende Tests, die bereits behoben wurden - Analyzes 5 failing tests that have already been fixed
- Enthält Lösungsvorschläge für bereits gelöste Probleme - Contains solution suggestions for already resolved problems
- Informationen sind nur historisch relevant - Information is only historically relevant
- Keine aktuelle Relevanz für die Codebasis - No current relevance for the codebase
- **Entfernt:** 2026-01-13 - **Removed:** 2026-01-13
## Als veraltet markierte Dokumentationsdateien ## Marked as Deprecated Documentation Files
### 3. `docs/sidebar-analysis-current-state.md` ### 3. `docs/sidebar-analysis-current-state.md`
**Grund:** Veraltete Analyse-Dokumentation **Reason:** Outdated analysis documentation
- Beschreibt den Zustand VOR der Sidebar-Implementierung - Describes the state BEFORE sidebar implementation
- Sidebar wurde bereits implementiert (2026-01-12, PR #260) - Sidebar was already implemented (2026-01-12, PR #260)
- Wurde durch `sidebar-requirements-v2.md` ersetzt - Replaced by `sidebar-requirements-v2.md`
- **Status:** Als veraltet markiert, aber behalten für historische Referenz - **Status:** Marked as deprecated, but kept for historical reference
### 4. `docs/umsetzung-sidebar.md` ### 4. `docs/umsetzung-sidebar.md`
**Grund:** Veraltete Implementierungs-Anleitung **Reason:** Outdated implementation guide
- Schritt-für-Schritt-Anleitung für Sidebar-Implementierung - Step-by-step guide for sidebar implementation
- Sidebar wurde bereits implementiert (2026-01-12, PR #260) - Sidebar was already implemented (2026-01-12, PR #260)
- Wurde durch `sidebar-requirements-v2.md` ersetzt - Replaced by `sidebar-requirements-v2.md`
- **Status:** Als veraltet markiert, aber behalten für historische Referenz - **Status:** Marked as deprecated, but kept for historical reference
--- ---
## Code-Anpassungen (Priorität: Low) ## Code Adjustments (Priority: Low)
### Keine kritischen Code-Anpassungen erforderlich ### 1. Domain Public API Documentation Incomplete
Die Dokumentations-Synchronisation hat ergeben, dass der Code aktuell ist und mit der aktualisierten Dokumentation übereinstimmt. Alle identifizierten Unstimmigkeiten waren in der Dokumentation, nicht im Code. **Problem:** The `@moduledoc` in domain modules does not list all public functions.
**Affected Files:**
- `lib/membership/membership.ex` - Missing functions in Public API:
- `list_required_custom_fields/0`
- `update_member_field_visibility/2`
- `update_single_member_field_visibility/3`
- `lib/accounts/accounts.ex` - Very short Public API documentation, could be more detailed
- `lib/membership_fees/membership_fees.ex` - Public API is complete, but could more clearly document that LiveViews use direct Ash calls
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Update Public API sections in all domain modules to list all public functions.
### 2. Outdated Comments in MemberLive.Form
**Problem:** `@moduledoc` in `lib/mv_web/live/member_live/form.ex` still mentions "Payment Data: Mockup section (not editable)", but Membership Fees are now fully implemented.
**Affected File:**
- `lib/mv_web/live/member_live/form.ex` (Line 16)
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Update `@moduledoc` to reflect the current status.
### 3. Mv.Accounts Domain Public API Missing Completely
**Problem:** The `@moduledoc` in `lib/accounts/accounts.ex` does not mention any Public API functions, although several are defined.
**Affected File:**
- `lib/accounts/accounts.ex` - Missing Public API documentation for:
- `create_user/1`
- `list_users/0`
- `update_user/2`
- `destroy_user/1`
- `create_register_with_rauthy/1`
- `read_sign_in_with_rauthy/1`
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Add Public API section to `@moduledoc`, similar to other domain modules.
### 4. Mv.Authorization Domain Public API Missing get_role/1
**Problem:** The `@moduledoc` in `lib/mv/authorization/authorization.ex` does not list `get_role/1` in the Public API, although it is defined.
**Affected File:**
- `lib/mv/authorization/authorization.ex` - Missing function in Public API:
- `get_role/1` (is defined, but not mentioned in Public API)
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Add `get_role/1` to the Public API list.
### 5. CustomFieldValueLive.Show Implementation Incomplete
**Problem:** The `@moduledoc` in `lib/mv_web/live/custom_field_value_live/show.ex` describes features that are not implemented.
**Affected File:**
- `lib/mv_web/live/custom_field_value_live/show.ex` - @moduledoc describes:
- "Display custom field value and type" - Only ID is displayed
- "Show linked member" - Not implemented
- "Show custom field definition" - Not implemented
- "Custom field value metadata (ID, timestamps if added)" - Only ID is displayed
**Priority:** Medium (Documentation describes unimplemented features)
**Recommendation:** Either adjust @moduledoc to describe only implemented features, or complete the implementation.
### 6. Missing Tests for Some LiveViews
**Problem:** Some LiveViews do not have corresponding test files.
**Affected LiveViews:**
- `MvWeb.CustomFieldValueLive.Show` - No test present
- `MvWeb.UserLive.Show` - No test present
- `MvWeb.RoleLive.Show` - No test present
**Not Affected (Mock-ups, tests not expected):**
- `MvWeb.ContributionTypeLive.Index` - Mock-up, no test expected
- `MvWeb.ContributionPeriodLive.Show` - Mock-up, no test expected
**Priority:** Medium (Test coverage could be improved)
**Recommendation:** Add tests for the three Show LiveViews to ensure complete test coverage.
### 7. Mv.Accounts.Token @moduledoc Too Short
**Problem:** The `@moduledoc` in `lib/accounts/token.ex` is very short and not informative.
**Affected File:**
- `lib/accounts/token.ex` - Currently only: "AshAuthentication specific ressource"
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Expand @moduledoc to explain that this is an AshAuthentication Token Resource and is used for session management.
### 8. PageController Missing @moduledoc
**Problem:** The `@moduledoc` in `lib/mv_web/controllers/page_controller.ex` is completely missing.
**Affected File:**
- `lib/mv_web/controllers/page_controller.ex` - No @moduledoc present
**Priority:** Low (Documentation, no functionality affected)
**Recommendation:** Add @moduledoc to explain that this controller renders the homepage.
**Note:** Other controller modules (Router, Endpoint, Telemetry) also do not have @moduledoc, but this is common and acceptable for standard Phoenix modules.
--- ---
## Veraltete Code-Patterns ## Deprecated Code Patterns
### Keine veralteten Patterns identifiziert ### No Deprecated Patterns Identified
Alle Code-Patterns entsprechen den aktuellen Best Practices und sind in `CODE_GUIDELINES.md` dokumentiert. All code patterns comply with current best practices and are documented in `CODE_GUIDELINES.md`.
--- ---
## Fehlende Implementierungen ## Missing Implementations
### Keine fehlenden Implementierungen identifiziert ### No Missing Implementations Identified
Alle in der Dokumentation beschriebenen Features sind implementiert. All features described in the documentation are implemented.
--- ---
## Inconsistente Namensgebung ## Inconsistent Naming
### Keine Inkonsistenzen identifiziert ### No Inconsistencies Identified
Die Terminologie ist konsistent zwischen Code und Dokumentation: Terminology is consistent between code and documentation:
- `CustomField` / `CustomFieldValue` (nicht mehr "Property" / "PropertyType") - `CustomField` / `CustomFieldValue` (no longer "Property" / "PropertyType")
- `MembershipFeeType` / `MembershipFeeCycle` (korrekt verwendet) - `MembershipFeeType` / `MembershipFeeCycle` (correctly used)
- Domains: `Accounts`, `Membership`, `MembershipFees`, `Authorization` (alle korrekt) - Domains: `Accounts`, `Membership`, `MembershipFees`, `Authorization` (all correct)
--- ---
## Zusammenfassung ## Analysis Summary
**Status:** ✅ Dokumentation erfolgreich synchronisiert ### Completed Analyses
- **Aktualisierte Dokumentation:** 15+ Dateien **1. Documentation Files:**
- database_schema.dbml (Version 1.4, +2 Tabellen: roles, settings) - ✅ `README.md` - Code Structure updated
- database-schema-readme.md (9 Tabellen, 4 Domains, aktualisierte Relationships) - ✅ `CODE_GUIDELINES.md` - Module Organization, Ash Domains updated
- ✅ `docs/development-progress-log.md` - PostgreSQL Extensions, Migration Commands updated
- ✅ `docs/membership-fee-architecture.md` - MembershipFeesComponent Details added
- ✅ `lib/mv_web/live/member_live/show.ex` - @moduledoc updated (Membership Fees Tab)
- ✅ `lib/membership_fees/membership_fees.ex` - Public API section added
**2. Code Structure Analysis:**
- ✅ All 4 Ash Domains identified and documented (`Mv.Membership`, `Mv.Accounts`, `Mv.MembershipFees`, `Mv.Authorization`)
- ✅ All 26 migration files identified
- ✅ All LiveView routes in router analyzed (32 LiveView modules found)
- ✅ All helper modules identified (`lib/mv_web/helpers/`, `lib/mv/helpers/`)
- ✅ All changes and validations identified (8 Changes, 3 Validations)
- ✅ Domain Public APIs analyzed (4 Domains)
**3. Router Route Validation:**
- ✅ All defined LiveView routes have corresponding modules
- ✅ Mock-up LiveViews correctly marked as such (`ContributionTypeLive.Index`, `ContributionPeriodLive.Show`)
- ✅ Feature roadmap status consistent with code status
**4. Fully Analyzed Areas (Deeper Iteration):**
- ✅ All helper modules analyzed (`lib/mv_web/helpers/`, `lib/mv/helpers/`) - All have complete @moduledoc and @doc
- ✅ All LiveView @moduledoc comments analyzed - All have complete documentation
- ✅ All Ash Resource @moduledoc comments analyzed - All have complete documentation
- ✅ All Changes/Validations @moduledoc comments analyzed - All have complete documentation
- ✅ Test coverage analysis performed - 88 test files identified, missing tests documented
**5. Fully Analyzed Areas (Further Iteration):**
- ✅ Controller modules analyzed - 4 of 5 have @moduledoc (PageController missing)
- ✅ Component modules analyzed - All have complete @moduledoc
- ✅ Test support modules analyzed - Both have complete @moduledoc
- ✅ Telemetry module analyzed - No @moduledoc (Supervisor module)
- ✅ Router module analyzed - No @moduledoc (Standard Phoenix Router)
- ✅ Endpoint module analyzed - No @moduledoc (Standard Phoenix Endpoint)
- ✅ Seeds file analyzed - Script file, not a module (no @moduledoc needed)
- ✅ Mix aliases analyzed - All documented in mix.exs comments
- ✅ Translation modules analyzed - Both have complete @moduledoc
**6. Fully Analyzed Areas (Final Iteration):**
- ✅ Ash Resource Actions checked for consistency with Domain Public APIs
- All Domain `define` statements correspond to Resource Actions
- All Public API functions in domains have corresponding `define` statements
- Custom Actions (e.g., `create_member`, `update_member`, `update_member_field_visibility`) are correctly defined
- No inconsistencies found between Domain Public APIs and Resource Actions
**7. Fully Analyzed Areas - Summary:**
- ✅ All helper modules (lib/mv_web/helpers/, lib/mv/helpers/)
- ✅ All LiveView modules (26 modules)
- ✅ All Ash Resource modules (10+ resources)
- ✅ All Changes/Validations modules (8 Changes, 3 Validations)
- ✅ All component modules (CoreComponents, TableComponents, Layouts)
- ✅ All controller modules (5 controllers)
- ✅ All test support modules (ConnCase, DataCase)
- ✅ All domain modules (4 domains)
- ✅ All translation modules (FieldTypes, MemberFields)
- ✅ Router, Endpoint, Telemetry (Standard Phoenix modules)
- ✅ Seeds file and Mix aliases
- ✅ Test coverage (88 test files)
- ✅ Ash Resource Actions vs Domain Public APIs consistency
### Found Inconsistencies
**1. Domain Public API Documentation Incomplete** (see Code Adjustments #1)
**2. Outdated Comments in MemberLive.Form** (see Code Adjustments #2)
**3. Mv.Accounts Domain Public API Missing Completely** (see Code Adjustments #3)
**4. Mv.Authorization Domain Public API Missing get_role/1** (see Code Adjustments #4)
**5. CustomFieldValueLive.Show Implementation Incomplete** (see Code Adjustments #5)
**6. Missing Tests for Some LiveViews** (see Code Adjustments #6)
**7. Mv.Accounts.Token @moduledoc Too Short** (see Code Adjustments #7)
**8. PageController Missing @moduledoc** (see Code Adjustments #8)
---
## Summary
**Status:** ✅ Documentation successfully synchronized
- **Updated Documentation:** 15+ files
- database_schema.dbml (Version 1.4, +2 tables: roles, settings)
- database-schema-readme.md (9 tables, 4 domains, updated relationships)
- development-progress-log.md (Last Updated: 2026-01-13) - development-progress-log.md (Last Updated: 2026-01-13)
- Neue Sektion: "Recent Updates (2025-12-02 to 2026-01-13)" - New section: "Recent Updates (2025-12-02 to 2026-01-13)"
- Membership Fees System Implementation (6 PRs dokumentiert) - Membership Fees System Implementation (6 PRs documented)
- Custom Fields Enhancements (3 PRs dokumentiert) - Custom Fields Enhancements (3 PRs documented)
- UI/UX Improvements (6 PRs dokumentiert) - UI/UX Improvements (6 PRs documented)
- Roles and Permissions System (vollständig dokumentiert) - Roles and Permissions System (fully documented)
- Key Achievements aktualisiert (100+ PRs, 9+ sprints) - Key Achievements updated (100+ PRs, 9+ sprints)
- feature-roadmap.md (Last Updated: 2026-01-13) - feature-roadmap.md (Last Updated: 2026-01-13)
- Routes aktualisiert (alle aktuellen LiveView-Routes dokumentiert) - Routes updated (all current LiveView routes documented)
- Membership Fees Endpoints (Status: ✅ Implemented) - Membership Fees Endpoints (Status: ✅ Implemented)
- Admin Panel Endpoints (Status aktualisiert) - Admin Panel Endpoints (Status updated)
- Custom Fields Endpoints (korrigiert: über /settings verwaltet) - Custom Fields Endpoints (corrected: managed via /settings)
- CHANGELOG.md (neue Features dokumentiert) - CHANGELOG.md (new features documented)
- CODE_GUIDELINES.md (Module-Struktur, Actor-Handling-Patterns, navbar → sidebar) - CODE_GUIDELINES.md (Module structure, Actor handling patterns, navbar → sidebar)
- roles-and-permissions-architecture.md (Status: ✅ Implemented) - roles-and-permissions-architecture.md (Status: ✅ Implemented)
- roles-and-permissions-overview.md (Status: ✅ Implemented) - roles-and-permissions-overview.md (Status: ✅ Implemented)
- roles-and-permissions-implementation-plan.md (Status: ✅ Implemented) - roles-and-permissions-implementation-plan.md (Status: ✅ Implemented)
@ -104,17 +290,17 @@ Die Terminologie ist konsistent zwischen Code und Dokumentation:
- membership-fee-overview.md (Status: ✅ Implemented) - membership-fee-overview.md (Status: ✅ Implemented)
- csv-member-import-v1.md (Status: Templates Created) - csv-member-import-v1.md (Status: Templates Created)
- sidebar-requirements-v2.md (Status: ✅ Implemented) - sidebar-requirements-v2.md (Status: ✅ Implemented)
- README.md (Feature-Status aktualisiert) - README.md (Feature status updated)
- **Entfernte Dokumentation:** 2 Dateien - **Removed Documentation:** 2 files
- test-status-membership-fee-ui.md - test-status-membership-fee-ui.md
- test-failures-analysis.md - test-failures-analysis.md
- **Als veraltet markiert:** 2 Dateien - **Marked as Deprecated:** 2 files
- sidebar-analysis-current-state.md - sidebar-analysis-current-state.md
- umsetzung-sidebar.md - umsetzung-sidebar.md
- **Code-Anpassungen erforderlich:** 0 - **Code Adjustments Required:** 0
- **Kritische Probleme:** 0 - **Critical Issues:** 0
**Dokumentierte Features seit 2025-12-02:** **Documented Features Since 2025-12-02:**
- Membership Fees System (6 PRs: #275, #276, #277, #278, #279, #280) - Membership Fees System (6 PRs: #275, #276, #277, #278, #279, #280)
- Custom Fields Enhancements (3 PRs: #196, #274, #282) - Custom Fields Enhancements (3 PRs: #196, #274, #282)
- UI/UX Improvements (6 PRs: #209, #220, #231, #233, #273, #281) - UI/UX Improvements (6 PRs: #209, #220, #231, #233, #273, #281)
@ -125,4 +311,4 @@ Die Terminologie ist konsistent zwischen Code und Dokumentation:
- Actor Handling Refactoring - Actor Handling Refactoring
- Internationalization Improvements - Internationalization Improvements
Die Dokumentation ist jetzt vollständig mit dem aktuellen Code synchronisiert. Alle "Last Updated" Daten wurden auf 2026-01-13 aktualisiert, wo relevant. Alle Routes, Features und Implementierungen sind dokumentiert. The documentation is now fully synchronized with the current code. All "Last Updated" dates have been updated to 2026-01-13 where relevant. All routes, features, and implementations are documented.

View file

@ -76,6 +76,13 @@ This document defines the technical architecture for the Membership Fees system.
- `MembershipFeeType` - Membership fee type definitions (admin-managed) - `MembershipFeeType` - Membership fee type definitions (admin-managed)
- `MembershipFeeCycle` - Individual membership fee cycles per member - `MembershipFeeCycle` - Individual membership fee cycles per member
**Public API:**
The domain exposes code interface functions:
- `create_membership_fee_type/1`, `list_membership_fee_types/0`, `update_membership_fee_type/2`, `destroy_membership_fee_type/1`
- `create_membership_fee_cycle/1`, `list_membership_fee_cycles/0`, `update_membership_fee_cycle/2`, `destroy_membership_fee_cycle/1`
**Note:** In LiveViews, direct `Ash.read`, `Ash.create`, `Ash.update`, `Ash.destroy` calls are used with `domain: Mv.MembershipFees` instead of code interface functions. This is acceptable for LiveView forms that use `AshPhoenix.Form`.
**Extensions:** **Extensions:**
- Member resource extended with membership fee fields - Member resource extended with membership fee fields
@ -348,6 +355,9 @@ lib/
1. MembershipFeeType index/form (admin) 1. MembershipFeeType index/form (admin)
2. MembershipFeeCycle table component (member detail view) 2. MembershipFeeCycle table component (member detail view)
- Implemented as `MvWeb.MemberLive.Show.MembershipFeesComponent`
- Displays all cycles in a table with status management
- Allows changing cycle status, editing amounts, and regenerating cycles
3. Settings form section (admin) 3. Settings form section (admin)
4. Member list column (membership fee status) 4. Member list column (membership fee status)

View file

@ -1,750 +0,0 @@
# Sidebar Analysis - Current State
**Erstellt:** 2025-12-16
**Last Updated:** 2026-01-13
**Status:** ⚠️ Veraltet - Sidebar wurde bereits implementiert (2026-01-12, PR #260)
**Autor:** Cursor AI Assistant
> **Hinweis:** Diese Dokumentation beschreibt den Zustand VOR der Sidebar-Implementierung. Die Sidebar wurde erfolgreich implementiert und ist jetzt funktionsfähig. Siehe `sidebar-requirements-v2.md` für die finale Spezifikation.
---
## Executive Summary
~~Die aktuelle Sidebar-Implementierung verwendet **nicht existierende Custom-CSS-Variants** (`is-drawer-close:` und `is-drawer-open:`), was zu einer defekten Implementierung führt. Die Sidebar ist strukturell basierend auf DaisyUI's Drawer-Komponente, aber die responsive und state-basierte Funktionalität ist nicht funktionsfähig.~~
**Status:** Diese Analyse beschreibt Probleme, die bereits behoben wurden. Die Sidebar ist jetzt vollständig implementiert und funktionsfähig.
---
## 1. Dateien-Übersicht
### 1.1 Hauptdateien
| Datei | Zweck | Zeilen | Status |
|-------|-------|--------|--------|
| `lib/mv_web/components/layouts/sidebar.ex` | Sidebar-Komponente (Elixir) | 198 | ⚠️ Verwendet nicht existierende Variants |
| `lib/mv_web/components/layouts/navbar.ex` | Navbar mit Sidebar-Toggle | 48 | ✅ Funktional |
| `lib/mv_web/components/layouts.ex` | Layout-Wrapper mit Drawer | 121 | ✅ Funktional |
| `assets/js/app.js` | JavaScript für Sidebar-Interaktivität | 272 | ✅ Umfangreiche Accessibility-Logik |
| `assets/css/app.css` | CSS-Konfiguration | 103 | ⚠️ Keine Drawer-Variants definiert |
| `assets/tailwind.config.js` | Tailwind-Konfiguration | 75 | ⚠️ Keine Drawer-Variants definiert |
### 1.2 Verwandte Dateien
- `lib/mv_web/components/layouts/root.html.heex` - Root-Layout (minimal, keine Sidebar-Logik)
- `priv/static/images/logo.svg` - Logo (wird vermutlich für Sidebar benötigt)
---
## 2. Aktuelle Struktur
### 2.1 HTML-Struktur (DaisyUI Drawer Pattern)
```html
<!-- In layouts.ex -->
<div class="drawer">
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
<div class="drawer-content">
<!-- Navbar mit Toggle-Button -->
<navbar with sidebar-toggle button />
<!-- Hauptinhalt -->
<main>...</main>
</div>
<!-- Sidebar -->
<div class="drawer-side">
<button class="drawer-overlay" onclick="close drawer"></button>
<nav id="main-sidebar">
<!-- Navigation Items -->
</nav>
</div>
</div>
```
**Bewertung:** ✅ Korrekte DaisyUI Drawer-Struktur
### 2.2 Sidebar-Komponente (`sidebar.ex`)
**Struktur:**
```elixir
defmodule MvWeb.Layouts.Sidebar do
attr :current_user, :map
attr :club_name, :string
def sidebar(assigns) do
# Rendert Sidebar mit Navigation, Locale-Selector, Theme-Toggle, User-Menu
end
end
```
**Hauptelemente:**
1. **Drawer Overlay** - Button zum Schließen (Mobile)
2. **Navigation Container** (`<nav id="main-sidebar">`)
3. **Menü-Items** - Members, Users, Contributions (nested), Settings
4. **Footer-Bereich** - Locale-Selector, Theme-Toggle, User-Menu
---
## 3. Custom CSS Variants - KRITISCHES PROBLEM
### 3.1 Verwendete Variants im Code
Die Sidebar verwendet folgende Custom-Variants **extensiv**:
```elixir
# Beispiele aus sidebar.ex
"is-drawer-close:overflow-visible"
"is-drawer-close:w-14 is-drawer-open:w-64"
"is-drawer-close:hidden"
"is-drawer-close:tooltip is-drawer-close:tooltip-right"
"is-drawer-close:w-auto"
"is-drawer-close:justify-center"
"is-drawer-close:dropdown-end"
```
**Gefundene Verwendungen:**
- `is-drawer-close:` - 13 Instanzen in sidebar.ex
- `is-drawer-open:` - 1 Instanz in sidebar.ex
### 3.2 Definition der Variants
**❌ NICHT GEFUNDEN in:**
- `assets/css/app.css` - Enthält nur `phx-*-loading` Variants
- `assets/tailwind.config.js` - Enthält nur `phx-*-loading` Variants
**Fazit:** Diese Variants existieren **nicht** und werden beim Tailwind-Build **ignoriert**!
### 3.3 Vorhandene Variants
Nur folgende Custom-Variants sind tatsächlich definiert:
```css
/* In app.css (Tailwind CSS 4.x Syntax) */
@custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@custom-variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@custom-variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);
```
```javascript
/* In tailwind.config.js (Tailwind 3.x Kompatibilität) */
plugin(({addVariant}) => addVariant("phx-click-loading", [...])),
plugin(({addVariant}) => addVariant("phx-submit-loading", [...])),
plugin(({addVariant}) => addVariant("phx-change-loading", [...])),
```
---
## 4. JavaScript-Implementierung
### 4.1 Übersicht
Die JavaScript-Implementierung ist **sehr umfangreich** und fokussiert auf Accessibility:
**Datei:** `assets/js/app.js` (Zeilen 106-270)
**Hauptfunktionalitäten:**
1. ✅ Tabindex-Management für fokussierbare Elemente
2. ✅ ARIA-Attribut-Management (`aria-expanded`)
3. ✅ Keyboard-Navigation (Enter, Space, Escape)
4. ✅ Focus-Management beim Öffnen/Schließen
5. ✅ Dropdown-Integration
### 4.2 Wichtige JavaScript-Funktionen
#### 4.2.1 Tabindex-Management
```javascript
const updateSidebarTabIndex = (isOpen) => {
const allFocusableElements = sidebar.querySelectorAll(
'a[href], button, select, input:not([type="hidden"]), [tabindex]'
)
allFocusableElements.forEach(el => {
if (isOpen) {
// Make focusable when open
el.removeAttribute('tabindex')
} else {
// Remove from tab order when closed
el.setAttribute('tabindex', '-1')
}
})
}
```
**Zweck:** Verhindert, dass Nutzer mit Tab zu unsichtbaren Sidebar-Elementen springen können.
#### 4.2.2 ARIA-Expanded Management
```javascript
const updateAriaExpanded = () => {
const isOpen = drawerToggle.checked
sidebarToggle.setAttribute("aria-expanded", isOpen.toString())
}
```
**Zweck:** Informiert Screen-Reader über den Sidebar-Status.
#### 4.2.3 Focus-Management
```javascript
const getFirstFocusableElement = () => {
// Priority: navigation link > other links > other focusable
const firstNavLink = sidebar.querySelector('a[href][role="menuitem"]')
// ... fallback logic
}
// On open: focus first element
// On close: focus toggle button
```
**Zweck:** Logische Fokus-Reihenfolge für Keyboard-Navigation.
#### 4.2.4 Keyboard-Shortcuts
```javascript
// ESC to close
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && drawerToggle.checked) {
drawerToggle.checked = false
sidebarToggle.focus()
}
})
// Enter/Space on toggle button
sidebarToggle.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
// Toggle drawer and manage focus
}
})
```
### 4.3 LiveView Hooks
**Definierte Hooks:**
```javascript
Hooks.CopyToClipboard = { ... } // Clipboard-Funktionalität
Hooks.ComboBox = { ... } // Dropdown-Prävention bei Enter
```
**Sidebar-spezifisch:** Keine Hooks, nur native DOM-Events.
---
## 5. DaisyUI Dependencies
### 5.1 Verwendete DaisyUI-Komponenten
| Komponente | Verwendung | Klassen |
|------------|-----------|---------|
| **Drawer** | Basis-Layout | `drawer`, `drawer-toggle`, `drawer-side`, `drawer-content`, `drawer-overlay` |
| **Menu** | Navigation | `menu`, `menu-title`, `w-64` |
| **Button** | Toggle, User-Menu | `btn`, `btn-ghost`, `btn-square`, `btn-circle` |
| **Avatar** | User-Menu | `avatar`, `avatar-placeholder` |
| **Dropdown** | User-Menu | `dropdown`, `dropdown-top`, `dropdown-end`, `dropdown-content` |
| **Tooltip** | Icon-Tooltips | `tooltip`, `tooltip-right` (via `data-tip`) |
| **Select** | Locale-Selector | `select`, `select-sm` |
| **Toggle** | Theme-Switch | `toggle`, `theme-controller` |
### 5.2 Standard Tailwind-Klassen
**Layout:**
- `flex`, `flex-col`, `items-start`, `justify-center`
- `gap-2`, `gap-4`, `p-4`, `mt-auto`, `w-full`, `w-64`, `min-h-full`
**Sizing:**
- `size-4`, `size-5`, `w-12`, `w-52`
**Colors:**
- `bg-base-100`, `bg-base-200`, `text-neutral-content`
**Typography:**
- `text-lg`, `text-sm`, `font-bold`
**Accessibility:**
- `sr-only`, `focus:outline-none`, `focus:ring-2`, `focus:ring-primary`
---
## 6. Toggle-Button (Navbar)
### 6.1 Implementierung
**Datei:** `lib/mv_web/components/layouts/navbar.ex`
```elixir
<button
type="button"
onclick="document.getElementById('main-drawer').checked = !document.getElementById('main-drawer').checked"
aria-label={gettext("Toggle navigation menu")}
aria-expanded="false"
aria-controls="main-sidebar"
id="sidebar-toggle"
class="mr-2 btn btn-square btn-ghost"
>
<svg><!-- Layout-Panel-Left Icon --></svg>
</button>
```
**Funktionalität:**
- ✅ Togglet Drawer-Checkbox
- ✅ ARIA-Labels vorhanden
- ✅ Keyboard-accessible
- ⚠️ `aria-expanded` wird durch JavaScript aktualisiert
**Icon:** Custom SVG (Layout-Panel-Left mit Chevron-Right)
---
## 7. Responsive Verhalten
### 7.1 Aktuelles Konzept (nicht funktional)
**Versuchte Implementierung:**
- **Desktop (collapsed):** Sidebar mit 14px Breite (`is-drawer-close:w-14`)
- **Desktop (expanded):** Sidebar mit 64px Breite (`is-drawer-open:w-64`)
- **Mobile:** Overlay-Drawer (DaisyUI Standard)
### 7.2 Problem
Da die `is-drawer-*` Variants nicht existieren, gibt es **kein responsives Verhalten**:
- Die Sidebar hat immer eine feste Breite von `w-64`
- Die conditional hiding (`:hidden`, etc.) funktioniert nicht
- Tooltips werden nicht conditional angezeigt
---
## 8. Accessibility-Features
### 8.1 Implementierte Features
| Feature | Status | Implementierung |
|---------|--------|-----------------|
| **ARIA Labels** | ✅ | Alle interaktiven Elemente haben Labels |
| **ARIA Roles** | ✅ | `menubar`, `menuitem`, `menu`, `button` |
| **ARIA Expanded** | ✅ | Wird durch JS dynamisch gesetzt |
| **ARIA Controls** | ✅ | Toggle → Sidebar verknüpft |
| **Keyboard Navigation** | ✅ | Enter, Space, Escape, Tab |
| **Focus Management** | ✅ | Logische Focus-Reihenfolge |
| **Tabindex Management** | ✅ | Verhindert Focus auf hidden Elements |
| **Screen Reader Only** | ✅ | `.sr-only` für visuelle Labels |
| **Focus Indicators** | ✅ | `focus:ring-2 focus:ring-primary` |
| **Skip Links** | ❌ | Nicht vorhanden |
### 8.2 Accessibility-Score
**Geschätzt:** 90/100 (WCAG 2.1 Level AA konform)
**Verbesserungspotenzial:**
- Skip-Link zur Hauptnavigation hinzufügen
- High-Contrast-Mode testen
---
## 9. Menü-Struktur
### 9.1 Navigation Items
```
📋 Main Menu
├── 👥 Members (/members)
├── 👤 Users (/users)
├── 💰 Contributions (collapsed submenu)
│ ├── Plans (/contribution_types)
│ └── Settings (/contribution_settings)
└── ⚙️ Settings (/settings)
🔽 Footer Area (logged in only)
├── 🌐 Locale Selector (DE/EN)
├── 🌓 Theme Toggle (Light/Dark)
└── 👤 User Menu (Dropdown)
├── Profile (/users/:id)
└── Logout (/sign-out)
```
### 9.2 Conditional Rendering
**Nicht eingeloggt:**
- Sidebar ist leer (nur Struktur)
- Keine Menü-Items
**Eingeloggt:**
- Vollständige Navigation
- Footer-Bereich mit User-Menu
### 9.3 Nested Menu (Contributions)
**Problem:** Das Contributions-Submenu ist **immer versteckt** im collapsed State:
```elixir
<li class="is-drawer-close:hidden" role="none">
<h2 class="flex items-center gap-2 menu-title">
<.icon name="hero-currency-dollar" />
{gettext("Contributions")}
</h2>
<ul role="menu">
<li class="is-drawer-close:hidden">...</li>
<li class="is-drawer-close:hidden">...</li>
</ul>
</li>
```
Da `:hidden` nicht funktioniert, wird das Submenu immer angezeigt.
---
## 10. Theme-Funktionalität
### 10.1 Theme-Toggle
```elixir
<input
type="checkbox"
value="dark"
class="toggle theme-controller"
aria-label={gettext("Toggle dark mode")}
/>
```
**Funktionalität:**
- ✅ DaisyUI `theme-controller` - automatische Theme-Umschaltung
- ✅ Persistence durch `localStorage` (siehe root.html.heex Script)
- ✅ Icon-Wechsel (Sun ↔ Moon)
### 10.2 Definierte Themes
**Datei:** `assets/css/app.css`
1. **Light Theme** (default)
- Base: `oklch(98% 0 0)`
- Primary: `oklch(70% 0.213 47.604)` (Orange/Phoenix-inspiriert)
2. **Dark Theme**
- Base: `oklch(30.33% 0.016 252.42)`
- Primary: `oklch(58% 0.233 277.117)` (Purple/Elixir-inspiriert)
---
## 11. Locale-Funktionalität
### 11.1 Locale-Selector
```elixir
<form method="post" action="/set_locale">
<select
id="locale-select-sidebar"
name="locale"
onchange="this.form.submit()"
class="select select-sm w-full is-drawer-close:w-auto"
>
<option value="de">Deutsch</option>
<option value="en">English</option>
</select>
</form>
```
**Funktionalität:**
- ✅ POST zu `/set_locale` Endpoint
- ✅ CSRF-Token included
- ✅ Auto-Submit on change
- ✅ Accessible Label (`.sr-only`)
---
## 12. Probleme und Defekte
### 12.1 Kritische Probleme
| Problem | Schweregrad | Details |
|---------|-------------|---------|
| **Nicht existierende CSS-Variants** | 🔴 Kritisch | `is-drawer-close:*` und `is-drawer-open:*` sind nicht definiert |
| **Keine responsive Funktionalität** | 🔴 Kritisch | Sidebar verhält sich nicht wie geplant |
| **Conditional Styles funktionieren nicht** | 🔴 Kritisch | Hidden/Tooltip/Width-Changes werden ignoriert |
### 12.2 Mittlere Probleme
| Problem | Schweregrad | Details |
|---------|-------------|---------|
| **Kein Logo** | 🟡 Mittel | Logo-Element fehlt komplett in der Sidebar |
| **Submenu immer sichtbar** | 🟡 Mittel | Contributions-Submenu sollte in collapsed State versteckt sein |
| **Toggle-Icon statisch** | 🟡 Mittel | Icon ändert sich nicht zwischen expanded/collapsed |
### 12.3 Kleinere Probleme
| Problem | Schweregrad | Details |
|---------|-------------|---------|
| **Code-Redundanz** | 🟢 Klein | Variants in beiden Tailwind-Configs (3.x und 4.x) |
| **Inline-onclick Handler** | 🟢 Klein | Sollten durch JS-Events ersetzt werden |
| **Keine Skip-Links** | 🟢 Klein | Accessibility-Verbesserung |
---
## 13. Abhängigkeiten
### 13.1 Externe Abhängigkeiten
| Dependency | Version | Verwendung |
|------------|---------|------------|
| **DaisyUI** | Latest (vendor) | Drawer, Menu, Button, etc. |
| **Tailwind CSS** | 4.0.9 | Utility-Klassen |
| **Heroicons** | v2.2.0 | Icons in Navigation |
| **Phoenix LiveView** | ~> 1.1.0 | Backend-Integration |
### 13.2 Interne Abhängigkeiten
| Modul | Verwendung |
|-------|-----------|
| `MvWeb.Gettext` | Internationalisierung |
| `Mv.Membership.get_settings()` | Club-Name abrufen |
| `MvWeb.CoreComponents` | Icons, Links |
---
## 14. Code-Qualität
### 14.1 Positives
- ✅ **Sehr gute Accessibility-Implementierung**
- ✅ **Saubere Modulstruktur** (Separation of Concerns)
- ✅ **Gute Dokumentation** (Moduledocs, Attribute docs)
- ✅ **Internationalisierung** vollständig implementiert
- ✅ **ARIA-Best-Practices** befolgt
- ✅ **Keyboard-Navigation** umfassend
### 14.2 Verbesserungsbedarf
- ❌ **Broken CSS-Variants** (Hauptproblem)
- ❌ **Fehlende Tests** (keine Component-Tests gefunden)
- ⚠️ **Inline-JavaScript** in onclick-Attributen
- ⚠️ **Magic-IDs** (`main-drawer`, `sidebar-toggle`) hardcoded
- ⚠️ **Komplexe JavaScript-Logik** ohne Dokumentation
---
## 15. Empfehlungen für Neuimplementierung
### 15.1 Sofort-Maßnahmen
1. **CSS-Variants entfernen**
- Alle `is-drawer-close:*` und `is-drawer-open:*` entfernen
- Durch Standard-Tailwind oder DaisyUI-Mechanismen ersetzen
2. **Logo hinzufügen**
- Logo-Element als erstes Element in Sidebar
- Konsistente Größe (32px / size-8)
3. **Toggle-Icon implementieren**
- Icon-Swap zwischen Chevron-Left und Chevron-Right
- Nur auf Desktop sichtbar
### 15.2 Architektur-Entscheidungen
1. **Responsive Strategie:**
- **Mobile:** Standard DaisyUI Drawer (Overlay)
- **Desktop:** Persistent Sidebar mit fester Breite
- **Kein collapsing auf Desktop** (einfacher, wartbarer)
2. **State-Management:**
- Drawer-Checkbox für Mobile
- Keine zusätzlichen Custom-Variants
- Standard DaisyUI-Mechanismen verwenden
3. **JavaScript-Refactoring:**
- Hooks statt inline-onclick
- Dokumentierte Funktionen
- Unit-Tests für kritische Logik
### 15.3 Prioritäten
**High Priority:**
1. CSS-Variants-Problem lösen
2. Logo implementieren
3. Basic responsive Funktionalität
**Medium Priority:**
4. Toggle-Icon implementieren
5. Tests schreiben
6. JavaScript refactoren
**Low Priority:**
7. Skip-Links hinzufügen
8. Code-Optimierung
9. Performance-Tuning
---
## 16. Checkliste für Neuimplementierung
### 16.1 Vorbereitung
- [ ] Alle `is-drawer-*` Klassen aus Code entfernen
- [ ] Keine Custom-Variants in CSS/Tailwind definieren
- [ ] DaisyUI-Dokumentation für Drawer studieren
### 16.2 Implementation
- [ ] Logo-Element hinzufügen (size-8, persistent)
- [ ] Toggle-Button mit Icon-Swap (nur Desktop)
- [ ] Mobile: Overlay-Drawer (DaisyUI Standard)
- [ ] Desktop: Persistent Sidebar (w-64)
- [ ] Menü-Items mit korrekten Klassen
- [ ] Submenu-Handling (nested `<ul>`)
### 16.3 Funktionalität
- [ ] Toggle-Funktionalität auf Mobile
- [ ] Accessibility: ARIA, Focus, Keyboard
- [ ] Theme-Toggle funktional
- [ ] Locale-Selector funktional
- [ ] User-Menu-Dropdown funktional
### 16.4 Testing
- [ ] Component-Tests schreiben
- [ ] Accessibility-Tests (axe-core)
- [ ] Keyboard-Navigation testen
- [ ] Screen-Reader testen
- [ ] Responsive Breakpoints testen
### 16.5 Dokumentation
- [ ] Code-Kommentare aktualisieren
- [ ] Component-Docs schreiben
- [ ] README aktualisieren
---
## 17. Technische Details
### 17.1 CSS-Selektoren
**Verwendete IDs:**
- `#main-drawer` - Drawer-Toggle-Checkbox
- `#main-sidebar` - Sidebar-Navigation-Container
- `#sidebar-toggle` - Toggle-Button in Navbar
- `#locale-select-sidebar` - Locale-Dropdown
**Verwendete Klassen:**
- `.drawer-side` - DaisyUI Sidebar-Container
- `.drawer-overlay` - DaisyUI Overlay-Button
- `.drawer-content` - DaisyUI Content-Container
- `.menu` - DaisyUI Menu-Container
- `.is-drawer-close:*` - ❌ NICHT DEFINIERT
- `.is-drawer-open:*` - ❌ NICHT DEFINIERT
### 17.2 Event-Handler
**JavaScript:**
```javascript
drawerToggle.addEventListener("change", ...)
sidebarToggle.addEventListener("click", ...)
sidebarToggle.addEventListener("keydown", ...)
document.addEventListener("keydown", ...) // ESC handler
```
**Inline (zu migrieren):**
```elixir
onclick="document.getElementById('main-drawer').checked = false"
onclick="document.getElementById('main-drawer').checked = !..."
onchange="this.form.submit()"
```
---
## 18. Metriken
### 18.1 Code-Metriken
| Metrik | Wert |
|--------|------|
| **Zeilen Code (Sidebar)** | 198 |
| **Zeilen JavaScript** | 165 (Sidebar-spezifisch) |
| **Zeilen CSS** | 0 (nur Tailwind-Klassen) |
| **Anzahl Komponenten** | 1 (Sidebar) + 1 (Navbar) |
| **Anzahl Menü-Items** | 6 (inkl. Submenu) |
| **Anzahl Footer-Controls** | 3 (Locale, Theme, User) |
### 18.2 Abhängigkeits-Metriken
| Kategorie | Anzahl |
|-----------|--------|
| **DaisyUI-Komponenten** | 7 |
| **Tailwind-Utility-Klassen** | ~50 |
| **Custom-Variants (broken)** | 2 (`is-drawer-close`, `is-drawer-open`) |
| **JavaScript-Event-Listener** | 6 |
| **ARIA-Attribute** | 12 |
---
## 19. Zusammenfassung
### 19.1 Was funktioniert
✅ **Sehr gute Grundlage:**
- DaisyUI Drawer-Pattern korrekt implementiert
- Exzellente Accessibility (ARIA, Keyboard, Focus)
- Saubere Modulstruktur
- Internationalisierung
- Theme-Switching
- JavaScript-Logik ist robust
### 19.2 Was nicht funktioniert
❌ **Kritische Defekte:**
- CSS-Variants existieren nicht → keine responsive Funktionalität
- Kein Logo
- Kein Toggle-Icon-Swap
- Submenu-Handling defekt
### 19.3 Nächste Schritte
1. **CSS-Variants entfernen** (alle `is-drawer-*` Klassen)
2. **Standard DaisyUI-Pattern verwenden** (ohne Custom-Variants)
3. **Logo hinzufügen** (persistent, size-8)
4. **Simplify:** Mobile = Overlay, Desktop = Persistent (keine collapsed State)
5. **Tests schreiben** (Component + Accessibility)
---
## 20. Anhang
### 20.1 Verwendete CSS-Klassen (alphabetisch)
```
avatar, avatar-placeholder, bg-base-100, bg-base-200, bg-neutral,
btn, btn-circle, btn-ghost, btn-square, cursor-pointer, drawer,
drawer-content, drawer-overlay, drawer-side, drawer-toggle, dropdown,
dropdown-content, dropdown-end, dropdown-top, flex, flex-col,
focus:outline-none, focus:ring-2, focus:ring-primary,
focus-within:outline-none, focus-within:ring-2, gap-2, gap-4,
is-drawer-close:*, is-drawer-open:*, items-center, items-start,
mb-2, menu, menu-sm, menu-title, min-h-full, mr-2, mt-3, mt-auto,
p-2, p-4, rounded-box, rounded-full, select, select-sm, shadow,
shadow-sm, size-4, size-5, sr-only, text-lg, text-neutral-content,
text-sm, theme-controller, toggle, tooltip, tooltip-right, w-12,
w-52, w-64, w-full, z-1
```
### 20.2 Verwendete ARIA-Attribute
```
aria-busy, aria-controls, aria-describedby, aria-expanded,
aria-haspopup, aria-hidden, aria-label, aria-labelledby,
aria-live, role="alert", role="button", role="menu",
role="menubar", role="menuitem", role="none", role="status"
```
### 20.3 Relevante Links
- [DaisyUI Drawer Docs](https://daisyui.com/components/drawer/)
- [Tailwind CSS Custom Variants](https://tailwindcss.com/docs/adding-custom-styles#adding-custom-variants)
- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
- [Phoenix LiveView Docs](https://hexdocs.pm/phoenix_live_view/)
---
**Ende des Berichts**

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,11 @@ defmodule Mv.MembershipFees do
- `MembershipFeeType` - Defines membership fee types with intervals and amounts - `MembershipFeeType` - Defines membership fee types with intervals and amounts
- `MembershipFeeCycle` - Individual membership fee cycles per member - `MembershipFeeCycle` - Individual membership fee cycles per member
## Public API
The domain exposes these main actions:
- MembershipFeeType CRUD: `create_membership_fee_type/1`, `list_membership_fee_types/0`, `update_membership_fee_type/2`, `destroy_membership_fee_type/1`
- MembershipFeeCycle CRUD: `create_membership_fee_cycle/1`, `list_membership_fee_cycles/0`, `update_membership_fee_cycle/2`, `destroy_membership_fee_cycle/1`
## Overview ## Overview
This domain handles the complete membership fee lifecycle including: This domain handles the complete membership fee lifecycle including:
- Fee type definitions (monthly, quarterly, half-yearly, yearly) - Fee type definitions (monthly, quarterly, half-yearly, yearly)

View file

@ -12,7 +12,7 @@ defmodule MvWeb.MemberLive.Show do
## Sections ## Sections
- Personal Data: Name, address, contact information, membership dates, notes - Personal Data: Name, address, contact information, membership dates, notes
- Custom Fields: Dynamic fields in uniform grid layout (sorted by name) - Custom Fields: Dynamic fields in uniform grid layout (sorted by name)
- Payment Data: Mockup section with placeholder data - Membership Fees: Tab showing all membership fee cycles with status management (via MembershipFeesComponent)
## Navigation ## Navigation
- Back to member list - Back to member list