Tier-gated RAG + Drive document sources (#42) (#54)
Unit Tests / test (push) Successful in 10s
Deploy Beta / unit-tests (push) Successful in 10s
Deploy Beta / docker (push) Successful in 21s
Deploy Beta / deploy-beta (push) Successful in 40s

## Summary

Implements epic [#42](#42) (children #43–#53) and advances [#11](#11).

- **Entitlement:** `allows_rag` on plans (founders / backer / pro / business; not standard); exposed as `features.rag`
- **Gates:** document REST + WS `PromptType.RAG` use `assert_feature_allowed(..., "rag")`
- **Lifecycle:** dedupe ingest, delete vectors by `document_id`, honor `active`, fix document detail PATCH/DELETE
- **Workspaces:** auto-create default company workspace; fail-closed scoping
- **Drive:** personal + company Google/Microsoft connect (`link_drive` / `link_company_drive`), resource selection, sync, webhooks stubs, `sync_drive_connections` management command
- **Docs/env:** README + `.env*.example` updated

Companion FE: `chat_web_app` branch `feature/rag-epic-42-ui` (#81–#85).

## Test plan

- [x] `SKIP_RAG_INIT=1 uv run python manage.py test` (457 OK)
- [ ] Migrate finance `0004` + chat_backend `0028` on beta
- [ ] Verify Standard user: Documents API 403 + no RAG retrieval
- [ ] Verify Founders/Pro: upload + list + active toggle
- [ ] Connect Google/Microsoft Drive (incremental scopes) and Sync
- [ ] Company manager: `link_company_drive`; non-manager 403
- [ ] Run `manage.py sync_drive_connections`Reviewed-on: #54
This commit was merged in pull request #54.
This commit is contained in:
2026-08-01 14:02:36 -07:00
parent 2e9e95e16c
commit d54094f5e0
38 changed files with 3166 additions and 98 deletions
+22
View File
@@ -32,6 +32,12 @@ ENABLE_ACCOUNT_REGISTRATION=false
# Redirect URIs (register in each IdP console):
# {OAUTH_CALLBACK_BASE_URL}/api/auth/oauth/google/callback/
# {OAUTH_CALLBACK_BASE_URL}/api/auth/oauth/microsoft/callback/
# Same client id/secret pair is reused for Drive linking (#47) — the extra
# Drive scopes below are requested incrementally via intent=link_drive /
# intent=link_company_drive, no separate app registration needed:
# Google: openid email profile https://www.googleapis.com/auth/drive.readonly
# Microsoft: openid email profile offline_access Files.Read (personal)
# openid email profile offline_access Files.Read.All Sites.Read.All (company)
GOOGLE_OAUTH_CLIENT_ID=
GOOGLE_OAUTH_CLIENT_SECRET=
MICROSOFT_OAUTH_CLIENT_ID=
@@ -40,6 +46,22 @@ MICROSOFT_OAUTH_TENANT=common
# Optional; defaults to request host. Example local: http://127.0.0.1:8001
OAUTH_CALLBACK_BASE_URL=http://127.0.0.1:8001
# Drive / RAG sync (#47-#53). Requires a subscription plan with allows_rag
# (Founders, Pro, Business, Backer by default — see finance PLAN_SEED).
# Start a link: GET /api/auth/oauth/google/start/?intent=link_drive (authenticated)
# GET /api/auth/oauth/google/start/?intent=link_company_drive (company manager)
# GET /api/auth/oauth/microsoft/start/?intent=link_drive
# GET /api/auth/oauth/microsoft/start/?intent=link_company_drive
# Manage: GET /api/drive/connections/
# DELETE /api/drive/connections/<id>/
# POST /api/drive/connections/<id>/resources/ { "resource_ids": [...] }
# POST /api/drive/connections/<id>/sync/
# Provider push notifications (best-effort; register with each provider's
# subscription/watch API pointing here, using ?connection_id=<id>):
# POST {OAUTH_CALLBACK_BASE_URL}/api/drive/webhooks/google/
# POST {OAUTH_CALLBACK_BASE_URL}/api/drive/webhooks/microsoft/
# Worker sync: `python manage.py sync_drive_connections [--connection-id N]`
# Stripe / finance (optional local — required for checkout + webhooks)
STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=