feat(groups): a group becomes somewhere you can go
It was a heading over some rows: a name, a colour, and whether it was folded.
Enough to tidy a list, and not enough to be what people mean by it — "Arbejde" is
a body of work with context of its own, and documents that belong to all of it
rather than to any one project inside it.
`/gruppe/{id}` carries three things a heading cannot. The projects in it, each
with what is still open — open tasks, not all of them, because "12" beside a
project somebody finished last year is a number that means nothing. A description,
written in place and saved on blur, the same shape a task's description has. And
the files that govern the whole group: the contract, the drawing, the agreement
everything else rests on.
The name in the sidebar is a link to it and the chevron beside it still folds.
Two intentions, two targets — the single one they used to share could only ever
serve the smaller.
Migration 0012 rebuilds `attachments`, because its CHECK spelled out exactly which
parent columns may be set and SQLite cannot alter a CHECK. The rule is still
"exactly one parent", counted rather than written out as pairwise comparisons:
with three columns that is three clauses, with four it is six, and the version
that is wrong looks exactly like the one that is right.
A group's file is reachable by its owner and nobody else. A group belongs to one
person and is never shared, so `reachAttachment` asks about ownership rather than
a project role — both old callers resolved straight to a task, so a group's
attachment answered 404 for the person who uploaded it.
Three tests also stopped racing their own navigation. Creating a project navigates
and `goto` is a promise nobody was holding, so a quick add fired straight after
could land in the Inbox instead — intermittent, and it read as the quick add
having failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0b467beb3e
commit
804963b222
@@ -0,0 +1,53 @@
|
||||
-- A group becomes somewhere you can go, rather than only a heading.
|
||||
--
|
||||
-- Until now a project group was a label over some rows in the sidebar: a name, a
|
||||
-- colour, and whether it was folded. That is enough to tidy a list and not enough
|
||||
-- to be the thing people actually mean by it — "Arbejde" is a body of work with
|
||||
-- context of its own: what it is, and the documents that belong to all of it
|
||||
-- rather than to any one project inside it.
|
||||
--
|
||||
-- Two changes. A description on the group, and attachments that can hang on one.
|
||||
--
|
||||
-- The attachments table has to be rebuilt for the second, because its CHECK spells
|
||||
-- out exactly which parent columns may be set, and SQLite cannot alter a CHECK.
|
||||
-- Foreign keys go off for the length of it — see the marker below and the note in
|
||||
-- `applyMigration` — because dropping the old table with them on is a cascading
|
||||
-- delete of every attachment in the instance.
|
||||
--
|
||||
-- The rule stays "exactly one parent": an attachment belongs to a task, a comment
|
||||
-- or a group, never two. An attachment with two parents is one that gets deleted
|
||||
-- once and stays visible in the other place.
|
||||
--
|
||||
-- verdande:rebuild-tables
|
||||
|
||||
ALTER TABLE project_groups ADD COLUMN description TEXT NOT NULL DEFAULT '';
|
||||
|
||||
CREATE TABLE attachments_rebuilt (
|
||||
id TEXT PRIMARY KEY,
|
||||
task_id TEXT REFERENCES tasks (id) ON DELETE CASCADE,
|
||||
comment_id TEXT REFERENCES comments (id) ON DELETE CASCADE,
|
||||
group_id TEXT REFERENCES project_groups (id) ON DELETE CASCADE,
|
||||
filename TEXT NOT NULL,
|
||||
mime_type TEXT NOT NULL DEFAULT 'application/octet-stream',
|
||||
size INTEGER NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
uploaded_by TEXT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
created_at INTEGER NOT NULL,
|
||||
-- Exactly one parent, counted rather than spelled out as a chain of pairwise
|
||||
-- comparisons: with three columns that is three clauses, with four it is six,
|
||||
-- and the version that is wrong looks exactly like the version that is right.
|
||||
CHECK ((task_id IS NOT NULL) + (comment_id IS NOT NULL) + (group_id IS NOT NULL) = 1)
|
||||
);
|
||||
|
||||
INSERT INTO attachments_rebuilt
|
||||
(id, task_id, comment_id, filename, mime_type, size, path, uploaded_by, created_at)
|
||||
SELECT id, task_id, comment_id, filename, mime_type, size, path, uploaded_by, created_at
|
||||
FROM attachments;
|
||||
|
||||
DROP TABLE attachments;
|
||||
|
||||
ALTER TABLE attachments_rebuilt RENAME TO attachments;
|
||||
|
||||
CREATE INDEX idx_attachments_task ON attachments (task_id) WHERE task_id IS NOT NULL;
|
||||
CREATE INDEX idx_attachments_comment ON attachments (comment_id) WHERE comment_id IS NOT NULL;
|
||||
CREATE INDEX idx_attachments_group ON attachments (group_id) WHERE group_id IS NOT NULL;
|
||||
Reference in New Issue
Block a user