The Atlas MikeOSS.Azure's docs, bound to the code — and to the migration that built it
108 documents

How the fork is published

The three-tier model that lets this repo be an open fork without leaking the proprietary deployment code — and the rules that route every file.

Per-file classification

Every file diverged from upstream baseline b780a4b ("Initial commit") is listed here with its tier and the rationale for the assignment.

Tiers are defined in README.md:

  • A — Upstream PR (zero Azure dependency, becomes upstream code)
  • B — Published to AGPL fork (application code, Azure adapters inclusive, but no deployment automation)
  • C — Private (deployment IP, marketplace packaging, internal-only scripts and runbooks)

Summary counts

Counting only files actually changed by this fork (not unchanged upstream files):

Tier Files Notes
A 5 (refactors only) Storage interface, auth interface; the change to auth.ts middleware to dispatch on AUTH_PROVIDER.
B ~115 All the Azure-functional code, all the local-stack docker config, the install configurator route + manifest, the schema migrations, the runtime-config endpoint + ConfigContext from issues 030–032.
C ~40 Bicep modules, deploy/check/install PowerShell, GitHub-OIDC bootstrap, ACR mirror script, deploy parameter files, internal runbooks, fork-internal issue docs.

Recent deletions (no longer in any tier — gone from the working tree as of issues 030–032):

  • frontend/src/lib/auth-provider.ts — replaced by ConfigContext.
  • frontend/.env.production — replaced by Dockerfile build-arg and runtime /config.

Full classification table

The table below lists every diverged file (A = added, M = modified, R = renamed) along with its tier and one-sentence rationale. Files omitted from this table are unchanged from upstream and require no action.

Backend application code

