# Environment Separation Validation Closeout

> **Retirement notice:** This closeout records the March 2026 environment at
> that time. The shared-development row is historical evidence, not a current
> deployment target; use `DEPLOYMENT.md` and the retirement runbook.

**Date:** March 24, 2026
**Status:** Complete

This document records the final validation pass for the local, development, and production environment split.

## Final Environment Matrix

| Environment | App Domain | Database | Clerk Mode | Stripe Mode | rclone Service |
| --- | --- | --- | --- | --- | --- |
| Local | `http://localhost:3000` | `stratofusion-local` | Test | Test | `http://localhost:3001` or local Fly override |
| Development | `https://dev.stratofusion.io` | `stratofusion-dev` | Test | Test | `https://stratofusion-rclone-dev.fly.dev` |
| Production | `https://stratofusion.io` | `stratofusion-prod` | Live | Live | `https://stratofusion-rclone-prod.fly.dev` |

## Separation Results

- Neon is split into `stratofusion-local`, `stratofusion-dev`, and `stratofusion-prod`.
- Vercel dev and prod projects use separate `DATABASE_URL` values.
- Fly.io rclone traffic is split between `stratofusion-rclone-dev` and `stratofusion-rclone-prod`.
- OAuth redirect URIs are separated for `localhost`, `dev.stratofusion.io`, and `stratofusion.io`.
- Clerk uses test-mode credentials for local/dev and live credentials for prod.
- Stripe uses test-mode keys and webhooks for local/dev and live-mode keys and webhooks for prod.
- Cron routes are protected by a stable-host guard so previews and unknown hosts are skipped.

## Automated Verification

Focused automated checks were run during the rollout, including:

```bash
pnpm typecheck
pnpm test -- src/lib/oauth.test.ts src/lib/oauth.integration.test.ts src/lib/oauth-route-integration.test.ts src/app/api/oauth-integration.test.ts
pnpm test -- src/app/api/auth/clerk-oauth/__tests__/route.test.ts
pnpm test -- src/lib/cron-environment.test.ts src/app/api/cron/__tests__/environment-guard.test.ts
pnpm exec vitest run src/lib/stripe/__tests__/price-mapping.test.ts src/app/api/webhooks/stripe/route.test.ts src/app/api/stripe/create-checkout-session/route.test.ts src/app/api/stripe/change-plan/route.test.ts src/app/api/stripe/create-portal-session/route.test.ts
pnpm test -- src/app/api/google/__tests__/route.test.ts
pnpm test -- src/app/api/dropbox/__tests__/route.test.ts
pnpm test -- src/app/api/dropbox/upload/__tests__/route.test.ts
```

## Manual Validation Summary

### Local

- Local `.env.local` was aligned to the isolated local environment.
- Local OAuth callback routes use `http://localhost:3000/api/{google|onedrive|dropbox}`.
- Local Stripe remains in test mode and uses Stripe CLI webhook forwarding when needed.
- Local provider connection flows were exercised during rollout debugging and fix verification.

### Development

- `dev.stratofusion.io` was verified to use the dev database, dev rclone service, test Clerk, and test Stripe.
- Auth and OAuth flows were validated for Google, OneDrive, Dropbox, and Clerk.
- Search returned results across all connected dev accounts.
- Scoped write-path smoke tests passed.
  - folder create.
  - upload.
  - copy.
  - move.
  - cleanup.
- Stripe test-mode configuration and webhook routing were verified against the dev project.

### Production

- `stratofusion.io` was verified to use the prod database, prod rclone service, live Clerk, and live Stripe.
- Billing showed the live `Unlimited` plan after a real Stripe transaction.
- Six provider connections were validated on the live site.
  - Google personal.
  - Google work/school.
  - OneDrive personal.
  - OneDrive work/school.
  - Dropbox personal.
  - Dropbox work/school.
- Root listing and cross-account search passed across all connected prod accounts.
- Deep scoped write-path tests passed in production for Google, OneDrive, and Dropbox.
  - create folder.
  - upload file.
  - open file.
  - copy.
  - move.
  - list verification.
  - cleanup.

## Runtime Issues Found During Validation

The validation pass surfaced three production-facing OAuth or file-operation issues. All were fixed, deployed, and committed:

- Google account intent was being dropped in header flows.
- Dropbox popup OAuth was reusing cached login state instead of forcing a fresh account prompt.
- Dropbox upload routes were not normalizing provider paths consistently before upload.

## Isolation Verification

- Database isolation was verified by checking the active database per environment and by confirming environment-specific writes.
- Fly.io isolation was verified through separate dev/prod health endpoints and successful environment-specific file operations.
- Clerk isolation was verified through test-mode local/dev sign-in and live-mode prod sign-in.
- Stripe isolation was verified through test-mode dev billing, live-mode prod billing, separate webhook endpoints, and separate test/live customer spaces.

## Notes

- OneDrive search can lag briefly after upload or delete even when the underlying write succeeded. Listing and direct open were used as the authoritative verification for those cases.
- Temporary validation artifacts were cleaned up after testing. Cleanup used provider trash/recycle-bin semantics where supported.

## Final Outcome

Environment separation is complete. Local, development, and production now operate with isolated databases, provider callbacks, authentication state, billing state, and rclone infrastructure.
