{"data":{"openapi":"3.1.0","info":{"title":"TamuHub Property Management System API","version":"1.0.0","description":"Backend modular monolith untuk HMS OpenCode. Auth: JWT session cookie (8 jam). Realtime: SSE pada /api/events."},"servers":[{"url":"/api"}],"security":[{"cookieAuth":[]}],"paths":{"/auth/login":{"post":{"operationId":"login","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginInput"}}}},"responses":{"200":{"description":"Logged in; sets pms_session cookie"},"401":{"description":"Invalid credentials"}}}},"/auth/logout":{"post":{"operationId":"logout","security":[],"responses":{"200":{"description":"Clears session cookie"}}}},"/auth/me":{"get":{"operationId":"me","responses":{"200":{"description":"Current session user"}}}},"/rooms":{"get":{"operationId":"listRooms","responses":{"200":{"description":"Room grid data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomsResponse"}}}}}}},"/rooms/{id}":{"patch":{"operationId":"updateRoomStatus","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"enum":["available","occupied","dirty","maintenance"]}},"required":["status"]}}}},"responses":{"200":{"description":"Room updated"},"404":{"description":"Not found"}}}},"/room-types":{"get":{"operationId":"listRoomTypes","responses":{"200":{"description":"Room types and rates"}}}},"/reservations":{"get":{"operationId":"listReservations","responses":{"200":{"description":"List reservations"}}},"post":{"operationId":"createReservation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationInput"}}}},"responses":{"201":{"description":"Reservation + invoice created"}}}},"/reservations/{id}/check-in":{"post":{"operationId":"checkIn","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checked in; room marked occupied"}}}},"/reservations/{id}/check-out":{"post":{"operationId":"checkOut","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checked out; room marked dirty"}}}},"/reservations/{id}/cancel":{"post":{"operationId":"cancelReservation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled"}}}},"/invoices":{"get":{"operationId":"listInvoices","responses":{"200":{"description":"List invoices"}}}},"/invoices/{id}/pdf":{"get":{"operationId":"getInvoicePdf","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Official HTML/PDF Printable Invoice"}}}},"/payments":{"post":{"operationId":"recordPayment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPaymentInput"}}}},"responses":{"201":{"description":"Payment recorded (idempotent by reference)"}}}},"/payments/webhook":{"post":{"operationId":"paymentWebhook","security":[],"description":"Payment gateway webhook handler (Xendit)","responses":{"200":{"description":"Webhook processed"},"401":{"description":"Invalid signature"}}}},"/settings":{"get":{"operationId":"getSettings","responses":{"200":{"description":"Property profile, team members, and audit logs"}}},"patch":{"operationId":"updateSettings","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Property updated"}}}},"/housekeeping/tasks":{"get":{"operationId":"listHousekeepingTasks","responses":{"200":{"description":"List housekeeping tasks"}}},"post":{"operationId":"createHousekeepingTask","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskInput"}}}},"responses":{"201":{"description":"Task created"}}}},"/housekeeping/tasks/{id}":{"patch":{"operationId":"updateHousekeepingTask","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"enum":["in_progress","completed"]}},"required":["status"]}}}},"responses":{"200":{"description":"Task updated; room set available when completed"}}}},"/maintenance":{"get":{"operationId":"listMaintenance","responses":{"200":{"description":"List maintenance reports"}}},"post":{"operationId":"createMaintenance","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMaintenanceInput"}}}},"responses":{"201":{"description":"Report created; room marked maintenance"}}}},"/maintenance/{id}":{"patch":{"operationId":"updateMaintenance","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"enum":["reported","scheduled","in_repair","resolved"]}},"required":["status"]}}}},"responses":{"200":{"description":"Report updated"}}}},"/reports/kpis":{"get":{"operationId":"getKpis","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Occupancy, ADR, RevPAR"}}}},"/audit-logs":{"get":{"operationId":"listAuditLogs","responses":{"200":{"description":"Audit trail"}}}},"/events":{"get":{"operationId":"streamEvents","description":"Server-Sent Events stream (room grid updates, housekeeping, billing).","responses":{"200":{"description":"text/event-stream"}}}},"/health":{"get":{"operationId":"health","security":[],"responses":{"200":{"description":"Service + DB health"},"503":{"description":"DB down"}}}}},"components":{"securitySchemes":{"cookieAuth":{"type":"apiKey","in":"cookie","name":"pms_session"}},"schemas":{"LoginInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":6}},"required":["email","password"]},"CreateReservationInput":{"type":"object","properties":{"guestName":{"type":"string"},"guestEmail":{"type":"string","format":"email"},"guestPhone":{"type":"string"},"roomTypeId":{"type":"string","format":"uuid"},"checkIn":{"type":"string","format":"date"},"checkOut":{"type":"string","format":"date"},"specialNotes":{"type":"string"}},"required":["guestName","roomTypeId","checkIn","checkOut"]},"RecordPaymentInput":{"type":"object","properties":{"reservationId":{"type":"string","format":"uuid"},"invoiceId":{"type":"string","format":"uuid"},"method":{"enum":["cash","bank_transfer","credit_card","qris"]},"amount":{"type":"number","exclusiveMinimum":0},"reference":{"type":"string"}},"required":["reservationId","method","amount"]},"CreateTaskInput":{"type":"object","properties":{"roomId":{"type":"string","format":"uuid"},"assigneeId":{"type":"string","format":"uuid"},"priority":{"enum":["low","normal","high"],"default":"normal"},"notes":{"type":"string"}},"required":["roomId"]},"CreateMaintenanceInput":{"type":"object","properties":{"roomId":{"type":"string","format":"uuid"},"issue":{"type":"string","minLength":3},"readyAt":{"type":"string","format":"date-time"}},"required":["roomId","issue"]},"RoomsResponse":{"type":"object","properties":{"rooms":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"roomNumber":{"type":"string"},"floor":{"type":"integer"},"status":{"enum":["available","occupied","dirty","maintenance"]},"type":{"type":"string"},"ratePerNight":{"type":"number"},"guestName":{"type":["string","null"]}}}}}}}}}}