01Sidebar · today → with Groups 02Share dialog · today → with Groups 03Note rendering · today → with attribution 04NavGroups · interaction states 05Group settings page 06Hashtag autocomplete · real dropdown 07Phone · Sheet sidebar 08Visual diff · what actually changed
01 Sidebar · today (faithful) → with Groups added Real shadcn primitive · 16rem wide · real labels · real icons
Today
(note stream)
With Groups
(IdeaFlow Team stream)
Δ from today: one new NavGroups section above Pinned (same Collapsible pattern as NavFolders / NavHashtags). Existing Globe-icon indicator on hashtag rows changes to the owning group's icon if the tag has defaultGroupId; tags without a group keep the Globe (when shared) or nothing (when private). Nav-main, Folders, Pinned, Mentions sections unchanged.
02 Share dialog · today → with Groups picker Real dialog title "Share this document" · Avatar rows · Select role · Switch for List publicly
Today
Share this document
Only people with access can open this document.
S
Sarah Kim
D
David Liu
With Groups
Share this document
Only people with access can open this document.
IF
IdeaFlow Team
S
Sarah Kim
Inherited
D
David Liu
Inherited
Δ: input placeholder changes from "Add people by email..." to "Add people or groups..." — typing a name fuzzy-matches both. New "Groups with access" section above the People section. People who gain access transitively via a group show with an "Inherited" tag in place of the Select; X is muted (can't remove without changing the group). Everything else is unchanged.
03 Note rendering · today → with group attribution Real: purple hashtags · flat rows with border-t · bg-blue-50/65 tint when shared
Today
JJacob ColeYOU 2 hours ago

Sprint review moved to Thursday — board prep conflict.

JJacob ColeYOU 2 hours ago

Lattice intro call. They build the same hashtag capture as us, but scoped to HR. #competitor for sure — they pitched at SHRM. Could also be #customer for OEM-ing the editor.

SSarah Kim yesterday

Pushed sprint review to Thursday. Pinged @jacob + @david to confirm. #design

With Groups
JJacob ColeYOU 2 hours ago

Sprint review moved to Thursday — board prep conflict.

JJacob ColeYOU 2 hours ago

Lattice intro call. They build the same hashtag capture as us, but scoped to HR. IF#competitor for sure — they pitched at SHRM. Could also be IF#customer for OEM-ing the editor.

IFIdeaFlow Team · via #competitor, #customer
SSarah Kim yesterday

Pushed sprint review to Thursday. Pinged @jacob + @david to confirm. IF#design

IFIdeaFlow Team · via #design
Δ: hashtags stay purple (real --mention-text). For team-owned hashtags, a 10×10px group glyph is prepended via inline-flex — no color change to the tag itself. Tint stays exactly as commit bb2747a shipped it (bg-blue-50/65). New note-foot row appears ONLY on tinted notes, showing which groups and which hashtags drive the share. Untinted notes (private) look identical to today.
04 NavGroups · interaction states (closed, expanded, action menu, empty) Same Collapsible + SidebarGroup pattern as NavFolders / NavPinnedNotes
Section closed
Groups
Section open + groups collapsed
Groups
214
8
12
Hover · action menu visible
Groups
214
Empty
Groups

Create a group to share streams of notes with people

05 Group settings · uses real Notestream shadcn primitives Inputs, Labels, Selects, Switch, Avatar — all matching what's in note-share-dialog.tsx + nav-folders.tsx
IF
IdeaFlow Team
8 members · 44 hashtags · 214 notes shared
Identity
How this group appears to members.
Members
8 people · 1 owner, 5 editors, 2 viewers
J
Jacob Cole
S
Sarah Kim
D
David Liu
K
Kim Mendez
Invited
Hashtags owned by this group
Tags with defaultGroupId set to this group. Notes you write with these auto-share to IdeaFlow Team.
IF #competitor IF #customer IF #design + 41 more · manage
Danger zone
Leave group
You'll lose access to group-shared notes you didn't author.
Delete group
All members lose access. Notes revert to private.
06 Hashtag autocomplete · matching the real HashtagDropdownList Plain shadcn-popover style · light + dark
Just talked to Acme — their existing tool burned them. #comp
Reading list for next month — #book
Δ: dropdown item adds a 14×14 group glyph between name and count, ONLY if the tag has defaultGroupId. Tag name itself stays purple (real --mention-text). Private tags (no group) get a grey Hash icon instead of purple — visual signal that they're not shared anywhere.
07 Phone · Sheet sidebar (real Notestream mobile pattern) Sidebar component renders as Sheet on mobile (sidebar.tsx:207). Width 18rem.
9:41📶 🔋
(stream view)
Notestream
Groups
214
8
12
9:41📶 🔋
IF IdeaFlow Team
Jyou 2h

Lattice intro. IF#competitor — could OEM editor.

via #competitor
SSarah yday

Sprint review → Thursday. @jacob confirm. IF#design

via #design
08 Visual diff · what actually changed in the existing components For each component: today's behavior → with Groups
File / component Today With Groups Δ size
app-sidebar.tsx 5 sections in <SidebarContent> (NavAuthorPublicHashtags, NavPinnedNotes, NavFolders, NavHashtags, NavMentions, NavReferencedNotes) +1 import, +1 line: <NavGroups /> first child of SidebarContent 2 lines
nav-groups.tsx (new) New component, copies NavFolders pattern: Collapsible + SidebarGroup + sticky label + chevron + plus action + SidebarMenu of GroupRow children ~180 lines
nav-hashtags.tsx · row Hash icon + name + (Globe if shared) + count badge + action menu Hash icon + name + (group-glyph if defaultGroupId set, else Globe if shared, else nothing) + count + menu (+ "Add to group" item) ~12 lines
note-share-dialog.tsx Input "Add people by email" → user-search dropdown → "People with access" list Input "Add people or groups" → unified search (users + groups) → new "Groups with access" section above People → People shows "Inherited" tag for transitive-via-group ~80 lines
HashtagMark.ts · render renderHTML returns <span class="hashtag"> Add optional data-group-id attr; CSS handles glyph injection. ProseMirror renderer extension already supports decorating marks with extra attrs. ~10 lines
tiptap.css · .hashtag .hashtag { color: var(--mention-text); } Add .hashtag[data-group-id]::before rendering a small group icon via background-image (or inline-flex wrapper if we accept HashtagMark refactor) ~15 lines
notes.tsx · tint check note.isShared || hashtagStore.noteHasSharedHashtag(id) Add: || noteSharingStore.isInAnyGroup(id). Plus render the new note-foot row showing groups + reasons. ~30 lines
schema.prisma enum PrincipalType { EMAIL ANONYMOUS } Add GROUP to enum. New Group + GroupMember models. Add SharedHashtag.defaultGroupId String?. ~45 lines
note-sharing-service.ts Validates EMAIL + ANONYMOUS principal types Add GROUP branch with comment explaining why this principalType is safe to add (group IDs are server-issued, no race) ~25 lines
search-service.ts · getVisibilityWhere Branches on caller's email for direct + hashtag grants Add 3rd branch: caller's GroupMember rows → NoteSharing(GROUP, group_id) matches ~40 lines
routes.ts Sharing routes mounted Mount new /groups + /groups/:id/members + /groups/:id/notes routes ~12 lines
Total new + modified 5 new files, ~450 lines added, 12 existing files touched
File: mockups/groups-v4.html · grounded in the actual app code · v1–v3 untouched.