API & Operations
API and Operations
Last reviewed: 2026-05-14.
This document summarizes the public/internal web API shape, local run commands, environment variables, CI gates, and production operations that are visible from the current repository.
Web API
Base URL:
- Local:
http://localhost:3000 - CLI config key:
api_base_url
Auth:
- Most account APIs require
Authorization: Bearer <access-token>. - Access and refresh tokens are issued by
/api/auth/loginand/api/auth/register.
Endpoint Summary
| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | /api/health | No | Checks Postgres and Redis. |
POST | /api/auth/register | No | Creates user, wallet, refresh token. |
POST | /api/auth/login | No | Verifies password/dev superaccount and returns tokens. |
POST | /api/auth/refresh | Refresh token | Rotates refresh token and returns new access token. |
GET | /api/balance | Yes | Returns current spendable wallet balance. |
GET | /api/usage | Yes | Returns completed usage rows with canonical usage. |
GET | /api/billing/ledger | Yes | Returns user-scoped wallet ledger entries. |
POST | /api/billing/admin/credit | Admin | Creates an idempotent manual wallet credit. |
GET | /api/payments | Yes | Returns current user's payment history. |
POST | /api/payments/checkout | Yes | Creates mock or YooKassa pending checkout depending on PAYMENTS_PROVIDER. |
POST | /api/payments/webhook/mock | Secret | Processes sandbox mock payment webhooks and idempotent wallet top-ups. |
POST | /api/payments/webhook/yookassa | Provider webhook | Verifies YooKassa payment state by provider re-fetch and credits wallet on success. |
POST | /api/payments/reconcile | Admin | Re-fetches YooKassa payment or refund state and applies missed succeeded/canceled provider states idempotently. |
POST | /api/payments/refund | Admin | Creates idempotent mock refunds and durable YooKassa provider refunds with ledger debits after provider success. |
POST | /api/payments/fiscal-receipts/reconcile | Admin | Submits/reconciles pending fiscal payment/refund receipts one-at-a-time or in bounded batch mode. |
GET | /api/audit | Admin | Exports DB-backed web audit events as JSON or NDJSON with filters. |
POST | /api/audit | Admin | Runs bounded audit-retention prune actions. |
GET | /api/models | No | Returns model catalog, schema version 2. |
GET | /api/account/models | Yes | Returns current account model settings. |
PUT | /api/account/models | Yes | Saves enabled models/reasoning settings; rejects all-disabled pool. |
GET | /api/reliability | Yes | Returns compliance-filtered model reliability stats. |
GET | /api/doctor/models | Yes | Checks model configured/reachable/compliant status. |
GET | /api/doctor/launch | Admin | Reports redacted paid-launch readiness checks for payments, fiscal receipts, scheduler evidence and legal/entity blockers. |
POST | /api/stream/run | Yes | Streams orchestration run, lifecycle events, progress, usage. |
/api/health
Checks:
- Postgres via Prisma.
- Redis via
PING.
Production requirement:
- Health should stay cheap and not call model providers.
- Readiness and liveness may need separate endpoints in deployment.
/api/auth/register
Behavior:
- Bounded JSON input.
- Creates
User. - Creates
CreditWalletwith zero balance. - Creates refresh token record.
Production gaps:
- Email verification.
- Password reset.
- Account deletion.
- Abuse controls beyond current rate-limit behavior.
/api/auth/login
Behavior:
- Bounded JSON input.
- Rate limited.
- Uses password hash verification.
- Supports dev superaccount outside production.
- Returns access and refresh tokens.
Production gaps:
- MFA is not implemented.
- Login event/audit surface should be added for support/security.
/api/auth/refresh
Behavior:
- Verifies refresh token.
- Rotates stored refresh token.
- Revoked/expired tokens fail.
Production requirement:
- Refresh-token table should be periodically cleaned up.
/api/balance
Behavior:
- Requires access token.
- Dev superaccount returns unlimited balance.
- Reads spendable balance as
CreditWallet.balanceMicroRubminus activeBalanceReservation.estimatedMicroRubholds. - Includes
total_micro_rubandreserved_micro_rubfor DB wallets. - Uses Redis cache with short TTL.
Production notes:
- Balance is updated by the usage-debit ledger transaction after completed positive-cost runs.
- Hard balance preflight rejection is available with
PLYRUM_BILLING_ENFORCE_BALANCE=1. - Balance hold/reservation is available behind the same flag and uses active
BalanceReservationrows.
/api/usage
Behavior:
- Requires access token.
- Returns completed usage rows only.
- Schema version:
X-Schema-Version: 2. - Pagination headers:
X-Total-Count,X-Page,X-Page-Size. - Supports date filters through query params.
- Includes canonical usage snapshot.
Production requirement:
- Add ledger/payment correlation once real billing exists.
- Keep usage rows user-scoped and never expose provider secrets.
/api/billing/ledger
Behavior:
- Requires access token.
- Returns the current user's immutable wallet ledger entries.
- Schema version:
X-Schema-Version: 1. - Pagination headers:
X-Total-Count,X-Page,X-Page-Size. - Uses snake_case numeric money fields:
amount_micro_rubandbalance_after_micro_rub.
Production requirement:
Payment,PaymentRefund,PaymentWebhookEvent,FiscalReceipt, andInvoicetables exist for the payment lifecycle. Mock checkout/history/webhook APIs exist for local sandbox testing, and YooKassa checkout/webhook/refund/reconcile paths exist for provider contract verification. Accepted top-ups/refunds create pendingFiscalReceiptrows, andPOST /api/payments/fiscal-receipts/reconcilecan submit/reconcile those rows through a mock provider or a guarded HTTP fiscalization endpoint. YooKassa checkout requires explicitaccept_terms=true. Add provider webhook signature verification if supported by the configured provider, live/sandbox fiscal provider proof, scheduled reconciliation jobs in deployment, final legal review/entity details for the linked legal pages, admin adjustment UI, and payment correlation runbooks before paid launch.
/api/payments/checkout
Behavior:
- Requires access token.
- Validates JSON input and integer
amount_rubagainstPAYMENTS_MIN_TOPUP_RUB/PAYMENTS_MAX_TOPUP_RUB. - Returns
503 payments_not_configuredunlessPAYMENTS_PROVIDERis set. - With
PAYMENTS_PROVIDER=mock, creates a localPayment(status=pending)row and returns a sandboxconfirmation_url. - With
PAYMENTS_PROVIDER=yookassa, requiresYOOKASSA_SHOP_ID,YOOKASSA_SECRET_KEY, and an absoluteYOOKASSA_RETURN_URL; creates a local pending payment, calls YooKassa/v3/paymentswithIdempotence-Key, redirect confirmation, and Plyrum metadata, then stores the provider payment id and confirmation URL. - Does not credit the wallet. Wallet credit must wait for verified webhook, admin credit, or provider reconciliation.
Production requirements:
- Keep provider checkout behind explicit provider env vars and live/sandbox operational runbooks.
- Add provider sandbox browser E2E with real YooKassa sandbox credentials before public paid launch.
- Add payment method UI, final legal review/entity details for
/legal/offer,/legal/privacy,/legal/refund,/legal/tariffs, scheduled provider-specific success/cancel/refund reconciliation, and fiscal receipt reconciliation.
/api/billing/admin/credit
Behavior:
- Requires access token.
- Requires admin identity through
PLYRUM_ADMIN_USER_IDS; local dev superaccount is also accepted outside production. - Requires
idempotency_key. - Accepts
user_id,reason, and eitheramount_ruboramount_micro_rub. - Bounds amount by
PLYRUM_ADMIN_CREDIT_MAX_RUB(default1000000). - Creates target wallet if missing.
- Creates exactly one
WalletLedgerEntry(type=admin_adjustment, sourceType=admin)per idempotency key. - Atomically increments
CreditWallet.balanceMicroRub. - Invalidates target balance cache.
- Emits a redacted web audit event through
web/lib/audit-log.ts; with a database configured, the event is stored inWebAuditEventand can be filtered/exported through/api/audit.
Production requirement:
- Keep this endpoint behind operational admin auth only. It is for B2B/manual
top-up, support adjustment and controlled promo credit, not public checkout.
Production deployments should configure database-backed audit storage,
operator retention policy, and admin-token handling for
/api/audit.
/api/audit
Behavior:
- Requires access token.
- Requires admin identity through
PLYRUM_ADMIN_USER_IDS; local dev superaccount is also accepted outside production. GETacceptskind,status,actor_user_id,target_user_id,from,to,limitandformat=json|ndjson.GETexports DB-backedWebAuditEventrows with schema version 1 and records anaudit.exportevent after a successful export.POSTaccepts{ "action": "prune", "before": "<ISO date>" }or{ "action": "prune", "retention_days": 365 }.POSTdeletes rows older than the cutoff and records anaudit.retention_pruneoperator event.
Production requirement:
- Wire prune execution to an explicit operator action or scheduled job. Keep retention length, admin token custody, and export storage in the deployment runbook.
/api/payments/webhook/mock
Behavior:
- Requires
PAYMENTS_PROVIDER=mock. - Requires
PAYMENTS_MOCK_WEBHOOK_SECRETand matchingx-plyrum-mock-webhook-secretheader. - Accepts
event_id,payment_id,status(succeededorcanceled) and optionalamount_micro_rub. - Stores
PaymentWebhookEventrows with payload hashes. - Rejects same-event payload mismatches and amount mismatches.
- For
succeeded, credits wallet exactly once throughWalletLedgerEntry(type=topup, sourceType=payment)and updatesCreditWallet.balanceMicroRub. - For
canceled, marks the payment canceled without wallet credit.
Production requirement:
- This endpoint is sandbox-only. Real providers need provider-specific signature verification, provider-side payment re-fetch/reconciliation, refund handling and fiscal receipts before accepting real money.
/api/payments/webhook/yookassa
Behavior:
- Requires
PAYMENTS_PROVIDER=yookassa. - Accepts YooKassa notification payloads for
payment.succeededandpayment.canceled. - Re-fetches the payment from YooKassa
/v3/payments/{id}before mutating any wallet state. - Deduplicates by deterministic event id
event:providerPaymentId. - Rejects duplicate event ids with different payload hashes.
- Rejects amount mismatches and Plyrum metadata mismatches.
- For
payment.succeeded, credits wallet exactly once throughWalletLedgerEntry(type=topup, sourceType=payment)and updatesCreditWallet.balanceMicroRub. - For
payment.canceled, marks the payment canceled without wallet credit.
Production requirement:
- YooKassa notifications do not become trusted just because a webhook was received; provider re-fetch is mandatory. Before live launch, add sandbox provider E2E, operational webhook delivery monitoring, fiscal receipt/refund receipt handling, and reconciliation jobs.
/api/payments/reconcile
Behavior:
- Requires access token.
- Requires admin identity through
PLYRUM_ADMIN_USER_IDS; local dev superaccount is also accepted outside production. - Available only with
PAYMENTS_PROVIDER=yookassa. - Requires either
payment_idfor a localPayment(provider=yookassa)with a storedproviderPaymentId, orrefund_id/provider_refund_idfor a localPaymentRefund(provider=yookassa)with a storedproviderRefundId. - Also accepts
{ "batch": true, "limit": 1..100 }to reconcile pending YooKassa payments and pending YooKassa refunds in one bounded operator/cron call. - Re-fetches
/v3/payments/{id}or/v3/refunds/{id}from YooKassa before local mutation. - Provider
succeededis passed through the same idempotent processing path aspayment.succeededwebhook and can create exactly one top-up ledger entry and one pending payment receipt. - Provider
canceledis passed through the same idempotent processing path aspayment.canceledwebhook and does not credit the wallet. - Provider non-final states such as
pendingupdaterawProviderStatus, return202, and do not mutate balance. - Refund provider
succeededcalls the same wallet mutation primitive as provider refund creation, creates or reuses exactly one refund ledger entry and one pending refund receipt, and updates the durablePaymentRefundrow withledgerEntryIdandcompletedAt. - Refund provider
pendingupdatesPaymentRefund.rawProviderStatus, returns202, and does not mutate balance. - Refund provider
canceledmarks thePaymentRefundcanceled and does not mutate balance. - Batch mode returns a per-object result array with
kind, local id,status_code,pending,duplicate,error, and the original one-object response body. It never hides per-object failures behind a single green status. - External schedulers can call the same batch contract through
pnpm -C web reconcile:yookassawithPLYRUM_RECONCILE_BASE_URL,PLYRUM_RECONCILE_TOKENand optionalPLYRUM_RECONCILE_LIMIT. - Fiscal receipt submission/reconciliation has a separate bounded runner:
pnpm -C web reconcile:fiscalwithPLYRUM_FISCAL_RECONCILE_BASE_URL,PLYRUM_FISCAL_RECONCILE_TOKENand optionalPLYRUM_FISCAL_RECONCILE_LIMIT. - Amount and metadata mismatches are rejected without wallet mutation.
Production requirement:
- This endpoint closes missed payment/refund provider-state recovery for one object at a time and provides a bounded batch operator/cron entrypoint plus a small runner script. Paid launch still needs actual scheduler configuration in the deployment platform and operator runbook evidence.
/api/payments/fiscal-receipts/reconcile
Behavior:
- Requires access token.
- Requires admin identity through
PLYRUM_ADMIN_USER_IDS; local dev superaccount is also accepted outside production. - Requires fiscal receipt provider configuration:
PLYRUM_FISCAL_RECEIPTS_PROVIDER=mockfor sandbox/operator proof orPLYRUM_FISCAL_RECEIPTS_PROVIDER=httpwithPLYRUM_FISCAL_RECEIPTS_ENDPOINT. - Accepts one receipt by
receipt_id, or{ "batch": true, "limit": 1..100 }for bounded processing of pending/submitted receipt rows. - For
mock, marks the receiptsucceededand records a deterministicmock-fiscal-<receipt_id>provider receipt id. - For
http, posts a bounded fiscal payload to the configured endpoint withIdempotence-Key: fiscal_receipt:<receipt_id>and optional bearer token fromPLYRUM_FISCAL_RECEIPTS_TOKEN. IfPLYRUM_FISCAL_RECEIPTS_STATUS_ENDPOINTis configured, submitted receipts can be rechecked by provider receipt id. - Updates only
FiscalReceipt.status,providerReceiptId, andrawPayload. It does not change wallet or payment balances. - Emits redacted DB/JSONL audit events for one-object and batch receipt reconciliation.
- External schedulers can call the batch contract through
pnpm -C web reconcile:fiscal.
Production requirement:
- This endpoint closes the local submission/reconciliation seam for payment and refund receipts. Paid launch still needs an approved fiscalization provider, live/sandbox provider proof, deployment scheduler configuration and an operator runbook.
/api/payments/refund
Behavior:
- Requires access token.
- Requires admin identity through
PLYRUM_ADMIN_USER_IDS; local dev superaccount is also accepted outside production. - Requires
payment_id,reason, andidempotency_key. - Refunds
Payment(provider=mock, status=succeeded)rows locally andPayment(provider=yookassa, status=succeeded)rows through YooKassa/v3/refunds. - Creates exactly one
WalletLedgerEntry(type=refund, sourceType=refund)per payment/idempotency key. - For mock payments, atomically decrements
CreditWallet.balanceMicroRub, marks the paymentrefunded, invalidates the user's balance cache, and rejects insufficient refundable mock balance. - For YooKassa payments, calls
/v3/refundswith Basic auth andIdempotence-Key; local wallet/payment mutation happens only after provider returnsstatus=succeeded. Provider amount mismatches,canceled, and non-final statuses do not mutate local balance. - Persists every YooKassa provider refund response in
PaymentRefund, including pending, canceled and amount-mismatched attempts, so operators can reconcile a pending provider refund later byrefund_idorprovider_refund_id. - Accepted refunds create
FiscalReceipt(type=refund, status=pending)records for later fiscalization/reconciliation. - Emits redacted DB/JSONL audit events for created, duplicate, pending and rejected refund attempts.
Production requirement:
- This is an admin refund contract, including durable YooKassa provider refund
creation, one-refund reconciliation and bounded batch reconciliation through
/api/payments/reconcile, plus pending refund receipt submission through/api/payments/fiscal-receipts/reconcile. Paid launch still needs provider sandbox browser proof, scheduled job wiring in deployment, approved external fiscal provider proof, and support runbook evidence.
/api/payments
Behavior:
- Requires access token.
- Returns current user's payment rows only.
- Schema version:
X-Schema-Version: 1. - Pagination headers:
X-Total-Count,X-Page,X-Page-Size.
/api/models
Behavior:
- Public catalog.
schema_version: 2.- Exposes model IDs, labels, capabilities, risk metadata, price metadata, privacy tier, hosted region, configured state.
Production requirement:
- Any public price shown here must match the tariff page and billing table.
/api/account/models
Behavior:
- Requires access token.
GETreturns account model settings.PUTacceptsmodel_settingsorenabled_models.- Rejects body over the limit.
- Rejects all-disabled settings.
Production requirement:
- Org admin permissions must be enforced before org-level settings are editable in UI.
/api/reliability
Behavior:
- Requires access token.
- Applies effective compliance policy.
- Returns per-model reliability stats.
- Response includes whether org policy is active.
Production requirement:
- Reliability stats should be explainable: source, window, sample count, last-updated time.
/api/doctor/models
Behavior:
- Requires access token.
- Uses user's enabled/compliant pool.
- Default shallow checks avoid real token spend.
- Optional deep check can call providers.
- Returns reachability, latency, credential count, and exhaustion flags.
Production requirement:
- Deep checks must be clearly labeled in the UI and rate limited.
- Provider auth errors should have support-safe messages.
/api/doctor/launch
Behavior:
- Requires admin access.
- Returns schema version 1 with
paid_launch_ready,overall_status,checks,blockers, andwarnings. - Reports only whether required launch evidence is present or blocked; secret values are never returned.
- Checks YooKassa live configuration, fiscal receipt provider configuration,
scheduler/operator dry-run evidence, strict all-active provider availability
evidence, live cost/capacity calibration evidence, seller/entity facts, legal
approval evidence, and whether
web/lib/legal-docs.tsstill contains draft launch blockers.
Production requirement:
- Treat this endpoint as an operator readiness aid, not legal advice.
- A green response is not a substitute for the legal/accounting/provider
evidence recorded in
docs/legal-launch-checklist.md.
/api/stream/run
Behavior:
- Requires access token.
- Validates request shape and idempotency key.
- Applies account allowlist and compliance policy.
- Scores candidate models.
- Can run scout/final, MoA, Self-MoA, specialized pipelines.
- Emits NDJSON lifecycle/progress frames.
- Persists
UsageEvent. - Debits completed positive-cost usage into
WalletLedgerEntryandCreditWalletthroughrecordUsageDebit. - If
PLYRUM_BILLING_ENFORCE_BALANCE=1, rejects non-dev requests with non-retryable402 billingbefore provider calls when estimated route cost exceeds spendable wallet balance. - Under the same flag, reserves estimated spend before provider calls and releases or consumes the hold when the run fails, is cancelled, completes at zero cost, or is debited into the wallet ledger.
- Records reliability events and provider failures.
Production requirements:
- Keep balance hold/reservation and trial quota behavior covered as real top-up lands.
- Add clearer user-facing error classes for provider timeouts and empty model outputs.
Environment Variables
Core web:
DATABASE_URLREDIS_URLJWT_PRIVATE_KEYorJWT_PRIVATE_KEY_FILEJWT_PUBLIC_KEYorJWT_PUBLIC_KEY_FILEACCESS_TOKEN_TTLREFRESH_TOKEN_TTL
Provider/model:
PLYRUM_PROVIDER_MOCKPLYRUM_MODELS_MD_PATHPLYRUM_OPENAI_BASE_URLPLYRUM_OPENAI_API_KEYPLYRUM_OPENAI_API_KEYSgpt_base_url/gpt_keylegacy aliases for the same OpenAI-compatible endpoint and keyANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKENprimary defaults for the Anthropic-compatible Claude endpointPLYRUM_ANTHROPIC_BASE_URL/PLYRUM_ANTHROPIC_AUTH_TOKENlegacy aliasesPLYRUM_ANTHROPIC_AUTH_TOKENSGROQ_API_KEYFIREWORKS_API_KEY/PLYRUM_FIREWORKS_API_KEYwhere configured by local model catalogNVIDIA_API_KEY/PLYRUM_NVIDIA_API_KEYwhere configured by local model catalogLINGHANGAPI_API_KEY/PLYRUM_LINGHANGAPI_API_KEY/linghangapi_api_keywhere configured by local model catalogOPENROUTER_API_KEY/PLYRUM_OPENROUTER_API_KEY/openrouter_api_keywhere configured by local model catalogOPENROUTER_BASE_URL/PLYRUM_OPENROUTER_BASE_URL; defaulthttps://openrouter.ai/api/v1- OpenRouter GPT-OSS models can emit reasoning tokens before visible content;
provider calls and
/api/doctor/modelsuse a small output-token floor for those IDs so shallow probes do not misclassify them as empty responses. - Provider base URLs are validated before provider fetches. Plain
http, private IPs, cloud metadata hosts, userinfo URLs and localhost are blocked by default. For explicit local provider gateways only, setPLYRUM_ALLOW_LOCAL_PROVIDER_BASE_URLS=1or the narrowerPLYRUM_ALLOW_LOCAL_<PROVIDER>_BASE_URL=1, for examplePLYRUM_ALLOW_LOCAL_OPENAI_BASE_URL=1.
Billing:
PLYRUM_PRICING_PATHPLYRUM_FX_SNAPSHOT_PATHPLYRUM_BILLING_ENFORCE_BALANCEPLYRUM_ADMIN_USER_IDScomma-separated user ids allowed to call admin billing endpoints.PLYRUM_ADMIN_CREDIT_MAX_RUBmaximum manual credit per request; default1000000.PLYRUM_WEB_AUDIT_DIRoptional JSONL audit directory. In tests, file audit writes are disabled unless this is explicitly set.PLYRUM_WEB_AUDIT_DB_DISABLED=1disables DB-backed web audit writes.PLYRUM_WEB_AUDIT_DB_STRICT=1makes DB audit write failures fail the originating request instead of falling back to best effort.PLYRUM_PROVIDER_AVAILABILITY_EVIDENCErecords strict all-active provider availability evidence for/api/doctor/launch.PLYRUM_PROVIDER_COST_CAPACITY_CALIBRATION_EVIDENCErecords live route, cost, latency and failure calibration evidence for/api/doctor/launch.PLYRUM_PROVIDER_CALIBRATION_REPORTwrites the orchestration smoke calibration artifact;scripts/smoke.shpoints it at.smoke/provider-calibration.json.PAYMENTS_PROVIDER=mockfor sandbox pending-checkout API. Keep unset ordisabledunless explicitly testing checkout contracts.PAYMENTS_MOCK_WEBHOOK_SECRETfor sandbox mock webhook wallet credit tests.PAYMENTS_PROVIDER=yookassato enable YooKassa hosted checkout and webhook processing.YOOKASSA_SHOP_IDYOOKASSA_SECRET_KEYYOOKASSA_RETURN_URLYOOKASSA_API_BASE_URLoptional; defaulthttps://api.yookassa.ru/v3.PAYMENTS_LIVE=1requires HTTPS YooKassa return URL.PAYMENTS_MIN_TOPUP_RUBPAYMENTS_MAX_TOPUP_RUBPLYRUM_RECONCILE_BASE_URL/PLYRUM_RECONCILE_TOKEN/PLYRUM_RECONCILE_LIMITfor the external YooKassa batch reconciliation runner (pnpm -C web reconcile:yookassa).PLYRUM_FISCAL_RECONCILE_BASE_URL/PLYRUM_FISCAL_RECONCILE_TOKEN/PLYRUM_FISCAL_RECONCILE_LIMITfor the external fiscal receipt batch reconciliation runner (pnpm -C web reconcile:fiscal).PLYRUM_PAYMENT_PROVIDER_PRODUCTION_EVIDENCEPLYRUM_FISCAL_PROVIDER_APPROVAL_EVIDENCEPLYRUM_RECONCILIATION_DRY_RUN_EVIDENCEPLYRUM_LEGAL_APPROVAL_IDPLYRUM_LEGAL_DOCS_VERSIONPLYRUM_SELLER_LEGAL_NAMEPLYRUM_SELLER_TAX_IDPLYRUM_SELLER_REGISTERED_ADDRESSPLYRUM_SUPPORT_EMAILPLYRUM_REFUND_SUPPORT_EMAILPLYRUM_PRIVACY_CONTACT_EMAILYOOKASSA_VAT_CODEYOOKASSA_TAX_SYSTEM_CODE
Local dev:
PLYRUM_DEV_SUPERACCOUNT_ENABLEDPLYRUM_DEV_SUPERACCOUNT_EMAILPLYRUM_DEV_SUPERACCOUNT_PASSWORDPLYRUM_DEV_SUPERACCOUNT_USER_ID
Future payments:
- see
docs/billing-and-payments.md.
Local Runbook
Start DB services:
cd /Users/example/plyrum
docker compose up -d postgres redis
Prepare web DB:
export DATABASE_URL="postgresql://plyrum:plyrum_dev@localhost:5432/plyrum"
pnpm -C web db:generate
pnpm -C web db:migrate
Start web:
PLYRUM_PROVIDER_MOCK=0 \
PLYRUM_DEV_SUPERACCOUNT_EMAIL=dev@plyrum.local \
PLYRUM_DEV_SUPERACCOUNT_PASSWORD=plyrum-dev-superaccount \
pnpm -C web dev -p 3000
Build and start CLI:
cargo build --release -p plyrum-cli
target/release/plyrum config --set api_base_url=http://localhost:3000
target/release/plyrum auth login --email dev@plyrum.local --password plyrum-dev-superaccount
target/release/plyrum
Health check:
curl -fsS http://localhost:3000/api/health
Smoke and Gates
Core gates:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace -- --test-threads=1
pnpm -C web test
pnpm -C web run typecheck
pnpm -C web run lint
pnpm -C web run build
make trust-guard
make smoke
Mock orchestration smoke:
PLYRUM_SMOKE_BASE_URL=http://localhost:3000 pnpm -C web smoke:orchestration
YooKassa batch reconciliation runner:
PLYRUM_RECONCILE_BASE_URL=http://localhost:3000 \
PLYRUM_RECONCILE_TOKEN=<admin-jwt> \
PLYRUM_RECONCILE_LIMIT=25 \
pnpm -C web reconcile:yookassa
Fiscal receipt reconciliation runner:
PLYRUM_FISCAL_RECONCILE_BASE_URL=http://localhost:3000 \
PLYRUM_FISCAL_RECONCILE_TOKEN=<admin-jwt> \
PLYRUM_FISCAL_RECONCILE_LIMIT=25 \
pnpm -C web reconcile:fiscal
Paid-launch readiness doctor:
curl -fsS \
-H "Authorization: Bearer <admin-jwt>" \
http://localhost:3000/api/doctor/launch
Launch-readiness smoke:
PLYRUM_LAUNCH_READINESS_BASE_URL=http://localhost:3000 \
PLYRUM_LAUNCH_READINESS_USER_TOKEN=<non-admin-jwt> \
pnpm -C web smoke:launch-readiness
By default this proves non-admin access to /api/doctor/launch is denied and
writes .smoke/launch-readiness.json. Set
PLYRUM_LAUNCH_READINESS_ADMIN_TOKEN=<admin-jwt> to also validate the
readiness response shape. Set PLYRUM_LAUNCH_READINESS_REQUIRE_ADMIN=1 when a
release gate must fail if the admin token is absent.
scripts/smoke.sh supplies a local-only smoke admin JWT automatically by
signing smoke-admin-user with the smoke JWT keypair and starting the web
server with PLYRUM_ADMIN_USER_IDS=smoke-admin-user. This keeps the release
smoke evidence local and repeatable while avoiding real provider or payment
credentials.
Scheduled reconciliation:
.github/workflows/payment-reconciliation.ymlruns every six hours and can also be triggered manually.- Configure repository variables
PLYRUM_RECONCILE_BASE_URL,PLYRUM_RECONCILE_LIMIT,PLYRUM_FISCAL_RECONCILE_BASE_URL, andPLYRUM_FISCAL_RECONCILE_LIMITas needed. - Configure repository secrets
PLYRUM_RECONCILE_TOKENandPLYRUM_FISCAL_RECONCILE_TOKENwith admin JWTs. The fiscal job falls back to the YooKassa base URL/token if fiscal-specific values are omitted. - The workflow skips safely when required URL/token values are not configured.
- Operators must inspect a failed workflow run and the redacted audit events before retrying, because a rejection may indicate provider amount/status mismatch rather than a transient network error.
Live smoke:
PLYRUM_SMOKE_LIVE=1 \
PLYRUM_SMOKE_BASE_URL=http://localhost:3000 \
PLYRUM_PROVIDER_CALIBRATION_REPORT=.smoke/provider-calibration.json \
PLYRUM_SMOKE_TOKEN=<jwt> \
pnpm -C web smoke:orchestration
smoke:orchestration writes a provider calibration report; scripts/smoke.sh
sets the path to root .smoke/provider-calibration.json so CI uploads it with
the other smoke artifacts. The report records route cost estimates, capacity
decisions, stream latency, canonical usage cost metadata, lifecycle evidence
and a copyable provider-calibration:<sha16> evidence id without storing
prompts, answers or credentials. For paid-launch evidence, review the live
artifact and copy its id or artifact URL into
PLYRUM_PROVIDER_COST_CAPACITY_CALIBRATION_EVIDENCE.
The scheduled .github/workflows/live-smoke.yml run stays shallow by default.
For release evidence, trigger it manually with
provider_availability_deep=true and provider_availability_require_all=true
to make scripts/smoke.sh run provider availability with
PLYRUM_AVAILABILITY_DEEP=1 and PLYRUM_AVAILABILITY_REQUIRE_ALL=1.
Provider availability smoke:
PLYRUM_AVAILABILITY_TOKEN=<jwt> \
PLYRUM_AVAILABILITY_REPORT=.smoke/provider-availability.json \
pnpm -C web smoke:availability
PLYRUM_AVAILABILITY_DEEP=1 \
PLYRUM_AVAILABILITY_REQUIRE_ALL=1 \
PLYRUM_AVAILABILITY_TOKEN=<jwt> \
pnpm -C web smoke:availability
The provider availability report includes an evidence_id field such as
provider-availability:<sha16>. When the strict/deep release run is reviewed
and accepted, copy that id or the artifact URL into
PLYRUM_PROVIDER_AVAILABILITY_EVIDENCE for /api/doctor/launch.
Browser E2E:
pnpm -C web test:e2e
Note: mock checkout/webhook/refund/reconciliation paths exist; YooKassa sandbox browser E2E remains blocked until safe sandbox credentials and provider flow access are available.
CI Workflows
| Workflow | Purpose |
|---|---|
.github/workflows/rust.yml | Rust fmt, clippy, tests, coverage thresholds. |
.github/workflows/web.yml | Web install, tests, typecheck, build. |
.github/workflows/smoke.yml | Trust guard, release-manifest check and mock vertical smoke; uploads .smoke/web.log, provider calibration, provider availability and launch-readiness artifacts. |
.github/workflows/live-smoke.yml | Scheduled live provider smoke with real credentials; uploads TTFT, provider calibration, provider availability and launch-readiness artifacts. |
.github/workflows/payment-reconciliation.yml | Scheduled YooKassa payment/refund and fiscal receipt reconciliation, skipped when secrets are absent. |
.github/workflows/security.yml | Cargo audit, pnpm audit, gitleaks. |
.github/workflows/trust-guard.yml | Intended-tree provider-key guard and gitleaks. |
Production Operations Needed
Before production:
- Managed Postgres with daily backups and restore drill.
- Managed Redis or equivalent cache.
- Secret manager for JWT keys, provider keys, payment keys.
- OTEL collector and dashboards for request latency, TTFT, provider failures, model reliability, cost, balance ledger failures.
- Error tracking with redaction.
- Admin dashboard or admin CLI for support actions.
- Payment reconciliation job.
- Usage/billing reconciliation job.
- Refresh-token cleanup job.
- Audit-log retention job or explicit operator prune process through
POST /api/audit. - Memory/persona retention policy.
- Incident response checklist.
Release Checklist
For every release:
- Run all core gates.
- Run smoke with mock provider.
- Run live smoke against configured providers.
- Run browser E2E.
- Run trust guard and secret scan.
- Review DB migrations.
- Confirm no provider keys are present in
crates/or client bundles. - Confirm pricing table and public tariff page match.
- Confirm
/api/healthis green in target environment. - Confirm rollback path.
- Verify
docs/release-manifest.jsonwithnode scripts/verify-release-manifest.mjs --json. - Stage only explicit manifest/reviewed paths; never use
git add .in the current dirty workspace. - Confirm
.smoke/launch-readiness.jsonexists from smoke; for a release gate, providePLYRUM_LAUNCH_READINESS_ADMIN_TOKENand require admin readiness validation.
Additional checklist after payments:
- Provider sandbox payment succeeds.
- Webhook replay does not double-credit.
- Refund flow updates ledger.
- Fiscal receipt is created or correctly delegated.
- Balance cache invalidates after top-up and usage debit.
- Payment secrets do not appear in logs or bundles.