Backup schedules are write-only on a premise that is false — GET /databases/{uuid}/backups exists, so a rebuilt database silently has no backups #51
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#51
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The claim, and why it is worth re-testing
docs/semantics.md:606files this under "Known limitations, not defects":The parenthesis is the load-bearing part, and it is not true as stated. It is true that a backup schedule is not on the database's own
GET— but the vendoredreference/coolify-openapi-4.1.2.jsoncarries a dedicated route for exactly this:cast already POSTs to that path to create the schedule. It has simply never GET'd it. "Coolify doesn't expose it back" appears to mean "it isn't on the resource I happened to read."
(The spec documents the GET's response body as "Content is very complex. Will be implemented later." — so the shape needs a live probe before implementing, the same way #46 needed one. That is a reason to probe, not a reason to conclude it cannot be read.)
What the limitation costs today
Backups are the only thing standing between a database and unrecoverable loss, and they are the one field of a database that cast writes and then never looks at again. Concretely:
backup:block was declared never gets one.applysets the schedule only inside the create branch (cli.ts:2073-2086). Addbackup:to a manifest for an existing Postgres, runapply, get a clean run and zero backups. Nothing says so.diffcannot see it, so the drift is not drift — it is nothing.--fulldiff that gates a production cutover passes with an unbacked-up production database. This is not hypothetical; the prod box's inventory row currently carries "⚠️ unverifiable by any tool, still owed: the postgres backup schedule (dropped fromdiff)" as a standing manual debt (heavy-duty/incubator#10).semantics.md:541states the consequence plainly and then accepts it: "backup schedules (not exposed on a database's GET — a rebuild has no backups until you declare them)" — in the section about disaster recovery.The DR argument is the one that settles it: the state of the world after a "rebuild from state" is a database with no backup schedule, and the tool reports that state as clean.
Suggested
GET /api/v1/databases/{uuid}/backups).frequency+retentionlike any other field — the spurious-drift fear insemantics.mdis exactly what a real read makes go away.applyset it on update, not only on create —PATCH /databases/{uuid}/backups/{uuid}exists. Declaringbackup:on an existing database should start backing it up, which is what every reader of that manifest already assumes it does.resolve.ts:389): say so on every run, out loud, rather than dropping the field silently. A declaredbackup:that cast cannot verify should printbackup schedule declared, NOT compared — verify in the Coolify UI, on the same principle as the placement line added in #41: the assumption goes on screen at the moment it is being made.semantics.md— the "not exposed" claim is what stopped anyone looking.Related