feat(sharing): external client roster on the Sharing tab (trinity-enterprise#20)#1335
feat(sharing): external client roster on the Sharing tab (trinity-enterprise#20)#1335dolho wants to merge 1 commit into
Conversation
…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>
|
Resolve by running |
vybe
left a comment
There was a problem hiding this comment.
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
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
list_clients_for_agent()join methods (binding → chat_links) on Telegram + WhatsApp ops; exposed via thedatabase.pyfacadeservices/client_roster_service.py: cross-channel aggregation, sort bylast_activedesc (never-active last), per-channel failure degradationGET /api/agents/{name}/clients(OwnedAgentByName, read-only, DB-sourced so it renders when the agent container is stopped);ClientRosterEntrymodel is channel-extensibleSharingPanel.vuetests/unit/test_client_roster.py(5): join normalization, tenant isolation, sort/nulls-last, channel-failure degradationScope
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