Blocker to land first — the SMS verification test hook (backend): the pre-registration flow verifies phone via Twilio Verify, and the code is never stored locally. Options (pick one; env is live-is-test so the safety gate is deferred but the hook must still be flag-gated):
Thread the existing SendVerificationCodeCommand.CustomCode through pre-registration behind a flag (e.g. PreRegistration:E2E:Enabled + fixed E2E_SMS_CODE). Recommended.
E2E-profile fake ITwilioVerifyService accepting a fixed code.
Test-only endpoint to mark PhoneVerified for a pre-registration id.
Email verification is automatable today: read emailVerificationCode/emailVerificationToken from Mongo PreRegistrations by unique test email (or hit the GET verify link).
Tasks:
Land the SMS hook (backend)
Playwright: full 4-step registration-stepper happy path (basic info → SMS consent → password/terms → verification codes → complete)
Validation/error paths (username/email taken, under-18, bad codes, resend)
Test-data hygiene: unique emails (e2e+<ts>@…), cleanup or GDPR-delete after runs
Phase P3 of epic #307.
**Blocker to land first — the SMS verification test hook** (backend): the pre-registration flow verifies phone via Twilio Verify, and the code is never stored locally. Options (pick one; env is live-is-test so the safety gate is deferred but the hook must still be flag-gated):
1. Thread the existing `SendVerificationCodeCommand.CustomCode` through pre-registration behind a flag (e.g. `PreRegistration:E2E:Enabled` + fixed `E2E_SMS_CODE`). **Recommended.**
2. E2E-profile fake `ITwilioVerifyService` accepting a fixed code.
3. Test-only endpoint to mark `PhoneVerified` for a pre-registration id.
**Email verification is automatable today**: read `emailVerificationCode`/`emailVerificationToken` from Mongo `PreRegistrations` by unique test email (or hit the GET verify link).
Tasks:
- [ ] Land the SMS hook (backend)
- [ ] Playwright: full 4-step registration-stepper happy path (basic info → SMS consent → password/terms → verification codes → complete)
- [ ] Validation/error paths (username/email taken, under-18, bad codes, resend)
- [ ] Reusable "fresh verified user" fixture (creates + completes a disposable account; storage-state login)
- [ ] Test-data hygiene: unique emails (`e2e+<ts>@…`), cleanup or GDPR-delete after runs
customCode threaded through ITwilioVerifyService → RemoteTwilioVerifyService → the existing SendVerificationCodeCommand.CustomCode → Twilio Verify custom-code feature. All three pre-registration send sites wired (initiate / verify-email / resend); the phone-check path is untouched (still a real Twilio round-trip).
Guardrails beyond the ticket sketch: in addition to PreRegistration:E2E:Enabled + a 4–10-digit SmsCode, the fixed code applies only to emails matching PreRegistration:E2E:EmailPattern (default e2e+*@spikersoft.com) — so while armed on the live env, real registrants still get generated codes. Armed sends log at Warning for Seq visibility. Guardrail test matrix included; full unit suite green.
To activate after merge (ops):
Enable the custom-code feature on the Twilio Verify service (Twilio console/support) if not already on.
Set PreRegistration__E2E__Enabled=true + PreRegistration__E2E__SmsCode=<secret> env vars on the API deployment (and the same secret as E2E_SMS_CODE for the Playwright suite).
Next on this ticket once merged+armed: the Playwright registration-stepper happy path, validation/error paths, and the reusable "fresh verified user" fixture (which also unblocks P4 without a manually seeded account).
### SMS hook implemented — spikersoft-backend PR #60 (option 1)
`customCode` threaded through `ITwilioVerifyService` → `RemoteTwilioVerifyService` → the existing `SendVerificationCodeCommand.CustomCode` → Twilio Verify custom-code feature. All three pre-registration send sites wired (initiate / verify-email / resend); the phone-check path is untouched (still a real Twilio round-trip).
Guardrails beyond the ticket sketch: in addition to `PreRegistration:E2E:Enabled` + a 4–10-digit `SmsCode`, the fixed code applies **only to emails matching `PreRegistration:E2E:EmailPattern`** (default `e2e+*@spikersoft.com`) — so while armed on the live env, real registrants still get generated codes. Armed sends log at Warning for Seq visibility. Guardrail test matrix included; full unit suite green.
**To activate after merge** (ops):
1. Enable the custom-code feature on the Twilio Verify service (Twilio console/support) if not already on.
2. Set `PreRegistration__E2E__Enabled=true` + `PreRegistration__E2E__SmsCode=<secret>` env vars on the API deployment (and the same secret as `E2E_SMS_CODE` for the Playwright suite).
Next on this ticket once merged+armed: the Playwright registration-stepper happy path, validation/error paths, and the reusable "fresh verified user" fixture (which also unblocks P4 without a manually seeded account).
✅ SMS hook merged (spikersoft-backend PR #60) — first checkbox done; merging deploys it, so the hook exists on the API but stays inert until armed (PreRegistration__E2E__Enabled=true + PreRegistration__E2E__SmsCode=<secret> env vars, plus the Twilio Verify custom-code feature check).
Ticket stays open for the Playwright side: registration-stepper happy path, validation/error paths, fresh-verified-user fixture, and test-data hygiene. Starting with the paths that don't need the hook armed (client-side validation, no backend mutations).
✅ SMS hook merged (spikersoft-backend PR #60) — first checkbox done; merging deploys it, so the hook exists on the API but stays **inert until armed** (`PreRegistration__E2E__Enabled=true` + `PreRegistration__E2E__SmsCode=<secret>` env vars, plus the Twilio Verify custom-code feature check).
Ticket stays open for the Playwright side: registration-stepper happy path, validation/error paths, fresh-verified-user fixture, and test-data hygiene. Starting with the paths that don't need the hook armed (client-side validation, no backend mutations).
Validation-path specs open: spikersoft-angular PR #111 — step-1 open/cancel, disabled-Next, username/email format errors, and the under-18 age gate, all mutation-free (safe on every PR run). Full anonymous project now 60 passed / 2 skipped.
Finding while writing them: the datepicker [max] (18 years ago) is the primary age gate — handleNext()'s isUnder18 branch can't be reached by normal typing; left in place as defense-in-depth but worth knowing it's untestable UI.
Remaining on this ticket (needs the merged #60 hook armed + runner access to read the email code): happy-path stepper run, bad-code/resend paths, fresh-verified-user fixture, and data hygiene. Two env prerequisites for that slice: (1) PreRegistration__E2E__Enabled + SmsCode on the API deployment, (2) a way for the suite to read emailVerificationCode — either Mongo access from the runner (VPN-internal mongo-router) or we add a sibling flag-gated echo of the code, worth deciding before I build it.
Validation-path specs open: spikersoft-angular PR #111 — step-1 open/cancel, disabled-Next, username/email format errors, and the under-18 age gate, all mutation-free (safe on every PR run). Full anonymous project now 60 passed / 2 skipped.
Finding while writing them: the datepicker `[max]` (18 years ago) is the *primary* age gate — `handleNext()`'s `isUnder18` branch can't be reached by normal typing; left in place as defense-in-depth but worth knowing it's untestable UI.
Remaining on this ticket (needs the merged #60 hook **armed** + runner access to read the email code): happy-path stepper run, bad-code/resend paths, fresh-verified-user fixture, and data hygiene. Two env prerequisites for that slice: (1) `PreRegistration__E2E__Enabled` + `SmsCode` on the API deployment, (2) a way for the suite to read `emailVerificationCode` — either Mongo access from the runner (VPN-internal `mongo-router`) or we add a sibling flag-gated echo of the code, worth deciding before I build it.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Phase P3 of epic #307.
Blocker to land first — the SMS verification test hook (backend): the pre-registration flow verifies phone via Twilio Verify, and the code is never stored locally. Options (pick one; env is live-is-test so the safety gate is deferred but the hook must still be flag-gated):
SendVerificationCodeCommand.CustomCodethrough pre-registration behind a flag (e.g.PreRegistration:E2E:Enabled+ fixedE2E_SMS_CODE). Recommended.ITwilioVerifyServiceaccepting a fixed code.PhoneVerifiedfor a pre-registration id.Email verification is automatable today: read
emailVerificationCode/emailVerificationTokenfrom MongoPreRegistrationsby unique test email (or hit the GET verify link).Tasks:
e2e+<ts>@…), cleanup or GDPR-delete after runsSMS hook implemented — spikersoft-backend PR #60 (option 1)
customCodethreaded throughITwilioVerifyService→RemoteTwilioVerifyService→ the existingSendVerificationCodeCommand.CustomCode→ Twilio Verify custom-code feature. All three pre-registration send sites wired (initiate / verify-email / resend); the phone-check path is untouched (still a real Twilio round-trip).Guardrails beyond the ticket sketch: in addition to
PreRegistration:E2E:Enabled+ a 4–10-digitSmsCode, the fixed code applies only to emails matchingPreRegistration:E2E:EmailPattern(defaulte2e+*@spikersoft.com) — so while armed on the live env, real registrants still get generated codes. Armed sends log at Warning for Seq visibility. Guardrail test matrix included; full unit suite green.To activate after merge (ops):
PreRegistration__E2E__Enabled=true+PreRegistration__E2E__SmsCode=<secret>env vars on the API deployment (and the same secret asE2E_SMS_CODEfor the Playwright suite).Next on this ticket once merged+armed: the Playwright registration-stepper happy path, validation/error paths, and the reusable "fresh verified user" fixture (which also unblocks P4 without a manually seeded account).
✅ SMS hook merged (spikersoft-backend PR #60) — first checkbox done; merging deploys it, so the hook exists on the API but stays inert until armed (
PreRegistration__E2E__Enabled=true+PreRegistration__E2E__SmsCode=<secret>env vars, plus the Twilio Verify custom-code feature check).Ticket stays open for the Playwright side: registration-stepper happy path, validation/error paths, fresh-verified-user fixture, and test-data hygiene. Starting with the paths that don't need the hook armed (client-side validation, no backend mutations).
Validation-path specs open: spikersoft-angular PR #111 — step-1 open/cancel, disabled-Next, username/email format errors, and the under-18 age gate, all mutation-free (safe on every PR run). Full anonymous project now 60 passed / 2 skipped.
Finding while writing them: the datepicker
[max](18 years ago) is the primary age gate —handleNext()'sisUnder18branch can't be reached by normal typing; left in place as defense-in-depth but worth knowing it's untestable UI.Remaining on this ticket (needs the merged #60 hook armed + runner access to read the email code): happy-path stepper run, bad-code/resend paths, fresh-verified-user fixture, and data hygiene. Two env prerequisites for that slice: (1)
PreRegistration__E2E__Enabled+SmsCodeon the API deployment, (2) a way for the suite to reademailVerificationCode— either Mongo access from the runner (VPN-internalmongo-router) or we add a sibling flag-gated echo of the code, worth deciding before I build it.Board-sweep status (2026-07-22): blocker delivered (backend PR #60 flag-gated E2E SMS hook + angular PR #111 step-1 validation specs). REMAINING: the full registration round-trip spec.