File Δ Tier Why
backend/src/index.ts M B Adds new routers + static-frontend serving; nothing Azure-specific. The static-frontend block can ship to upstream too if we want — it's just an Express trick that any deployment can use.
backend/src/middleware/auth.ts M A Provider dispatch on AUTH_PROVIDER; supabase remains the default. Pure provider boundary, no Azure imports.
backend/src/middleware/tenantAccess.ts A B Entra-only tenant lifecycle middleware. Reads principal.tenantId and the tenants table; only runs when AUTH_PROVIDER=entra.
backend/src/middleware/requireRole.ts A B Tiny role-guard helper; only used by Entra paths today but provider-neutral in shape. Ship to B; consider a follow-up A PR once role mapping is generalized.
backend/src/lib/storage.ts M A + B (split) The StorageProvider interface, R2Provider class, factory and singleton wiring → Tier A. The AzureBlobProvider class and the factory's Azure branch → Tier B. The split is documented in docs/issues/azure-migration/006.1-storage-provider-interface.md.
backend/src/lib/supabase.ts M B Adds the entra mode fetch wrapper that strips the /rest/v1 prefix and Authorization header so internal PostgREST works without JWTs. Provider boundary; the supabase function name is now historical.
backend/src/lib/userSettings.ts M B Adds Azure OpenAI per-user settings + global-key fallback chain + upsertUserProfile. The shape is provider-neutral but the Azure OpenAI block is the immediate motivator.
backend/src/lib/access.ts M B Defensive logging + JSON containment fix for shared_with. Mostly bug-fix-shaped; would be a clean upstream PR but we are not investing in upstreaming it because it doesn't unblock our merge story.
backend/src/lib/downloadTokens.ts M B Production-mode hard requirement on DOWNLOAD_SIGNING_SECRET. Generic improvement; could PR upstream if upstream wants it. Not blocking.
backend/src/lib/auth/types.ts A A Provider-neutral AuthPrincipal and AuthValidationResult.
backend/src/lib/auth/providers/supabase.ts A A Supabase validation extracted from the middleware; behaviour-equivalent.
backend/src/lib/auth/providers/entra.ts A B Entra JWT validator with JWKS, issuer/audience/tenant/expiry checks, group extraction.
backend/src/lib/auth/providers/local.ts A B Local HS256 JWT validator for the docker-compose dev stack.
backend/src/lib/auth/roles.ts A B Maps Entra group OIDs → app roles via ENTRA_ADMIN_GROUP_IDS / ENTRA_MEMBER_GROUP_IDS.
backend/src/lib/llm/index.ts M B Adds OpenAI + Azure OpenAI dispatch alongside Claude/Gemini.
backend/src/lib/llm/types.ts M B Adds azureOpenai provider type + AzureOpenaiSettings shape.
backend/src/lib/llm/models.ts M B Adds OpenAI tier IDs + aoai:<deployment> prefix routing.
backend/src/lib/llm/openai.ts A B OpenAI streaming + completion adapter. Could PR upstream as a generic OpenAI adapter (not Azure-specific) — flagged in 02-upstream-prs.md as a possible future PR.
backend/src/lib/llm/azureOpenai.ts A B Azure OpenAI adapter (endpoint + apiVersion + deployment).
backend/src/lib/llm/azureOpenaiDeployments.ts A B Lists deployments configured against the user's AOAI resource for the model picker.
backend/src/lib/config.ts A B Key Vault-backed config reader with env-var override + TTL cache. Azure-specific (uses @azure/keyvault-secrets); the env-override design lets it stay quiet during local dev.
backend/src/lib/install/installAuth.ts A B Bootstrap-token + Entra OIDC auth for the /install configurator.
backend/src/lib/install/manifest.ts A B Declarative manifest of every config item (anthropic-api-key, kv-mike secret names, etc.). Mike-specific but ships in the published fork — anyone with this code can rebuild it.
backend/src/lib/install/types.ts A B Manifest model types.
backend/src/routes/auth.ts A B Local-login endpoint + MatterAI-style Entra OpenID provider selection + callback. Issue 030 added GET /auth/logout so the browser bundle no longer constructs the Microsoft logout URL itself.
backend/src/routes/install.ts A B The /install configurator's HTML routes + write handlers. Operator scripts the route serves are kept private (Tier C).
backend/src/routes/diagnostics.ts A B /admin/diagnostics health-check page. Operator-grade tool, useful in any deployment.
backend/src/routes/llm.ts A B /llm/azure-openai/deployments route used by the model picker.
backend/src/routes/config.ts A B New (issue 030) — GET /config returns { authProvider, entra: { tenantId, clientId } } from server env / Key Vault. Replaces build-time NEXT_PUBLIC_* baking; the bundle is now tenant-portable.
backend/src/routes/chat.ts M B title_modelfast_model rename + cosmetic-failure fallback. Worth upstreaming as a follow-up bug-fix PR.
backend/src/routes/projects.ts M B JSONB shared_with containment fix (PostgREST shape) + replaces db.auth.admin.listUsers (Supabase-only) with a user_profiles lookup.
backend/src/routes/tabular.ts M B Same shared_with JSONB fix as projects.ts.
backend/src/routes/user.ts M B Full /user/profile REST surface (replaces the old single-row upsert) + global-key flags + AOAI settings columns.
backend/src/routes/workflows.ts M B Minor adjustments tied to the user-profile shape change.
backend/src/routes/documents.ts M B Minor adjustments.
backend/src/scripts/runMigrations.ts A B node-pg-migrate runner used by the Container App migrate job.

Backend infrastructure-of-runtime files

