namespace CareFix.Api.Options;
public sealed class CareFixOptions
{
public string ControlDb { get; set; } = "";
public string MasterKey { get; set; } = "";
public JwtOptions Jwt { get; set; } = new();
public ClaudeOptions Claude { get; set; } = new();
public SafetyOptions Safety { get; set; } = new();
public int AiWorkers { get; set; } = 4;
public BootstrapAdminOptions? BootstrapAdmin { get; set; }
public IntegrationOptions Integration { get; set; } = new();
public RetentionOptions Retention { get; set; } = new();
public MaintenanceOptions Maintenance { get; set; } = new();
}
/// How long CareFix keeps each kind of record. Must match the hospital addendum. 0 = keep forever.
public sealed class RetentionOptions
{
/// Masked query results are cleared after this many days; the query text and counts stay.
public int QueryResultDays { get; set; } = 90;
/// Query log rows are deleted after this many days.
public int QueryLogDays { get; set; } = 365;
/// AI transcripts of closed tickets are deleted after this many days.
public int TranscriptDays { get; set; } = 180;
/// Pre-change row snapshots (used for rollback) are deleted after this many days.
public int SnapshotDays { get; set; } = 180;
/// Uploaded ticket history used for learning is deleted after this many days.
public int LearningDays { get; set; } = 180;
}
public sealed class MaintenanceOptions
{
/// UTC hour for the nightly run. 19 is about 00:30 IST.
public int HourUtc { get; set; } = 19;
/// Recapture a hospital's schema snapshot when it is older than this. 0 = never.
public int SchemaRecaptureDays { get; set; } = 30;
}
public sealed class IntegrationOptions
{
/// Key the helpdesk sends in X-CareFix-Integration-Key to create tickets. Empty = inbound API off.
public string InboundKey { get; set; } = "";
/// URL CareFix posts ticket status changes to. Empty = outbound updates off.
public string WebhookUrl { get; set; } = "";
/// Shared secret used to sign outbound payloads (X-CareFix-Signature: sha256=HEX).
public string WebhookSecret { get; set; } = "";
}
public sealed class JwtOptions
{
public string Issuer { get; set; } = "CareFix";
public string Audience { get; set; } = "CareFix";
public string SigningKey { get; set; } = "";
public int HoursValid { get; set; } = 8;
}
public sealed class ClaudeOptions
{
public string ApiKey { get; set; } = "";
public string Model { get; set; } = "claude-sonnet-5";
public string BaseUrl { get; set; } = "https://api.anthropic.com";
public int MaxTokens { get; set; } = 4096;
public int MaxToolCallsPerRun { get; set; } = 15;
/// Stop starting new AI work once this much has been spent in the calendar month. 0 = no cap.
public decimal MonthlyBudgetUsd { get; set; } = 300m;
/// Stop the AI on one ticket once it has cost this much. 0 = no cap.
public decimal MaxUsdPerTicket { get; set; } = 1.50m;
public PricingOptions Pricing { get; set; } = new();
}
/// US dollars per million tokens. Check against claude.com/pricing when the model changes.
public sealed class PricingOptions
{
public decimal InputPerMTok { get; set; } = 2m;
public decimal OutputPerMTok { get; set; } = 10m;
public decimal CacheWritePerMTok { get; set; } = 2.50m;
public decimal CacheReadPerMTok { get; set; } = 0.20m;
}
public sealed class SafetyOptions
{
public int MaxRowsPerSelect { get; set; } = 200;
public int SelectTimeoutSeconds { get; set; } = 30;
public int LockTimeoutMs { get; set; } = 5000;
public int MaxStepsPerFix { get; set; } = 50;
public int HighRiskStepThreshold { get; set; } = 10;
public int MaxConsentFileBytes { get; set; } = 5 * 1024 * 1024;
}
public sealed class BootstrapAdminOptions
{
public string Username { get; set; } = "";
public string Password { get; set; } = "";
public string FullName { get; set; } = "CareFix Admin";
}