TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/pabloeferreyra/Turnero/llms.txt
Use this file to discover all available pages before exploring further.
TurnsController is the primary surface for managing clinic appointments in Turnero. It handles the full lifecycle of a turn (appointment): creating, listing, editing, marking as accessed, and deleting records. The controller is backed by a suite of injected services for data access and uses a SignalR hub (TurnsTableHub) to push real-time table updates to connected browsers. A companion TurnsPublicController exposes an unauthenticated booking page that lets walk-in patients register themselves for a same-day appointment without requiring a staff login.
Endpoint summary
| Method | Path | Roles | Description |
|---|---|---|---|
GET | /Turns/Index | Ingreso, Medico | Appointment list page |
POST | /Turns/InitializeTurns | Ingreso, Medico | DataTables server-side data feed |
GET | /Turns/Details/{id} | Ingreso, Medico | Turn detail view |
GET | /Turns/Create | Ingreso, Medico | Returns _Create partial view |
POST | /Turns/Create | Ingreso, Medico | Inserts a new turn |
GET | /Turns/Edit/{id} | Ingreso | Returns _Edit partial view |
PUT | /Turns/Edit | Ingreso | Updates an existing turn |
DELETE | /Turns/Delete/{id} | Admin, Ingreso | Deletes a turn |
POST | /Turns/Accessed/{id} | Medico | Marks turn as accessed by doctor |
POST | /Turns/CheckTurn | Admin, Ingreso | Checks slot availability |
POST | /Turns/ExportExcel | Ingreso, Medico | Downloads current view as .xlsx |
POST | /Turns/ExportPdf | None | Downloads current view as .pdf |
GET | /TurnsPublic/Index | Anonymous | Public walk-in booking page |
POST | /TurnsPublic/Create | Anonymous | Submits a public walk-in turn |
GET /Turns/Index
Renders the main appointment management view. When the authenticated user is a doctor (has a correspondingMedic record linked by ASP.NET Core Identity user ID), the controller sets ViewBag.MedicId to that doctor’s Guid so the front-end table filters automatically to their own appointments. A cached list of all medics is loaded into ViewBag.Medics as a SelectList for the filter dropdown.
Required roles: Ingreso, Medico
Response: HTML view Index
GET /Turns/Details/
Returns the full detail view for a single appointment. Required roles:Ingreso, Medico
The
Turn.Id to display.Details with the Turn model, or 404 Not Found when no turn with that ID exists.
POST /Turns/InitializeTurns
Server-side DataTables endpoint. The controller reads pagination, search, and sorting parameters from the POST form body and returns the matching page ofTurnDTO records as JSON. When the authenticated user has a linked Medic record, the medicId filter is locked to that doctor’s ID regardless of form input. Each returned TurnDTO has its IsMedic flag set based on whether the caller is a doctor.
Required roles: Ingreso, Medico
Request — application/x-www-form-urlencoded
DataTables draw counter; echoed back unchanged in the response so the client can match async responses.
Zero-based index of the first record to return. Used for offset-based pagination.
Number of records per page. Pass
-1 to return all records without pagination.Global search term. Currently used as a pass-through; column-level filters are the primary search mechanism.
Filters appointments by medic. Must be a valid
Guid corresponding to a Medic.Id. Ignored when the caller is themselves a doctor — the server substitutes the caller’s own medic ID.Filters by appointment date. Accepts any string parseable by
DateOnly.TryParse. Defaults to today when absent or unparseable.Zero-based index of the column to sort by.
Sort direction:
asc or desc.200 OK, application/json
GET /Turns/Create
Returns the_Create partial view. Medics and available time slots are loaded from the in-memory cache (IMemoryCache) and bound to ViewBag.Medics and ViewBag.Time as SelectList objects respectively.
Required roles: Ingreso, Medico
Response: Partial view _Create
POST /Turns/Create
Creates a new appointment. TheTurnDTO is mapped to a Turn entity via Mapster and persisted. On success, a SignalR UpdateTableDirected message is sent to the assigned doctor’s connection so their appointment table refreshes immediately.
Required roles: Ingreso, Medico
Request — application/x-www-form-urlencoded or application/json
Optional client-supplied ID; the database generates one automatically via
DatabaseGeneratedOption.Identity.Patient’s full name.
Patient’s national identity number.
The
Id of the Medic who owns this appointment.Appointment date in
dd-MM-yyyy or dd/MM/yyyy format. Defaults to today when absent.The
Id of the TimeTurn slot selected for this appointment.Patient’s health insurance / obra social name.
Reason for the appointment. Trailing quotation marks are automatically stripped.
| Status | Meaning |
|---|---|
200 OK | Turn created successfully. |
409 Conflict | An exception occurred during insertion (e.g. duplicate slot). |
UpdateTableDirected on the SignalR hub to the assigned doctor’s user connection, passing the doctor’s name, a “new turn” message, and the formatted appointment date.
GET /Turns/Edit/
Returns the_Edit partial view pre-populated with the existing TurnDTO for the given ID. Medics and time slots are injected into ViewBag.Medics and ViewBag.TimeEdit.
Required roles: Ingreso
The
Turn.Id to edit._Edit with the TurnDTO model, or null when the turn is not found.
PUT /Turns/Edit
Persists changes to an existing appointment. On success, a SignalRUpdateTableDirected message is broadcast to all users in the Ingreso role so every reception terminal refreshes its table.
Required roles: Ingreso
Request body — same fields as POST /Turns/Create, plus Id (required).
The
Turn.Id to update. Used to verify existence before saving.| Status | Meaning |
|---|---|
200 OK | Turn updated successfully. |
404 Not Found | No turn with the given Id exists. |
409 Conflict | ModelState was invalid. |
UpdateTableDirected to every user in the Ingreso role.
DELETE /Turns/Delete/
Deletes the specified appointment and notifies all connected clients. Required roles:Admin, Ingreso
The
Turn.Id to delete.200 OK
Side effects: Broadcasts UpdateTable to all SignalR hub connections (including Medico and Ingreso views).
POST /Turns/Accessed/
Called by the doctor’s interface when a patient enters the consultation room. SetsTurn.Accessed = true on the matching record. After updating, the server enumerates all Ingreso users and sends a UpdateTableDirected message to each so the front desk UI reflects the change in real time.
Required roles: Medico
The
Turn.Id to mark as accessed.| Status | Meaning |
|---|---|
200 OK | Marked as accessed. |
| NotFound view | The id was null, or the turn does not exist, or it fails the existence check. |
UpdateTableDirected to each user in the Ingreso role individually.
POST /Turns/CheckTurn
Returns a boolean indicating whether a particular time slot is already taken for a given doctor and date. This is called client-side before confirming turn creation to prevent double-booking. Required roles:Admin, Ingreso
Request — application/x-www-form-urlencoded
The medic to check availability for.
The requested appointment date/time.
The
TimeTurn.Id of the requested slot.200 OK with true (slot is taken) or false (slot is available) as the response body.
POST /Turns/ExportExcel
Generates an Excel workbook from the current filtered view (same filters asInitializeTurns) and returns it as a file download. Records are sorted ascending by appointment time before writing.
Required roles: Ingreso, Medico
Request: Same form parameters as POST /Turns/InitializeTurns (date, medicId, pagination).
Response: 200 OK
- Content-Type:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - Filename:
turnos.xlsx - Columns: Nombre, DNI, Obra Social, Motivo, Médico, Fecha, Hora
POST /Turns/ExportPdf
Generates a PDF document from the current filtered view and returns it as a file download. Records are sorted ascending by appointment time. The PDF is built with QuestPDF and contains a header and a five-column table. Required roles: None (no[Authorize] attribute is applied to this action).
Request: Same form parameters as POST /Turns/InitializeTurns.
Response: 200 OK
- Content-Type:
application/pdf - Filename:
turnos.pdf - Columns: Nombre, DNI, Obra, Médico, Hora
GET /TurnsPublic/Index
Renders the public walk-in booking page. No authentication is required. The page displays a form backed by the same medics and time-slot data served to the authenticated create view, loaded from the in-memory cache. Authentication: Anonymous ([AllowAnonymous])
Response: HTML view Index
POST /TurnsPublic/Create
Accepts a walk-in booking submitted from the public page. The server overrides several fields to prevent manipulation: the date is always set to today, the reason is fixed to"Turno espontáneo", and the TimeId is hard-coded to 78496444-276d-4389-8b2f-f668c5350e3f (the walk-in slot). On success, a SignalR UpdateTableDirected message is sent to the assigned doctor.
Authentication: Anonymous ([AllowAnonymous])
Request — application/x-www-form-urlencoded
Patient’s full name.
Patient’s national identity number.
The doctor the patient wishes to see.
Patient’s health insurance name.
| Field | Fixed value |
|---|---|
Date | DateTime.Today formatted as dd/MM/yyyy |
TimeId | 78496444-276d-4389-8b2f-f668c5350e3f |
Reason | "Turno espontáneo" |
| Status | Meaning |
|---|---|
200 OK | Walk-in turn created. |
400 Bad Request | ModelState is invalid. |
409 Conflict | An exception occurred during insertion. |
UpdateTableDirected on the SignalR hub to the assigned doctor’s user connection.