feat: group DM conversations — state + search (2/3)#25
Merged
Conversation
Wraps the group-DM surface at /api/v1/messages/groups/* that the
Python SDK shipped in colony-sdk v1.13.0 (#56 over there). First of
three PRs that complete group-DM coverage in the JS SDK; per-message
ops + attachments will follow.
Lifecycle (6 methods):
- createGroupConversation(title, members, options?)
- listGroupTemplates(options?)
- createGroupFromTemplate(template, members, { titleOverride? })
- getGroupConversation(convId, { limit?, offset? })
- updateGroupConversation(convId, { title?, description? })
- sendGroupMessage(convId, body, { replyToMessageId?, idempotencyKey? })
Member management (7 methods):
- listGroupMembers, addGroupMember, removeGroupMember, setGroupAdmin,
transferGroupCreator, respondToGroupInvite, markGroupAllRead
New exported types: GroupConversation, GroupConversationDetail,
GroupMember, GroupMembersResponse, GroupTemplate,
GroupTemplatesResponse, GroupInviteResponse, MarkGroupReadResponse.
Internal: RequestOptions gains an extraHeaders field so write methods
can set per-request headers like Idempotency-Key cleanly. Booleans on
query-string endpoints use the lowercase "true"/"false" FastAPI
expects, not JavaScript's default capitalised String(true).
19 new unit tests cover request shape, header threading, default-vs-
omitted parameters, the FastAPI lowercase-bool quirk, query-string
escaping (`R&D Lab` → `title=R%26D+Lab`), and the three-state
description contract on update (empty clears, undefined omits).
No version bump per the multi-PR release plan; CHANGELOG entry lands
in Unreleased.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
4 tasks
Two branches in the new methods weren't exercised by the original test set: - updateGroupConversation with only `title` (not just description) — the `if (options.title !== undefined)` true-branch was never hit - createGroupFromTemplate without `titleOverride` — the optional- param branch was only exercised in the override-set case Adds two focused tests; client.ts branch coverage moves from 97.41 to 98.27. All remaining uncovered branches are pre-existing in register() and extractItems(), not introduced by this PR. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors colony-sdk Python PR #57 / v1.13.0 — 8 new methods layered
over the lifecycle methods from the prior PR.
State (per-participant — affects only the caller's notifications):
- muteGroupConversation(convId, { until? })
- unmuteGroupConversation(convId)
- snoozeGroupConversation(convId, duration)
- unsnoozeGroupConversation(convId)
- setGroupReadReceipts(convId, { show? }) — three-state override:
true/false/undefined (undefined clears, falling back to user pref)
Pins (group-wide, admin-only):
- pinGroupMessage(convId, msgId)
- unpinGroupMessage(convId, msgId) — idempotent
Search:
- searchGroupMessages(convId, q, { limit?, offset? }) — PostgreSQL
FTS within one group, with <mark>...</mark> highlights pre-rendered
New exported types: GroupMuteResponse, GroupSnoozeResponse,
GroupReadReceiptsResponse, GroupPinResponse, GroupSearchHit,
GroupSearchResponse.
13 new unit tests cover the three-state set-receipts surface
(true/false/undefined), the FastAPI lowercase-bool quirk
(`show=false` not `show=False`), query-string escaping
(`R&D` → `q=R%26D`), default-vs-custom pagination, and the bare-POST
shape for muteGroupConversation when `until` is omitted.
No version bump per the multi-PR release plan; CHANGELOG entry lands
in Unreleased above the lifecycle entry.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
05d8c64 to
18c1bdf
Compare
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second of three PRs porting the group-DM surface from
colony-sdkPython v1.13.0. Stacked on top of #24 (lifecycle + members) so this PR's diff shows only its own changes — switch the base tomasterafter #24 merges, or merge in order. No version bump.Methods added (8)
State (per-participant — affects only the caller's notifications):
muteGroupConversation(convId, { until? })— omituntilfor permanent; tokens"1h"/"8h"/"1d"/"1w"/"forever"unmuteGroupConversation(convId)— idempotentsnoozeGroupConversation(convId, duration)— required token:"1h"/"3h"/"until_morning"/"1d"/"1w"unsnoozeGroupConversation(convId)— idempotentsetGroupReadReceipts(convId, { show? })— three-state override:trueforces on,falseforces off,undefinedclears (falls back to user-level preference)Pins (group-wide, admin-only):
pinGroupMessage(convId, msgId)unpinGroupMessage(convId, msgId)— idempotentSearch:
searchGroupMessages(convId, q, { limit?, offset? })— PostgreSQL FTS within a single group; returns{hits, total, has_more}with<mark>…</mark>highlights pre-renderedNew exported types
GroupMuteResponse,GroupSnoozeResponse,GroupReadReceiptsResponse,GroupPinResponse,GroupSearchHit,GroupSearchResponse.Test plan
npm run typecheck— cleannpm run lint— cleannpm run format:check— cleannpm run test— 237 passed (+13 new tests vs PR feat: group DM conversations — lifecycle + members (1/3) #24's 224)The 13 new tests pin:
setGroupReadReceipts(show: true→?show=true,show: false→?show=false, omitted → no query string at all)not.toContain("show=False")muteGroupConversationwhenuntilis omitted (server reads as forever)R&Dquery escaping:q=R%26DsearchGroupMessagesPer the TheColonyCC/* convention, holding the merge button for human review.
🤖 Generated with Claude Code