113 lines
6.8 KiB
Markdown
113 lines
6.8 KiB
Markdown
# Groups MVP (Design in Progress)
|
|
|
|
Status: not implemented. [groups.md](groups.md) works out the underlying model (what a group is,
|
|
how "acting as a group" is authenticated across federation). This document doesn't re-derive any
|
|
of that; it takes that design as given and asks a narrower question: what is the smallest set of
|
|
screens and actions that makes groups usable, reusing the UI patterns Toolshed already has for
|
|
friends and inventory rather than inventing new ones.
|
|
|
|
## Goals
|
|
|
|
- Ship something a user can actually click through: create a group, add/remove members, and have
|
|
the group own items, end to end.
|
|
- Reuse existing screens and interaction patterns wherever the shape already matches, instead of
|
|
designing new ones (see below).
|
|
- Leave every deferred piece as an explicit non-goal rather than a silent gap, so it's clear what
|
|
MVP does and doesn't cover.
|
|
|
|
## Non-goals (for now)
|
|
|
|
- **Group-to-group friending, and letting outside users friend a group.** groups.md's model
|
|
supports both, but the only audience for a group's items in MVP is the group's own members;
|
|
"private" already covers that (see "Availability policy for group items" below). Extending
|
|
visibility to non-members via the group's own friends list is real, valuable, and deferred as a
|
|
fast-follow, not designed here.
|
|
- **Transferring an existing personally-owned item's ownership to a group.** MVP only supports
|
|
creating a *new* item directly owned by a group. Moving an already-existing item across owners is
|
|
a separate piece of work (ownership transfer isn't something Toolshed supports for user-to-user
|
|
either today).
|
|
- **Deleting a group.** MVP has no explicit "delete this group" action. A group's lifecycle is just
|
|
"created, membership changes over time"; the orphaning guard (a group can't be left with zero
|
|
members, see groups.md's Known Gaps) means a group that's no longer wanted just sits unused rather
|
|
than needing a teardown flow.
|
|
- **Any governance, roles, or per-item permissions.** Same non-goal as groups.md: every member has
|
|
equal, full privileges over the group and everything it owns.
|
|
|
|
## User-facing features
|
|
|
|
### Creating a group
|
|
|
|
A new "Groups" section, entry point styled like Inventory's "Add" button. The form is just a name;
|
|
the handle (`#name@yourdomain`) is derived from it the same way a username becomes part of a user's
|
|
handle. The creator becomes the group's first member automatically — there's no empty-group state
|
|
to design for.
|
|
|
|
### My Groups list
|
|
|
|
A "Groups" nav entry/page, modeled directly on `Friends.vue`: a table of groups the current user is
|
|
a member of (name/handle, member count), each row linking into that group's detail page. No
|
|
separate "discover groups you're not in" browsing for MVP — you land in a group by being added to
|
|
it, the same way you become friends with someone by request/accept, not by browsing a directory of
|
|
all users.
|
|
|
|
Known limitation: this list only ever queries the member's own home backend, so it only shows
|
|
groups actually hosted there (groups you created, or joined on your own domain). Membership itself
|
|
works regardless of which backend hosts the group — a remote member can still be invited, accept,
|
|
and fully edit/delete the group's items (see "Owning items as a group" below) — but a group hosted
|
|
on someone else's backend won't show up in your own "My Groups" list, because unlike friendship
|
|
(which both sides record), group membership is only ever recorded on the group's own home backend,
|
|
and there's no index anywhere of "which other backends has this identity been added to." Making a
|
|
remote membership discoverable would need a small personal pointer index (written by the client at
|
|
join time) plus a handle-based group lookup on the group's own backend; deferred as a fast-follow
|
|
alongside group-friending.
|
|
|
|
### Group detail page
|
|
|
|
One page per group, with two sections, each reusing an existing pattern wholesale:
|
|
|
|
- **Members** — the add/remove-row pattern from `Friends.vue`'s friend list: an inline "add member"
|
|
field (enter a handle, `user@domain`), and a remove (trash icon) action per row. Any member can
|
|
add or remove any other member — flat privilege, no confirmation step beyond the orphaning guard
|
|
(removing the group's last member is blocked, with an error explaining why, rather than silently
|
|
emptying the group).
|
|
- **Group inventory** — the exact table/grid pattern from `Inventory.vue` (Name, Availability
|
|
Policy, Amount, Edit/Delete), scoped to items owned by this group, with the same "Add" button
|
|
leading into the existing item-creation form (see below).
|
|
|
|
A "Leave group" action removes the current user from Members; if they're the last member, it's
|
|
blocked by the same orphaning guard.
|
|
|
|
### Owning items as a group
|
|
|
|
The existing item create/edit form (`InventoryNew.vue` / `InventoryEdit.vue`) gets one new field:
|
|
an "Owner" selector, defaulting to "Myself," with the groups you belong to as the other options.
|
|
Every other field on that form (tags, properties, availability policy, storage location, quantity)
|
|
is unchanged, and a group-owned item behaves exactly like a personally-owned one everywhere else in
|
|
the app (edit, delete, detail view) — any member can edit or delete it, the same way the owner can
|
|
today.
|
|
|
|
### Where group-owned items show up
|
|
|
|
The main "Inventory" page stays scoped to items you personally own, unchanged from today. A group's
|
|
items are visible and managed in exactly one place: that group's detail page. This keeps "my
|
|
inventory" meaning one thing (what I personally own) and avoids merging two different item lists
|
|
with different edit semantics into one view for MVP.
|
|
|
|
### Availability policy for group items
|
|
|
|
The item form's existing Availability Policy field (private/share/lend/rent/sell) is unchanged and
|
|
applies to group-owned items the same way it does today. Since group-friending is out of scope for
|
|
MVP (see Non-goals), "share/lend/rent/sell" have no wider audience to expand to yet, only "private"
|
|
is fully meaningful right now — a private group item is visible to and editable by every group
|
|
member, which is already the core value the Problem statement in groups.md is after (a shared
|
|
workshop's members all having a say over shared equipment). The field stays as-is rather than being
|
|
trimmed down to just "private," so nothing needs to change on it once group-friending ships.
|
|
|
|
## Open scoping call
|
|
|
|
Deferring group-friending is the one judgment call in this document worth flagging explicitly:
|
|
it means an MVP group can't yet share an item with anyone outside its own membership, which is a
|
|
real limitation, not just a simplification. It was scoped out because it pulls in a second piece of
|
|
UI (a group's own Friends tab, and "who can accept a friend request on the group's behalf") that
|
|
isn't needed for the core "shared ownership among members" use case to work end to end. Worth
|
|
confirming this is the right line before building against it.
|