Files
suaveplan/packages/commerce/contacts/api-plugin-contacts
2026-05-27 23:29:53 +01:00
..
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00
2026-05-27 23:29:53 +01:00

@suaveplan/api-plugin-contacts - Contacts + groups HTTP plugin for @suaveplan/api. Mounts /contacts and /groups (with /groups/:id/members and /groups/:id/resolve) on a Hono OpenAPI registry, backed by SurrealDB-implementations of the @suaveplan/contacts ContactStore / GroupStore / MembershipStore interfaces. Bulk-import with per-row error reporting, repository-level maxGroupDepth enforcement, six OTel instruments, typed Hono ContextVariableMap + ServiceRegistry augmentations, and the 12-code CONTACTS_API.* error namespace.

Contacts and Groups HTTP plugin for @suaveplan/api. Mounts the /contacts and /groups route trees on a Hono OpenAPIHono, backed by SurrealDB implementations of the @suaveplan/contacts store interfaces.

Documentation tree

  • context — Module augmentation declaring four typed slots on Hono's ContextVariableMap: contactRepository, groupRepository,…
    • context — Module augmentation declaring four typed slots on Hono's ContextVariableMap: contactRepository, groupRepository,…
  • error-codes — Single source of truth for every failure path inside @suaveplan/api-plugin-contacts. Built on the `@suaveplan…
    • error-codes — Single source of truth for every failure path inside @suaveplan/api-plugin-contacts. Built on the `@suaveplan…
  • otel — Exposes the six OpenTelemetry instruments emitted by @suaveplan/api-plugin-contacts in production: four counters cove…
    • instruments — Exposes the six OpenTelemetry instruments emitted by @suaveplan/api-plugin-contacts in production: four counters cove…
  • plugin — Returns the PluginDescriptor<ContactsPluginConfig> consumed by the @suaveplan/api plugin host. Runs the 5-step `onI…
    • plugin — Returns the PluginDescriptor<ContactsPluginConfig> consumed by the @suaveplan/api plugin host. Runs the 5-step `onI…
    • schema — Inlined SurrealQL DDL for the three tables the contacts plugin owns: contact, contact_group, and group_membership…
  • contact-repository — Concrete implementation of the universal ContactStore interface from @suaveplan/contacts, backed by a connecte…
  • group-repository — Concrete implementation of the GroupStore interface from @suaveplan/contacts, backed by SurrealAdapter. I…
  • membership-repository — Concrete implementation of the MembershipStore interface from @suaveplan/contacts, backed by `SurrealAdapte…
  • build-routes — Returns the seven PluginRouteEntry values that compose the /contacts route tree. Mounted by the plugin's onInit v…
  • contacts-bulk-routes — Two PluginRouteEntry builders for the bulk-operation contact endpoints: POST /contacts/import and `POST /contacts/m…
  • contacts-crud-routes — Five PluginRouteEntry builders for the contact CRUD endpoints: GET /contacts, POST /contacts, GET /contacts/:id…
  • build-routes — Returns the 11 PluginRouteEntry values that compose the /groups route tree: 5 CRUD (list, create, get, `updat…
  • groups-crud-routes — Five PluginRouteEntry builders for the group CRUD endpoints: GET /groups, POST /groups, GET /groups/:id, `PATCH…
  • groups-members-routes — Four PluginRouteEntry builders for the group-membership endpoints: GET /groups/:id/members, `POST /groups/:id/membe…
  • groups-tree-routes — Two PluginRouteEntry builders for the hierarchical-group endpoints: GET /groups/:id/tree materialises a typed `Grou…
  • require-tenant — Centralised guard that extracts and validates the request Principal on every /contacts and /groups handler. Retur…
  • strip-undefined — Bridges Zod's optional-field semantics (.optional() → string | undefined) with the @suaveplan/contacts inpu…
  • contacts-schemas — Zod schemas mounted on every /contacts route via @hono/zod-openapi. They validate inbound bodies / query strings, s…
  • groups-schemas — Zod schemas for the seven /groups routes (list, create, get, update, delete, tree, move) plus the three `/groups/:id/…
  • options — Zod schema that validates the optional bag of options passed to createContactsPlugin. Every field is optional with a…
  • services — Adds typed contactRepository, groupRepository, and membershipRepository slots to the shared `@suaveplan/api-plugi…
    • registry-augmentation — Adds typed contactRepository, groupRepository, and membershipRepository slots to the shared `@suaveplan/api-plugi…
  • tree — Constructs a typed GroupTreeNode rooted at the supplied Group, given a flat list of descendants in arbitrary order.…
    • build-tree — Constructs a typed GroupTreeNode rooted at the supplied Group, given a flat list of descendants in arbitrary order.…
  • types — Pure type declarations that downstream consumers of @suaveplan/api-plugin-contacts depend on at compile time. Keeping…
    • types — Pure type declarations that downstream consumers of @suaveplan/api-plugin-contacts depend on at compile time. Keeping…

Status

  • Version: 0.1.0
  • Tier: server / universal
  • suaveplan-policy: 100% test coverage, 0 mocks, real SurrealDB via @suaveplan/testing-integration-surrealdb.

Quick start

import { createContactsPlugin } from "@suaveplan/api-plugin-contacts";

const plugin = createContactsPlugin({
    routePrefix: "/api",
    maxImportBatchSize: 500,
    maxGroupDepth: 10,
    enforceGroupDepth: true,
});
// host.use(plugin);

The plugin is suaveplan-compatible with the @suaveplan/api-plugin descriptor contract; load it after the database and auth plugins so the ServiceRegistry db and authService slots resolve.

Endpoints

Method Path Purpose
GET /contacts List contacts (search / status / channelType / tags / paging)
POST /contacts Create a contact
GET /contacts/:id Read a contact (tenant-scoped)
PATCH /contacts/:id Update a contact
DELETE /contacts/:id Delete a contact
POST /contacts/import Bulk import (Zod-capped) with per-row errors
POST /contacts/merge Channel + tag union into a primary contact
GET /groups List groups
POST /groups Create a group (depth-enforced)
GET /groups/:id Read a group
PATCH /groups/:id Update a group
DELETE /groups/:id Delete a group (cascade members)
GET /groups/:id/tree Typed GroupTreeNode subtree
POST /groups/:id/move Reparent (depth-enforced)
GET /groups/:id/members List members
POST /groups/:id/members Idempotent add
DELETE /groups/:id/members Idempotent remove
GET /groups/:id/resolve Flatten group + descendants → unique contacts

Modules

Tests

bunx turbo test --filter=@suaveplan/api-plugin-contacts
bunx turbo test:coverage --filter=@suaveplan/api-plugin-contacts

Integration tests under tests/integration/ boot a SurrealDB testcontainer (Docker required) and exercise the full plugin lifecycle end-to-end.