@volter/twin-calcom
v0.1.37
Published
Local Cal.com twin — a faithful, stateful local Cal.com v2 API your scheduling integration talks to unmodified. Mirror, simulate, and fork. Built on @volter/world-core.
Readme
@volter/twin-calcom
The Cal.com twin — a local, stateful, vendor-faithful replica of the Cal.com
v2 API on the shared @volter/world-core kernel. An unmodified scheduling
integration (raw fetch/axios against api.cal.com/v2) talks to it and gets vendor-correct
responses; it is the QA stack's authoritative local Cal.com.
State lives in the kernel's append-only action/event log — a write appends an action that
projects into visible state; reads use the kernel’s tree. No real Cal.com is ever called (the only
network path is the connector, over an injected client). Auth is a faked-locally Bearer API
key (cal_…) — Cal.com's API auth is a plain bearer key, so there is NO JWT, NO JWKS, NO
webhook signing.
Usage
bun run src/cli.ts serve # the Cal.com v2 API twin (writable)
bun run src/cli.ts serve --read-only
bun run src/cli.ts mirror # the React dashboard mirror (bookings + event types)
bun run src/cli.ts conformance # offline spec check over projected stateResponses use Cal.com's v2 envelope: { "status": "success" | "error", "data": … } (errors carry
{ status: "error", error: { code, message } }).
Coverage
The capability manifest (src/calcom-capabilities.ts) is the real Cal.com v2 surface as the
denominator — coverage is honest and partial. Run bun scripts/manifest-baseline-one.ts calcom
for the live count. As of writing: done=54 / total=84 (regressions=0).
Modeled (proven done, each with a failable offline verify):
- Me —
GET /v2/me(the API-key owner profile, faithful shape). - Slots —
GET /v2/slots(availability keyed by date),POST/GET /v2/slots/reservations. - Bookings — create / get / list (+status filter) / cancel / reschedule / confirm / decline.
Stateful: a created booking is retrievable by
uid,canceltransitionsaccepted → cancelled, a double-cancel is a400, an unknownuidis a404,reschedulecancels the old and creates a new accepted booking,confirm/declineonly act on apendingbooking (else400). - Event types — create / get / list / update / delete CRUD (delete then
404). - Schedules — create / get / list / update / delete CRUD.
- Teams + memberships — team create/get/list, membership create/list.
- Webhooks — registration CRUD (create/list/update/delete). Registration only — no signing.
- Protocol —
{ status, data }success +{ status:"error", error }envelopes, unmodeled ops fail like the vendor (404), read-only rejects writes (405). - Connector — pull bookings + event types into the observed log (idempotent re-pull), push a pending local create to the real API and confirm it (over an injected executor; offline in tests).
- UI mirror — the Bookings and Event Types dashboard screens are data-coupled (seed via the twin → serve via the mirror server → render the dashboard's own component over the served rows → assert one row per seeded record).
Todo (real surface, not yet modeled): profile update, slot-reservation delete, instant/recurring/
seated bookings, mark-absent, recordings/references/reassign, public event-type lookup, team event
types, locations/booking-fields/seats/buffers config, availability overrides, membership/team
update+delete, per-event-type webhooks, cal-api-version behavior pinning, pagination, rate limits,
booking-detail / availability-editor / teams UI screens.
The twin records booking intent without sending: no confirmation or reminder email or SMS leaves the machine, no Zoom/Meet/Daily link is minted by an external provider, no Google/Outlook/CalDAV account is synced, and no Stripe charge is captured. Its bearer key is seeded locally rather than minted by Cal.com's platform OAuth.
Files
src/calcom-twin.ts— the v2 request handler (routes → kernel writes/reads).src/calcom-server.ts—createCalcomTwinServer({ root?, port?, readOnly? }).src/calcom-mirror-ui.ts+client/calcom-mirror.tsx— the React dashboard mirror.src/calcom-connector.ts— pull/push over an injected executor (liveCalcomExecutefor real I/O).src/calcom-conformance.ts— offline, failable spec check (dev-only; lazy-imported by the CLI).src/calcom-capabilities.ts— the capability manifest (the real vendor surface).
Rate budget — the fail-closed backstop on live calls
liveCalcomExecute is the one place this pack issues a live request, so every call it makes is charged
against a persistent, fail-closed spend ledger before the request goes out. Past the ceiling, or
while a Retry-After/429 cooldown is armed, it throws instead of calling. The ledger is keyed by
vendor and a hash of the credential (limits are per credential, so it is deliberately not
cwd-scoped) and persists across processes, so a fresh process does not get a fresh allowance; a
corrupt ledger counts as a full window rather than zero spend. There is no option to disable it,
and no value you can pass for budget that yields an unguarded client — an injected budget is
validated by method identity, so a subclass or a Proxy that replaces checkBudget is refused.
The declared numbers: 60 weighted units / 60s — half Cal.com's documented 120 requests/minute per API key. POST /bookings costs 3 (it sends e-mail, writes real connected calendars and fires webhooks — a human blast radius, not just a throttle) and GET /slots costs 2 (availability computed across every connected calendar); both judgement calls.
The mechanism is shared and vendor-agnostic — it lives in the kernel (@volter/world-core →
packages/world-core/src/rateBudget.ts); what lives here in src/calcom-budget.ts is this vendor's
declaration (window, ceiling, per-endpoint weights, and a reason citing the limits above) plus
the vendor-bound CalcomBudget. The rule is ratified as
../../../docs/contributing/architecture.md D8, and the kernel module's header documents what the
guard does not guarantee — read that before trusting it.
