Skip to content

Reconcile the four dispatcher↔client shape mismatches (analytics ×2, storage ×2) — #3563 follow-up #3584

Description

@os-zhuang

Split from #3563. The route audit found four routes where a client method exists but speaks a different dialect than the dispatcher — ledgered as mismatch in packages/runtime/src/route-ledger.ts (the only non-sdk/non-deliberate dispositions left after PR-1…PR-5 drove the gap ratchet 27→0).

The four

Dispatcher servesClient callsLedger row
GET /analytics/meta (domains/analytics.ts:49)analytics.meta(cube)GET /analytics/meta/:cubeextra path segment only the REST server understands
POST /analytics/sql (analytics.ts:55)analytics.explain()POST /analytics/explaindifferent route name entirely
POST /storage/upload (domains/storage.ts:47)storage.upload() → presigned/chunked protocol (/upload/presigned, /upload/complete, /upload/chunked/*)client can't upload through a bare dispatcher
GET /storage/file/:id (storage.ts:56)storage.getDownloadUrl()GET /storage/files/:id/urlditto for download

Consequence: these client methods work only where @objectstack/rest fronts the dispatcher. Against a bare-dispatcher runtime they 404 — the method exists, the call fails, and nothing in types or tests says why.

The decision to make (API-shape call, needs an owner)

  • Option A — server-side aliases (compatible): the dispatcher additionally accepts the REST shapes (/analytics/meta/:cube, /analytics/explain, the presigned protocol). No client change, no breakage; the dispatcher grows a few routes whose ledger rows become sdk.
  • Option B — client aligns to the dispatcher (breaking): rename/reshape the four client methods. Clean long-term, but a breaking change for every SDK consumer and likely needs the REST server to serve the dispatcher shapes too.

Recommendation from the audit: A, with the REST shapes documented as canonical and the dispatcher aliases marked as such in the ledger.

Acceptance

  • A decision recorded (ADR note or PR description) on which side moves.
  • The four ledger rows reclassified from mismatch to sdk (or a documented deliberate disposition).
  • The conformance guard keeps passing throughout — mismatch rows already require notes, so the reclassification is mechanical once shapes agree.

Refs: audit doc docs/audits/2026-07-dispatcher-client-route-coverage.md §4; ledger rows at route-ledger.ts (analytics/storage sections).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions