{"service":"ZricksLeadApi","status":"ok","note":"Real EF Core against ConnectionStrings:ZricksCrm (see appsettings.json / user-secrets). No demo/in-memory mode in this version — set a real connection string to run this. AI features additionally need AiProvider:ApiKey (user-secrets, never appsettings.json). Added 2026-09-03 (fourteenth pass): every /api/* endpoint below now requires 'Authorization: Bearer <token>' EXCEPT POST /api/auth/login and GET /api/auth/captcha — see authEndpoints. A request with no/invalid/expired token gets a 401 with a JSON body, not a redirect; the HTML pages themselves redirect to /login.html client-side (see wwwroot/auth.js).","ui":"GET /ai-report.html — pick a lead or RM, ask AI for a report","chatUi":"GET /ask-chat.html — full-page ChatGPT-style chat; same saved conversations as the 'Or just ask' box on /ai-report.html","skillsAdminUi":"GET /skills-manage.html — added 2026-09-02 (twelfth pass): edit each skill's display name/description/extra instructions, enable or disable it, and test-run it, without a redeploy","loginUi":"GET /login.html — added 2026-09-03 (fourteenth pass): Bootstrap login page (captcha + your real CRM user ID/password) — start here if you don't already have a token","dashboardUi":"GET /dashboard.html — added 2026-09-03 (fourteenth pass): post-login landing page linking to the three UIs above","authEndpoints":["GET  /api/auth/captcha — [AllowAnonymous] a fresh { captchaToken, svg } challenge","POST /api/auth/login — [AllowAnonymous] body: { loginId, password, captchaToken, captchaAnswer } -> { token, userId, fullName, expiresAt } (loginId matches your CRM's Email OR Mobile column, same as the real query this checks — see Auth/CrmLoginValidator.cs)","GET  /api/auth/me — requires a bearer token; returns { userId, fullName } for whichever token you sent"],"leadEndpoints":["GET  /api/leads/{contactId}","POST /api/leads/summary","POST /api/leads/count","POST /api/leads/followup-breakdown","GET  /api/leads/rm-daily-report/{rmUserId}?date=yyyy-MM-dd","GET  /api/leads/rm-monthly-report/{rmUserId}?year=&month=","GET  /api/leads/group-daily-report/{groupId}?date=yyyy-MM-dd","GET  /api/leads/group-monthly-report/{groupId}?year=&month=","GET  /api/rms?groupId=","GET  /api/rms/search?name="],"lookupEndpoints":["GET  /api/lookups","GET  /api/lookups/{headerCode}"],"aiEndpoints":["GET  /api/skills — public catalog of registered AI skills (disabled ones excluded — see skillsAdminEndpoints for the admin-facing list)","POST /api/skills/{code}/run — generic skill runner (lead-quality-scoring, ai-report, ask-crm, ask-crm-agent)","GET  /api/ai-report/lead/{contactId}","GET  /api/ai-report/rm/{rmUserId}?period=daily|monthly&date=","GET  /api/ai-report/team/{groupId}?period=daily|monthly&date=","POST /api/ask — free-text question, body: { question, scope, leadId, rmUserId, groupId, period, date, conversationId, history: [{question, answer}] }; deterministic — this app classifies once and phrases the answer itself, a number can never be misstated by the AI","POST /api/ask-agent — same body as /api/ask, answered instead by giving the model a query_crm tool and letting it decide when/how many times to call it before writing its own final sentence (see AskCrmAgentSkill's header comment for the accuracy trade-off vs /api/ask)","POST /api/ask-agent/stream — added 2026-09-02 (twelfth pass): same body as /api/ask-agent, streamed back as Server-Sent Events instead of one buffered response — see AskAgentController.AskAgentStream"],"skillsAdminEndpoints":["GET    /api/skills-admin — every registered skill, disabled ones included, merged with its DB overlay (see Persistence/SkillDefinition.cs)","GET    /api/skills-admin/{code} — one skill's admin row","PUT    /api/skills-admin/{code} — save { displayName, description, extraInstructions, isEnabled, updatedBy } as that skill's overlay","DELETE /api/skills-admin/{code} — reset to code defaults (deletes the overlay row)"]}