← Back

DOCS

Документация

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/login and /api/auth/register.

Endpoint Summary

MethodPathAuthPurpose
GET/api/healthNoChecks Postgres and Redis.
POST/api/auth/registerNoCreates user, wallet, refresh token.
POST/api/auth/loginNoVerifies password/dev superaccount and returns tokens.
POST/api/auth/refreshRefresh tokenRotates refresh token and returns new access token.
GET/api/balanceYesReturns current spendable wallet balance.
GET/api/usageYesReturns completed usage rows with canonical usage.
GET/api/billing/ledgerYesReturns user-scoped wallet ledger entries.
POST/api/billing/admin/creditAdminCreates an idempotent manual wallet credit.
GET/api/paymentsYesReturns current user's payment history.
POST/api/payments/checkoutYesCreates mock or YooKassa pending checkout depending on PAYMENTS_PROVIDER.
POST/api/payments/webhook/mockSecretProcesses sandbox mock payment webhooks and idempotent wallet top-ups.
POST/api/payments/webhook/yookassaProvider webhookVerifies YooKassa payment state by provider re-fetch and credits wallet on success.
POST/api/payments/reconcileAdminRe-fetches YooKassa payment or refund state and applies missed succeeded/canceled provider states idempotently.
POST/api/payments/refundAdminCreates idempotent mock refunds and durable YooKassa provider refunds with ledger debits after provider success.
POST/api/payments/fiscal-receipts/reconcileAdminSubmits/reconciles pending fiscal payment/refund receipts one-at-a-time or in bounded batch mode.
GET/api/auditAdminExports DB-backed web audit events as JSON or NDJSON with filters.
POST/api/auditAdminRuns bounded audit-retention prune actions.
GET/api/modelsNoReturns model catalog, schema version 2.
GET/api/account/modelsYesReturns current account model settings.
PUT/api/account/modelsYesSaves enabled models/reasoning settings; rejects all-disabled pool.
GET/api/reliabilityYesReturns compliance-filtered model reliability stats.
GET/api/doctor/modelsYesChecks model configured/reachable/compliant status.
GET/api/doctor/launchAdminReports redacted paid-launch readiness checks for payments, fiscal receipts, scheduler evidence and legal/entity blockers.
POST/api/stream/runYesStreams 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 CreditWallet with 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.balanceMicroRub minus active BalanceReservation.estimatedMicroRub holds.
  • Includes total_micro_rub and reserved_micro_rub for 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 BalanceReservation rows.

/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_rub and balance_after_micro_rub.

