Part of the cross-team channels epic (#404). Sub-issue 1 of 4 — backend only, merges first.
Summary
Build the load-bearing data model and ACL for cross-team channels: the channel_shares table, model/DTO/policy plumbing, and the visibleChannelIds union. No UI in this issue.
Locked decisions
channel_shares table: channel keeps its single owning team_id; channel_shares rows list additional teams a channel is shared into (with share status: pending/active — the handshake state machine lands in sub-issue 2, but the column/enum is defined here).
- ACL union:
User::visibleChannelIds returns owned channels ∪ channels actively shared into the user's team, respecting each channel's visibility.
- Ownership stays with
team_id — governance, settings, retention, deletion all key off the owner team.
Acceptance criteria
Out of scope
- The propose/accept/revoke flow and any UI (sub-issues 2–4). This issue may seed shares directly in tests/factories.
Part of the cross-team channels epic (#404). Sub-issue 1 of 4 — backend only, merges first.
Summary
Build the load-bearing data model and ACL for cross-team channels: the
channel_sharestable, model/DTO/policy plumbing, and thevisibleChannelIdsunion. No UI in this issue.Locked decisions
channel_sharestable: channel keeps its single owningteam_id;channel_sharesrows list additional teams a channel is shared into (with share status: pending/active — the handshake state machine lands in sub-issue 2, but the column/enum is defined here).User::visibleChannelIdsreturns owned channels ∪ channels actively shared into the user's team, respecting each channel's visibility.team_id— governance, settings, retention, deletion all key off the owner team.Acceptance criteria
channel_shares(id,channel_id,team_id, status, timestamps; unique['channel_id','team_id']).Channelrelationships:sharedTeams()/shares(); helper to test whether a channel is shared into a given team.visibleChannelIds(and any sibling channel-scoping queries) union in actively-shared channels, honoring public/private visibility for the viewing team.ChannelDataDTO exposes owner team + shared-team info needed downstream (badging, governance checks).view/join/participation authorization accounts for share membership, whileupdate/archive/deleteremain owner-team-gated.Out of scope