Commit Graph
8 Commits
Author SHA1 Message Date
westfarn acb3a51618 Add Google/Microsoft SSO OAuth for register and sign-in (#24) (#29)
Unit Tests / test (push) Successful in 10s
## Summary
- Closes #24 (backend half)
- Add `OAuthIdentity` model (provider + `sub`, access/refresh tokens) for SSO now and Drive reuse later (#11)
- Endpoints: `GET /api/auth/oauth/<google|microsoft>/start/` and `/callback/`
- Create or link `CustomUser` by verified email; issue same JWT access/refresh; redirect FE to `/auth/callback/`
- Document `GOOGLE_OAUTH_*` / `MICROSOFT_OAUTH_*` / `OAUTH_CALLBACK_BASE_URL` in `.env.example` and `.env.prod.example`
- Expose configured providers on `GET /api/public/settings/` as `oauth.google` / `oauth.microsoft`

## Pair with
- Frontend PR: `chat_web_app` branch `feature/sso-oauth-24`

## Test plan
- [ ] `python manage.py test chat_backend.tests.test_oauth`
- [ ] With local Google/Microsoft client IDs set, complete start → IdP → callback → JWT redirect
- [ ] Existing password user with same email links identity (no duplicate)
- [ ] Unverified / missing email redirects with error code
- [ ] Registration disabled: signup start 403; login without account → `account_not_found`
- [ ] Secrets not committed; env examples onlyReviewed-on: #29
2026-07-27 05:13:32 -07:00
westfarn 16442b336c Fix password reset flow (#1) (#27)
Unit Tests / test (push) Successful in 9s
## Summary
- Closes #1
- Replace broken `csrf_exempt` `reset_password` FBV (responses never returned; missing `requests` import) with working DRF `ResetUserPassword`
- Deduplicate reset email helper; build set-password links from `FRONTEND_BASE_URL`
- Harden `SetUserPassword`: require unusable password, min 8 chars, handle missing slug
- Accept reCAPTCHA v2 (success only) and v3 (score ≥ 0.5); avoid email enumeration (200 after valid captcha)
- Add unit tests for reset + set-password edge cases

## Test plan
- [ ] `manage.py test chat_backend.tests.test_views_users.ResetPasswordTestCase chat_backend.tests.test_views_users.SetPasswordTestCase`
- [ ] With SMTP configured: request reset for known email → receive link → set password → sign in
- [ ] Unknown email still returns 200 and sends no mail
- [ ] Failed captcha returns 400
- [ ] Pair with chat_web_app `feature/password-reset-1` PRReviewed-on: #27
2026-07-27 05:07:42 -07:00
westfarn a049e4f685 Track token in/out per prompt on PromptMetric (#18)
Unit Tests / test (push) Successful in 9s
Closes #15

## Summary
- Add nullable `tokens_in` / `tokens_out` `IntegerField`s to `PromptMetric` to record real prompt/completion token counts per turn.
- New `extract_token_usage()` helper parses provider usage payloads (LangChain `usage_metadata`, OpenAI-style `prompt_tokens`/`completion_tokens`, Ollama `prompt_eval_count`/`eval_count`). When a provider reports no usage, the fields stay **null** — counts are never estimated/fabricated.
- `create_prompt_metric` / `finish_prompt_metric` in both `consumers.py` and `consumers_graph.py` accept and persist optional `tokens_in` / `tokens_out` (added to `update_fields` only when present).
- Admin panel (this ticket's deliverable):
  - `PromptMetricAdmin` lists `tokens_in` / `tokens_out` and adds `event` / `model_name` / `has_file` filters.
  - `ConversationAdmin` shows summed `tokens_in` / `tokens_out` / `tokens_total` per conversation.
- Migration `0023_promptmetric_tokens_in_promptmetric_tokens_out` (existing rows remain valid — null).

## Note on live capture
The streaming chat path uses LangChain `StrOutputParser`, which yields plain string chunks with no usage metadata, so live turns currently persist `null` tokens (honest, per acceptance criteria — no fabricated counts). The plumbing + helper are in place so wiring real provider usage is a drop-in once the services expose it.

## Follow-ups
- #16 — Show token in/out in chat web app UI (FE + API exposure)
- #17 — Token-based billing, quotas, and enforcement

## Test plan
- [x] `uv run python manage.py test` — full suite green (266 tests, 6 skipped)
- [x] Model: token fields default null + persist when set
- [x] `extract_token_usage`: LangChain / OpenAI / Ollama key variants, attribute sources, bool/float handling, missing usage → (None, None)
- [x] Metric lifecycle: tokens persist when provided, stay null when absent (both consumers)
- [x] Admin: conversation token totals sum across metrics and ignore other conversationsReviewed-on: #18
2026-07-26 08:22:34 -07:00
westfarn d1660792ad Dockerize chat_backend + Ollama LAN + DB file storage (#6) (#7)
Unit Tests / test (push) Successful in 13s
## Summary

Implements [chat_backend#6](#6) Part A:

- **uv** packaging (`pyproject.toml` + `uv.lock`), Docker/compose (dev + prod), entrypoint/validate-env, Gitea unit-test + auto-deploy workflows (mirror `scha`)
- Env-driven Django settings (`DJANGO_*`, `DATABASE_URL`, CSRF/CORS)
- **`OLLAMA_BASE_URL`** wired through all Ollama/LangChain clients (prod → `http://10.0.0.128:11434`)
- **DatabaseStorage** — prompt/document file blobs in Postgres (`StoredFile`), not container FS; RAG materializes temp paths for loaders
- ASGI via `gunicorn` + `UvicornWorker` (HTTP + WebSockets)

Companion server-infra PR registers `app_catalog` / `host_apps` (port **8003**).

## Test plan

- [ ] `uv sync && cd llm_be && SKIP_RAG_INIT=1 uv run python manage.py test`
- [ ] `docker compose build && docker compose up` against bundled Postgres
- [ ] Confirm Ollama calls use `OLLAMA_BASE_URL` (not hardcoded localhost)
- [ ] Upload a document / prompt file → row in `chat_backend_storedfile`, no disk under `media/`
- [ ] After server-infra merge + secret/Postgres/NPM: deploy via `deploy.sh --app chat_backend --env prod`Reviewed-on: #7
2026-07-25 05:23:33 -07:00
westfarn 8a259158c8 Updated data analysis to generate images to perform data analysis 2025-09-24 11:49:08 -05:00
westfarn a85f1222eb Syncing with updates from prod and formatted 2025-05-18 06:15:07 -05:00
westfarn f5d29166a6 RAG implementation, content moderation, prompt classification, new LLM chain, document storage 2025-05-14 03:27:38 -05:00
westfarn 57695353d0 temp checkin 2025-03-07 12:23:00 -06:00