Skip to content
File

Blob: docs/operations.md

Markdown130 lines

Operations

Required Configuration

Set these secrets before running a non-test Worker:

  • TESSERA_OIDC_CLIENT_ID
  • TESSERA_OIDC_CLIENT_SECRET
  • DAB_SESSION_SECRET

Local harnesses write throwaway .dev.vars files with deterministic test-only values. Production and shared staging environments must use real secrets.

Cloudflare Resources

Create and bind these resources in wrangler.jsonc:

  • D1: DAV_CONTROL_PLANE, with migrations from drizzle/d1.
  • R2: FILE_BLOBS.
  • Durable Objects: AuthObject, FileDavObject, CalDavObject, CardDavObject.
  • Queues: BLOB_GC and REPAIR_JOBS, each configured as both producer and consumer as shown in wrangler.jsonc.
  • Rate limits: RL_AUTH, RL_DAV_AUTH, and RL_REPORT.

The Rate Limit binding namespace_id is a project-defined string containing a positive integer. Keep each value unique within the Cloudflare account; two bindings with the same namespace_id intentionally share counters.

Wrangler can create the D1 database, R2 bucket, and queues:

wrangler d1 create dab-control-plane
wrangler r2 bucket create dab-file-blobs
wrangler queues create dab-blob-gc
wrangler queues create dab-repair-jobs

After creation, copy the returned D1 database_id into wrangler.jsonc.

Migrations

Generate migrations with the narrow command for the store being changed:

npm run db:generate:d1
npm run db:generate:auth-do
npm run db:generate:file-dav-do
npm run db:generate:cal-dav-do
npm run db:generate:card-dav-do

Apply the control-plane D1 migrations locally or remotely with Wrangler:

npm run db:migrate:local
npm run db:migrate:remote

Deploy by applying remote control-plane migrations and publishing the Worker:

npm run deploy

Durable Object SQLite migrations are loaded by the Worker object constructors.

Storage Repair

REPAIR_JOBS messages are idempotent. A repair job initializes the file, calendar, and address book Durable Objects for the subject storage, aborts expired pending file uploads, deletes expired file locks, and enqueues BLOB_GC messages for stale pending upload blobs.

Repair message shape:

{
  "type": "storage_repair",
  "subject_id": "tessera-subject-id",
  "storage_id": "stg_0123456789abcdef0123456789abcdef",
  "reason": "operator",
  "created_at_ms": 1780000000000
}

BLOB_GC message shape:

{
  "type": "r2_blob_gc",
  "subject_id": "tessera-subject-id",
  "storage_id": "stg_0123456789abcdef0123456789abcdef",
  "blob_id": "blob_0123456789abcdef0123456789abcdef",
  "blob_key": "files/stg_0123456789abcdef0123456789abcdef/blob_0123456789abcdef0123456789abcdef",
  "not_before_ms": 1780000000000
}

The consumer retries future-dated BLOB_GC messages until not_before_ms. If the File DAV object cannot verify a blob, the queue handler retries instead of acknowledging the message.

Validation

Run these before shipping changes:

npm run typecheck
npm run test:worker
npm run test:litmus
npm run test:caldav

npm run test:worker runs both worker test projects. During narrower iteration, use:

npm run test:worker-unit
npm run test:worker-runtime

Additional CalDAV checks can be selected with:

DAB_CALDAV_TESTER_CHECKS=CheckSearch npm run test:caldav
DAB_CALDAV_TESTER_FULL=1 npm run test:caldav

Current automated coverage includes:

  • Worker unit tests for pure auth, routing, DAV runtime, If-header, iCalendar, and XML/parser behavior.
  • Worker runtime tests for queue retry behavior, stale pending upload cleanup, expired lock cleanup, repair no-ops, OpenAPI JSON/YAML equivalence, XML body limits, Depth infinity limits, REPORT result limits, recurrence limits, and CardDAV text-match limits.
  • test:litmus for WebDAV file compatibility through the isolated local Worker harness.
  • test:caldav for the default caldav-server-tester acceptance gate plus the local calendar-collection creation probe.

Manual compatibility coverage still needed:

  • CalDAV desktop/mobile client manual run.
  • CardDAV desktop/mobile client manual run.