Blob: docs/operations.md
Operations
Required Configuration
Set these secrets before running a non-test Worker:
TESSERA_OIDC_CLIENT_IDTESSERA_OIDC_CLIENT_SECRETDAB_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 fromdrizzle/d1. - R2:
FILE_BLOBS. - Durable Objects:
AuthObject,FileDavObject,CalDavObject,CardDavObject. - Queues:
BLOB_GCandREPAIR_JOBS, each configured as both producer and consumer as shown inwrangler.jsonc. - Rate limits:
RL_AUTH,RL_DAV_AUTH, andRL_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-jobsAfter 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-doApply the control-plane D1 migrations locally or remotely with Wrangler:
npm run db:migrate:local
npm run db:migrate:remoteDeploy by applying remote control-plane migrations and publishing the Worker:
npm run deployDurable 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:caldavnpm run test:worker runs both worker test projects. During narrower iteration, use:
npm run test:worker-unit
npm run test:worker-runtimeAdditional CalDAV checks can be selected with:
DAB_CALDAV_TESTER_CHECKS=CheckSearch npm run test:caldav
DAB_CALDAV_TESTER_FULL=1 npm run test:caldavCurrent 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:litmusfor WebDAV file compatibility through the isolated local Worker harness.test:caldavfor 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.