Skip to main content

Documentation 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.

Turnero persists all clinic data — appointments, patients, doctors, visit histories, and identity records — in a PostgreSQL database. The data-access layer lives in the Turnero.DAL project and uses Npgsql as the ADO.NET driver together with Entity Framework Core for schema management and query generation. The single connection string key LocalConnection is the only value you must supply before the application can start.

Connection String

Turnero reads the connection string at startup with:
AppSettings.ConnectionString = builder.Configuration.GetConnectionString("LocalConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseNpgsql(AppSettings.ConnectionString));
The resolved value is also stored in the static AppSettings.ConnectionString property so it can be accessed by internal infrastructure code without requiring dependency injection. The expected Npgsql connection string format is:
Host=<host>;Port=<port>;Database=<dbname>;Username=<user>;Password=<password>
Storing credentials in appsettings.json risks accidentally committing them to source control. Use the .NET user-secrets store instead:
dotnet user-secrets set "ConnectionStrings:LocalConnection" \
  "Host=localhost;Port=5432;Database=turnero;Username=postgres;Password=yourpassword" \
  --project Turnero
Run the command from the repository root so the --project flag correctly resolves to the Turnero host project that contains Program.cs.

Production: appsettings.json

For server deployments, add the key directly to appsettings.json on the host. Keep the original file as a backup before editing:
cp appsettings.json appsettings.json.bak
Then add or update the connection string section:
{
  "ConnectionStrings": {
    "LocalConnection": "Host=db.example.com;Port=5432;Database=turnero;Username=app;Password=strongpassword"
  }
}
Do not commit production credentials to your repository. Use environment variables or a secrets manager (e.g. Azure Key Vault, AWS Secrets Manager) for hosted environments.

ApplicationDbContext

ApplicationDbContext in Turnero.DAL inherits from IdentityDbContext, which automatically adds all ASP.NET Identity tables alongside the Turnero-specific entity sets:
DbSetTable purpose
TurnsScheduled appointments
MedicsDoctor records
TimeTurnsAvailable appointment time slots
PatientsPatient demographic records
ContactInfoPatient contact details
AllergiesPatient allergy entries
VisitsClinical visit history
ParentsDataParent / guardian information
PersonalBackgroundPersonal medical history
PerinatalBackgroundPerinatal history
VaccinesVaccination records
PermMedsPermanent medication records
GrowthChartsAnthropometric growth data
CongErrorsCongenital anomaly records
Column-type overrides and default-value constraints are applied in OnModelCreating. The full set of rules is:
EntityProperty typeOverride
TurnDateTurnSQL date column type
PatientBirthDateSQL date column type
VisitVisitDateSQL date column type
AllergiesAll DateTime? propertiesSQL date column type, default null
VisitAll string propertiesDefault "" (empty string)
PersonalBackgroundAll bool propertiesDefault false
ParentsDataAll string propertiesDefault "" (empty string)
ParentsDataAll DateOnly propertiesSQL date column type, default DateOnly.MinValue
ParentsDataAll int propertiesDefault 0
CongErrorsAll string propertiesDefault "" (empty string)
PerinatalBackgroundAll int propertiesDefault 0
These rules prevent null surprises and ensure consistent defaults when records are inserted without all optional fields populated.

Applying Migrations

1

Ensure the EF Core tools are installed

dotnet tool restore
# or install globally
dotnet tool install --global dotnet-ef
2

Apply all pending migrations to the target database

dotnet ef database update \
  --project Turnero.DAL \
  --startup-project Turnero
This command runs every migration that has not yet been applied, creating tables and applying any schema changes in order.
3

Verify the schema

Connect to the database with psql or a GUI tool (e.g. pgAdmin, DBeaver) and confirm that the Turns, Patients, and AspNetUsers tables exist.

Adding New Migrations

When you modify a model class in Turnero.DAL, generate a new migration to capture the schema change:
dotnet ef migrations add <MigrationName> \
  --project Turnero.DAL \
  --startup-project Turnero
Replace <MigrationName> with a descriptive Pascal-case name such as AddPatientBirthDateIndex. After reviewing the generated files in Turnero.DAL/Migrations/, apply them with database update as shown above.
Always review the generated migration file before applying it in production. EF Core cannot always infer whether a column rename should be modelled as a drop-and-add or a true rename, which can result in data loss if not corrected manually.

Startup Cache Initialization

After the application is built and before it begins serving requests, Turnero pre-warms the IMemoryCache with the two most-frequently-read lookup tables:
using (var scope = app.Services.CreateScope())
{
    var timeTurnsRepository = scope.ServiceProvider.GetRequiredService<ITimeTurnRepository>();
    var medicsRepository    = scope.ServiceProvider.GetRequiredService<IMedicRepository>();

    await timeTurnsRepository.GetCachedTimes();
    await medicsRepository.GetCachedMedics();
}
The cache is configured with a seven-day expiration scan frequency:
builder.Services.AddMemoryCache(options =>
{
    options.ExpirationScanFrequency = TimeSpan.FromDays(7);
});
This means appointment scheduling pages load immediately without hitting the database for every time-slot or doctor lookup. If you add new TimeTurn or Medic records at runtime, restart the application (or implement a cache-invalidation call in the relevant write service) to ensure the new entries appear.

Build docs developers (and LLMs) love