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"; }