Skip to content

Document referential integrity and the delete behavior changes - #150

Merged
mastacontrola merged 1 commit into
masterfrom
document-referential-integrity
Aug 29, 2026
Merged

Document referential integrity and the delete behavior changes#150
mastacontrola merged 1 commit into
masterfrom
document-referential-integrity

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

Documents the user-visible half of fogproject ADR 0031 (FOGProject/fogproject#1469
and FOGProject/fog-plugins#29, both merged): FOG 1.6 declares its
relationships in the database, so deletes now behave consistently no matter
what performed them.

What is here

  • New: docs/kb/reference/referential-integrity.md — the full set of
    rules, what each delete now does, what a refused delete looks like and how
    to read it, and what the upgrade does to existing data.
  • management/web/storage-node.md — a "Moving and deleting nodes"
    section, because this is where the two behavior changes an admin will
    actually trip over live.
  • management/web/images.md — a short note that deleting an image
    definition unassigns the hosts that had it.

The three an admin will notice

  • Deleting a storage group is now refused while nodes still belong to it,
    a location names it, or file deletions are queued against it. This is the
    one worth documenting loudly: before 1.6 it was allowed and silently
    orphaned. On one real installation, deleting a single storage group left
    three storage nodes belonging to nothing.
  • There is no "remove node from group" any more. A node must belong to a
    group; a group with no nodes is fine. Moving a node means assigning it to
    the group you want it in, which moves it in one step.
  • Deleting an image unassigns its hosts rather than leaving them naming
    an image that is gone.

Two choices worth flagging for review

It documents the raw error text. FOG surfaces the database's own message
on a refused delete — we do not translate it. The page prints a real example
and explains how to read it, because the constraint name is
fk_<table>_<column> and therefore already says what is holding the record.
Writing a friendlier message we do not actually emit would be worse than
ugly, it would be wrong. (A friendlier one is worth doing in fogproject; it
is a change to a shared base class and belongs in its own change.)

It states that the upgrade can skip a rule without failing. That is
deliberate rather than a caveat buried in a note: ADD CONSTRAINT validates
existing rows, so a server holding data this release did not anticipate would
otherwise abort the upgrade and strand itself on ?node=schema over data
that is otherwise intact. Instead the rule is skipped, the reason is logged,
and FOG keeps 1.5 behavior for that one relationship. The case that occurs in
practice is a storage node sitting in no group, which nothing can guess a
group for.

Verified

npm run docs:build — 115 files, no errors. Beyond that, the failures this
repo's own conventions warn about are silent, so each was checked directly:

  • zero unparsed [[ in all three pages
  • both cross-links resolve to real hrefs (path-qualified, each on one line)
  • the new page is in the content index, so it appears in nav and search
  • its context_id redirect stub was emitted
  • context_id is unique site-wide, and every tag used already exists

🤖 Generated with Claude Code

https://claude.ai/code/session_019Q7gwbNYDmYVFRBrXDXFz5

FOG 1.6 declares its relationships in the database (fogproject ADR 0031).
Before, cleaning up after a delete was the job of whatever PHP ran the
delete, so every delete path had to remember every dependent table and the
ones that forgot left rows pointing at something gone. Nothing told an admin
that; they found out when one of those rows did something visible.

Three of the changes are ones an admin will actually hit, so they get a
reference page plus a note where they will be standing when they hit them:

- Deleting a storage group is now REFUSED while nodes still belong to it, a
  location names it, or file deletions are queued against it. This is the one
  worth documenting loudly -- before 1.6 it was allowed and silently
  orphaned. On one real installation, deleting a single storage group left
  three storage nodes belonging to nothing.
- There is no "remove node from group" any more. A node must belong to a
  group; a group with no nodes is fine. Moving a node means assigning it to
  the group you want it in.
- Deleting an image unassigns the hosts that had it, rather than leaving them
  naming an image that is gone.

The page states what a refused delete LOOKS like, and how to read it. FOG
surfaces the database's own message, and the constraint in it is named
fk_<table>_<column> -- so the message already says what is holding the
record, if you know to read it that way. Documenting the real text rather
than a friendlier one we do not emit.

Also covers what the upgrade does: it cleans up orphaned rows once, before it
can declare any rule, and records what it removed in the audit log with a
per-table count under `schema.orphan.sweep`. And that a rule which cannot be
applied does not fail the upgrade -- it is skipped, logged, and FOG keeps 1.5
behavior for that one relationship until the data is fixed. The case that
occurs in practice is a storage node in no group, which nothing can guess a
group for.

Two cross-links added, both path-qualified and on one line so they parse.
Verified by building the site: 115 files, no errors, zero unparsed `[[` in
the three pages, both links resolving to real hrefs, and the new page present
in the content index and its context_id redirect stub emitted.
@mastacontrola
mastacontrola merged commit 27b9385 into master Aug 29, 2026
@mastacontrola
mastacontrola deleted the document-referential-integrity branch August 29, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant