Skip to content

How orgware Is Built

Doug Hatcher edited this page Jul 5, 2026 · 1 revision

How it's built

This page is for the curious and for operators. You don't need it to use waccamaw.org — but orgware is meant to be understandable, so here's the whole shape of it.

The idea

orgware runs entirely on Cloudflare's edge. There are no servers to patch, no virtual machines, no monthly hosting bill beyond usage. Each part of the platform is a Cloudflare Worker — a small program that runs at the edge, close to whoever's asking — backed by Cloudflare's databases (D1), file storage (R2), and key-value store (KV).

The result is a full member platform that costs a few dollars a month, scales automatically, and has no single box that can die.

The four services

Each service is independent — its own repo, its own deploy, its own database binding. One can break or be replaced without touching the others.

Service Domain Storage Role
members-service members.waccamaw.org + waccamaw.org/members/* D1 (roll), R2 (photos, corpus scans), KV (rate limit) Portal, library, API keys, roll book, cost console
contact-service contact.waccamaw.org D1 (contacts, access grants) Directory + public contact forms
meetings-service meetings.waccamaw.org R2 / content Meeting archive
corpus-mcp mcp.waccamaw.org D1 (shared with members-service) The record as an MCP endpoint for AI assistants

The tourist-facing waccamaw.org site itself is a separate Hugo site published through micro.blog. orgware only takes over at /members.

One origin, two doors

The member experience is served under waccamaw.org/members/* by an authenticated Worker — but the login page (/members) stays on the public site. So:

  • /members — public login, on the Hugo site.
  • /members/library, /members/usage, … — private, rendered by the Worker only after it verifies your session.

Nothing private is served until you're verified. The old members.waccamaw.org subdomain still answers too, for backward compatibility.

Access, in one place

Everything comes down to one function that turns a credential into a principalwho are you, and what ring are you in? It accepts any of three credentials, so the portal, the API, and the AI endpoint all share the exact same rules:

  1. your sign-in session cookie,
  2. a member API key (wcm_live_…), or
  3. a member JWT.

From that it resolves your ring (public / member / leadership) and every page and query enforces it the same way.

The record

The Tribal Record's source of truth is a private git repository (waccamaw/leadership) of governing documents and their primary-source scans. An idempotent ingest turns those into database records (with provenance and checksums) and uploads the scans to file storage. Because it's idempotent, the tribe can add or clear a record and re-run the ingest to push just the change — "index as it comes."

Backups — three layers

The tribe's data is protected in depth:

  1. Point-in-time — the database's own 30-day time-travel.
  2. Daily, encrypted — each service exports an encrypted dump to a private release every night.
  3. Off-site — a separate machine pulls those dumps and mirrors the record repo, then syncs everything to Backblaze B2. Failures now alert.

The most sensitive data (the roll) is encrypted at every hop; its key is held offline.

Operator notes

  • Cost console token: the live Cloudflare panel on /members/usage needs a read-only Account Analytics token set as CF_ANALYTICS_TOKEN on members-service (its co-requisite account id is already wired as a runtime var). Without the token, that one panel shows "not connected"; everything else works.
  • Deploys are release-triggered: cutting a GitHub release on a service repo runs its CI, applies migrations, and deploys the Worker.
  • corpus-mcp deploys manually (wrangler deploy) and needs its mcp.waccamaw.org route; it has no secrets (it authenticates against the shared key table).

That's the whole platform. Back to the index.

Clone this wiki locally