|
| 1 | +# VPC Deploy Log |
| 2 | + |
| 3 | +## v10.0.0 — 2026-04-22 |
| 4 | + |
| 5 | +A forward-compatible release. No data loss paths, every migration is idempotent |
| 6 | +and every new column has a safe default. Existing integrations, backups, pipelines |
| 7 | +and sessions continue to work without manual intervention. |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +### 🚀 Highlights |
| 12 | + |
| 13 | +- **Perfect 1-click Pipeline promotion** — preflight plan, typed confirmation, auto-snapshot, staged execute, one-click rollback. |
| 14 | +- **Exact beta fork** — full data copy (not just schema), auto-deploy, env-var remap from prod → beta DB. |
| 15 | +- **GitHub-style browser sign-in** across VS Code (`vpc-sync-10.0.0.vsix`) and CLI (`vpc-pull login`) — no more pasting PATs. |
| 16 | +- **33 integration platforms** (up from 7) with one-click automations (Supabase→Backup, GitHub→Import, Slack→Alerts, Cloudflare→DNS+SSL). |
| 17 | +- **Supabase backup destination** — off-site backups on a schedule + cloud-restore fallback. |
| 18 | +- **Lazy-loaded apps** — main bundle 1.2 MB → 498 KB (−59%). |
| 19 | +- **System Health widget** — central logger captures every error, Dashboard surfaces 24h counts. |
| 20 | +- **Versioned encryption** with `rekey.js` script for key rotation. |
| 21 | +- **Baseline tests** via `node --test` — 8/8 passing. |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +### 📦 Deploy checklist |
| 26 | + |
| 27 | +Run in order. Each step is idempotent and safe to re-run. |
| 28 | + |
| 29 | +```bash |
| 30 | +# 1. Apply new migrations (all use CREATE TABLE IF NOT EXISTS / ADD COLUMN IF NOT EXISTS) |
| 31 | +psql "$DATABASE_URL" < backend/migrations/041_vpc_device_codes.sql |
| 32 | +psql "$DATABASE_URL" < backend/migrations/042_vpc_backup_destinations.sql |
| 33 | +psql "$DATABASE_URL" < backend/migrations/043_vpc_pipeline_promotions.sql |
| 34 | +psql "$DATABASE_URL" < backend/migrations/044_vpc_system_logs.sql |
| 35 | + |
| 36 | +# 2. Restart backend — new schedulers + logger wire up on boot |
| 37 | +pm2 restart vpc-backend # or `systemctl restart vpc` |
| 38 | + |
| 39 | +# 3. Rebuild frontend (lazy-split chunks) |
| 40 | +cd frontend && npm install && npx vite build && cd .. |
| 41 | + |
| 42 | +# 4. (Optional) Install the new VS Code extension |
| 43 | +code --install-extension vscode-extension/vpc-sync-10.0.0.vsix --force |
| 44 | + |
| 45 | +# 5. Verify |
| 46 | +cd backend && npm test # 8/8 should pass |
| 47 | +curl http://localhost:8001/health |
| 48 | +``` |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +### 🔒 Backward-compatibility notes |
| 53 | + |
| 54 | +| Change | Existing behavior preserved? | |
| 55 | +|---|---| |
| 56 | +| `vpc_integrations.visibility` column added | Default `'shared'` → all existing integrations visible to every admin as before. | |
| 57 | +| `vpc_integrations.created_by` column added | Nullable, default NULL — no backfill needed. | |
| 58 | +| `vpc_settings.enc_key_version` column added | Default 1 — existing blobs continue decrypting. | |
| 59 | +| Encryption blob format: new blobs prefix `v{N}:` | `decrypt()` accepts both legacy and versioned formats — verified by smoke test `encryption: decrypt handles legacy (v-less) format`. | |
| 60 | +| `pipelineService.forkToBeta()` default `copyData` | Was `false`, now `true` (per user request for exact forks). Frontend always passes explicit `{ copyData: true }`; direct API callers using the default now get the new behavior. | |
| 61 | +| `POST /pipelines/:id/promote` response shape | ⚠ Changed — old response `{ schemaPRs, deployedSites, errors }` moved to `/pipelines/:id/promote-legacy`. New response `{ run_id, status, backup_id, schema_applied, deployed, deployErrors, stages }`. Only caller was the web UI, which is updated. | |
| 62 | +| `integrationService.getAll(pool)` | Backward compatible — existing signature still works. Optional `{ forUserId }` param enables per-admin filtering. | |
| 63 | +| Lazy-loaded apps | First open of each app shows loading spinner briefly; functional behavior unchanged. | |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +### 📂 New files |
| 68 | + |
| 69 | +**Backend** |
| 70 | +- `backend/migrations/041_vpc_device_codes.sql` |
| 71 | +- `backend/migrations/042_vpc_backup_destinations.sql` |
| 72 | +- `backend/migrations/043_vpc_pipeline_promotions.sql` |
| 73 | +- `backend/migrations/044_vpc_system_logs.sql` |
| 74 | +- `backend/routes/deviceAuth.js` — VS Code / CLI sign-in flow |
| 75 | +- `backend/routes/realtime.js` — SSE event stream |
| 76 | +- `backend/services/backupScheduler.js` — polls supabase destinations every 60s |
| 77 | +- `backend/services/credentialResolver.js` — shared integration creds for any app |
| 78 | +- `backend/services/integrationAutomations.js` — one-click automators |
| 79 | +- `backend/services/pipelinePromoteService.js` — staged promote + rollback |
| 80 | +- `backend/services/realtimeBus.js` — in-process pub/sub for SSE |
| 81 | +- `backend/services/supabaseBackupService.js` — upload & restore via Supabase Storage |
| 82 | +- `backend/scripts/rekey.js` — re-encrypt all secrets with new key |
| 83 | +- `backend/utils/logger.js` — central logger writing to `vpc_system_logs` |
| 84 | +- `backend/views/deviceApprove.html` — browser approval page for device flow |
| 85 | +- `backend/tests/smoke.test.js` — 8 zero-dep smoke tests |
| 86 | + |
| 87 | +**Frontend** |
| 88 | +- `frontend/src/components/apps/BackupDestinations.jsx` |
| 89 | +- `frontend/src/components/apps/Connections.jsx` (rewritten — 33 platforms, categories, automations) |
| 90 | +- `frontend/src/components/apps/Dashboard.jsx` |
| 91 | +- `frontend/src/components/desktop/CommandPalette.jsx` |
| 92 | +- `frontend/src/components/desktop/ContextBreadcrumb.jsx` |
| 93 | +- `frontend/src/components/desktop/JobQueue.jsx` |
| 94 | +- `frontend/src/components/desktop/KeyboardShortcutsOverlay.jsx` |
| 95 | +- `frontend/src/components/desktop/NotificationCenter.jsx` |
| 96 | +- `frontend/src/components/desktop/StatusBar.jsx` |
| 97 | +- `frontend/src/components/desktop/WorkspaceSwitcher.jsx` |
| 98 | +- `frontend/src/components/integrations/*` |
| 99 | +- `frontend/src/components/pipeline/PromoteDialog.jsx` |
| 100 | +- `frontend/src/components/widgets/*` (incl. `SystemHealthWidget`) |
| 101 | +- `frontend/src/hooks/useGlobalKeyboard.js` |
| 102 | +- `frontend/src/lib/realtime.js` |
| 103 | +- `frontend/src/lib/widgetRegistry.js` |
| 104 | +- `frontend/src/stores/useCommandStore.js` |
| 105 | +- `frontend/src/stores/useContextStore.js` |
| 106 | +- `frontend/src/stores/useDashboardStore.js` |
| 107 | +- `frontend/src/stores/useIntegrationsStore.js` |
| 108 | +- `frontend/src/stores/useJobStore.js` |
| 109 | +- `frontend/src/stores/useNotificationStore.js` |
| 110 | +- `frontend/src/stores/useWorkspaceStore.js` |
| 111 | + |
| 112 | +**VS Code Extension** (packaged as `vpc-sync-10.0.0.vsix`) |
| 113 | +- `vscode-extension/src/auth/deviceFlow.ts` — AuthenticationProvider + device-flow poller |
| 114 | +- `vscode-extension/src/vcs/merge.ts` — 3-way merge port |
| 115 | + |
| 116 | +**CLI** |
| 117 | +- `cli/src/commands/login.js` — `vpc-pull login` browser sign-in |
| 118 | + |
| 119 | +--- |
| 120 | + |
| 121 | +### 🩺 New endpoints |
| 122 | + |
| 123 | +``` |
| 124 | +# Device auth (public + JWT mix) |
| 125 | +POST /api/admin/auth/device/code |
| 126 | +POST /api/admin/auth/device/token |
| 127 | +GET /api/admin/auth/device/pending?code=XXXX |
| 128 | +POST /api/admin/auth/device/confirm { user_code } |
| 129 | +POST /api/admin/auth/device/deny { user_code } |
| 130 | +
|
| 131 | +# Backup destinations |
| 132 | +GET /api/admin/backup/destinations |
| 133 | +POST /api/admin/backup/destinations |
| 134 | +PATCH /api/admin/backup/destinations/:id |
| 135 | +DELETE /api/admin/backup/destinations/:id |
| 136 | +POST /api/admin/backup/destinations/:id/test |
| 137 | +POST /api/admin/backup/destinations/:id/run |
| 138 | +GET /api/admin/backup/destinations/:id/runs |
| 139 | +
|
| 140 | +# Integration automations |
| 141 | +GET /api/admin/integrations/automations |
| 142 | +POST /api/admin/integrations/:id/automate { automation, options } |
| 143 | +
|
| 144 | +# Perfect pipeline promote |
| 145 | +GET /api/admin/pipeline/pipelines/:id/promote/preflight |
| 146 | +POST /api/admin/pipeline/pipelines/:id/promote { confirmations, skipBackup, dryRun } |
| 147 | +POST /api/admin/pipeline/pipelines/:id/promote-legacy (old behavior preserved) |
| 148 | +GET /api/admin/pipeline/pipelines/:id/promotions |
| 149 | +POST /api/admin/pipeline/pipelines/:id/promotions/:runId/rollback |
| 150 | +
|
| 151 | +# Logs |
| 152 | +GET /api/admin/logs/health |
| 153 | +GET /api/admin/logs/system?level=error&limit=100 |
| 154 | +
|
| 155 | +# Static page |
| 156 | +GET /auth/device (approval UI for device codes) |
| 157 | +``` |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +### ⚠ Rollback plan |
| 162 | + |
| 163 | +If something goes wrong after deploy: |
| 164 | + |
| 165 | +1. **Database**: new tables are independent. Drop them if needed — nothing else depends on them: |
| 166 | + ```sql |
| 167 | + DROP TABLE IF EXISTS vpc_pipeline_promotions CASCADE; |
| 168 | + DROP TABLE IF EXISTS vpc_system_logs; |
| 169 | + DROP TABLE IF EXISTS vpc_backup_destination_runs; |
| 170 | + DROP TABLE IF EXISTS vpc_backup_destinations; |
| 171 | + DROP TABLE IF EXISTS vpc_device_codes; |
| 172 | + ALTER TABLE vpc_integrations DROP COLUMN IF EXISTS visibility; |
| 173 | + ALTER TABLE vpc_integrations DROP COLUMN IF EXISTS created_by; |
| 174 | + ALTER TABLE vpc_settings DROP COLUMN IF EXISTS enc_key_version; |
| 175 | + ``` |
| 176 | +2. **Code**: `git revert HEAD` and redeploy. Because migrations are additive, |
| 177 | + reverting code without reverting the schema is also safe — the extra tables |
| 178 | + simply sit unused. |
| 179 | +3. **Pipeline promotions in flight**: any running promotion records its |
| 180 | + pre-promote backup in `vpc_pipeline_promotions.backup_id`. Use |
| 181 | + `POST /promotions/:runId/rollback` or restore the backup directly |
| 182 | + via the Backup Manager. |
| 183 | + |
| 184 | +--- |
| 185 | + |
| 186 | +### ✅ Verification |
| 187 | + |
| 188 | +``` |
| 189 | +cd backend && npm test |
| 190 | +✔ encryption: round-trip preserves plaintext |
| 191 | +✔ encryption: decrypt handles legacy (v-less) format |
| 192 | +✔ encryption: decrypt returns null for garbage |
| 193 | +✔ integrations: all types have name + fields |
| 194 | +✔ integrations: every type has a tester case |
| 195 | +✔ automations: registry is consistent |
| 196 | +✔ pipeline promote service: exports expected API |
| 197 | +✔ logger: forSource returns level methods |
| 198 | +ℹ 8 pass, 0 fail |
| 199 | +``` |
| 200 | + |
| 201 | +Frontend build: `✓ built in 8.07s` — main chunk 498 KB (was 1,204 KB). |
0 commit comments