docs(migration): document individual memberships and email forwarder#698
docs(migration): document individual memberships and email forwarder#698dealako wants to merge 1 commit into
Conversation
Add current-state and migration write-ups for two flows being migrated from myprofile + membership-ui into LFX Self Serve: - Individual Memberships ($99/yr TLF Supporter): cross-app user journey, Stripe + Salesforce wiring, and gap analysis vs LFX Self Serve. - Linux.com Email Forwarder ($150 lifetime alias): purchase + claim flow spanning myprofile, membership-ui, and the ITX mail-forwarder service, with UX unification as the primary migration win. Also relax markdownlint MD013 to a 120-char limit (code/tables exempt), disable MD060, and add a Migration section to the mkdocs nav. Jira: https://jira.linuxfoundation.org/browse/LFXV2-1664 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Deal <ddeal@linuxfoundation.org>
WalkthroughThis PR adds two comprehensive migration documentation pages describing the current Individual Memberships and Linux.com Email Forwarder implementations with strategy and gaps for LFX One migration. It also updates markdownlint rules to enforce consistent line length and extends mkdocs navigation to surface the new Migration section. ChangesMigration Documentation and Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds migration documentation for two legacy membership-related user journeys (Individual Supporter membership and Linux.com email forwarder add-on) and updates the documentation toolchain/navigation to support these new docs in LFX Self Serve.
Changes:
- Added two detailed migration/current-state write-ups under
docs/migration/. - Updated MkDocs navigation to include a new “Migration” section.
- Adjusted markdownlint configuration (MD013 to 120 chars with code/table exemptions; disabled MD060).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
.markdownlint.json |
Updates Markdown linting rules/limits to better accommodate long-form migration docs. |
mkdocs.yaml |
Adds a “Migration” nav section pointing to the new docs. |
docs/migration/individual-memberships.md |
New documentation describing the current Individual Supporter membership flow and migration considerations. |
docs/migration/linux-com-email-forwarder.md |
New documentation describing the current Linux.com email forwarder add-on flow and migration considerations. |
Comments suppressed due to low confidence (1)
docs/migration/individual-memberships.md:440
- Typo in the function name:
Notifiy...should be spelledNotify...for readability/searchability (even in docs).
1. `NotifiyMembershipServiceError()` auto-files a **Jira ticket** and sends an SES email
with subject "URGENT: Individual Enrollment" to support (`backend/modules/enrollment/index.js:416–456`).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| MUI --- AUTH0 | ||
| ``` | ||
|
|
||
| Three distinct backend services are involved — `member-service`, `user-service`, and `ITX` — each with a separate responsibility. This is the main complexity to carry over in the migration. |
|
|
||
| 6. On success → return `{ ID: membershipId }`. | ||
| 7. On member-service failure **after** Stripe already charged: | ||
| `NotifiyMembershipServiceError()` → files a Jira ticket + sends SES |
|
|
||
| ### Stripe-succeeded-but-member-service-failed | ||
|
|
||
| Same as the Individual Supporter flow — the same `NotifiyMembershipServiceError()` path |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docs/migration/linux-com-email-forwarder.md (1)
246-256: 🏗️ Heavy liftNon-atomic rename operation is a significant operational risk.
The documentation correctly identifies that the alias rename is a four-step sequence with no rollback or transaction boundaries (lines 248-256). If steps 3 or 4 fail, the user loses their old alias without getting the new one. This is an excellent opportunity for improvement in the migration to LFX One—consider wrapping this in a saga pattern or compensating transaction to ensure atomicity.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/migration/linux-com-email-forwarder.md` around lines 246 - 256, The UpdateForwardAlias flow (enrollment.service.ts: UpdateForwardAlias) performs a non-atomic 4-step rename using userService.UpdateUserEmails and itxService.DeleteForward/CreateForward which can leave users without an alias if steps 3 or 4 fail; fix by making the operation compensatable or atomic: implement a saga/compensating transaction around UpdateForwardAlias that either (a) creates the new ITX forward (itxService.CreateForward(newAlias, recipient)) and adds the new alias to the user (userService.UpdateUserEmails(token, add new alias)) before removing the old forward and old alias, or (b) on any failure run compensating steps to recreate the old forward and re-add the old alias (use itxService.CreateForward with the oldAlias and userService.UpdateUserEmails(token, add old alias)), add retry/backoff and clear, well-scoped logging for each step, and surface errors so callers can coordinate retries; update UpdateForwardAlias to orchestrate these compensations and unit tests to cover failure points.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/migration/linux-com-email-forwarder.md`:
- Around line 322-333: The docs note that member-service, ITX, and user-service
are independent and not automatically kept in sync, which is an operational
risk; update the migration plan to define a concrete consistency solution: add a
reconciliation job (e.g., a periodic reconciler service) that compares
member-service records for productID = 01t2M000005wBazQAE against ITX
alias/forward-to and user-service email lists and repairs or alerts on
mismatches, and/or define a saga/orchestration flow for purchase/alias changes
with compensating actions and robust error handling and logging; include clear
instructions in the document on how to run the reconciler, expected invariants,
and where to find logs/alerts.
---
Nitpick comments:
In `@docs/migration/linux-com-email-forwarder.md`:
- Around line 246-256: The UpdateForwardAlias flow (enrollment.service.ts:
UpdateForwardAlias) performs a non-atomic 4-step rename using
userService.UpdateUserEmails and itxService.DeleteForward/CreateForward which
can leave users without an alias if steps 3 or 4 fail; fix by making the
operation compensatable or atomic: implement a saga/compensating transaction
around UpdateForwardAlias that either (a) creates the new ITX forward
(itxService.CreateForward(newAlias, recipient)) and adds the new alias to the
user (userService.UpdateUserEmails(token, add new alias)) before removing the
old forward and old alias, or (b) on any failure run compensating steps to
recreate the old forward and re-add the old alias (use itxService.CreateForward
with the oldAlias and userService.UpdateUserEmails(token, add old alias)), add
retry/backoff and clear, well-scoped logging for each step, and surface errors
so callers can coordinate retries; update UpdateForwardAlias to orchestrate
these compensations and unit tests to cover failure points.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 115b792b-b15d-43d1-9409-4ee4961693d2
📒 Files selected for processing (4)
.markdownlint.jsondocs/migration/individual-memberships.mddocs/migration/linux-com-email-forwarder.mdmkdocs.yaml
| In `myprofile`, the "purchased" state is detected by the presence of a `member-service` | ||
| record for `productID = 01t2M000005wBazQAE`. The alias management state is then read from | ||
| **ITX** (not from member-service). The two services are independent: | ||
|
|
||
| ```text | ||
| member-service → "did this user purchase the add-on?" | ||
| ITX → "what is their current alias and forward-to?" | ||
| user-service → "does this user have a @linux.com address in their email list?" | ||
| ``` | ||
|
|
||
| All three must be consistent for the feature to work correctly. They are not automatically | ||
| kept in sync — there is no saga or compensating transaction. |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift
Important consistency concern across three services.
The documentation explicitly states that member-service, ITX, and user-service are independent and "not automatically kept in sync — there is no saga or compensating transaction" (lines 332-333). This is a significant operational risk that should be addressed in the LFX One migration, potentially through eventual consistency patterns, saga orchestration, or at minimum better error handling and reconciliation tooling.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/migration/linux-com-email-forwarder.md` around lines 322 - 333, The docs
note that member-service, ITX, and user-service are independent and not
automatically kept in sync, which is an operational risk; update the migration
plan to define a concrete consistency solution: add a reconciliation job (e.g.,
a periodic reconciler service) that compares member-service records for
productID = 01t2M000005wBazQAE against ITX alias/forward-to and user-service
email lists and repairs or alerts on mismatches, and/or define a
saga/orchestration flow for purchase/alias changes with compensating actions and
robust error handling and logging; include clear instructions in the document on
how to run the reconciler, expected invariants, and where to find logs/alerts.
Summary
Add current-state and migration write-ups for two flows being migrated from
myprofile + membership-ui into LFX Self Serve:
Stripe + Salesforce wiring, and gap analysis vs LFX Self Serve.
spanning myprofile, membership-ui, and the ITX mail-forwarder service, with
UX unification as the primary migration win.
Also relax markdownlint MD013 to a 120-char limit (code/tables exempt),
disable MD060, and add a Migration section to the mkdocs nav.
Changes
Jira: LFXV2-1664