Skip to content

feat(sharing): external client roster on the Sharing tab (trinity-enterprise#20)#1335

Open
dolho wants to merge 1 commit into
devfrom
feature/20-client-roster
Open

feat(sharing): external client roster on the Sharing tab (trinity-enterprise#20)#1335
dolho wants to merge 1 commit into
devfrom
feature/20-client-roster

Conversation

@dolho

@dolho dolho commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Surfaces the external client roster on the agent Sharing tab — outside channel users (no Trinity account) who have messaged the agent, aggregated across Telegram + WhatsApp and ordered by most-recent activity. The per-channel activity (verified_email, message_count, last_active) was already collected but never shown.

Read-only surface for the Access/Sharing redesign (epic trinity-enterprise#16). Per-client block / revoke / approve controls build on this next (trinity-enterprise#21).

Changes

  • dblist_clients_for_agent() join methods (binding → chat_links) on Telegram + WhatsApp ops; exposed via the database.py facade
  • serviceservices/client_roster_service.py: cross-channel aggregation, sort by last_active desc (never-active last), per-channel failure degradation
  • apiGET /api/agents/{name}/clients (OwnedAgentByName, read-only, DB-sourced so it renders when the agent container is stopped); ClientRosterEntry model is channel-extensible
  • ui — read-only Client Roster table in SharingPanel.vue
  • teststests/unit/test_client_roster.py (5): join normalization, tenant isolation, sort/nulls-last, channel-failure degradation
  • docs — requirements §44, architecture endpoint + service entries

Scope

Roster v1 = Telegram + WhatsApp (the channels recording the full email/count/last-active triple). Slack (verifications carry email but no activity counters) and VoIP (call logs) are additive follow-ups — the response model already accommodates them without a contract change.

Testing

24 passed — 5 new roster tests + existing Telegram/WhatsApp channel suites, no regressions.

Related to Abilityai/trinity-enterprise#20

🤖 Generated with Claude Code

…erprise#20)

Surface external channel users (no Trinity account) who have messaged an agent,
aggregated across Telegram + WhatsApp into one read-only roster on the Sharing
tab. Activity (verified_email, message_count, last_active) was already recorded
per channel link but never shown.

- db: list_clients_for_agent() join methods (binding -> chat_links) on the
  Telegram + WhatsApp ops, exposed via the database facade
- service: client_roster_service aggregates + sorts by last_active desc
  (never-active last), degrades per-channel on read failure
- api: GET /api/agents/{name}/clients (OwnedAgentByName, read-only, DB-sourced
  so it renders when the agent container is stopped); ClientRosterEntry model
  is channel-extensible (Slack/VoIP additive)
- ui: read-only Client Roster section in SharingPanel.vue
- tests: join normalization, tenant isolation, sort/nulls-last, channel-failure
  degradation (5 new, all green)
- docs: requirements section 44, architecture endpoint + service entries

Roster v1 = Telegram + WhatsApp (channels recording the full
email/count/last-active triple). Per-client block/revoke/approve controls are
the follow-up (trinity-enterprise#21).

Related to Abilityai/trinity-enterprise#20

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dolho dolho requested a review from vybe June 24, 2026 09:23
@github-actions

Copy link
Copy Markdown

⚠️ Nightly unit-suite check skipped — merge conflict against dev.

Resolve by running git merge dev locally and pushing the result. The next nightly run will re-test once the conflict is gone.

@vybe vybe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated via /validate-pr — no schema/security issues, but CONFLICTING with dev after #1317. #1317 restructured SharingPanel.vue (operator management moved to the new Access tab; the panel was reframed around Identity Proof / access policy). This PR was built on the old standalone "Team Sharing Section" layout, so the SharingPanel.vue conflict is a semantic re-integration — the Client Roster section needs to be grafted onto the new structure (the #18/#20 Sharing redesign you scoped), not just line-merged. The backend conflicts (sharing.py imports, architecture.md table row) are trivial.

Please rebase onto current dev.

— posted via /validate-pr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants