diff --git a/CHANGELOG.md b/CHANGELOG.md index 28b4a37..2c23c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- **Roles and Permissions System (RBAC)** - Complete implementation (#345, 2026-01-08) + - Four hardcoded permission sets: `own_data`, `read_only`, `normal_user`, `admin` + - Database-backed roles with permission set references + - Member resource policies with scope filtering (`:own`, `:linked`, `:all`) + - Authorization checks via `Mv.Authorization.Checks.HasPermission` + - System role protection (critical roles cannot be deleted) + - Role management UI at `/admin/roles` +- **Membership Fees System** - Full implementation + - Membership fee types with intervals (monthly, quarterly, half_yearly, yearly) + - Individual billing cycles per member with payment status tracking + - Cycle generation and regeneration + - Global membership fee settings + - UI components for fee management +- **Global Settings Management** - Singleton settings resource + - Club name configuration (with environment variable support) + - Member field visibility settings + - Membership fee default settings +- **Sidebar Navigation** - Replaced navbar with standard-compliant sidebar (#260, 2026-01-12) +- **CSV Import Templates** - German and English templates (#329, 2026-01-13) + - Template files in `priv/static/templates/` + - CSV specification documented - User-Member linking with fuzzy search autocomplete (#168) - PostgreSQL trigram-based member search with typo tolerance - WCAG 2.1 AA compliant autocomplete dropdown with ARIA support @@ -19,8 +40,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - German/English translations - Docker secrets support via `_FILE` environment variables for all sensitive configuration (SECRET_KEY_BASE, TOKEN_SIGNING_SECRET, OIDC_CLIENT_SECRET, DATABASE_URL, DATABASE_PASSWORD) +### Changed +- **Actor Handling Refactoring** (2026-01-09) + - Standardized actor access with `current_actor/1` helper function + - `ash_actor_opts/1` helper for consistent authorization options + - `submit_form/3` wrapper for form submissions with actor + - All Ash operations now properly pass `actor` parameter +- **Error Handling Improvements** (2026-01-13) + - Replaced `Ash.read!` with proper error handling in LiveViews + - Consistent flash message handling for authorization errors + - Early return patterns for unauthenticated users + ### Fixed - Email validation false positive when linking user and member with identical emails (#168 Problem #4) - Relationship data extraction from Ash manage_relationship during validation - Copy button count now shows only visible selected members when filtering +- Language headers in German `.po` files (corrected from "en" to "de") +- Critical deny-filter bug in authorization system (2026-01-08) +- HasPermission auto_filter and strict_check implementation (2026-01-08) diff --git a/CODE_GUIDELINES.md b/CODE_GUIDELINES.md index 5cc792c..fe2d816 100644 --- a/CODE_GUIDELINES.md +++ b/CODE_GUIDELINES.md @@ -83,7 +83,18 @@ lib/ │ ├── member.ex # Member resource │ ├── custom_field_value.ex # Custom field value resource │ ├── custom_field.ex # CustomFieldValue type resource +│ ├── setting.ex # Global settings (singleton resource) │ └── email.ex # Email custom type +├── membership_fees/ # MembershipFees domain +│ ├── membership_fees.ex # Domain definition +│ ├── membership_fee_type.ex # Membership fee type resource +│ ├── membership_fee_cycle.ex # Membership fee cycle resource +│ └── changes/ # Ash changes for membership fees +├── mv/authorization/ # Authorization domain +│ ├── authorization.ex # Domain definition +│ ├── role.ex # Role resource +│ ├── permission_sets.ex # Hardcoded permission sets +│ └── checks/ # Authorization checks ├── mv/ # Core application modules │ ├── accounts/ # Domain-specific logic │ │ └── user/ @@ -96,6 +107,11 @@ lib/ │ ├── membership/ # Domain-specific logic │ │ └── member/ │ │ └── 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 │ ├── mailer.ex # Email mailer │ ├── release.ex # Release tasks @@ -107,7 +123,7 @@ lib/ │ │ ├── table_components.ex │ │ ├── layouts.ex │ │ └── layouts/ # Layout templates -│ │ ├── navbar.ex +│ │ ├── sidebar.ex │ │ └── root.html.heex │ ├── controllers/ # HTTP controllers │ │ ├── auth_controller.ex @@ -116,6 +132,11 @@ lib/ │ │ ├── error_html.ex │ │ ├── error_json.ex │ │ └── 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 │ │ ├── components/ # LiveView-specific components │ │ │ ├── search_bar_component.ex @@ -123,11 +144,16 @@ lib/ │ │ ├── member_live/ # Member CRUD LiveViews │ │ ├── custom_field_value_live/ # CustomFieldValue CRUD LiveViews │ │ ├── custom_field_live/ -│ │ └── user_live/ # User management LiveViews +│ │ ├── user_live/ # User management LiveViews +│ │ ├── role_live/ # Role management LiveViews +│ │ ├── membership_fee_type_live/ # Membership fee type LiveViews +│ │ ├── membership_fee_settings_live.ex # Membership fee settings +│ │ ├── global_settings_live.ex # Global settings +│ │ └── contribution_type_live/ # Contribution types (mock-up) │ ├── auth_overrides.ex # AshAuthentication overrides │ ├── endpoint.ex # Phoenix endpoint │ ├── gettext.ex # I18n configuration -│ ├── live_helpers.ex # LiveView helpers +│ ├── live_helpers.ex # LiveView lifecycle hooks and helpers │ ├── live_user_auth.ex # LiveView authentication │ ├── router.ex # Application router │ └── telemetry.ex # Telemetry configuration @@ -176,7 +202,7 @@ test/ **Module Naming:** - **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`) - **Context functions:** Use `snake_case` and verb-first naming (e.g., `create_user`, `list_members`) @@ -818,14 +844,17 @@ end ```heex -