Adds UserKeyClient, which fetches (and caches) an account's LiteLLM virtual
key from the users service's internal endpoint. AiProvider gains
complete_as_user(), and LiteLLMProvider resolves the caller's key when
available, falling back to the master key otherwise so existing behavior
is unchanged where no per-account key is wired up yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Remove build-and-deploy-forgejo.yml from GitHub Actions
- Forgejo CI at ci.nxtgauge.com now handles all builds and deployments
- All images pushed to Forgejo registry (ci.nxtgauge.com/ashwin/*)
- Update workflow to push to ci.nxtgauge.com/ashwin/nxtgauge-ai-assistant
- Use FORGEJO_USERNAME and FORGEJO_TOKEN secrets
- Fix gitops repo cloning to use x-access-token
jsonwebtoken v10's default features are just use_pem - neither of its
crypto backend features (rust_crypto/aws_lc_rs) is enabled by default,
so decode::<Claims>() panicked on every real bearer token (not caught
by earlier testing, which only exercised the no-token 401 path).
backend-rust's own crates already enable rust_crypto for the same
crate; matches that here.
Wires up 8 previously missing/stub Ask Ash capabilities: resume
improvement, job post improvement, professional/jobseeker/company
profile improvement, service description generation, KB
article/notification writing, admin support ticket summarization, and
lead/credit guidance. Also upgrades explain_plan_limits and
check_ai_pack_balance from static canned strings to real generated
answers.
Adds AiProvider::complete_as(model, ...) so callers can target
specific LiteLLM model aliases (jd-generator, profile-writer,
service-writer, support-drafter, decision-support, askash-main/fast)
that were already defined in apps/litellm/base/configmap.yaml but
never actually used by ai-assistant, since it wasn't even configured
to use the litellm provider (defaulted to plain Ollama with the tiny
gemma3:270m model for every task, with no LLM_PROVIDER/LITELLM_* env
vars set in the deployment).
New content_tools module holds the shared generation logic; new
routes registered for each feature; KB content generation and support
ticket summarization are gated to ADMIN/EMPLOYEE roles via JWT claims.
Registry gains 4 new ActionDefinitions (improve_job_post,
generate_kb_content, lead_credit_guidance, ai_auto_apply_status) to
match the existing registry pattern.
require_auth and NxtgaugeTicketProvider::create_ticket both called
env::var(...).expect(...) on every request, crashing instead of
returning a proper error when JWT_SECRET/AI_SERVICE_KEY were unset.
Both are now loaded once into AppConfig at startup and checked with
a graceful 401/500 response.
- Add src/auth.rs with require_auth middleware extracting user_id from Bearer token
- Wire auth middleware onto all /api/* routes
- Replace CorsLayer::permissive() with env-driven FRONTEND_URL/ADMIN_URL origins
- Pass real auth_user.user_id to confirm_action instead of conversation_id
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>