chore(apps): rename analytics-api-client Sandbox -> Box via in-repo swagger spec#721
Conversation
…wagger spec The analytics client was the last generated client still on sandbox-named paths/symbols after #706 renamed its dashboard consumers, leaving the dashboard referencing exports (ModelsBoxUsage, organizationOrganizationIdUsageBoxGet, ...) that did not exist. Its swagger previously lived only as an uncommitted tmp/swagger.json from the external analytics service, so the client could not be regenerated from this repo at all. Commit the contract as apps/libs/analytics-api-client/swagger.json (reconstructed 1:1 from the committed client, sandbox -> box renamed: paths, models.BoxUsage, boxId, boxCount), point generate:api-client at it, and regenerate with the pinned openapi-generator 7.23.0 (was stale 7.12.0 output). Now that the spec is in-repo, drop the analytics exclusion from the api-client-drift gate and regenerate+diff it like the other clients. Also ignore the gitignored nx cache in eslint: the generate target caches its src/ output under apps/.nx/cache, and lint after a local regen tripped on the cached copy of generated code. Verified: dashboard typecheck has zero analytics-related errors with the new client (13 rename-mismatch errors against the old one); regen is byte-identical across runs (drift gate safe); make lint:apps exit 0. Part of #711. Signed-off-by: dorianzheng <xingzhengde72@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughRegenerates analytics API client from a new Swagger spec: adds organization-scoped usage/telemetry endpoints (box-scoped), updates models and client code, enhances shared runtime (serialization/AWSv4), adds generated docs, and includes CI/workspace updates for generation and drift detection. Changes Analytics API Client OpenAPI Generation Update
Estimated code review effort 🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly Related Issues
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
apps/libs/analytics-api-client/src/configuration.ts (1)
14-24: ⚡ Quick winExport
AWSv4Configurationinterface for public API.The
AWSv4Configurationinterface is not exported but is used by the publicConfigurationParametersandConfigurationtypes. While TypeScript allows this, consumers cannot directly reference or type-annotateAWSv4Configurationobjects, limiting type reusability. Export the interface to make it part of the explicit public API.📤 Recommended fix
-interface AWSv4Configuration { +export interface AWSv4Configuration { options?: {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/libs/analytics-api-client/src/configuration.ts` around lines 14 - 24, The AWSv4Configuration interface is currently unexported but referenced by the public types ConfigurationParameters and Configuration; export it so consumers can reference it directly. Update the declaration of AWSv4Configuration to be exported (export interface AWSv4Configuration) and ensure any imports/users (e.g., where ConfigurationParameters or Configuration are defined) continue to compile without other changes.apps/libs/analytics-api-client/swagger.json (3)
58-60: ⚡ Quick winConsider adding
maxItemsconstraints to array responses.Array responses lack
maxItemsconstraints, which could allow unbounded result sets that risk memory exhaustion in clients. For production APIs, consider adding reasonable limits (e.g., 1000 or 10000) and documenting pagination if larger result sets are needed.🛡️ Example fix for one array response
"schema": { "type": "array", + "maxItems": 10000, "items": { "$ref": "`#/definitions/models.UsagePeriod`" } }Also applies to: 143-146, 184-187, 260-263, 315-318, 377-380, 419-421
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/libs/analytics-api-client/swagger.json` around lines 58 - 60, Several array response schemas (e.g., the array whose items reference models.UsagePeriod and other array definitions in swagger.json) lack maxItems constraints; update those array definitions to include a reasonable "maxItems" value (e.g., 1000 or 10000) and add accompanying description/notes about pagination where appropriate so clients cannot receive unbounded arrays. Locate the array schemas that reference "`#/definitions/models.UsagePeriod`" and the other array entries called out (around the other occurrences) and add a "maxItems": <limit> property and documentation text in each schema to enforce and document a practical upper bound.Source: Linters/SAST tools
1-15: ⚡ Quick winAdd
schemesfield to specify HTTPS for production.The spec is missing a
schemesfield, which defaults to HTTP in Swagger 2.0. For production deployments, the API should enforce HTTPS to protect the Bearer tokens in transit.🔒 Recommended addition
Add after line 8:
"host": "localhost:8080", + "schemes": ["https"], "securityDefinitions": {For development/testing, you can include both schemes:
"schemes": ["http", "https"],🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/libs/analytics-api-client/swagger.json` around lines 1 - 15, The Swagger 2.0 spec is missing the "schemes" field so it defaults to HTTP; add a "schemes" entry to the root object in apps/libs/analytics-api-client/swagger.json (near the existing "swagger" and "info" fields) to include "https" for production (optionally ["http","https"] for dev/testing) so the API enforces HTTPS for Bearer token transport.
2-2: ⚖️ Poor tradeoffConsider upgrading to OpenAPI 3.0+ in future iterations.
The spec uses Swagger 2.0, which is the legacy format. OpenAPI 3.0+ offers better tooling support, enhanced security scheme definitions, and improved schema validation. While not blocking for this PR, consider upgrading when time permits.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/libs/analytics-api-client/swagger.json` at line 2, The spec currently uses Swagger 2.0 (the JSON key "swagger": "2.0"); upgrade it to OpenAPI 3.x by replacing the top-level "swagger" key with "openapi": "3.0.3" (or later) and migrating Swagger 2 constructs to OpenAPI 3 equivalents: move "definitions" to "components.schemas", convert "parameters"/"responses" into "components", transform any formData parameters into requestBody with content/media type, and adjust securityDefinitions to components.securitySchemes; you can use a converter tool like swagger2openapi to automate the migration and then verify with an OpenAPI 3 validator and update any downstream codegen or tooling that expects the Swagger 2 format.apps/libs/analytics-api-client/src/common.ts (1)
69-71: 💤 Low valueConsider handling Set more explicitly to avoid loose type cast.
The code casts
parameter as any[]when it could be a Set. While this works because both Array and Set have compatibleforEachmethods, it's not type-safe. Consider handling them separately or converting Set to Array explicitly for clarity.♻️ More type-safe alternative
- if (Array.isArray(parameter) || parameter instanceof Set) { - (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); - } + if (Array.isArray(parameter)) { + parameter.forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + } + else if (parameter instanceof Set) { + Array.from(parameter).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + }Alternatively, if you prefer the combined branch:
if (Array.isArray(parameter) || parameter instanceof Set) { - (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + const items = parameter instanceof Set ? Array.from(parameter) : parameter; + items.forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/libs/analytics-api-client/src/common.ts` around lines 69 - 71, The branch inside setFlattenedQueryParams that currently does (parameter as any[]).forEach(...) is not type-safe for Sets; update it to handle Set explicitly or convert the Set to an array before iterating: detect if parameter is Array (Array.isArray) then iterate, else if parameter is instance of Set convert via Array.from(parameter) or use parameter.forEach with proper typing, then call setFlattenedQueryParams(urlSearchParams, item, key); this preserves behavior while removing the loose cast and clarifying intent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/libs/analytics-api-client/src/.openapi-generator/VERSION`:
- Line 1: Update the OpenAPI generator bump verification by re-checking the
7.23.0 impact for the typescript-axios client: inspect the API schemas for use
of allOf/anyOf (particularly inheritance via allOf and anyOf title usage) and
either regenerate the client with typescript-axios at 7.23.0 (the version string
in VERSION) and run a compile + smoke test (npm/yarn build and sample request
flow) or explicitly confirm no schemas use those patterns; if regeneration
surfaces type changes, fix or pin schemas/generator options to preserve previous
behavior.
In `@apps/libs/analytics-api-client/swagger.json`:
- Around line 40-51: The OpenAPI parameter definitions for the query parameters
named "from" and "to" are missing the format hint, so generators treat them as
plain strings; update each relevant parameter object in swagger.json (every
occurrence of parameters named "from" and "to" e.g., the blocks around those
entries) to include "format": "date-time" alongside "type": "string" so they are
recognized as RFC3339 timestamps and validated accordingly; apply this change to
all listed occurrences (around lines with the "from"/"to" parameter blocks).
---
Nitpick comments:
In `@apps/libs/analytics-api-client/src/common.ts`:
- Around line 69-71: The branch inside setFlattenedQueryParams that currently
does (parameter as any[]).forEach(...) is not type-safe for Sets; update it to
handle Set explicitly or convert the Set to an array before iterating: detect if
parameter is Array (Array.isArray) then iterate, else if parameter is instance
of Set convert via Array.from(parameter) or use parameter.forEach with proper
typing, then call setFlattenedQueryParams(urlSearchParams, item, key); this
preserves behavior while removing the loose cast and clarifying intent.
In `@apps/libs/analytics-api-client/src/configuration.ts`:
- Around line 14-24: The AWSv4Configuration interface is currently unexported
but referenced by the public types ConfigurationParameters and Configuration;
export it so consumers can reference it directly. Update the declaration of
AWSv4Configuration to be exported (export interface AWSv4Configuration) and
ensure any imports/users (e.g., where ConfigurationParameters or Configuration
are defined) continue to compile without other changes.
In `@apps/libs/analytics-api-client/swagger.json`:
- Around line 58-60: Several array response schemas (e.g., the array whose items
reference models.UsagePeriod and other array definitions in swagger.json) lack
maxItems constraints; update those array definitions to include a reasonable
"maxItems" value (e.g., 1000 or 10000) and add accompanying description/notes
about pagination where appropriate so clients cannot receive unbounded arrays.
Locate the array schemas that reference "`#/definitions/models.UsagePeriod`" and
the other array entries called out (around the other occurrences) and add a
"maxItems": <limit> property and documentation text in each schema to enforce
and document a practical upper bound.
- Around line 1-15: The Swagger 2.0 spec is missing the "schemes" field so it
defaults to HTTP; add a "schemes" entry to the root object in
apps/libs/analytics-api-client/swagger.json (near the existing "swagger" and
"info" fields) to include "https" for production (optionally ["http","https"]
for dev/testing) so the API enforces HTTPS for Bearer token transport.
- Line 2: The spec currently uses Swagger 2.0 (the JSON key "swagger": "2.0");
upgrade it to OpenAPI 3.x by replacing the top-level "swagger" key with
"openapi": "3.0.3" (or later) and migrating Swagger 2 constructs to OpenAPI 3
equivalents: move "definitions" to "components.schemas", convert
"parameters"/"responses" into "components", transform any formData parameters
into requestBody with content/media type, and adjust securityDefinitions to
components.securitySchemes; you can use a converter tool like swagger2openapi to
automate the migration and then verify with an OpenAPI 3 validator and update
any downstream codegen or tooling that expects the Swagger 2 format.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 822a4b0b-a177-4fe3-86c7-689ae1b31858
📒 Files selected for processing (33)
.github/workflows/api-client-drift.ymlapps/eslint.config.mjsapps/libs/analytics-api-client/project.jsonapps/libs/analytics-api-client/src/.openapi-generator/FILESapps/libs/analytics-api-client/src/.openapi-generator/VERSIONapps/libs/analytics-api-client/src/api.tsapps/libs/analytics-api-client/src/api/telemetry-api.tsapps/libs/analytics-api-client/src/api/usage-api.tsapps/libs/analytics-api-client/src/base.tsapps/libs/analytics-api-client/src/common.tsapps/libs/analytics-api-client/src/configuration.tsapps/libs/analytics-api-client/src/docs/ModelsAggregatedUsage.mdapps/libs/analytics-api-client/src/docs/ModelsBoxUsage.mdapps/libs/analytics-api-client/src/docs/ModelsLogEntry.mdapps/libs/analytics-api-client/src/docs/ModelsMetricPoint.mdapps/libs/analytics-api-client/src/docs/ModelsSpan.mdapps/libs/analytics-api-client/src/docs/ModelsTraceSummary.mdapps/libs/analytics-api-client/src/docs/ModelsUsageChartPoint.mdapps/libs/analytics-api-client/src/docs/ModelsUsagePeriod.mdapps/libs/analytics-api-client/src/docs/TelemetryApi.mdapps/libs/analytics-api-client/src/docs/UsageApi.mdapps/libs/analytics-api-client/src/index.tsapps/libs/analytics-api-client/src/models/index.tsapps/libs/analytics-api-client/src/models/models-aggregated-usage.tsapps/libs/analytics-api-client/src/models/models-box-usage.tsapps/libs/analytics-api-client/src/models/models-log-entry.tsapps/libs/analytics-api-client/src/models/models-metric-point.tsapps/libs/analytics-api-client/src/models/models-sandbox-usage.tsapps/libs/analytics-api-client/src/models/models-span.tsapps/libs/analytics-api-client/src/models/models-trace-summary.tsapps/libs/analytics-api-client/src/models/models-usage-chart-point.tsapps/libs/analytics-api-client/src/models/models-usage-period.tsapps/libs/analytics-api-client/swagger.json
💤 Files with no reviewable changes (1)
- apps/libs/analytics-api-client/src/models/models-sandbox-usage.ts
436c4ea to
5005c75
Compare
…lient, fix dead env vars + stale refs (#723) Part of #711 — closes out the "Part 1 of N" remainder. A repo-wide sweep found the rename effectively complete in source (`runner`/`cli`/`daemon`/`dashboard`/`proxy` at zero tokens; `apps/api` leftovers are historical migrations, correct as-is). What remained is below. ## Generated client (the bulk of the diff) **`toolbox-api-client` regenerated** from the committed `apps/daemon/pkg/toolbox/docs/swagger.json` (which #718 already renamed — `git grep "sandbox entrypoint"` has zero hits outside the generated client). This kills the last 4 generated `sandbox entrypoint session` doc-comments and moves the client from generator 7.12.0 to the pinned 7.23.0, same modernization #721 did for analytics (hence the `src/docs/*.md` additions — 7.23 emits them, and the drift gate requires committed == emitted). Determinism verified: regen run twice locally (with and without `--excludeTaskDependencies`), byte-identical both times. **Drift gate now covers it** (`api-client-drift.yml`): regen via `--excludeTaskDependencies` so the committed daemon swagger is the contract and the job needs no Go/swag toolchain. Daemon-source↔swagger drift stays ungated (the cli/daemon-docs sibling gate noted in #711 remains a follow-up). actionlint + shellcheck clean. ## Why the toolbox client was never regenerated: broken nx paths The regen target failed outright: `-i apps/daemon/pkg/toolbox/docs/swagger.json` resolves relative to the nx workspace root, which *is* `apps/` → `apps/apps/daemon/...` (spec not found). Kept from upstream daytona's repo layout; #716 fixed only the product clients' targets. Fixed here: - `libs/toolbox-api-client/project.json` — `-i daemon/pkg/toolbox/docs/swagger.json` - `libs/runner-api-client/project.json` — same latent bug (`-i runner/...` + its `{workspaceRoot}` input) - `nx.json` — `apiClient`/`goProduction` named inputs pointed at `{workspaceRoot}/apps/...` paths that don't exist, so swagger/go.work changes never invalidated task caches ## Functional config fixes - **`scripts/test/e2e/bootstrap.sh` + `apps/infra-local/configs/api.env`** wrote `ADMIN_MAX_{CPU,MEMORY,DISK}_PER_SANDBOX`, but the API reads `ADMIN_MAX_*_PER_BOX` (`apps/api/src/config/configuration.ts:292-294`) with default `0` — admin-org per-box quotas were silently unset. - **`apps/infra-local/scripts/stack-reset.sh` + README runbook snippets** ran `TRUNCATE TABLE sandbox, ...` / `SELECT ... FROM sandbox` — that table was renamed to `box` by migration `1781016743403`, so these failed as written. Also `/api/sandbox` → `/api/box` (route is `@Controller('box')`) and `{{sandboxId}}` → `{{boxId}}` (matches the `configuration.dto.ts` example). infra-local merged in #595 on a pre-#706 vocabulary. ## Vocabulary sweep (no behavior change) Comments, docstrings, and three e2e test function names (`test_*_above_per_sandbox_limit_*` → `per_box`; no `-k` selector, workflow, or Makefile references them) across `scripts/test/e2e/`, `scripts/deploy/runner-update-binary.sh`, and `apps/infra-local/`. File/path references verified against the tree (`box.service.ts`, `volume.manager.ts:47`, `box_sync.go`, `CREATE_BOX` journal tokens). All three trees now grep-clean for `sandbox`. Also includes 3 files prettier-normalized by the repo's `make lint:fix` pre-commit autofixer (`eslint.config.mjs`, `Sidebar.tsx`, `Onboarding.tsx`) — they were out of format on `main` and the repo-wide hook re-applies them on every commit until committed. ## Verification - Regen byte-identical across repeated runs, including the exact CI invocation - `actionlint` + `shellcheck` on the workflow; `shellcheck` on all 6 edited shell scripts (only pre-existing findings on untouched lines); `py_compile` on all 7 edited Python files - Every text replacement applied with an exact-unique-match assertion (count==1 before replace) - OS-isolation uses of "sandbox" (jailer/seatbelt/bwrap, docs/faq) deliberately untouched — different concept per the rename's scope Signed-off-by: dorianzheng <xingzhengde72@gmail.com>
…follow-up) (#726) ## What Regenerates the committed API clients against the post-#715 (merged A2 + MVP) API surface — the follow-up that #715's merge commit explicitly deferred: >⚠️ **CI will be red until generated clients are regenerated** against the merged API surface … **Generated clients now carry ZERO diff in this PR** (reset to main in `f9ea0730`) — regenerate upstream against the merged API surface. Since that merge, the **API client drift** check fails on every PR touching `apps/**` (e.g. #725's run 8 minutes after the merge). This PR turns it green again. ## Content **Commit 2 — the regen (`apps/libs/api-client`, `apps/api-client-go`, 231 files).** Pure `openapi-generator` 7.23.0 output, zero hand edits, produced with the exact `api-client-drift.yml` recipe (pinned generator via `openapitools.json`, NestJS spec boot with local Redis, GNU sed for the postprocess script). `analytics-api-client` and `toolbox-api-client` regenerated to **zero diff** (already current since #721/#723). Surface delta (mirrors the A2 + MVP API changes): - **removed:** snapshots / docker-registry / build / backup / archive-lifecycle / quota / usage-overview endpoints and models; `BoxState` build states (`pending_build`, `build_failed`, …); `write:snapshots` + `delete:snapshots` permission values; `listBoxesPaginated`'s `snapshots` filter param - **added:** `SystemRole`, `UpdateOrganizationName` (+ `PATCH /organizations/{organizationId}/name`), admin overview/observability models **Commit 1 — prek lint unblock (34 deleted lines, dashboard).** The Sandbox→Box rename left `LEGACY_*` route enum members byte-identical to the canonical ones — 4 pre-existing `@typescript-eslint/no-duplicate-enum-values` errors at HEAD that fail the repo's prek pre-commit hook (`make lint:fix`) for *every* local commit. The legacy routes are unreachable (identical paths, canonical registrations precede them), so this deletes them plus the orphaned `LegacyBoxRedirect`. No behavior change. Included here because nothing can be committed locally until it lands. ## Verification - `go build ./...` passes in `apps/api-client-go` (standalone), `apps/common-go`, `apps/otel-collector/exporter`. - The **API client drift** check on this PR is the canonical byte-for-byte proof. ## Known follow-up (intentionally split) Per review preference, this PR is generated code only. Three consumers still reference removed APIs and will not compile against the new clients until the prepared follow-up PR lands (branched on top of this one): - `apps/cli` — Dockerfile-build flow (`CreateBuildInfo`, `BOXSTATE_BUILD_FAILED`/`PENDING_BUILD`, `--dockerfile`/`--context`, MCP `buildInfo` arg, `pkg/minio`) - `apps/dashboard` — Registries page + registry hooks, usage-overview wiring in Spending/Limits, `templates` filter arg - `apps/libs/sdk-typescript` — `Box.buildInfo`/`backupState`/`backupCreatedAt`, `getBuildLogsUrl` No CI workflow compiles these consumers on PR today (the drift check is the only `apps/**` gate), so this PR is green-mergeable; the follow-up restores local builds. Note `apps/runner` has a **pre-existing** unrelated compile failure on main (`boxlite.WithPort` undefined in `pkg/boxlite`) — out of scope here.
Summary
Closes out the analytics-api-client item of #711 (Sandbox→Box Part 1 follow-ups).
#706 renamed the dashboard's analytics consumers to Box-named symbols (
ModelsBoxUsage,organizationOrganizationIdUsageBoxGet, …) but the committed client still only exported Sandbox-named ones — the dashboard could not typecheck against the in-repo client. The client also couldn't be regenerated from this repo at all: its generator input was an uncommittedtmp/swagger.jsonfrom the external analytics service (the reason #716 excluded it).Changes
apps/libs/analytics-api-client/swagger.json, reconstructed 1:1 from the previously committed client with only sandbox→box renamed (paths/organization/{organizationId}/box/{boxId}/…,models.BoxUsage,boxId,boxCount). This is now the spec any future analytics service must implement — same spec-first direction asopenapi/box.openapi.yaml.generate:api-clientat it (project.json), with nx cache inputs tracking the spec instead of the unrelatedapiClientnamed input.sandboxtokens remain.api-client-drift.yml— it now regenerates + diffs analytics like the other clients (actionlint clean).**/.nx/**— the generate target caches itssrc/output under the gitignoredapps/.nx/cache, and lint after a local regen tripped on the cached copy of generated code.Verification
'ModelsBoxUsage'… Did you mean 'ModelsSandboxUsage'?); against the new client → zero analytics-related errors (remaining 24 are pre-existing, unrelated: Playground/VNC files + unbuilt@boxlite-ai/sdkdist).--skip-nx-cache), so the drift gate won't false-positive.make lint:appsexit 0.Notes
ANALYTICS_API_URLis configured, no analytics service exists in the org today, and the API's own (already-renamed)box/:boxId/telemetry/*endpoints serve the dashboard otherwise (AnalyticsApiDisabledGuardmakes the two mutually exclusive).apps/dashboard/tsconfig.app.jsonpath mappings (\"@boxlite-ai/*\": [\"../../libs/*\"]) have pointed outside the workspace since the apps tree was flattened (refactor: replace Rust server with apps workspace #460), so rawtsc -pnever resolved any@boxlite-ai/*import. Worth its own follow-up.Part of #711.
Summary by CodeRabbit
New Features
Documentation
Chores