Health New Zealand | Te Whatu Ora
Radiology Tools Architecture and handover

Delivery and governance

Operations, cost and handover

What it costs to run, who holds each piece today, and the steps that move each piece to Health NZ so that no single person is needed to keep it going.

Running cost

US$10per month, Cloudflare, steady state
US$191total Cloudflare invoices, Nov 2025 to Sep 2026
US$0for servers, databases, certificates, DDoS protection
ItemCostNotes
Cloudflare Workers PaidUS$5 / monthCovers Workers, Pages Functions, D1, KV, Vectorize and Workers AI within included allowances. Usage here is well inside them.
Cloudflare Images bundleUS$5 / monthProfile photos and announcement images.
Cloudflare R2Pay as you goStorage here is a few megabytes, inside the free allowance.
Zones hnzradtools.nz, hnzradiology.nzFree planDNS, TLS, DDoS protection and caching included.
Anthropic APIUsage basedTriage reranking and Site Profiles' Scout. Planned to move to Health NZ's contained AI endpoints.
ResendUsage basedTriage password-reset mail only. Retired when Triage's own sign-in is removed.
GitHubCurrent personal planMoves to Health NZ's organisation plan on transfer.
Domain registrationsAnnualTwo .nz domains.

Cloudflare figures are from the account's subscriptions and invoice history, 25 September 2026. The invoice total includes a few usage-based charges, and the account also hosts unrelated projects (below), so not all of it is attributable to these tools.

Who holds what today

AssetTodayTarget under Health NZ
Source codePrivate repository on one personal GitHub account; one collaborator.Health NZ GitHub organisation, with team-based access.
Cloudflare accountSix members, two with Super Administrator. Two-factor sign-in is not enforced at account level.Owned by Health NZ, at least two named administrators, two-factor enforced, members managed through Health NZ identities.
Deploy credentialOne account API token, stored as a GitHub repository secret, used for preview and production.Two least-privilege tokens: preview in the repository, production in a protected GitHub environment.
Runtime secretsSet by hand from one workstation's git-ignored .env. The list of names exists only in configuration comments.Values in a Health NZ vault; a secrets register (name, component, environment, owner, last rotated) in the repository.
API hostnamesService Sizing and Triage APIs use the developer's personal workers.dev subdomain.Custom domains under hnzradtools.nz (R8).
Third-party keysAnthropic and Resend accounts held personally.Health NZ AI endpoints; Resend retired.
KnowledgeThis pack, DEPLOYMENT.md, the cutover run sheet, the access model, and per-app guides (some out of date, R24).This pack maintained in the repository, and reviewed at each release.

The Cloudflare account also hosts other projects

Besides the components in this pack, the account holds the other radiology tools outside this pack's scope (radiology-cleaner, radiology-ai, resource-links, strategic-outsourcing, MRI protocols and some prototypes), several projects unrelated to Health NZ, and a third domain.

There are two ways to separate them:

Option A: a new Health NZ account recommended

Health NZ creates an account it owns from day one. The in-scope components are recreated there by the existing GitHub Actions workflows (a change of account ID and token), the D1 databases are exported and imported unchanged (encrypted data moves as-is because the keys move with it), and the two zones are moved. It is also a full rehearsal of disaster recovery.

Option B: transfer this account

Move the unrelated projects out, then make Health NZ the owner of the existing account. Less migration work, but Health NZ inherits the account's history, members and any residual resources.

Either way, do the API custom domains (R8) first, so that frontends stop depending on the personal workers.dev subdomain, which would otherwise change during a move.

Handover checklist

Stage 0: before sharing more widely

  • Close the two urgent items in the risk register: the launch-page deploy that publishes the whole repository (R1) and the unauthenticated email worker (R2).
  • Remove historical referral extracts from the repository and its history (R5).

Stage 1: ownership

  • Transfer the repository to a Health NZ organisation. Protect develop and the production branches.
  • Decide Option A or B for the Cloudflare account; enforce two-factor sign-in; name at least two Health NZ administrators.
  • Move secret values into a Health NZ vault, and commit a secrets register.
  • Create a production GitHub environment with required reviewers and a production-only Cloudflare token.

Stage 2: hardening

  • Work through the high and medium items in the risk register, starting with the ones marked quick.
  • Route AI calls through Health NZ's contained endpoints.
  • Turn on logs for every Worker and set up basic alerting.

Stage 3: Entra ID

  • Add Entra sign-in to the identity hub (see where it plugs in), then move the member portal onto the hub.

Day-to-day operation

TaskHow
Release an appActions tab, promote-to-prod.yml, choose the app. See release flow.
Grant or remove accessHub admin screen. See the admin screen.
Change a database schemaAdd a numbered migration; run the drift check first. See migrations.
Rotate a secretReplace it in Cloudflare for each affected component and environment. Encryption and blind-index keys cannot be rotated without re-encrypting or re-hashing the data; there is no tooling for that yet (R23).
Restore dataD1 Time Travel restores a database to any minute in the last 30 days. Not yet documented as a procedure (R15).
Investigate a problemWorkers Logs for the hub and email worker; Cloudflare analytics for traffic. Other components have no logs enabled yet (R22).

Getting a developer started

  1. Access to the repository, and a Cloudflare account membership scoped to Workers and D1 read.
  2. Node 24 and npm. Run npm install at the root to install the workspaces; the nested projects under Triage, Service Sizing's frontend and the email worker install separately.
  3. Read the root CLAUDE.md, DEPLOYMENT.md and this pack.
  4. Work on develop (or a branch with a pull request, once protection is on). Every push deploys to preview.
  5. Never deploy from a laptop, and never copy data from production to preview.