Skip to content
Packages

Platform Control Plane

平台控制平面

The lowest shared layer: database, config, provider selection, tenant locks, gateway-core contracts, health, rate limits, traces, and repository boundaries.

21 packages, 377 source files and 81 test files in packages/platform. · Source ↗ · Docs ↗

Downward-only platform stack

Feature packages stand above this stack; platform packages must not pull product logic upward.

  • @nebutra/dbPrisma v7, schema policy, generation scripts
  • @nebutra/tenant-storeper-tenant serialization and scoped stores
  • @nebutra/provider-factoryexplicit/env/detect/fallback provider resolution
  • @nebutra/gateway-coreshared gateway contracts below the Hono backend
  • @nebutra/trace-storeasync traces for agents, tools, and LLM spans

What it owns

  • Prisma schema, database client, migrations, and multi-schema policy
  • Tenant locks, trace store, health checks, config, errors, and rate limiting
  • Provider factory and repository boundaries used by higher-level packages

Where it stops

  • No app-specific UI or product copy belongs in platform packages.
  • Feature packages depend downward; platform does not import feature domains.

How we know it works

  • schema drift audits, db generation, and architecture dependency tests
  • tenant-store and trace-store package-local doctor/debug commands

In code

platform.ts
1import { getTenantDb } from "@nebutra/db";
2import { getCurrentTenant } from "@nebutra/tenant";
3
4const tenant = getCurrentTenant();
5
6// Row-level security scopes every query to the tenant.
7const posts = await getTenantDb(tenant.tenantId).post.findMany({
8  where: { published: true },
9  orderBy: { publishedAt: "desc" },
10  take: 10,
11});

Packages

21 packages in packages/platform.

Active rules3
error.rate > 5%
FIRING→ Slack #ops
p95.latency > 800ms
WARNING→ PagerDuty
disk.usage > 80%
OK→ Email
evaluated every 30swebhook delivery
alerting

Alert rules + delivery on top of @nebutra/metering. Threshold/anomaly detection, route to PagerDuty, Discord, or in-product banners.

analytics

First-party product analytics on ClickHouse — event ingest, funnel queries, no third-party loader on the marketing site.

SDK · 8 moduleskit
  • config
  • db
  • queue
  • vault
  • events
  • ai
  • tenant
  • schedule

pnpm nebutra capability scaffold

capability-kit

Composable capability primitives — pricing tier ↔ feature flag ↔ quota ↔ UI gating wired into one declarative manifest.

config.schema.ts4
  • config.database.urlstring· required
  • config.ai.defaultModelstring· default "claude-sonnet-5"
  • config.ai.maxTokensnumber· default 4096
  • config.cache.ttlnumber· default 60

validated at startup

config

Typed environment + runtime config — Zod schemas at boot, no scattered process.env reads, fail-fast on missing keys.

db

Typed Prisma client wrapper — extension-aware, RLS-friendly, with per-tenant connection pinning when the deployment splits writes from reads.

Recent errors3
2m agoERRORBILLING_PROVIDER_TIMEOUT
1 occurrence
9m agoWARNQUEUE_RETRY_LIMIT
3 occurrences
21m agoINFOAUTH_TOKEN_REFRESHED
12 occurrences
at packages/commerce/billing/src/charge.ts:42at @nebutra/queue: retryHandler
Sentry · structured logs
errors

Typed application error taxonomy — UserError, AuthError, RateLimitError. Maps cleanly to HTTP, to logs, to Sentry, to the in-product toast.

feature-flags

Server + client flag evaluator with GrowthBook / Statsig / custom. Per-tenant overrides, sticky bucketing, exported as React hooks.

gateway-core

BFF primitives shared by backends/gateway and edge handlers — middleware chains, route matchers, header normalization, request-id propagation.

user:alice
owns
org:acme
member
user:bob
ReBACtyped relations
graph-model

Property-graph model layer for knowledge / org / asset graphs. Edges/nodes typed by Zod, persisted via Prisma or Neo4j adapter.

GET /healthz200 OK · 4ms
· database2ms
· redis1ms
· queue1ms
· s3degraded
composed via @nebutra/health
health

Liveness + readiness probes for every backend service. Aggregates downstream deps (db, queue, search) into one /healthz response.

i18n·34 locales
auth.welcome
en·Welcome back, {name}!
zh·欢迎回来,{name}!
ja·{name}さん、おかえり!
es·¡Bienvenido, {name}!
next-intl · ICU MessageFormat99.2% coverage
i18n

next-intl bridge — runtime locale, ICU plural, currency/date formatters, sided JSON bundles per route. Build-time guarantees on key drift.

Sentry connected
logs.stream
[INFO]user.signupuserId=usr_8c41 tenantId=org_abc
[WARN]cache.misskey=user:abc 3ms
[ERROR]payment.failedorderId=ord_5a18 code=card_declined
[DEBUG]tenant.resolvetenantId=org_xyz 1ms
trace-id propagated · 4 sinks
logger

Structured logging with pino + Sentry transport. One log object per request, breadcrumbs forwarded, PII-stripper plugged into the standard sink.

provider.billing
Creem
WeChat Pay
Alipay
Live once its keys are set
both rails can run at once
provider-factory

Auto-detecting provider factory pattern — env vars choose between queue / search / notifications backends with a single getX() call.

rate · 100 req/s · token bucket
  • /api/posts200 ok87 left
  • /api/users429 throttledretry-after 12s
per-tenant · 8ms p99
rate-limit

Token-bucket rate limiter — Upstash Redis or in-memory. Per-route + per-tenant policy, 429 with retry-after, decision logged for audit.

repositories

Repository-pattern primitives — findAll, findById, create, update, delete behind one Repository'<T>'. Swap Prisma for any backend without changing callers.

Nebutra Status
All systems operational
99.97% uptime · 90 days
status

Public status page primitives — incident timeline, component graph, subscriber emails. Renders both /status pages and embeddable widgets.

postgres · RLS
tenant scope
SET LOCAL app.tenant_id = 'org_abc123';
SELECT * FROM posts;
-- → 12 rows (tenant_abc only)
tenant_abc · 12 rowstenant_xyz · hidden
withTenant()AsyncLocalStorage scope
tenant-store

Tenant-bound key/value cache for lookups too hot for the database. Auto-invalidates on tenant settings change.

trace-store

OpenTelemetry-compatible span store and query layer. Lets agents trace a tool call across iam, billing, and webhooks.