diff --git a/deploy/DEV_PROD_MIGRATION_PLAN.md b/deploy/DEV_PROD_MIGRATION_PLAN.md new file mode 100644 index 0000000..469970f --- /dev/null +++ b/deploy/DEV_PROD_MIGRATION_PLAN.md @@ -0,0 +1,165 @@ +# Dev/Prod Migration + SSO Plan + +**Status:** Drafted 2026-04-28. IT ticket submitted to add redirect URIs to the shared Entra app. Action deferred to later in the week. + +**Goal:** Move the HM AI QC tool from the shared sandbox onto dedicated Dev and Prod servers, replace local username/password auth with Azure AD SSO, and put a proper deploy script in place. + +## Decisions (locked in) + +| | Value | +|---|---| +| URL path on both servers | `hm-aiqc` | +| Dev URL | `https://optical-dev.oliver.solutions/hm-aiqc/` | +| Prod URL | `https://optical-prod.oliver.solutions/hm-aiqc/` | +| Branch strategy | `develop` → Dev, `main` (tagged) → Prod | +| Auth flow | Browser MSAL.js PKCE popup → server validates JWT → httpOnly cookie (mirrors AI QC) | +| Entra app | Shared with AI QC. Tenant `e519c2e6-bc6d-4fdf-8d9c-923c2f002385`, Client `9079054c-9620-4757-a256-23413042f1ef` | +| Authorization | Replicate AI QC's `user_access.json` pattern (admins + allowed users), simplified to drop AI QC's "clients" multi-tenancy | +| Bootstrap admin | `nick.viljoen@brandtech.plus` (same as AI QC) | +| Database migrations | Bootstrap Flask-Migrate / Alembic before any server cutover | +| Sandbox→Dev/Prod data | Fresh start everywhere | +| Box folder IDs / LLM keys | Shared across environments (no separate creds available) | +| Apache config | Placed manually by Nick via SSH on each server | +| Local auth fallback | **Removed entirely** — if MS login is down, the app is unreachable. Acceptable trade-off; matches AI QC. | + +## Reference: sibling project to copy from + +`/Users/nickviljoen/Desktop/AI_QC_Bitbucket/ai_qc/` — already deployed to the new servers with this exact auth/deploy pattern. Key files to lift: + +| Source | Target | Notes | +|---|---|---| +| `backend/auth_middleware.py` (245 lines) | `core/auth/middleware.py` | Replace cookie name `ai_qc_auth_token` → `hm_aiqc_auth_token` | +| `backend/jwt_validator.py` (196 lines) | `core/auth/jwt_validator.py` | Lift verbatim | +| `backend/user_access.py` (243 lines) | `core/auth/user_access.py` | Strip out `clients` machinery — HM QC has no multi-tenancy | +| `backend/scripts/deploy.sh` (174 lines) | `deploy.sh` | Adapt for Docker (compose build/up + flask db upgrade instead of pip + systemctl) | +| `backend/scripts/rollback.sh` | `deploy/rollback.sh` | Adapt similarly | +| `backend/scripts/health-check.sh` | `deploy/health-check.sh` | Tiny — copy as-is | +| `frontend/index.html:2174-2287` (MSAL JS) | `templates/login.html` + `templates/base.html` | Lift the JS, place in templates | +| MSAL CDN script tag from `frontend/index.html:7-15` | `templates/base.html` head | `