{"ok":true,"uptimeSeconds":2764,"node":"v22.23.3","env":"production","database":{"ok":true,"message":"twinslab-dev-db-d7mcvn:3306/twinslab"},"endpoints":[{"method":"GET","path":"/api/health","note":"liveness JSON"},{"method":"GET","path":"/api/status","note":"this page as JSON"},{"method":"GET","path":"/api/me","note":"current user (needs session)"},{"method":"GET","path":"/api/drafts","note":"approval queue, scoped by role"},{"method":"POST","path":"/api/drafts/:id/approve","note":"approve a ready draft and queue the send"},{"method":"POST","path":"/api/drafts/:id/send-edited","note":"send edited draft text"},{"method":"POST","path":"/api/drafts/:id/reject","note":"reject a draft with a reason"},{"method":"POST","path":"/api/drafts/:id/retry","note":"re-queue draft generation after a timeout"},{"method":"POST","path":"/api/drafts/:id/cancel-auto","note":"cancel a pending auto-send"},{"method":"POST","path":"/api/auth/sign-up/email","note":"better-auth"},{"method":"POST","path":"/api/auth/sign-in/email","note":"better-auth"},{"method":"GET","path":"/api/auth/get-session","note":"better-auth"},{"method":"POST","path":"/webhooks/minicrew/{message,message-status,channel-status,group-membership}","note":"minicrew webhooks (signed)"},{"method":"GET","path":"/api/conversations","note":"conversations (scoped)"},{"method":"GET","path":"/api/conversations/:id","note":"conversation"},{"method":"GET","path":"/api/conversations/:id/messages","note":"thread"},{"method":"POST","path":"/api/conversations/:id/{messages,notes,assign}","note":"reply, note, assign"},{"method":"POST","path":"/api/conversations/:id/messages/:mid/{arrived,resend}","note":"delivery follow-up"},{"method":"GET","path":"/api/integration/connection","note":"minicrew connection state"},{"method":"GET","path":"/api/integration/health","note":"integration health (admin)"},{"method":"POST","path":"/api/integration/sync","note":"recover missed messages (admin)"},{"method":"POST","path":"/api/integration/test-webhook","note":"ask minicrew to send a signed test ping webhook (admin)"},{"method":"GET","path":"/api/settings","note":"settings"},{"method":"PATCH","path":"/api/settings","note":"update settings (admin)"},{"method":"GET","path":"/api/settings/groups","note":"groups & routing"},{"method":"POST","path":"/api/settings/groups","note":"save group rule (admin)"},{"method":"PATCH","path":"/api/settings/channels/:uuid","note":"WhatsApp number label (admin)"},{"method":"POST","path":"/api/settings/connections/minicrew/test","note":"minicrew connection test (admin)"},{"method":"GET","path":"/api/settings/connections","note":"SQL Accounting, 聚力 and minicrew connection details, secrets masked (admin)"},{"method":"PUT","path":"/api/settings/connections/{sql,juli,minicrew}","note":"save connection details (admin)"},{"method":"POST","path":"/api/settings/connections/{sql,juli}/test","note":"SQL Accounting / 聚力 connection test (admin)"},{"method":"GET","path":"/api/settings/auto-send/readiness","note":"auto-send shadow report; ?days(1-90, default 30) (admin)"},{"method":"GET","path":"/api/orders/source","note":"聚力 orders with validation result; ?page&pageSize(≤200)&status=Held,Failed&q → {items,total,page,pageSize,counts}"},{"method":"GET","path":"/api/orders/sql","note":"SQL Accounting Sales Orders (read-only)"},{"method":"GET","path":"/api/orders/runs","note":"integration log"},{"method":"GET","path":"/api/orders/status","note":"last / next poll, write-back, connections"},{"method":"GET","path":"/api/orders/mappings","note":"聚力 → SQL Accounting code mapping; ?page&pageSize(≤200)&type&q&unmapped=true → {items,total,page,pageSize}"},{"method":"GET","path":"/api/orders/sql-master","note":"SQL Accounting customers / items for mapping"},{"method":"POST","path":"/api/orders/mappings","note":"save mapping, re-validate held orders (admin)"},{"method":"POST","path":"/api/orders/source/:juliRef/{retry,skip}","note":"create SO / skip with reason (admin)"},{"method":"POST","path":"/api/orders/run","note":"poll 聚力 now (admin)"},{"method":"POST","path":"/api/orders/sync","note":"queue a past-orders sync for a MYT date range, max 31 days (admin)"},{"method":"GET","path":"/api/faq/proposals","note":"FAQ proposals to review (supervisor+)"},{"method":"PATCH","path":"/api/faq/proposals/:id","note":"edit a pending FAQ proposal"},{"method":"POST","path":"/api/faq/proposals/:id/approve","note":"insert or update the FAQ in minicrew"},{"method":"POST","path":"/api/faq/proposals/:id/discard","note":"discard a proposal"},{"method":"GET","path":"/api/faq","note":"FAQ library, read from minicrew"},{"method":"GET","path":"/api/faq/log","note":"FAQ learning log (supervisor+)"},{"method":"POST","path":"/api/conversations/:id/summary","note":"advisory AI summary (not stored, not posted)"},{"method":"GET","path":"/api/handoffs","note":"hand-offs in scope"},{"method":"GET","path":"/api/handoffs/routes","note":"routes available for a conversation"},{"method":"GET","path":"/api/handoffs/owners","note":"active users for owner pickers"},{"method":"POST","path":"/api/handoffs","note":"request a hand-off (summarises synchronously)"},{"method":"GET","path":"/api/handoffs/:id","note":"one hand-off"},{"method":"PATCH","path":"/api/handoffs/:id","note":"edit a waiting hand-off summary"},{"method":"PATCH","path":"/api/handoffs/:id/open-points/:index","note":"set an open point owner"},{"method":"POST","path":"/api/handoffs/:id/post","note":"post into the receiving group"},{"method":"POST","path":"/api/handoffs/:id/repost","note":"post again after a failed delivery"},{"method":"GET","path":"/api/settings/handoff-routes","note":"hand-off routes (admin)"},{"method":"POST","path":"/api/settings/handoff-routes","note":"create or update a route (admin)"},{"method":"DELETE","path":"/api/settings/handoff-routes/:id","note":"deactivate a route (admin)"}]}