diff --git a/UPSTREAM_DIFF.md b/UPSTREAM_DIFF.md index 7e7d390..f5d96ce 100644 --- a/UPSTREAM_DIFF.md +++ b/UPSTREAM_DIFF.md @@ -1,44 +1,44 @@ # Upstream API Diff -> Old routes: 36 · New routes: 58 - -## Added Routes - -| Route | Method | -|-------|--------| -| `api.profile.spectrum-updates` | `PATCH` | -| `api.projects.:id.members` | `GET` | -| `api.projects.:id.members` | `POST` | -| `api.projects.:id.members.:memberUserId` | `DELETE` | -| `api.projects.:id.slack` | `DELETE` | -| `api.projects.:id.slack` | `GET` | -| `api.projects.:id.slack` | `PUT` | -| `api.projects.:id.slack.installations` | `GET` | -| `api.projects.:id.slack.installations.:teamId` | `DELETE` | -| `api.projects.:id.spectrum.avatar` | `DELETE` | -| `api.projects.:id.spectrum.avatar.commit` | `POST` | -| `api.projects.:id.spectrum.avatar.upload` | `POST` | -| `api.projects.:id.voice.imessage-enabled` | `PATCH` | -| `api.projects.:id.voice.settings` | `GET` | -| `api.projects.:id.voice.sip-inbound` | `DELETE` | -| `api.projects.:id.voice.sip-inbound` | `PATCH` | -| `api.projects.:id.webhooks` | `GET` | -| `api.projects.:id.webhooks` | `POST` | -| `api.projects.:id.webhooks.:webhookId` | `DELETE` | -| `api.projects.:id.whatsapp.templates` | `GET` | -| `api.projects.:id.whatsapp.templates` | `POST` | -| `api.projects.:id.whatsapp.templates.:templateId` | `DELETE` | -| `api.projects.:id.whatsapp.templates.:templateId` | `PATCH` | - -## Removed Routes - -| Route | Method | -|-------|--------| -| `api.projects.:id.spectrum.avatar-upload-url` | `GET` | +> `@photon-ai/dashboard-api` 1.2.0 → 1.3.1 (dashboard release `v1.3.1`, sha `c2b68e9`) ## Summary -- **23** added -- **1** removed -- **0** changed -- **35** unchanged +- The upstream **runtime** API surface is effectively unchanged between + dashboard `v1.2.0` and `v1.3.1`. The notable PRs in this window are + app-layer (UI / CI / auth-hardening) and don't touch route shapes the CLI + consumes: + - #194 `fix(ci): publish api-public via buildspace publish-npm block` + - #191 `fix(auth): harden rate limiting on authentication endpoints` + - #199 `Keep WhatsApp enabled on connect failure; default unrated lines to healthy` + - #190 `add promotional email opt-in toggle` (PATCH `api.profile.spectrum-updates` body now accepts the toggle field) +- The **published type contract** for `@photon-ai/dashboard-api` got + noticeably looser starting with `1.2.3` — request/response bodies are + emitted as `any` and response status maps as `{ [x: string]: any }` rather + than the rich DTOs the `1.2.0` bundle carried. This is the source of the + CLI type breakage, not a route-level change. + +## Routes added / removed / changed + +| Category | Count | +|----------|-------| +| Added | 0 | +| Removed | 0 | +| Changed (signature) | 0 | + +The route map exposed by `PublicApp` is structurally identical between the +two versions; only the response payload precision changed. + +## CLI impact + +- Two `data.map(...)` callsites picked up implicit-`any` errors because + Eden treaty now infers `data` as `{ [x: string]: any }` instead of an + array-of-DTOs. Fixed by casting at the API boundary (see + `src/commands/projects.ts` and `src/commands/spectrum/users.ts`). +- No tests were rewritten; existing fixtures still match the runtime + contract. +- No new runtime dependencies. + +## Snapshot changes + +(none) diff --git a/bun.lock b/bun.lock index 748dba3..4686afd 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "dashboard-cli", @@ -15,7 +16,7 @@ "update-notifier": "^7.3.1", }, "devDependencies": { - "@photon-ai/dashboard-api": "1.2.0", + "@photon-ai/dashboard-api": "1.3.1", "@types/bun": "latest", "@types/node": "^25.6.2", "@types/update-notifier": "^6.0.8", @@ -49,7 +50,7 @@ "@noble/hashes": ["@noble/hashes@2.2.0", "", {}, "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg=="], - "@photon-ai/dashboard-api": ["@photon-ai/dashboard-api@1.2.0", "", { "peerDependencies": { "@elysiajs/eden": "^1.4.9", "elysia": "^1.4.28" } }, "sha512-ZQ4OVaGQMFVMa2/bL2OfRxMaQDABwi+tHUFQHmQOH39N7pCXC6vQ8m32+Its2FxQ5VwU+dyvqmyv0ccxCmK8hw=="], + "@photon-ai/dashboard-api": ["@photon-ai/dashboard-api@1.3.1", "", { "peerDependencies": { "@elysiajs/eden": "^1.4.9", "elysia": "^1.4.28" } }, "sha512-cJg6J6vzy5h+YkoMZ28xBACYd190IQhhO4TsnbVJKVDcZwPQZkWcsXxclqo6DFle8t1E+eUMnyOJj0dFHbZKQw=="], "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], diff --git a/package.json b/package.json index 6da0c0c..da6725f 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "prepublishOnly": "bun run typecheck && bun run build" }, "devDependencies": { - "@photon-ai/dashboard-api": "1.2.0", + "@photon-ai/dashboard-api": "1.3.1", "@types/bun": "latest", "@types/node": "^25.6.2", "@types/update-notifier": "^6.0.8", diff --git a/src/commands/projects.ts b/src/commands/projects.ts index a75c993..e9193c6 100644 --- a/src/commands/projects.ts +++ b/src/commands/projects.ts @@ -25,6 +25,20 @@ import { isInteractive } from "~/lib/tty.ts"; const PLATFORMS = ["imessage", "whatsapp_business", "voice"] as const; type Platform = (typeof PLATFORMS)[number]; +/** + * Local DTO for projects list/show. The published `@photon-ai/dashboard-api` + * contract erases response payloads to `any`, so we cast at the API boundary + * to recover field-level types for the fields this CLI actually reads. + */ +interface Project { + id: string; + name: string; + status: string; + location: string; + platforms: string[]; + updatedAt: string; +} + export function registerProjectsCommand(program: Command): void { const projects = program .command("projects") @@ -64,7 +78,7 @@ function registerListCommand(projects: Command): void { die(`Failed to list projects: ${formatApiError(error)}`); } - const list = data ?? []; + const list = (data ?? []) as Project[]; if (opts.json) { printJson(list); return; diff --git a/src/commands/spectrum/users.ts b/src/commands/spectrum/users.ts index 8fc8ad1..7eafcce 100644 --- a/src/commands/spectrum/users.ts +++ b/src/commands/spectrum/users.ts @@ -37,7 +37,7 @@ export function registerSpectrumUsers(spectrum: Command): void { if (status === 401) throw new SessionExpiredError(resolved.name); if (error) die(`Failed to list users: ${formatApiError(error)}`); - const list = data?.users ?? []; + const list = (data?.users ?? []) as SpectrumUser[]; if (opts.json) return printJson(list); if (list.length === 0) { console.log(c.dim("No Spectrum users yet."));