Objective
- Give users control over shared dashboard views so they are not automatically added to saved views (or equivalent shared boards) they did not ask for, with no way to decline or leave.
- Deliver one of two acceptable outcomes from the June 16 implementation call:
- Invite / acceptance — a shared view does not appear on someone's dashboard until they accept, or
- Self-remove — a clean way for a recipient to remove themselves from a shared view after being added.
- Apply the chosen membership model wherever admin saved views with sharing exist today and where new revenue-dashboard saved views ship (ATT-1939).
Background
- On the June 16 implementation call, users reported being added to boards or views they do not want on their dashboard and having no way to decline in advance or cleanly opt out afterward.
- Client Care Dashboard saved views (ATT-1214 Done) are the primary shipped example:
- Schema:
ccDashboardViewSchema.ts — visibleToUserIds array lists users who can see a view.
- API:
ccDashboardSavedViews.ts — canSeeView() returns true for creator or anyone in visibleToUserIds; GET / lists all views the user can see immediately.
- UI:
SaveViewModal.tsx and ViewSharePopover.tsx let the owner add users to visibleToUserIds; shared users see the view on the view picker landing (ClientCareViewsClient.tsx) as soon as they are added — no pending/accepted state.
- Delete is owner-only (
DELETE /:id — "Only the creator can delete"); shared users have no leave / hide action.
- Revenue dashboards (Launchpad Revenue, Post-Inspection Revenue) do not have saved views yet (ATT-1939 Backlog); when sharing ships there, the same auto-add pattern would apply unless this issue changes the membership model first or in parallel.
- Custom worklists use a separate
members array on worklistSchema.ts — when set, only listed users see the worklist in WorklistMenu.tsx (inverse: assignment restricts visibility rather than sharing a dashboard view). June 16 language included "boards"; confirm whether worklist member assignment is in scope or only admin saved views.
- No attachments, linked documents, or inline media on this ticket.
Product Decisions
Locked
- Problem — Users should not be forced onto shared views with no decline or exit path when someone else shares a dashboard view with them.
- Acceptable solutions (either/or from June 16 call) — Product will ship invite/acceptance before the view appears, or a self-remove flow (or both if product chooses in Open #1).
- Distinct workflow issue — This is membership / consent UX, not the feature of creating saved views themselves (ATT-1939 adds views; this issue governs how sharing behaves).
Open
- Primary mechanism — Invite + accept only, self-remove only, or both (pending invites plus leave for already-accepted shares)?
- Surface scope — Client Care saved views only for v1, or a shared membership model applied to ATT-1939 revenue saved views (and any future admin dashboards) at the same time?
- Worklist
members — Include custom worklist member assignment in this issue, or admin saved views only?
- Pending invite UX — Where do invites appear (view picker card, notifications bell, email)? Is decline supported, and can the owner re-invite after decline?
- Self-remove behavior — Remove user from
visibleToUserIds (or equivalent) via API; view disappears from picker immediately; owner sees updated share list?
- Existing shares migration — Treat current
visibleToUserIds as already accepted, or force one-time re-acceptance?
- Creator powers after remove — Can the owner re-add someone who left or declined without that person's consent (if opt-in model)?
- Permissions — Any new admin permission for sharing vs accepting (e.g. separate from
admin-client-care-dashboard-view), or reuse existing view access permissions?
Scope
Backend (attik-backend)
- Current sharing model:
ccDashboardSavedViews.ts — create/update sets visibleToUserIds; list/get uses canSeeView() with immediate access.
- Likely changes (once Open decisions locked): extend
ccDashboardViewSchema (or companion collection) with membership status per user (pending | accepted | declined?) and/or POST .../leave for recipients; update list query so pending shares do not appear until accepted.
- ATT-1939 coordination: If revenue saved views reuse or extend the same schema, membership rules should be shared rather than reimplemented per dashboard.
- Worklists (if in scope):
worklistSchema.ts members + worklist CRUD routes — separate from CC views unless product unifies "shared surface" semantics.
Frontend (attik-frontend)
- Client Care Dashboard:
ClientCareViewsClient.tsx (view picker), SaveViewModal.tsx, ViewSharePopover.tsx, CCDashboardClient.tsx (owner delete today; no recipient leave).
- Recipient UX: pending-invite cards and/or Leave view action on shared (non-owned) views.
- Revenue dashboards: only if Open #2 includes ATT-1939 surfaces in v1.
Out of scope (unless product expands Open decisions)
- Building saved views on revenue dashboards from scratch (ATT-1939).
- Tools → Dashboard per-company instance dashboard (different product surface).
- Company/user account invite flows (
inviteSchema, signup) — unrelated membership system.
References
- ATT-1214 — CC saved views (Done)
- ATT-1939 — Revenue dashboard saved views (Backlog, will use sharing)
- Backend:
attik-backend/src/models/ccDashboardViewSchema.ts, attik-backend/src/routes/ccDashboardSavedViews.ts
- Frontend:
attik-frontend/src/app/admin/client-care-dashboard/ClientCareViewsClient.tsx, _components/SaveViewModal.tsx, _components/ViewSharePopover.tsx