sync email between user and member closes #167 #181

Merged
moritz merged 9 commits from feature/email-sync into main 2025-10-30 16:25:36 +01:00
Owner

Description of the implemented changes

The changes were:

  • Bugfixing
  • New Feature
  • Breaking Change
  • Refactoring

#167

What has been changed?

  • add action changes for the email syncronisation

Definition of Done

Code Quality

  • No new technical depths
  • Linting passed
  • Documentation is added were needed

Accessibility

  • New elements are properly defined with html-tags
  • Colour contrast follows WCAG criteria
  • Aria labels are added when needed
  • Everything is accessible by keyboard
  • Tab-Order is comprehensible
  • All interactive elements have a visible focus

Testing

  • Tests for new code are written
  • All tests pass
  • axe-core dev tools show no critical or major issues

TODOs

  • Test updating a member email to a already used user email
  • Test updating a user email to a already used member email
  • Create a validation, that shows the correct error message
## Description of the implemented changes The changes were: - [ ] Bugfixing - [x] New Feature - [ ] Breaking Change - [ ] Refactoring https://git.local-it.org/local-it/mitgliederverwaltung/issues/167 ## What has been changed? - add action changes for the email syncronisation ## Definition of Done ### Code Quality - [ ] No new technical depths - [x] Linting passed - [x] Documentation is added were needed ### Accessibility - [ ] New elements are properly defined with html-tags - [ ] Colour contrast follows WCAG criteria - [ ] Aria labels are added when needed - [ ] Everything is accessible by keyboard - [ ] Tab-Order is comprehensible - [ ] All interactive elements have a visible focus ### Testing - [x] Tests for new code are written - [x] All tests pass - [ ] axe-core dev tools show no critical or major issues ## TODOs - [x] Test updating a member email to a already used user email - [x] Test updating a user email to a already used member email - [x] Create a validation, that shows the correct error message
moritz added this to the Accounts & Logins milestone 2025-10-16 19:09:26 +02:00
moritz self-assigned this 2025-10-16 19:09:26 +02:00
moritz added 2 commits 2025-10-16 19:09:27 +02:00
add action changes for email sync
All checks were successful
continuous-integration/drone/push Build is passing
1c31b821ba
moritz added this to the Sprint 7 - 02.10 - 23.10. project 2025-10-16 19:09:28 +02:00
moritz added 3 commits 2025-10-17 14:35:13 +02:00
moritz added 1 commit 2025-10-17 16:02:01 +02:00
refactor: email sync changes
Some checks failed
continuous-integration/drone/push Build is failing
623cc86826
moritz force-pushed feature/email-sync from 623cc86826 to 387a627783 2025-10-17 16:17:41 +02:00 Compare
moritz changed title from WIP: sync email between user and member closes #167 to sync email between user and member closes #167 2025-10-17 16:17:53 +02:00
requested reviews from simon, carla, rafael 2025-10-17 16:21:27 +02:00
moritz force-pushed feature/email-sync from 387a627783 to df8cc74d11 2025-10-17 19:01:06 +02:00 Compare
moritz added 2 commits 2025-10-20 14:53:53 +02:00
add seed test
Some checks failed
continuous-integration/drone/push Build is failing
152ca611e7
Author
Owner

Complete reference for email behavior between User and Member entities.

Where should we document this?

Core Rules

  1. User.email is source of truth - Always overrides member email when linking
  2. DB constraints - Prevent duplicates within same table (users.email, members.email)
  3. Custom validations - Prevent cross-table conflicts only for linked entities
  4. Sync is bidirectional: User ↔ Member (but User always wins on link)

Decision Tree

Action: Create/Update/Link Entity with Email X
│
├─ Does Email X violate DB constraint (same table)?
│  └─ YES → ❌ FAIL (two users or two members with same email)
│
├─ Is Entity currently linked? (or being linked?)
│  │
│  ├─ NO (unlinked entity)
│  │  └─ ✅ SUCCESS (no custom validation)
│  │
│  └─ YES (linked or linking)
│     │
│     ├─ Action: Update Linked User Email
│     │  ├─ Email used by other member? → ❌ FAIL (validation)
│     │  └─ Email unique? → ✅ SUCCESS + sync to member
│     │
│     ├─ Action: Update Linked Member Email  
│     │  ├─ Email used by other user? → ❌ FAIL (validation)
│     │  └─ Email unique? → ✅ SUCCESS + sync to user
│     │
│     ├─ Action: Link User to Member (both directions)
│     │  ├─ User email used by other member? → ❌ FAIL (validation)
│     │  └─ Otherwise → ✅ SUCCESS + override member email