File Δ Tier Why
backend/.env.example M B (sanitized) Lists AUTH_PROVIDER, all three of supabase/local/entra blocks, Azure storage and AOAI vars, R2 fallback. Sanitize: strip references to internal tenant before publishing — see 05-config-extraction.md.
backend/.dockerignore A B Standard; nothing Azure-specific.
backend/package.json M B Adds @azure/identity, @azure/keyvault-secrets, @azure/storage-blob, openai, node-pg-migrate, pg, cookie-parser. All published.
backend/migrations/0000_initial.sql R B Renamed from 000_one_shot_schema.sql to fit node-pg-migrate's 4-digit numeric ordering, with Supabase-specific items removed (RLS, auth.users FK, handle_new_user trigger). Application-layer change, ships in B.
backend/migrations/0001_tenant_policy.sql A B tenants + tenant_group_policies tables for Entra-mode tenant lifecycle.
backend/migrations/0002_user_profile_email.sql A B Adds email column to user_profiles.
backend/migrations/0003_user_profile_provider_keys.sql A B Adds OpenAI + AOAI per-user key columns.
backend/migrations/0004_user_profile_fast_model.sql A B Adds fast_model column.
backend/migrations/0005_postgres_roles.sql A B Recreates the PostgREST role topology (web_anon, authenticated, service_role) on Azure Postgres where Supabase's bootstrap doesn't run.

Frontend application code

File Δ Tier Why
frontend/src/contexts/AuthContext.tsx M B Provider boundary supports supabase + local + entra. The boundary shape is upstream-PR-eligible; the entra/local branches are fork policy. After issue 030 the provider mode comes from useConfig() (runtime), not module-level env vars; sign-out redirects through GET /auth/logout.
frontend/src/contexts/ConfigContext.tsx A B New (issue 030) — ConfigProvider, useConfig(), getCachedAuthProvider(). Fetches /config on mount and caches the resolved provider in localStorage so module-level helpers can answer "what mode are we in?" without a React context.
frontend/src/contexts/UserProfileContext.tsx M B Adds AOAI settings + global-key flags + the AOAI deployment cache.
frontend/src/lib/auth-provider.ts deleted Existed pre-030; deleted by issue 030. Module-level isLocalAuth / isEntraAuth / entraConfig reads replaced by useConfig().
frontend/src/lib/auth-token.ts A B Central browser token retrieval helper + bounceIfUnauthorized. Post-030 uses getCachedAuthProvider() and the lazy supabase factory.
frontend/src/lib/supabase.ts M B Lazy getSupabaseClient() factory (issue 031). Throws a clear error in non-supabase deployments rather than constructing against placeholder env vars.
frontend/src/lib/supabase-server.ts, frontend/src/lib/auth.ts M B Same lazy-factory treatment (issue 031); handle missing supabase env vars gracefully (return null / skip) instead of asserting on placeholder values.
frontend/src/components/providers.tsx M B Wraps app shell with ConfigProvider outside AuthProvider so auth bootstrap can read from runtime config.
frontend/src/app/lib/mikeApi.ts M B Routes auth header through getBrowserAccessToken instead of supabase session.
frontend/src/app/lib/modelAvailability.ts M B OpenAI + AOAI availability flags.
frontend/src/app/login/page.tsx M B Adds Microsoft sign-in button + local-login form path.
frontend/src/app/signup/page.tsx M B Adapted to the new provider boundary.
frontend/src/app/page.tsx M B Provider-aware redirect.
frontend/src/app/(pages)/account/page.tsx M B Account page surfaces provider state + new profile fields.
frontend/src/app/(pages)/account/models/page.tsx M B Models page surfaces AOAI deployment dropdown + per-provider keys.
frontend/src/app/(pages)/assistant/chat/[id]/AssistantChatClient.tsx A B Code-split client extracted from page.tsx; preserves SSR shell for static export.
frontend/src/app/(pages)/assistant/chat/[id]/page.tsx M B Becomes the SSR shell that delegates to the client component above.
frontend/src/app/(pages)/projects/[id]/page.tsx M B Same SSR-shell pattern.
frontend/src/app/(pages)/projects/[id]/assistant/chat/[chatId]/page.tsx + ProjectAssistantChatClient.tsx M + A B Same SSR-shell split.
frontend/src/app/(pages)/projects/[id]/tabular-reviews/[reviewId]/page.tsx M B Same.
frontend/src/app/(pages)/tabular-reviews/[id]/page.tsx M B Same.
frontend/src/app/(pages)/workflows/[id]/page.tsx + WorkflowDetailClient.tsx M + A B Same SSR-shell split.
frontend/src/app/components/assistant/{AssistantMessage,ChatInput,EditCard,ModelToggle}.tsx M B Provider-aware tweaks — model picker shows AOAI deployments, etc.
frontend/src/app/components/shared/{DocPanel,DocxView}.tsx M B Provider-aware doc fetch + 401 bounce.
frontend/src/app/components/tabular/{TRChatPanel,TabularReviewView}.tsx M B Same.
frontend/src/app/hooks/{useDocumentVersions,useFetchDocxBytes,useFetchSingleDoc}.ts M B Provider-aware fetch + 401 bounce.
frontend/.env.local.example M B Sample env vars. Issue 032 trimmed the file to its current minimal shape: only NEXT_PUBLIC_API_BASE_URL plus the optional supabase pair.
frontend/.env.production deleted Existed pre-032 with real tenant GUIDs and FQDN. Issue 032 deleted the file and the .gitignore whitelist; NEXT_PUBLIC_API_BASE_URL is now a Docker --build-arg and customer-specific values come from /config at runtime.
Dockerfile M B Issue 032 added ARG NEXT_PUBLIC_API_BASE_URL= on the frontend-builder stage so the deploy pipeline passes the same-origin / split-origin choice as a build arg.
.gitignore M B Issue 032 removed the !frontend/.env.production whitelist; the existing .env.* rule keeps every variant out by default.
frontend/next.config.ts M B output: 'export' for the static export bundled into the Container App.
frontend/package.json M B Removes resend, bumps AWS SDK.

