Skip to content

feat: cross-team channels — foundation (data model + ACL) #405

Description

@emmpaul

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

  • Migration creates channel_shares (id, channel_id, team_id, status, timestamps; unique ['channel_id','team_id']).
  • Channel relationships: 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.
  • ChannelData DTO exposes owner team + shared-team info needed downstream (badging, governance checks).
  • Policies updated so a shared-in member's view/join/participation authorization accounts for share membership, while update/archive/delete remain owner-team-gated.
  • Backend tests: shared-in public channel is visible/joinable to the other team; private shared channel only to explicitly-added members; owner-only governance still enforced; unique constraint. 100% coverage.

Out of scope

  • The propose/accept/revoke flow and any UI (sub-issues 2–4). This issue may seed shares directly in tests/factories.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:adminWorkspace admin & operationsenhancementNew feature or requestpost-mvpDeferred beyond the MVP; net-new vs docs/FUTURE.md

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions