feat(project): give issues a parent link and depth so they can form a tree - #10
Merged
Conversation
… tree A task too big for one run has to be decomposed into sub-issues, and Issue carried nothing to express that: no parent, no depth. Add both, so the ledger can hold a ticket tree. Depth is DERIVED from the parent inside addIssue(), never passed in. That is what makes a depth cap enforceable later: a caller cannot understate how deep a decomposition already went, and hanging a sub-issue off an id that does not exist fails on the parent lookup rather than silently creating an orphan. settleAncestors() carries the completion rule — a parent is Done only when every child is. It walks up and stops at the first ancestor still holding open work. An ancestor a human already Closed is left alone: a finishing child must not reopen someone else's decision. Existing project dbs are migrated in place. CREATE TABLE IF NOT EXISTS is a no-op on a table that already exists, so a db registered before these columns would never gain them and every read of parent_id/depth would fail; SQLite has no ADD COLUMN IF NOT EXISTS, so the live columns are read first and only the missing ones are added. Covered by a test that rebuilds the pre-tree table and reopens the store, and verified against a real registered project.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groundwork for
Decompose: a task too big for one run is split into sub-issues, andIssuecarried nothing to express that — no parent, no depth.What changes
issuesgainsparent_idanddepth;Issuegains the matching fields.addIssue($title, $description, $parent)opens a sub-issue. Depth is derived from the parent, never passed in — that is what makes a depth cap enforceable later: a caller cannot understate how deep a decomposition already went. The parent is loaded rather than trusted, so hanging a sub-issue off a non-existent id fails instead of silently creating an orphan.childIssues()— the direct children, soft-deleted ones hidden (a deleted sub-issue must not hold its parent open forever).settleAncestors()— the completion rule: a parent is Done only when every child is. Walks up, stops at the first ancestor still holding open work, and leaves an ancestor a human already Closed alone.Migration
CREATE TABLE IF NOT EXISTSis a no-op on an existing table, so a db registered before these columns would never gain them and every read would fail. SQLite has noADD COLUMN IF NOT EXISTS, so the live columns are read viaPRAGMA table_infoand only the missing ones are added.Covered by a test that rebuilds the pre-tree table with a row in it and reopens the store, and verified by hand against a real registered project (existing issues read as roots, new sub-issues get depth 1).
Tests
5 added, 219 passing. PHPStan level 8 clean, php-cs-fixer clean.