Infrastructure-as-code (Bicep)

All files in this section are Tier C — private. They encode our deployment topology, naming conventions, and parameterization choices. Publishing them removes the gap between "fork code" and "deployed service," which destroys the marketplace IP.

File Δ Tier Why
infra/main.bicep A C Composes every module; reveals our deployment shape.
infra/main.parameters.dev.json A C Names acrmike.azurecr.io, our region, our SKUs.
infra/main.parameters.prod.json A C Same; tighter SKUs.
infra/modules/acr.bicep A C
infra/modules/containerapp-backend.bicep A C
infra/modules/containerapp-job-migrate.bicep A C
infra/modules/containerapp-postgrest.bicep A C The internal-PostgREST trust-model rationale lives here; valuable IP.
infra/modules/containerapps-env.bicep A C
infra/modules/keyvault-secret.bicep A C
infra/modules/keyvault.bicep A C
infra/modules/managed-identity.bicep A C
infra/modules/network.bicep A C
infra/modules/postgres.bicep A C
infra/modules/storage.bicep A C

Operator and deployment scripts

File Δ Tier Why
deploy.ps1 A C The deploy pipeline. Pure deployment IP.
check-azure.ps1 A C Read-only health check tied to our resource names.
scripts/setup-github-oidc.sh A C Bootstraps the GitHub-Actions federated identity. Internal CI plumbing.
scripts/mirror-postgrest.sh A C ACR mirror of upstream PostgREST. Internal supply-chain step.
scripts/install/create-entra-apps.ps1 A C Operator script — creates Entra app registrations. The fact that we ship a one-shot creator is part of the marketplace UX IP.
scripts/install/register-redirect-uris.ps1 A C Same — operator OIDC convenience.
scripts/install/reset-install.ps1 A C
scripts/install/revoke-installer-access.ps1 A C
scripts/install/setup-aoai.ps1 A C Operator script that provisions or connects an Azure OpenAI resource.

The /install route in the backend (Tier B) gracefully degrades when these scripts are absent — see 06-agent-runbook.md for the "degrade-gracefully" check the agent must add before publishing.

Local-stack scripts (developer machine)

These are shipped in B because they make the published code testable on a developer's laptop without touching Azure.

File Δ Tier Why
scripts/local-stack/00-init-roles.sql A B PostgREST role topology for local Postgres.
scripts/local-stack/Caddyfile A B Local proxy that maps /rest/v1/*:3000 so the unmodified supabase-js client works.
scripts/local-stack/forge-jwt.mjs A B Mints local HS256 service-role JWTs.
scripts/dev-infra-check.ps1 A B Smoke-check the local docker stack.
docker-compose.dev.yml A B Local Postgres + PostgREST + Caddy + Azurite.
Dockerfile A B The bundled-frontend multi-stage build.
.dockerignore A B

Documentation

The repo's docs/ tree is mixed. Some docs reveal deployment IP (Tier C); some are general design context that ships with the fork (Tier B); some are entirely about local development and obviously ship.

File Tier Why
AGENTS.md B General agent guidance for the repo.
README.md B (rewrite) Replace deployment instructions with prereqs prose; see 03-fork-publication.md.
docs/fork-delta.md B Useful for any forker.
docs/local-first-upstream-strategy.md B Useful for any forker.
docs/runbook-local-stack.md B Local dev runbook.
docs/runbook-entra-local-auth.md B Local Entra runbook.
docs/auth-provider-selection-flow.md B Generic auth design.
docs/agent-handoff.md B
docs/runbook-dev-deployment.md C Names our rg-mike-dev, FQDNs, SKUs.
docs/azure-production-hardening.md C Production-hardening recipe specific to our deployment.
docs/AzureMove/azure-migration-proposal.md B (sanitized) Design doc; useful context for the published fork. Sanitize tenant names.
docs/Postgres/* B (sanitized) Database design docs.
docs/storage/* B Storage design docs.
docs/email/* B Email design (not Azure-specific).
docs/entraId/* B (sanitized) Entra implementation deep-dives. Sanitize.
docs/install/scripts.md C Documents the scripts that are themselves Tier C.
docs/infra/* C Bicep-and-deployment-specific.
docs/issues/azure-migration/* mixed The 006.1, 006.2, 008.0, 017, 020, 021, 022 design docs are Tier B (provider-boundary thinking). The 001–006, 007, 015, 016, 023, 029 docs are Tier C (deployment / install configurator / marketplace IP). The 010–014 + 024–028 docs are mixed — most are Tier B but each one needs a sanitization pass. 06-agent-runbook.md lists the per-file decisions.
docs/migration/* C This directory itself. Internal planning.
.claude/ C Internal agent config. Not relevant to the published fork.

Build artefacts and lockfiles

File Δ Tier Why
backend/package-lock.json M B Regenerated as part of the squashed PR.
frontend/package-lock.json M B Same.
backend/bun.lock, frontend/bun.lock unchanged B Already upstream-shape.
.gitignore M B Adds .claude/. Sanitize: keep .claude/ in .gitignore if we're not publishing it.

Notes on classification edge cases

backend/src/index.ts static-frontend serving. The findShell() + SPA-fallback machinery is generic Express + Next.js static-export glue and could go upstream as a contribution. We have chosen to ship it in Tier B for now and revisit upstreaming after the public fork is published.

backend/src/lib/access.ts JSONB containment fix. This is a genuine upstream bug — the shipped behaviour throws on Postgres JSONB columns when the user has shared projects. It would make a clean A-tier PR. We have chosen to ship it in Tier B because the provider-boundary PRs are higher-value upstream contributions and we don't want to multiply review surface.

backend/src/lib/llm/openai.ts plain OpenAI adapter. Not Azure- specific; could go upstream. Deferred to a future PR.

Frontend AuthContext.tsx provider abstraction. The shape is generic but the implementation interleaves all three providers in one file. Splitting it cleanly enough for an upstream PR would be a real refactor. Deferred.

Documentation sanitization. Several B-tier docs reference our internal tenant GUIDs, FQDNs, or resource names. The agent runbook includes a regex pass that the publication script must run before pushing to the public fork — see 05-config-extraction.md.