Skip to main content

Backend Service

The greenfield backend microservice for Subscriberbotwspace-subscriberbot-svc. It is the federated GraphQL system of record for every recurring digital relationship: providers (global discovery registry), relationships (subscriptions / memberships / licenses / contracts — the fundamental object), plans, entitlements, assets, payment instruments, invoices, communication channels + the universal inbox, and AI agents / workflows / autonomous policies.

Service facts

  • Service port: 3291
  • PostgreSQL port: 5291
  • Valkey port: 6291
  • Layer: Workspace (wspace)
  • Hive service name: subscriberbot (registry: burdenoff/workspaces/*)
  • Runtime: Bun 1.3.14+
  • Framework: ElysiaJS + GraphQL Yoga (via @burdenoff/be-sdk), Apollo Federation v2
  • Database: Postgres 18 + Prisma 7 (adapter-pg), split schema under prisma/schema/

Quick Start

# Install dependencies
bun install

# Start state services (PostgreSQL + Valkey)
cd ../wspace-subscriberbot-state
docker compose up -d

# Start development server
cd ../wspace-subscriberbot-svc
bun run dev

Commands

bun run dev              # Start development server with watch mode
bun run gendb # Generate Prisma client
bun run codegen # Generate GraphQL types + .hive-schema.graphql
bun run migrate # Create a new migration
bun run migrate:deploy # Apply migrations (via migrate-safe.sh)
bun run lint # ESLint
bun run type:check # TypeScript type checking
bun run format # Prettier
bun run test # Unit tests (vitest/bun:test)
bun run sanity # format, codegen, gendb, migrate, lint, type:check, build, coverage, knip
bun run hive:publish # Publish schema to Hive development target

Always run bun run sanity before commits, PRs, and deployments.

Architecture

src/
├── index.ts # Entry point (graphql-modules createApplication + be-sdk Yoga)
├── telemetry.ts # OpenTelemetry bootstrap (imported first)
├── graph.config.ts # Knowledge-graph entity/relationship config
├── config/ # service.ts (port/name/i18n), sdk-init.ts (be-sdk config)
├── services/ # Logger + Database DI providers (global singletons)
├── utils/ # prisma accessor, pagination helpers, field-encryption, pii-masking
├── plugins/ # operation-audit-plugin (GraphQL → activity/audit)
└── modules/
├── base/ # federation directives, scalars, entity stubs, global providers
├── main/ # config, declarations (context), scalar-types, rest endpoints
├── subscriberbot/ # top-level module composition + dataloaders + graph stub
├── registry/ # global provider registry + plans (RegistryService)
├── relationships/ # core domain: relationships, entitlements, assets, renewal events
├── payments/ # Universal Billing Layer + Universal Inbox: instruments, invoices, channels, messages
└── automation/ # AI agents, workflows, autonomous policies

prisma/schema/ # split schema: schema.prisma + enums + per-domain *.prisma + migrations/

GraphQL naming contract

To avoid collisions in the shared workspaces supergraph:

  • Every product-owned type/enum/input is prefixed Sub (SubRelationship, SubInvoiceStatus, SubCreateRelationshipInput).
  • Every root Query/Mutation field is prefixed sub (subListRelationships, subCreateRelationship, subProvider, subHealth).
  • Shared platform types (OperationContext, ContextInput, etc.) and federation entity stubs (User, Workspace, File, UniversalTag) are reused byte-identical from src/modules/base/ and never redefined.
  • Every Query/Mutation field carries an @rbac(action, resource, scopeType) directive; the gateway enforces it.

GraphQL Hive

  • Project: burdenoff/workspaces/{development,staging,production}
  • Service Name: subscriberbot
  • Subgraph URLs published for the staging and production targets must be port-less.
  • wspace-int-gateway / wspace-public-gateway — workspace API gateways
  • wspace-files-svc — owns File (assets/invoices reference it via federation)
  • wspace-tags-svc — owns the shared UniversalTag shape
  • global-notification-svc — owns outbound renewal/trial reminders
  • global-billing-svc — owns the real platform PaymentMethod; SubPaymentInstrument here is a passive annotation only, not a card vault
Environment selection

The backend service connects to production gateways when deployed to the managed cloud environments. For local development, it uses localhost:4003 (workspace public gateway) and localhost:4000 (global public gateway) as upstreams. The gateway itself reads the supergraph from Hive Cloud CDN. See Environment Selection for endpoint details.