fix(#571): a grant is not a link, and shared-with-me gets its own list #582

Merged
Cordy merged 4 commits from fix-571sv into main 2026-09-17 22:30:27 +00:00
Owner

Backend for the tabbed Shares view — and a latent defect that was already shipped.

The defect. FileStore.List(ctx, createdBy) filters on the creator and nothing else, so from the moment the first grant exists, GET /api/v1/shares returns grants mixed in with links. Every row then goes through toResp, which builds strings.TrimSuffix(base,"/") + "/s/" + s.Token. A grant has no token — so the existing Shares view would render a row with an empty path after /s/ and a Copy button handing over a URL that resolves to nothing.

Nobody would have seen this until someone made a grant and opened Shares. TestShareListDistinguishesGrantsFromLinks now pins it: a grant carries no url, and carries addressee, role and the id needed to revoke it.

toResp returns early for a grant rather than filling in link fields it does not have. token and url gained omitempty so a grant does not ship empty strings that look like a broken link.

GET /api/v1/shared answers "what has been shared with me": the grants addressed to the caller, directly or through any of their groups, via the share.GrantsFor fan-in that already deduplicates.

Each row carries vpath/shared/<owner>/<name> — so the view navigates to the real overlay path instead of rebuilding that string itself. It also carries addresseeKind and addressee, because a grant held through a group behaves differently from one addressed to you: leave the group and it goes. Saying so in the list is the honest answer to "where did that file go?" later.

The /shared overlay still resolves all of this as a real tree; this endpoint exists so the view asks once rather than once per owner.

Red witnessed on the runner before any of it existed.

Verified: three new API tests green, full Go suite green, go build ./... green, all ten web tests green.

Backend for the tabbed Shares view — and a latent defect that was already shipped. **The defect.** `FileStore.List(ctx, createdBy)` filters on the creator and nothing else, so from the moment the first grant exists, `GET /api/v1/shares` returns grants mixed in with links. Every row then goes through `toResp`, which builds `strings.TrimSuffix(base,"/") + "/s/" + s.Token`. A grant has **no token** — so the existing Shares view would render a row with an empty path after `/s/` and a Copy button handing over a URL that resolves to nothing. Nobody would have seen this until someone made a grant and opened Shares. `TestShareListDistinguishesGrantsFromLinks` now pins it: a grant carries no `url`, and carries `addressee`, `role` and the `id` needed to revoke it. `toResp` returns early for a grant rather than filling in link fields it does not have. `token` and `url` gained `omitempty` so a grant does not ship empty strings that look like a broken link. **`GET /api/v1/shared`** answers "what has been shared with me": the grants addressed to the caller, directly or through any of their groups, via the `share.GrantsFor` fan-in that already deduplicates. Each row carries `vpath` — `/shared/<owner>/<name>` — so the view navigates to the real overlay path instead of rebuilding that string itself. It also carries `addresseeKind` and `addressee`, because **a grant held through a group behaves differently from one addressed to you**: leave the group and it goes. Saying so in the list is the honest answer to "where did that file go?" later. The `/shared` overlay still resolves all of this as a real tree; this endpoint exists so the view asks once rather than once per owner. Red witnessed on the runner before any of it existed. Verified: three new API tests green, full Go suite green, `go build ./...` green, all ten web tests green.
Cordy merged commit c7431396ee into main 2026-09-17 22:30:27 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#582
No description provided.