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:
Kristian Wind
2026-08-18 09:20:03 +02:00
co-authored by Claude Opus 5
parent 0b467beb3e
commit 804963b222
12 changed files with 1047 additions and 82 deletions
+2
View File
@@ -344,8 +344,10 @@ func New(cfg *config.Config, db *store.DB, log *slog.Logger, web fs.FS) *Server
r.Post("/", s.handleCreateProjectGroup)
// Above /{groupID}, or chi reads "reorder" as an id.
r.Post("/reorder", s.handleReorderProjectGroups)
r.Get("/{groupID}", s.handleGetProjectGroup)
r.Patch("/{groupID}", s.handleUpdateProjectGroup)
r.Delete("/{groupID}", s.handleDeleteProjectGroup)
r.Post("/{groupID}/attachments", s.handleUploadGroupAttachment)
})
// The trash is outside the block above: a deleted project is invisible