cast/src
claude-hdb bbca3cfff0 feat(service): set and diff per-container service hostnames via urls (#72)
Services could not carry hostnames through cast: `desiredFromManifest`
dropped a service's `domains` and warned they were a manual Coolify UI act,
citing a re-checked "no flat `domains` on a 4.1.2 service, on any route."
The audit (#72) disproved that — the same failure mode #51 corrected for
backup schedules. The FLAT shape genuinely has no route; the per-container
CAPABILITY was there at 4.1.2 all along.

`POST /services` and `PATCH /services/{uuid}` both take a `urls` list
([{name, url}], url comma-joined) that `applyServiceUrls` matches to a
`ServiceApplication` by name and stores as its `fqdn`; `GET /services/{uuid}`
loads `applications` and returns each `fqdn` (verified against
ServicesController v4.1.2). So services now speak the SAME per-container
vocabulary a dockercompose app does:

- **Manifest:** `service_domains: { <container>: [url] }` replaces the flat,
  unhonorable `domains` on a service (a flat list cannot name which container
  a hostname belongs to — exactly what `urls` requires). Canonicalized (keys
  and each URL array sorted) so container order never false-drifts.
- **Write:** `serviceApiFields` builds `urls` on create and update.
- **Read/diff:** a supplementary `GET /services/{uuid}` per service
  (`attachServiceDomains`, gated to `diff`/`apply` like backups) projects
  `applications[].fqdn` back into `service_domains`, so a declared hostname is
  compared every run — no perpetual drift, no manual UI step.
- **Pre-flight:** a service create's `service_domains` joins
  `desiredDomainsOfCreate`, the more important because a service create whose
  domain conflicts is DELETED server-side before the 409 (rollback).

Two limits stated out loud: the read is fail-closed (an unreachable/
unrecognized `GET /services/{uuid}` aborts rather than projecting empty and
re-PATCHing forever), and `inventory --emit-draft` does not yet make the
per-service GET, so a drafted service's hostnames are still declared by hand
(same as backups) — draft/semantics say so.

`npm run check` clean · 514 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:14:29 +00:00
..
apply.ts fix(apply): refuse to write the generated-secret placeholder over a live value 2026-07-14 22:56:27 +00:00
bindings.ts feat(destroy): a scoped teardown verb, gated in state (#43) 2026-07-14 22:52:17 +00:00
capture.ts Merge pull request #56 from claude-hdb/fix/reserved-env-names 2026-07-14 23:54:15 +01:00
cli.ts feat(service): set and diff per-container service hostnames via urls (#72) 2026-07-16 15:14:29 +00:00
config.ts feat: select the Coolify instance by name instead of editing .coolify.env (#14) 2026-07-13 16:42:45 +00:00
coolify.ts feat(service): set and diff per-container service hostnames via urls (#72) 2026-07-16 15:14:29 +00:00
destroy.ts feat(destroy): a scoped teardown verb, gated in state (#43) 2026-07-14 22:52:17 +00:00
diff.ts fix(diff): converge live projection on compose domains and is_static 2026-07-15 16:23:27 +00:00
draft.ts feat(service): set and diff per-container service hostnames via urls (#72) 2026-07-16 15:14:29 +00:00
envtemplate.ts feat(resolve): derive base-URL env vars from manifest domains via ${domain:...} (#66) 2026-07-15 12:02:33 +00:00
fleet.ts feat: --all — every project in an environment, and a report that says so (#26) 2026-07-13 20:23:23 +00:00
inventory.ts fix(inventory): biome lint — a bare template literal and a string concat 2026-07-13 19:22:07 +00:00
manifest.ts feat(service): set and diff per-container service hostnames via urls (#72) 2026-07-16 15:14:29 +00:00
reserved.ts fix: never write an env var whose name Coolify injects itself (#50) 2026-07-14 22:29:23 +00:00
resolve.ts feat(service): set and diff per-container service hostnames via urls (#72) 2026-07-16 15:14:29 +00:00
secrets.ts fix: hand the age identity to age on stdin — fd paths resolve only in cast's process 2026-07-13 22:43:00 +00:00
server.ts feat: cast — the Coolify executor, extracted from the infra state repo 2026-07-11 12:25:44 +00:00
smoke.ts fix: never write an env var whose name Coolify injects itself (#50) 2026-07-14 22:29:23 +00:00
team.ts feat: assert the token's team before touching Coolify (fail-closed) 2026-07-12 20:55:04 +00:00