CommunityPro / CommunityPro/community-pro-api
Mentorship: session booking + ICS emails (Phase 6.4)
- Dominant language
- C#
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Scope
Book sessions against mentor availability, with calendar-attachment emails.
## Data model
```csharp
public sealed class Session
{
public Guid Id { get; set; }
public Guid MentorshipId { get; set; }
public DateTimeOffset StartUtc { get; set; } // stored UTC, always
public int DurationMinutes { get; set; } // 30 | 60
public SessionStatus Status { get; set; } // Scheduled | Completed | Cancelled
public string? MeetingUrl { get; set; } // mentor-provided free text (Meet/Zoom)
}
```
## Endpoints (participants of the mentorship only)
| Method | Path | Notes |
|---|---|---|
| GET | `/mentorship/{id}/slots?weekOf=` | open slots: availability minus existing sessions, computed in the mentor's IANA tz via NodaTime, returned as UTC instants |
| POST | `/mentorship/{id}/sessions` | book; validations below |
| POST | `/mentorship/sessions/{id}/cancel` | either participant, only while `Scheduled` |
## Booking validations
1. Slot falls entirely inside the mentor's availability (evaluated in mentor-local time — DST-correct via NodaTime).
2. No overlap with any of the mentor's existing `Scheduled` sessions (across all their mentorships).
3. Start ≥ 12h in the future.
4. Duration ∈ {30, 60}; mentorship is `Active`.
## Emails
Booked/cancelled → **both** parties via Brevo, with an `.ics` attachment generated via [Ical.Net](https://github.com/ical-org/ical.net) (UTC times, summary, meeting URL when present). Best-effort as always.
## Error codes
`mentorship.not_found`, `mentorship.slot_unavailable`, `mentorship.slot_conflict`, `mentorship.too_soon`, `mentorship.invalid_state`, `mentorship.forbidden`
## Dependencies
Blocked by #9 and #10.
## Acceptance criteria
- [ ] **DST boundary tests are mandatory**: a slot spanning a DST transition in e.g. `Europe/London` or `America/New_York` books correctly; test both spring-forward and fall-back weeks
- [ ] Overlap check covers sessions from the mentor's *other* mentorships
- [ ] Concurrent booking of the same slot → exactly one succeeds
- [ ] ICS content asserted in tests (times, attendees)
### 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` (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//` following the existing harness patterns (see `Members/MembersTestHarness.cs`).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.