Test Plan: Member-Created Events¶
Generated by /plan-eng-review on 2026-06-05 Branch: master Repo: rakletadmin/rakletv3 Source design doc: member-created-events-design.md
Affected Pages/Routes¶
Member portal (App2 area, gercek.raklet.net)¶
/Events/Submit— member submission form (new)/Events/MySubmissions— member's own submissions list (new)/Events/Submissions/{id}/Edit— edit pending OR approved-with-draft submission (new)
Admin panel (Raklet.Backend, gercek.raklet.org)¶
- Existing events list — now shows pending member submissions with badge (no new tab)
- Existing event detail page — now has approval panel embedded inline when SubmissionStatus=Pending
APIs touched¶
POST /api/app/events/submissions— member submission endpoint (new)PATCH /api/app/events/submissions/{id}— member edit (new)GET /api/app/events/submissions/mine— member's submissions list (new)POST /api/v2/events/{id}/approve— admin approval (new)POST /api/v2/events/{id}/reject— admin rejection (new)- All existing event-read endpoints (
/api/app/events,/api/v2/events, public Explore, Zapier, etc.) — refactored to useEventQueryFilters.VisibleTo()helper
Key Interactions to Verify¶
Member submission flow (browse-tests required — happy path + double-click idempotency)¶
- Fill all required fields → submit → land on My Submissions with new pending row
- Submit twice rapidly → only one event created
- Submit with PaymentAccountId from another org → 403
- Submit without cover image → succeeds
- Navigate away mid-form → form discards cleanly (no orphan blobs)
Member edit flow (browse-tests for explicit-submit pattern)¶
- Open approved event → edit fields → Save → public event unchanged
- Save multiple times → all changes accumulate in PendingDraft
- Click Submit-for-approval → SubmissionStatus flips to Pending; public still shows old version
- Admin approves → PendingDraft merges into top-level fields atomically
- Member edits Pending event while admin is mid-approval → second-writer-wins OR Concurrency exception (verify expected behavior)
Admin approval (browse-tests — load admin events list → click pending → approve)¶
- Pending events appear in existing events list with badge
- Approval panel embedded in detail page with bank-account dropdown
- Click Approve with default PaymentAccountId → SubmissionStatus=Approved, IsPublished=true
- Click Approve with override PaymentAccountId → routing reflects override
- Click Reject with reason → SubmissionStatus=Rejected, member receives email with reason
- Approval is atomic — partial-success state never observable
Notifications¶
- Submission created → admin bell counter increments real-time
- Daily digest fires at scheduled time with N pending events for opted-in admins
- Opted-out admin (via ManagerEmailSettings.PendingEventSubmissionEmails=false) receives nothing
- Empty queue day → no email sent
- 3-day SLA reminder fires for events still Pending
- 7-day owner escalation fires for events Pending too long
- Org with zero admins → escalation logs warning, no crash
Reminders¶
- Approved event with no explicit reminder → 24h-before reminder fires (hardcoded default)
- Admin sets per-event explicit reminders → those override the default
Edge Cases¶
Filter helper (EventQueryFilters.VisibleTo())¶
- Member context → only
IsPublished=true AND SubmissionStatus=Approved - Admin context (with Manage Events permission on this org) → all events in org including pending and rejected
- Public/anonymous context → same as Member
- Null caller context → safest filter (Public)
- Admin context for ANOTHER org → only public events of that org (no cross-org pending leak)
Data model edge cases¶
- EventDoc with PendingDraft=null → unchanged behavior for all read paths
- EventDoc with PendingDraft + IsPublished=true → public reads see top-level fields only; never PendingDraft
- EventDoc with SubmissionStatus=Rejected → no public read paths return it
- Approving an event whose PendingDraft has invalid ticket prices (e.g., negative) → reject with validation error before write
Background jobs¶
- Daily digest job — idempotent on retry (no duplicate emails)
- Daily digest job — partial admin failure (some sends fail) → log + continue, don't fail entire job
- SLA escalation job missed for 25h → alert fires (observability requirement)
- SLA escalation backfills missed days on startup after outage
Member portal¶
- Member without auth tries
/Events/Submit→ redirect to login - Member of Org A tries to edit Org B's pending event → 403
- Submission form max-length validation matches admin form (reused DTO)
- Cover image upload partial-failure → orphan blob cleanup runs within 24h
- Member with read-only role (if applicable) can't submit — verify auth gates
Critical Paths (must work end-to-end)¶
-
Hiking-leader happy path: Member opens portal → submission form loads in <2s → fills form → submits → sees Pending status immediately → admin sees pending event in events list within 10s → admin approves → member receives approval email within 60s → event appears in public event listing.
-
Admin daily-digest flow: 5 events submitted across a day → next morning admin receives one email listing all 5 → admin clicks first event → lands in event detail with approval panel → approves → returns to email/list → approves second → digest correctly excludes already-approved events on subsequent days.
-
Rejection feedback loop: Admin rejects with reason "ticket prices too high" → member receives email with reason → member edits pending event with new prices → Submit-for-approval → admin approves → published.
-
Edit-after-approval draft pattern: Member edits approved event description → Save → public event still shows old description → Submit-for-approval → public still shows old description until admin approves → admin approves → public now shows new description.
-
SLA escalation: Submit event → admin doesn't review → 3 days pass → admin gets reminder email → still no review → 7 days pass → org owner gets escalation email → submission still visible in queue (not auto-rejected, not auto-approved).
Regression Test Scope (IRON RULE — 24 callsites)¶
Per skill: the 24 EventDoc-touching callsites refactored to use EventQueryFilters.VisibleTo() ALL need regression tests proving filter behavior matches pre-refactor for legacy admin-created (SubmissionStatus=Approved AND IsPublished=true) events.
Integration tests preferred over Moq per feedback_no_test_only_di_seams.md. Hit a real EventDoc test fixture (or test Cosmos container) with a known set of legacy approved events + new test pending events + new test rejected events; assert each callsite returns the expected subset.
High-priority regression targets (member + public facing)¶
Raklet.Api/Controllers/App/Events/EventsController.cs:41(member-facing read)Application/Areas/Events/Controllers/HomeController.cs(public event detail page)Raklet.Api/Controllers/Public/ExploreController.cs(public event listing)Raklet.Api/Controllers/App/Zapier/ZapierEventsController.cs(third-party integration)Raklet.Api/Controllers/V2/V2EventsController.cs:417(admin list — visibility-aware)
Medium-priority (services + background work)¶
Services/EventOrgSummaryService.csServices/EmailServices/EventEmailService.csServices/EmailServices/EventEmailReminderInstanceSyncService.csServices/EmailServices/EventEmailReminderSchedulerService.csServices/Integrations/UseCases/Zoom/ParticipantJoinedWebhookInteractor.csRaklet.WebJobs.Secondary/Export/ExportFunctions.csRaklet.WebJobs.Secondary/Email/EmailFunctions.cs
Lower-priority (smoke test acceptable)¶
- Remaining ~12 callsites surfaced at implementation time via full grep audit
Tooling¶
- Unit tests: xUnit + integration test infrastructure already present (per
Raklet.UnitTests/EventOrgSummaryServiceTests.cs) - Browse tests:
browse-tests/payment-regression/style — extend withevents-submission/suite covering member portal flows on.raklet.net - CI: PR-CI workflow already runs on every PR; browse-smoke dispatches against ci-runner pool
NOT in this test plan (deferred)¶
- LLM eval suites — no LLM in v1 (AI submission deferred to v1.5)
- Load / stress testing — defer until 30-day post-launch metrics inform whether scale concerns materialize
- Accessibility / screen-reader audit — separate concern; cover in /plan-design-review