- Implemented regenerate_cycles_on_type_change helper in Member resource
- Cycles that haven't ended yet (cycle_end >= today) are deleted and regenerated
- Paid and suspended cycles remain unchanged (not deleted)
- CycleGenerator reloads member with new membership_fee_type_id
- Adjusted tests to work with current cycles only (no future cycles)
- All integration tests passing
Phase 4 completed: Cycle regeneration on type change
- Log warnings when cycle generation fails in Member create/update
- Extract generate_fn to reduce code duplication
- Improves debuggability of silent failures
- Replace Application.get_env(:mv, :env) with :sql_sandbox config
- Remove redundant :env config from test.exs
- More explicit and less error-prone for test environment detection
- Escape SQL LIKE wildcards (% and _) to prevent pattern injection
- Limit search query length to 100 characters
- Apply sanitization in both :search action and linking filters
- FTS and fuzzy search use unsanitized query (wildcards not special there)
Custom field LIKE queries on JSONB are expensive (no index).
User linking only needs name/email search for autocomplete.
Custom fields are still searchable via main member search (uses FTS index).
Remove unnecessary credo:disable as function complexity is now acceptable.
The fields parameter was accepted but never used in the :search action.
Simplify API to only accept the query parameter.
Update @doc to reflect the actual functionality.
Explain the two-tier matching approach:
- % operator with server-wide threshold (0.3) for fast index scans
- similarity functions with configurable threshold (0.2) for edge cases
Add rationale for threshold value based on German name testing
- Replace 4 LIKE checks with 2 in build_custom_field_filter
- Simplify CASE blocks in migration trigger functions
- ->> operator always returns text, no need for -> + ::text fallback
- Performance improvement: 50% fewer LIKE operations
- Add @spec for public functions in Member and UserLive.Form
- Replace magic numbers with module constants:
- @member_search_limit = 10
- @default_similarity_threshold = 0.2
- Add comprehensive @doc for filter_by_email_match and fuzzy_search