Scope
Read-heavy admin surfaces for the dashboard, plus one intervention action.
Mentorship oversight
| Method |
Path |
Notes |
| GET |
/admin/mentorship/pairs |
active pairs, paginated |
| GET |
/admin/mentorship/sessions?upcoming=true |
upcoming sessions |
| GET |
/admin/mentorship/mentors |
capacity overview (capacity vs active count) |
| POST |
/admin/mentorship/{id}/conclude |
conclude-on-behalf for disputes (audit-logged via Serilog structured fields) |
Sponsorship oversight
| Method |
Path |
Notes |
| GET |
/admin/sponsors |
list with status, tier, subscription state |
| GET |
/admin/sponsors/summary |
MRR computed from active subscriptions (annual normalized to monthly) + counts by status |
| GET |
/admin/sponsors/{id}/invoices |
mirrored invoices with status + Stripe hosted links |
Rules
Error codes
admin.forbidden, mentorship.not_found, sponsorship.not_found
Dependencies
Blocked by #1; mentorship endpoints need #10/#11; sponsorship endpoints need #16.
Acceptance criteria
Conventions (project-wide, non-negotiable)
- .NET 9, records for immutable shapes, file-scoped namespaces, primary constructors where they read well. Minimal-API endpoints grouped per module via
IEndpointModule.MapEndpoints.
Result<T> (SharedKernel) instead of exception-driven control flow. Endpoint results map failures to ProblemDetails with the stable error codes listed above — the frontend keys off them.
- Module owns its EF Core
DbContext mapped to its own Postgres schema. Modules never reference each other's internals — cross-module needs go through a public contract interface or an in-process domain event (IEventPublisher).
- All external calls (GitHub, Stripe, Brevo, Cloudinary, Meilisearch) behind interfaces owned by the consuming module.
- Every list endpoint paginated (offset is fine). xUnit tests in
tests/CommunityPro.Tests/<Module>/ following the existing harness patterns (see Members/MembersTestHarness.cs).
Scope
Read-heavy admin surfaces for the dashboard, plus one intervention action.
Mentorship oversight
/admin/mentorship/pairs/admin/mentorship/sessions?upcoming=true/admin/mentorship/mentors/admin/mentorship/{id}/concludeSponsorship oversight
/admin/sponsors/admin/sponsors/summary/admin/sponsors/{id}/invoicesRules
/admin/*with the admin policy at group level (Admin: policy-based authorization + member management endpoints (Phase 8.1, 8.2, 2.6) #1's pattern) — the Admin module itself owns nothing here.Error codes
admin.forbidden,mentorship.not_found,sponsorship.not_foundDependencies
Blocked by #1; mentorship endpoints need #10/#11; sponsorship endpoints need #16.
Acceptance criteria
Conventions (project-wide, non-negotiable)
IEndpointModule.MapEndpoints.Result<T>(SharedKernel) instead of exception-driven control flow. Endpoint results map failures to ProblemDetails with the stable error codes listed above — the frontend keys off them.DbContextmapped to its own Postgres schema. Modules never reference each other's internals — cross-module needs go through a public contract interface or an in-process domain event (IEventPublisher).tests/CommunityPro.Tests/<Module>/following the existing harness patterns (seeMembers/MembersTestHarness.cs).