{"openapi":"3.0.3","info":{"title":"Hamshift API","version":"1.0.0","description":"Hospital ward shift scheduling API. This initial specification documents health, setup status, and password-session authentication. Scheduling, staff management, requests, and administration endpoints are not yet described here. Protected operations require an authorized account; automated clients have the same role and ward restrictions as the web app."},"servers":[{"url":"https://hmshift.ir"}],"externalDocs":{"description":"API documentation","url":"https://hmshift.ir/api/docs"},"security":[{"sessionCookie":[]}],"paths":{"/api/health":{"get":{"operationId":"getHealth","summary":"Check application and database health","security":[],"responses":{"200":{"description":"Application and database are available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"example":{"ok":true,"db":"up"}}}},"503":{"description":"Database is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"example":{"ok":false,"db":"down"}}}}}}},"/api/setup":{"get":{"operationId":"getSetupStatus","summary":"Check whether first-run setup is needed","security":[],"responses":{"200":{"description":"First-run setup status","content":{"application/json":{"schema":{"type":"object","required":["needsSetup"],"properties":{"needsSetup":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/auth/login":{"post":{"operationId":"login","summary":"Sign in with an existing account","description":"Creates a session and sets the HttpOnly nobat_sid cookie. Failed sign-in attempts are rate limited. Accounts are provisioned by a manager, invitation, or first-run setup.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Signed in; retain the session cookie for subsequent requests","headers":{"Set-Cookie":{"description":"HttpOnly session cookie","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/auth/logout":{"post":{"operationId":"logout","summary":"End the current session","description":"Send Content-Type: application/json (an empty JSON object is sufficient). Clears the session cookie; also succeeds if already signed out.","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object"},"example":{}}}},"responses":{"200":{"description":"Signed out","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"}}}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/me":{"get":{"operationId":"getCurrentUser","summary":"Read the current user's profile and today's date","responses":{"200":{"description":"Current user and ISO Gregorian date in the server's configured timezone","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/UserResponse"},{"type":"object","required":["today"],"properties":{"today":{"type":"string","format":"date"}}}]}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"default":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"sessionCookie":{"type":"apiKey","in":"cookie","name":"nobat_sid"}},"schemas":{"Health":{"type":"object","required":["ok","db"],"properties":{"ok":{"type":"boolean"},"db":{"type":"string","enum":["up","down"]}}},"UserResponse":{"type":"object","required":["user"],"properties":{"user":{"type":"object","required":["id","name","username","role"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"username":{"type":"string"},"role":{"type":"string","enum":["manager","employee"]},"mustChangePassword":{"type":"boolean"}},"additionalProperties":true}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"code":{"type":"string"}},"additionalProperties":true}},"responses":{"Error":{"description":"Request failed; error contains a human-readable message, usually in Persian, and code may contain a machine-readable reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}