Production requirement:

  • Payment, PaymentRefund, PaymentWebhookEvent, FiscalReceipt, and Invoice tables 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 pending FiscalReceipt rows, and POST /api/payments/fiscal-receipts/reconcile can submit/reconcile those rows through a mock provider or a guarded HTTP fiscalization endpoint. YooKassa checkout requires explicit accept_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_rub against PAYMENTS_MIN_TOPUP_RUB / PAYMENTS_MAX_TOPUP_RUB.
  • Returns 503 payments_not_configured unless PAYMENTS_PROVIDER is set.
  • With PAYMENTS_PROVIDER=mock, creates a local Payment(status=pending) row and returns a sandbox confirmation_url.
  • With PAYMENTS_PROVIDER=yookassa, requires YOOKASSA_SHOP_ID, YOOKASSA_SECRET_KEY, and an absolute YOOKASSA_RETURN_URL; creates a local pending payment, calls YooKassa /v3/payments with Idempotence-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 either amount_rub or amount_micro_rub.
  • Bounds amount by PLYRUM_ADMIN_CREDIT_MAX_RUB (default 1000000).
  • 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 in WebAuditEvent and 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.
  • GET accepts kind, status, actor_user_id, target_user_id, from, to, limit and format=json|ndjson.
  • GET exports DB-backed WebAuditEvent rows with schema version 1 and records an audit.export event after a successful export.
  • POST accepts { "action": "prune", "before": "<ISO date>" } or { "action": "prune", "retention_days": 365 }.
  • POST deletes rows older than the cutoff and records an audit.retention_prune operator 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_SECRET and matching x-plyrum-mock-webhook-secret header.
  • Accepts event_id, payment_id, status (succeeded or canceled) and optional amount_micro_rub.
  • Stores PaymentWebhookEvent rows with payload hashes.
  • Rejects same-event payload mismatches and amount mismatches.
  • For succeeded, credits wallet exactly once through WalletLedgerEntry(type=topup, sourceType=payment) and updates CreditWallet.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.succeeded and payment.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 through WalletLedgerEntry(type=topup, sourceType=payment) and updates CreditWallet.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_id for a local Payment(provider=yookassa) with a stored providerPaymentId, or refund_id / provider_refund_id for a local PaymentRefund(provider=yookassa) with a stored providerRefundId.
  • 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 succeeded is passed through the same idempotent processing path as payment.succeeded webhook and can create exactly one top-up ledger entry and one pending payment receipt.
  • Provider canceled is passed through the same idempotent processing path as payment.canceled webhook and does not credit the wallet.
  • Provider non-final states such as pending update rawProviderStatus, return 202, and do not mutate balance.
  • Refund provider succeeded calls 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 durable PaymentRefund row with ledgerEntryId and completedAt.
  • Refund provider pending updates PaymentRefund.rawProviderStatus, returns 202, and does not mutate balance.
  • Refund provider canceled marks the PaymentRefund canceled 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:yookassa with PLYRUM_RECONCILE_BASE_URL, PLYRUM_RECONCILE_TOKEN and optional PLYRUM_RECONCILE_LIMIT.
  • Fiscal receipt submission/reconciliation has a separate bounded runner: pnpm -C web reconcile:fiscal with PLYRUM_FISCAL_RECONCILE_BASE_URL, PLYRUM_FISCAL_RECONCILE_TOKEN and optional PLYRUM_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=mock for sandbox/operator proof or PLYRUM_FISCAL_RECEIPTS_PROVIDER=http with PLYRUM_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 receipt succeeded and records a deterministic mock-fiscal-<receipt_id> provider receipt id.
  • For http, posts a bounded fiscal payload to the configured endpoint with Idempotence-Key: fiscal_receipt:<receipt_id> and optional bearer token from PLYRUM_FISCAL_RECEIPTS_TOKEN. If PLYRUM_FISCAL_RECEIPTS_STATUS_ENDPOINT is configured, submitted receipts can be rechecked by provider receipt id.
  • Updates only FiscalReceipt.status, providerReceiptId, and rawPayload. 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, and idempotency_key.
  • Refunds Payment(provider=mock, status=succeeded) rows locally and Payment(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 payment refunded, invalidates the user's balance cache, and rejects insufficient refundable mock balance.
  • For YooKassa payments, calls /v3/refunds with Basic auth and Idempotence-Key; local wallet/payment mutation happens only after provider returns status=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 by refund_id or provider_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.
  • GET returns account model settings.
  • PUT accepts model_settings or enabled_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, and warnings.
  • 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.ts still 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 WalletLedgerEntry and CreditWallet through recordUsageDebit.
  • If PLYRUM_BILLING_ENFORCE_BALANCE=1, rejects non-dev requests with non-retryable 402 billing before 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_URL
  • REDIS_URL
  • JWT_PRIVATE_KEY or JWT_PRIVATE_KEY_FILE
  • JWT_PUBLIC_KEY or JWT_PUBLIC_KEY_FILE
  • ACCESS_TOKEN_TTL
  • REFRESH_TOKEN_TTL

Provider/model:

  • PLYRUM_PROVIDER_MOCK
  • PLYRUM_MODELS_MD_PATH
  • PLYRUM_OPENAI_BASE_URL
  • PLYRUM_OPENAI_API_KEY
  • PLYRUM_OPENAI_API_KEYS
  • gpt_base_url / gpt_key legacy aliases for the same OpenAI-compatible endpoint and key
  • ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN primary defaults for the Anthropic-compatible Claude endpoint
  • PLYRUM_ANTHROPIC_BASE_URL / PLYRUM_ANTHROPIC_AUTH_TOKEN legacy aliases
  • PLYRUM_ANTHROPIC_AUTH_TOKENS
  • GROQ_API_KEY
  • FIREWORKS_API_KEY / PLYRUM_FIREWORKS_API_KEY where configured by local model catalog
  • NVIDIA_API_KEY / PLYRUM_NVIDIA_API_KEY where configured by local model catalog
  • LINGHANGAPI_API_KEY / PLYRUM_LINGHANGAPI_API_KEY / linghangapi_api_key where configured by local model catalog
  • OPENROUTER_API_KEY / PLYRUM_OPENROUTER_API_KEY / openrouter_api_key where configured by local model catalog
  • OPENROUTER_BASE_URL / PLYRUM_OPENROUTER_BASE_URL; default https://openrouter.ai/api/v1
  • OpenRouter GPT-OSS models can emit reasoning tokens before visible content; provider calls and /api/doctor/models use 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, set PLYRUM_ALLOW_LOCAL_PROVIDER_BASE_URLS=1 or the narrower PLYRUM_ALLOW_LOCAL_<PROVIDER>_BASE_URL=1, for example PLYRUM_ALLOW_LOCAL_OPENAI_BASE_URL=1.

Billing:

  • PLYRUM_PRICING_PATH
  • PLYRUM_FX_SNAPSHOT_PATH
  • PLYRUM_BILLING_ENFORCE_BALANCE
  • PLYRUM_ADMIN_USER_IDS comma-separated user ids allowed to call admin billing endpoints.
  • PLYRUM_ADMIN_CREDIT_MAX_RUB maximum manual credit per request; default 1000000.
  • PLYRUM_WEB_AUDIT_DIR optional JSONL audit directory. In tests, file audit writes are disabled unless this is explicitly set.
  • PLYRUM_WEB_AUDIT_DB_DISABLED=1 disables DB-backed web audit writes.
  • PLYRUM_WEB_AUDIT_DB_STRICT=1 makes DB audit write failures fail the originating request instead of falling back to best effort.
  • PLYRUM_PROVIDER_AVAILABILITY_EVIDENCE records strict all-active provider availability evidence for /api/doctor/launch.
  • PLYRUM_PROVIDER_COST_CAPACITY_CALIBRATION_EVIDENCE records live route, cost, latency and failure calibration evidence for /api/doctor/launch.
  • PLYRUM_PROVIDER_CALIBRATION_REPORT writes the orchestration smoke calibration artifact; scripts/smoke.sh points it at .smoke/provider-calibration.json.
  • PAYMENTS_PROVIDER=mock for sandbox pending-checkout API. Keep unset or disabled unless explicitly testing checkout contracts.
  • PAYMENTS_MOCK_WEBHOOK_SECRET for sandbox mock webhook wallet credit tests.
  • PAYMENTS_PROVIDER=yookassa to enable YooKassa hosted checkout and webhook processing.
  • YOOKASSA_SHOP_ID
  • YOOKASSA_SECRET_KEY
  • YOOKASSA_RETURN_URL
  • YOOKASSA_API_BASE_URL optional; default https://api.yookassa.ru/v3.
  • PAYMENTS_LIVE=1 requires HTTPS YooKassa return URL.
  • PAYMENTS_MIN_TOPUP_RUB
  • PAYMENTS_MAX_TOPUP_RUB
  • PLYRUM_RECONCILE_BASE_URL / PLYRUM_RECONCILE_TOKEN / PLYRUM_RECONCILE_LIMIT for the external YooKassa batch reconciliation runner (pnpm -C web reconcile:yookassa).
  • PLYRUM_FISCAL_RECONCILE_BASE_URL / PLYRUM_FISCAL_RECONCILE_TOKEN / PLYRUM_FISCAL_RECONCILE_LIMIT for the external fiscal receipt batch reconciliation runner (pnpm -C web reconcile:fiscal).
  • PLYRUM_PAYMENT_PROVIDER_PRODUCTION_EVIDENCE
  • PLYRUM_FISCAL_PROVIDER_APPROVAL_EVIDENCE
  • PLYRUM_RECONCILIATION_DRY_RUN_EVIDENCE
  • PLYRUM_LEGAL_APPROVAL_ID
  • PLYRUM_LEGAL_DOCS_VERSION
  • PLYRUM_SELLER_LEGAL_NAME
  • PLYRUM_SELLER_TAX_ID
  • PLYRUM_SELLER_REGISTERED_ADDRESS
  • PLYRUM_SUPPORT_EMAIL
  • PLYRUM_REFUND_SUPPORT_EMAIL
  • PLYRUM_PRIVACY_CONTACT_EMAIL
  • YOOKASSA_VAT_CODE
  • YOOKASSA_TAX_SYSTEM_CODE

Local dev:

  • PLYRUM_DEV_SUPERACCOUNT_ENABLED
  • PLYRUM_DEV_SUPERACCOUNT_EMAIL
  • PLYRUM_DEV_SUPERACCOUNT_PASSWORD
  • PLYRUM_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.yml runs every six hours and can also be triggered manually.
  • Configure repository variables PLYRUM_RECONCILE_BASE_URL, PLYRUM_RECONCILE_LIMIT, PLYRUM_FISCAL_RECONCILE_BASE_URL, and PLYRUM_FISCAL_RECONCILE_LIMIT as needed.
  • Configure repository secrets PLYRUM_RECONCILE_TOKEN and PLYRUM_FISCAL_RECONCILE_TOKEN with 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

WorkflowPurpose
.github/workflows/rust.ymlRust fmt, clippy, tests, coverage thresholds.
.github/workflows/web.ymlWeb install, tests, typecheck, build.
.github/workflows/smoke.ymlTrust guard, release-manifest check and mock vertical smoke; uploads .smoke/web.log, provider calibration, provider availability and launch-readiness artifacts.
.github/workflows/live-smoke.ymlScheduled live provider smoke with real credentials; uploads TTFT, provider calibration, provider availability and launch-readiness artifacts.
.github/workflows/payment-reconciliation.ymlScheduled YooKassa payment/refund and fiscal receipt reconciliation, skipped when secrets are absent.
.github/workflows/security.ymlCargo audit, pnpm audit, gitleaks.
.github/workflows/trust-guard.ymlIntended-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:

  1. Run all core gates.
  2. Run smoke with mock provider.
  3. Run live smoke against configured providers.
  4. Run browser E2E.
  5. Run trust guard and secret scan.
  6. Review DB migrations.
  7. Confirm no provider keys are present in crates/ or client bundles.
  8. Confirm pricing table and public tariff page match.
  9. Confirm /api/health is green in target environment.
  10. Confirm rollback path.
  11. Verify docs/release-manifest.json with node scripts/verify-release-manifest.mjs --json.
  12. Stage only explicit manifest/reviewed paths; never use git add . in the current dirty workspace.
  13. Confirm .smoke/launch-readiness.json exists from smoke; for a release gate, provide PLYRUM_LAUNCH_READINESS_ADMIN_TOKEN and require admin readiness validation.

Additional checklist after payments:

  1. Provider sandbox payment succeeds.
  2. Webhook replay does not double-credit.
  3. Refund flow updates ledger.
  4. Fiscal receipt is created or correctly delegated.
  5. Balance cache invalidates after top-up and usage debit.
  6. Payment secrets do not appear in logs or bundles.