Sync Triggers

Action Sync Direction When
Update linked user email User → Member Email changed
Update linked member email Member → User Email changed
Link user to member User → Member Always (override)
Link member to user User → Member Always (override)
Unlink None Emails stay as-is
Complete reference for email behavior between `User` and `Member` entities. Where should we document this? ## Core Rules 1. **User.email is source of truth** - Always overrides member email when linking 2. **DB constraints** - Prevent duplicates within same table (users.email, members.email) 3. **Custom validations** - Prevent cross-table conflicts only for linked entities 4. **Sync is bidirectional**: User ↔ Member (but User always wins on link) --- ## Decision Tree ``` Action: Create/Update/Link Entity with Email X │ ├─ Does Email X violate DB constraint (same table)? │ └─ YES → ❌ FAIL (two users or two members with same email) │ ├─ Is Entity currently linked? (or being linked?) │ │ │ ├─ NO (unlinked entity) │ │ └─ ✅ SUCCESS (no custom validation) │ │ │ └─ YES (linked or linking) │ │ │ ├─ Action: Update Linked User Email │ │ ├─ Email used by other member? → ❌ FAIL (validation) │ │ └─ Email unique? → ✅ SUCCESS + sync to member │ │ │ ├─ Action: Update Linked Member Email │ │ ├─ Email used by other user? → ❌ FAIL (validation) │ │ └─ Email unique? → ✅ SUCCESS + sync to user │ │ │ ├─ Action: Link User to Member (both directions) │ │ ├─ User email used by other member? → ❌ FAIL (validation) │ │ └─ Otherwise → ✅ SUCCESS + override member email ``` ## Sync Triggers | Action | Sync Direction | When | |--------|---------------|------| | Update linked user email | User → Member | Email changed | | Update linked member email | Member → User | Email changed | | Link user to member | User → Member | Always (override) | | Link member to user | User → Member | Always (override) | | Unlink | None | Emails stay as-is |
moritz force-pushed feature/email-sync from 152ca611e7 to abe1c96050 2025-10-20 15:41:17 +02:00 Compare
moritz force-pushed feature/email-sync from abe1c96050 to d8f3a9ecd4 2025-10-20 15:50:03 +02:00 Compare
moritz added 1 commit 2025-10-20 19:29:42 +02:00
empty commit to test ci
All checks were successful
continuous-integration/drone/push Build is passing
d3b6aeb6f9
moritz force-pushed feature/email-sync from d3b6aeb6f9 to d8f3a9ecd4 2025-10-20 19:31:57 +02:00 Compare
moritz force-pushed feature/email-sync from d8f3a9ecd4 to 259d63b66e 2025-10-20 20:11:53 +02:00 Compare
simon modified the project from Sprint 7 - 02.10 - 23.10. to Sprint 8 - 23.10 - 20.11 2025-10-23 13:13:43 +02:00
moritz force-pushed feature/email-sync from 259d63b66e to 899039b3ee 2025-10-23 13:13:45 +02:00 Compare
carla approved these changes 2025-10-24 11:47:38 +02:00
carla left a comment
Owner

Nice work, thanks 💯

Nice work, thanks 💯
@ -0,0 +37,4 @@
Updates an email field directly via Ecto within the current transaction.
This bypasses Ash's action system to ensure the update happens in the
same database transaction as the parent action.
Owner

Maybe you can explain that to us a bit in the next weekly :)

Maybe you can explain that to us a bit in the next weekly :)
Author
Owner

In Ash, if you call another Ash action within a around_transaction callback, it would run in a separate transaction. This can lead to inconsistencies if, for example, the first action is successful, but the email synchronization fails. By using Ecto directly (Mv.Repo.update()) the update remains in the same transaction as the parent action. If anything fails, the entire transaction is rolled back.

In Ash, if you call another Ash action within a `around_transaction` callback, it would run in a separate transaction. This can lead to inconsistencies if, for example, the first action is successful, but the email synchronization fails. By using Ecto directly (`Mv.Repo.update()`) the update remains in the same transaction as the parent action. If anything fails, the entire transaction is rolled back.
moritz merged commit 687d653fb7 into main 2025-10-30 16:25:36 +01:00
moritz deleted branch feature/email-sync 2025-10-30 16:25:37 +01:00
Sign in to join this conversation.
No description provided.