feat(contacts): cover full public API for MCP, move logic into business services - #1093
Open
realcodesiman wants to merge 2 commits into
Open
feat(contacts): cover full public API for MCP, move logic into business services#1093realcodesiman wants to merge 2 commits into
realcodesiman wants to merge 2 commits into
Conversation
…ss services Adds the remaining contacts public-API surface (bulk ops, export, refresh profile, notes/sequences/inboxes/filter-fields as their own features) so MCP and other workspace-token callers can fully manage contacts. In the process, moves business logic that lived only in server-action inner functions (create/update/delete contact, tag attach/detach/replace, custom-field apply, message send, contact import) into packages/business services and packages/database repositories, so the public API and the action call the same code path instead of duplicating it — fixing a refresh-profile 401 caused by a stray session check and a stale contact-notes cache that never invalidated on write. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Sep 6, 2026
…invalidation, close public API gaps Closes the review findings on the contacts public API/MCP surface: a workspace-A token could enroll contacts into a workspace-B sequence (sequential bigint ids, never validated); tag writes invalidated cache tags nothing ever reads, so renamed/deleted tags and stale contact tag lists persisted for up to 24h; and the custom-field update path silently dropped writes to fields 51+ in workspaces with more than 50 custom fields. Also makes bulk endpoints report skipped ids instead of a blind 204, surfaces channel-send enqueue failures instead of swallowing them, restores the sequential (not concurrent) pre-auth rate-limit gate, adds read caching now that invalidation is correct, and removes dead code left behind by the original PR. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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
packages/businessservices andpackages/databaserepositories, so the public API handler and the private server action call the exact same code path instead of diverging copies.refresh-profilereturned 401 for token callers because the old code path required a browser session;contacts_createNote→contacts_listNotesin the same MCP session could see a stale note because nothing invalidated the notes cache on write.Changes
contact-notes,contact-sequences,contact-inboxes,contact-filter(each with its ownapi/public.ts+schema/public.ts), composed intofeatures/contacts/api/public.ts; pluscontacts/api/public/{bulk,export,refresh-profile,tags,custom-fields}.ts.contact/create-with-inbox.ts,contact/update-fields.ts,contact-export/service.ts,message/create-outgoing.ts,database/repositories/contact/,database/repositories/media-library-file/.create-contact,delete-contact,add/remove/update-contact-tag,add-contact-custom-field,update-contact-field,create-message,create-tag,delete-tag,import-contacts,create-webhook,create-flow,create-trigger,create-automated-response) now delegate to the shared business service instead of holding their own copy of the logic.features/contacts/server/**(legacy ad-hoc business layer),queries/public-find-contact.ts,folders/actions/utils.ts, unused tag store provider files.packages/database/drizzle/20260905151444_...)..agents/skills/{orpc-api,feature-scaffold}/SKILL.md(submodule composition pattern,server/directory ban),docs/developer/workspace-api-tokens.md(accurate endpoint-to-scope table and test list).Test plan
pnpm lintpnpm --filter @chatbotx.io/database check-types && testpnpm --filter @chatbotx.io/business check-types && testpnpm --filter builder check-types && test(418 files / 2684 tests green, snapshot unchanged)pnpm --filter worker check-types && testchatbotx-mcp-server—contacts_refreshProfile,contacts_createNote→contacts_listNotesimmediately after,contacts_createwith a mismatched inbox channel (expect 400, not 500)