## Summary
- Image attachments (PNG, JPEG, WebP, GIF) skip the document parser and go to a vision-capable Ollama model (`OLLAMA_MODEL_VISION`, default `gemma4:latest`).
- The image is stored on the prompt. `PromptSerializer` returns `file_type` and base64 `image` so history can redraw it.
- Unsupported image types and files over 8 MB return a websocket error and are not saved.
- A later text turn does not reuse a previous image as a spreadsheet.
Pairs with `chat_web_app` `feat/128-vision-image-prompt` ([#128](ai_ml_operations/chat_web_app#128)).
## Test plan
- [ ] `manage.py test chat_backend.tests.test_vision chat_backend.tests.test_consumers.GraphNodeTestCase`
- [ ] Send a prompt plus PNG over `ws/chat_again/` and confirm the vision model is called.
- [ ] `GET conversation_details` includes `image` and `file_type` for that turn.
- [ ] CSV upload still follows the document path.
Reviewed-on: #82
## Summary
- Closes#80.
- Password self-registration is on by default (`ENABLE_ACCOUNT_REGISTRATION`). `/user/create/` issues tokens and `needs_checkout`, and the web sign-up page already redirects into Stripe Checkout.
- Browser SSO stays off (`ENABLE_SSO`, default false). Live Google and Microsoft client ids stay available for Drive linking, but public settings no longer advertise them, and login/signup OAuth start and callback are rejected.
Stripe path checked before this change: Checkout builds a subscription session (Founders at $10/month, or `STRIPE_PRICE_ID`), stores a draft invoice, and signed `checkout.session.completed` / `invoice.paid` webhooks grant the plan. Checkout, webhook, portal, registration, and OAuth tests passed.
## Deploy note
If `chat_backend_prod.env` or `chat_backend_beta.env` on the control node still sets `ENABLE_ACCOUNT_REGISTRATION=false`, that line overrides this default. Set it to `true` or remove it, and leave `ENABLE_SSO` unset or `false`.
## Test plan
- [ ] `GET /api/public/settings/` returns `enable_account_registration: true` and `oauth.google` / `oauth.microsoft` false.
- [ ] Sign-up form creates an account and redirects to Stripe Checkout. No Google or Microsoft button.
- [ ] Checkout success grants the Founders plan after the webhook.
- [ ] `/api/auth/oauth/google/start/?intent=signup` returns 403. Drive connect still starts.
- [ ] Setting `ENABLE_ACCOUNT_REGISTRATION=false` closes `/user/create/` again.
Reviewed-on: #81
## Summary
- Mobile access is granted by `POST /api/finance/store/confirm/` after the app finishes a StoreKit or Play Billing purchase.
- App Store signed transactions are checked against Apple Root CA G3. Play purchase tokens are checked with the Play Developer API.
- The RevenueCat webhook no longer grants a plan. Stripe Checkout and the Stripe webhook stay for the website.
- A purchase account token must match the signed-in user, and a transaction already linked to another account is rejected. Access ends when the verified period end passes unless the app confirms again.
Client: ai_ml_operations/chat_web_app#122
## Config
- `APPLE_IAP_BUNDLE_ID` (default `ai.hesychia.chat`)
- `GOOGLE_PLAY_PACKAGE_NAME`
- `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON` (JSON or a file path)
- Plan `revenuecat_product_id` or `REVENUECAT_PRODUCT_PLAN_MAP` maps the store product to a plan
## Test plan
- [x] `python manage.py test monetization.tests.test_store_purchases monetization.tests.test_revenuecat monetization.tests.test_plans_quotas`
- [ ] Confirm an App Store sandbox transaction and a Play license-test purchase against a configured backend
- [ ] Confirm a token already linked to another user is rejected
- [ ] Confirm `GET /subscription/` returns `store_account_token` and flips a lapsed store sub to canceled
Reviewed-on: #79
## Summary
- Closes Phases 1–3 of [#62](#62) (Phase 4 eval harness left for a follow-up).
- **Accuracy:** Retrieval is decided every turn (`GroundingDecider`, fails open). `FAST` no longer skips search — it only selects `OLLAMA_MODEL_FAST`. Search failures surface an explicit error instead of hallucinating from parametric memory.
- **Search:** Pluggable `services/search/` with **SearxNG primary** + DDGS failover, ranking/dedupe/rumour filtering, numbered dated source blocks, citations persisted on `Prompt.citations` and emitted as `{"v":1,"type":"citations",...}` after stream end.
- **Models:** Role-scoped `OLLAMA_MODEL_THINKING` / `_FAST` / `_UTILITY` / `OLLAMA_EMBED_MODEL=nomic-embed-text`, configurable `num_ctx`, real model name on `PromptMetric`, `reindex_embeddings` management command + loud embedding-dimension mismatch.
## SearxNG (ops)
See README **SearxNG** section. Short version: run `searxng/searxng` on the GPU host, enable `json` in `settings.yml`, set `SEARXNG_BASE_URL=http://10.0.0.128:8080` in prod/beta secrets, open `:8080` on the LAN firewall like Ollama.
## Test plan
- [x] `SKIP_RAG_INIT=1 python manage.py test chat_backend.tests` — 442 OK (6 skipped)
- [ ] Deploy beta with updated secrets (`OLLAMA_MODEL_*`, `OLLAMA_EMBED_MODEL=nomic-embed-text`, `SEARXNG_BASE_URL`)
- [ ] After embed change: `python manage.py reindex_embeddings`
- [ ] Verify `did Taylor Swift get married` in FAST and THINKING returns grounded answer with citations frame
- [ ] Kill SearxNG and confirm factual turns return search_unavailable (not Joe Alwyn hallucination); non-factual chat still worksReviewed-on: #65
## Summary
- Add `ENABLE_ACCOUNT_REGISTRATION` (default `false`) for self-serve sign-up, set via env / control-node secret (`chat_backend_<env>.env`)
- Harden `POST /api/user/create/` to create company + user, return JWTs, and reject when the flag is off
- Expose `GET /api/public/settings/` with `enable_account_registration` for the SPA
Supports frontend: [chat_web_app#31](ai_ml_operations/chat_web_app#31)
## Test plan
- [ ] `cd llm_be && uv run python manage.py test chat_backend.tests.test_views_users`
- [ ] Confirm `POST /api/user/create/` returns 403 when flag unset/false
- [ ] With `ENABLE_ACCOUNT_REGISTRATION=true`, register returns access/refresh + creates company
- [ ] `GET /api/public/settings/` returns the flag
- [ ] Add `ENABLE_ACCOUNT_REGISTRATION=false` to control-node `chat_backend_prod.env` / `chat_backend_beta.env` before deploy (see `.env.prod.example`)Reviewed-on: #25