Mentorship: session booking + ICS emails (Phase 6.4)
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- csharp, postgresql
- Ambito
- api, backend, backend-api-design
Direzione di ricerca
Esamina prima il lavoro in #9 e #10, quindi segui i pattern IEndpointModule.MapEndpoints esistenti e il test harness in tests/CommunityPro.Tests/Members/MembersTestHarness.cs. Implementa i tre endpoint di sessione e il comportamento di prenotazione/e-mail descritti qui, con test che coprano entrambe le transizioni DST, le sovrapposizioni tra rapporti di mentoring, le prenotazioni concorrenti e il contenuto ICS verificato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Scope
Book sessions against mentor availability, with calendar-attachment emails.
Data model
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
- Slot falls entirely inside the mentor's availability (evaluated in mentor-local time — DST-correct via NodaTime).
- No overlap with any of the mentor's existing
Scheduledsessions (across all their mentorships). - Start ≥ 12h in the future.
- Duration ∈ {30, 60}; mentorship is
Active.
Emails
Booked/cancelled → both parties via Brevo, with an .ics attachment generated via 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/LondonorAmerica/New_Yorkbooks 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<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
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). - 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 (seeMembers/MembersTestHarness.cs).
- Lingua principale
- C#
- Stelle
- 0
- Fork
- 0
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CommunityPro/community-pro-api
-
cross-cutting decision
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
cross-cutting
Difficoltà 4/5 3-5 giorni Idoneità per principianti 58/100
-
admin
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
admin
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
-
sponsorship
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
Tutte le issue di CommunityPro/community-pro-api
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
activescott/lessmsi#306 ·
-
Python: Bug: split_plaintext_paragraph / split_markdown_paragraph can return a chunk larger than max_tokensForse già presa @xThreeh l’ha presa oggi. Apertapython triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
microsoft/semantic-kernel#14566 ·
I maintainer di solito rispondono entro 4 giorni
-
triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
rjmurillo/moq.analyzers#1384 ·
-
Variables passed to Compensated are not set on the routing slipForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
MassTransit/MassTransit#6249 ·
-
security
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
Sendspin/sendspin-dotnet#339 ·
I maintainer di solito rispondono entro 1 giorno