stash
This commit is contained in:
parent
c345372382
commit
395a9b156a
9 changed files with 1434 additions and 0 deletions
113
docs/design-in-progress/groups-mvp.md
Normal file
113
docs/design-in-progress/groups-mvp.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue