@voltro/cli 0.51.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +127 -0
- package/dist/{agentsMd-D6yD7IQv.js → agentsMd-0l980yhL.js} +4 -1
- package/dist/agentsMd-SDDSkyl4.js +2 -0
- package/dist/apiBuild-BYBpL7Pz.js +2 -0
- package/dist/{apiBuild-CPDHXF72.js → apiBuild-CSFI8QGq.js} +3 -3
- package/dist/bin.js +1 -1
- package/dist/build-CPgcMQug.js +793 -0
- package/dist/checkCommand-2SbqzukH.js +2 -0
- package/dist/{checkCommand-DNuPiWMc.js → checkCommand-COmqc2cB.js} +92 -46
- package/dist/{cloudCmd-F4YJeqM3.js → cloudCmd-QUXh-b5w.js} +1 -1
- package/dist/codegen-CctkDO-1.js +2 -0
- package/dist/{codegen-CrMXs4hb.js → codegen-VF479Cnb.js} +1 -1
- package/dist/{codegenCommand-BNBHcNNj.js → codegenCommand-DCdG2JN-.js} +12 -12
- package/dist/{codemodRunner-BDVixlSw.js → codemodRunner-r7J9lIa7.js} +588 -540
- package/dist/{commands-B1OiS9bX.js → commands-Cc_nV8WI.js} +35 -35
- package/dist/{dashboardCommand-C-vvPY1B.js → dashboardCommand-C-gKvwqh.js} +5 -5
- package/dist/{dataCommand-C1GxXW5q.js → dataCommand-BgpBHnlB.js} +27 -27
- package/dist/dbCommand-DNb6yeOG.js +2 -0
- package/dist/{dbCommand-If4Y1xQ-.js → dbCommand-sHedr-NJ.js} +2 -2
- package/dist/dev--A3nsxA3.js +3 -0
- package/dist/{dev-kdAg9Q7l.js → dev-CRHoCEiy.js} +2142 -2103
- package/dist/doctorCommand-CqoWA2p5.js +2 -0
- package/dist/{doctorCommand-nKmeW78u.js → doctorCommand-DtfJ3FA6.js} +314 -234
- package/dist/{dormancyCommand-CY3wa_SW.js → dormancyCommand-Drn7o0No.js} +1 -1
- package/dist/{embeddingsCommand-BDLIgje_.js → embeddingsCommand-Z-jO1fWN.js} +1 -1
- package/dist/{envCommand-C6V_xVlT.js → envCommand-D4gCrrTZ.js} +8 -8
- package/dist/{evolveCommand-D3c4DSfN.js → evolveCommand-CMROeKeA.js} +2 -2
- package/dist/fileConventions-DOqD3lPS.js +34 -0
- package/dist/{fileTaxonomy-CJfgOllU.js → fileTaxonomy-DvDUV9wq.js} +1 -1
- package/dist/frameworkTableAssembly-C6ETawPR.js +2 -0
- package/dist/{frameworkTableAssembly-BwJVEKLr.js → frameworkTableAssembly-w-XnLa3q.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/{infoCommand-BnRFEF1o.js → infoCommand-DXM868o_.js} +1 -1
- package/dist/inspectMetrics-CGF94puw.js +143 -0
- package/dist/{metaCommands-CfRLra0s.js → metaCommands-C6RFmF1r.js} +2 -2
- package/dist/{migrate-DehuBakM.js → migrate-D0F-eTlK.js} +2 -2
- package/dist/{pageConvention-cEiRxdab.js → pageConvention-CzUiSbtU.js} +1 -1
- package/dist/{privacyCommand-XejDMvmu.js → privacyCommand-DGdopOI6.js} +1 -1
- package/dist/{projectScaffold-mIX_DpSe.js → projectScaffold-B4dmTlwT.js} +1 -1
- package/dist/{projectScaffold-BIl97_E6.js → projectScaffold-EzlErR4E.js} +1 -1
- package/dist/{renderModeScan-D7J1B7Kw.js → renderModeScan-CcH2X1_D.js} +25 -10
- package/dist/{renderProfile-1OWWAAtx.js → renderProfile-Ck32Fzxr.js} +2 -2
- package/dist/{runtimeTrace-ZsBU7Tkx.js → runtimeTrace-BPQyCmC5.js} +1 -1
- package/dist/{sdkgen-O4XqWOjM.js → sdkgen-Se88ifTd.js} +1 -1
- package/dist/serveCommand-DLc-BznW.js +2 -0
- package/dist/{serveCommand-DdiYNBBu.js → serveCommand-DkP3OT0W.js} +885 -868
- package/dist/serveEntry.js +1 -1
- package/dist/start-DfL3fOiN.js +3 -0
- package/dist/start-jw89Xbqy.js +1339 -0
- package/dist/startEntry.js +1 -1
- package/dist/{staticCommand-Dr2M6tpU.js → staticCommand-BwNEDlSU.js} +1 -1
- package/dist/{test-rXFq4S76.js → test-f3amja6a.js} +1 -1
- package/dist/updateCommand-5gFVfK5q.js +2 -0
- package/dist/{updateCommand-Bs322Q78.js → updateCommand-BMk2e4ky.js} +1 -1
- package/dist/{webDev-B-ubQEMX.js → webDev-BgWL9gKV.js} +1156 -835
- package/dist/webDev-CZbTsDcH.js +2 -0
- package/dist/{webhooksCommand-FLYY9IXh.js → webhooksCommand-CoIO3jbj.js} +1 -1
- package/package.json +30 -17
- package/templates/AGENTS.core.md +11 -0
- package/templates/AGENTS.md +15 -4
- package/templates/agent-docs/_index.md +4 -4
- package/templates/agent-docs/_manifest.json +11 -11
- package/templates/agent-docs/cli.md +96 -14
- package/templates/agent-docs/data.md +210 -7
- package/templates/agent-docs/database/schema.md +1 -1
- package/templates/agent-docs/database/seedsdialects.md +1 -1
- package/templates/agent-docs/deployment.md +22 -3
- package/templates/agent-docs/introduction.md +46 -0
- package/templates/agent-docs/local-first-mobile.md +34 -7
- package/templates/agent-docs/plugins/ai-flows.md +1 -1
- package/templates/agent-docs/plugins/audit.md +5 -5
- package/templates/agent-docs/plugins/cdc-out.md +2 -2
- package/templates/agent-docs/plugins/{versioning.md → row-history.md} +22 -22
- package/templates/agent-docs/plugins/storage.md +2 -2
- package/templates/agent-docs/plugins.md +29 -7
- package/templates/agent-docs/reference.md +39 -2
- package/templates/agent-docs/routing.md +341 -47
- package/templates/agent-docs/schema-driven-ui.md +78 -2
- package/templates/agent-docs/security.md +125 -8
- package/templates/agent-docs/templates/apibackends.md +14 -14
- package/templates/agent-docs/templates/overview.md +1 -1
- package/templates/agent-docs/whats-new.md +76 -53
- package/templates/apps/api-ai/package.json +6 -7
- package/templates/apps/api-ai/tests/summarize.test.ts +1 -1
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -10
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/{api-versioning → api-row-history}/README.md +3 -3
- package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.server.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.server.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/app.config.ts +3 -3
- package/templates/apps/{api-versioning → api-row-history}/database/schema.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.server.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.ts +1 -1
- package/templates/apps/{api-versioning → api-row-history}/package.json +8 -8
- package/templates/apps/api-row-history/template.json +6 -0
- package/templates/apps/{api-versioning → api-row-history}/tests/documents.create.test.ts +1 -1
- package/templates/apps/api-saas/app.config.ts +1 -0
- package/templates/apps/api-saas/package.json +10 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +9 -9
- package/templates/apps/frontend-auth/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-cms/package.json +9 -9
- package/templates/apps/frontend-collab/package.json +10 -10
- package/templates/apps/frontend-collab/src/pages/page.test.tsx +10 -9
- package/templates/apps/frontend-collab/src/pages/page.tsx +42 -65
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +6 -7
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +6 -7
- package/templates/apps/frontend-portal/package.json +8 -8
- package/templates/apps/frontend-saas/package.json +8 -8
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/templates/apps/frontend-status/package.json +8 -8
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/agentsMd-Bu_XQgVf.js +0 -2
- package/dist/apiBuild-GDKuGOMV.js +0 -2
- package/dist/build-DETLZAFt.js +0 -752
- package/dist/checkCommand-CWcnDArJ.js +0 -2
- package/dist/codegen-DiMn2KkZ.js +0 -2
- package/dist/dbCommand-C27HIsGE.js +0 -2
- package/dist/dev-CK522MV5.js +0 -3
- package/dist/doctorCommand-BK4l18eG.js +0 -2
- package/dist/fileConventions-Cof68_BL.js +0 -33
- package/dist/frameworkTableAssembly-CVDB2hCq.js +0 -2
- package/dist/inspectMetrics-CfdKLh6t.js +0 -72
- package/dist/serveCommand-BRnPCxVd.js +0 -2
- package/dist/start-BLNmWkLa.js +0 -1154
- package/dist/start-Dzicuyw8.js +0 -3
- package/dist/updateCommand-eXB35SEv.js +0 -2
- package/dist/webDev-DposiF3j.js +0 -2
- package/templates/apps/api-versioning/template.json +0 -6
- /package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.ts +0 -0
- /package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.ts +0 -0
- /package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.server.ts +0 -0
- /package/templates/apps/{api-versioning → api-row-history}/tsconfig.json +0 -0
|
@@ -222,7 +222,7 @@ createVerifier({ secret: [process.env.WEBHOOK_SECRET, process.env.WEBHOOK_SECRET
|
|
|
222
222
|
...t === void 0 ? {} : { payload: t }
|
|
223
223
|
};
|
|
224
224
|
}, S = u({ scope: "voltro:webhooks" }), C = ["--out", "--name"], w = async (e) => {
|
|
225
|
-
let { walk: t, loadDiscovered: n } = await import("./dev
|
|
225
|
+
let { walk: t, loadDiscovered: n } = await import("./dev--A3nsxA3.js"), { outgoingFromEvents: r } = await import("./webhookDiscovery-il9ti-HE.js");
|
|
226
226
|
return r((await n(await t(e))).events.map((e) => ({
|
|
227
227
|
file: e.file,
|
|
228
228
|
descriptor: e.descriptor
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"description": "The `voltro` CLI — dev server, codegen, migrations, project scaffolding, agent-docs seeding, and production serve.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -718,6 +718,18 @@
|
|
|
718
718
|
"title": "`<I18nProvider>`: `timeZone` is its own prop, not an `intlConfig` member",
|
|
719
719
|
"kind": "transform"
|
|
720
720
|
},
|
|
721
|
+
{
|
|
722
|
+
"version": "0.52.0",
|
|
723
|
+
"id": "0.52.0/01_plugin-versioning-to-row-history",
|
|
724
|
+
"title": "@voltro/plugin-versioning → @voltro/plugin-row-history (the name now says what it does)",
|
|
725
|
+
"kind": "transform"
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
"version": "0.52.0",
|
|
729
|
+
"id": "0.52.0/02_http-interceptor-fail-closed",
|
|
730
|
+
"title": "A throwing `onHttpRequest` interceptor now refuses the request (500) instead of being ignored",
|
|
731
|
+
"kind": "manual"
|
|
732
|
+
},
|
|
721
733
|
{
|
|
722
734
|
"version": "0.6.0",
|
|
723
735
|
"id": "0.6.0/01_no-dev-session-secret",
|
|
@@ -793,22 +805,23 @@
|
|
|
793
805
|
"@effect/platform-node": "^0.108.0",
|
|
794
806
|
"@effect/sql": "^0.52.0",
|
|
795
807
|
"@effect/workflow": "^0.19.0",
|
|
796
|
-
"@voltro/ai": "0.
|
|
797
|
-
"@voltro/cache": "0.
|
|
798
|
-
"@voltro/
|
|
799
|
-
"@voltro/
|
|
800
|
-
"@voltro/
|
|
801
|
-
"@voltro/
|
|
802
|
-
"@voltro/
|
|
803
|
-
"@voltro/
|
|
804
|
-
"@voltro/plugin-
|
|
805
|
-
"@voltro/plugin-
|
|
806
|
-
"@voltro/plugin-
|
|
807
|
-
"@voltro/plugin-
|
|
808
|
-
"@voltro/
|
|
809
|
-
"@voltro/
|
|
810
|
-
"@voltro/
|
|
811
|
-
"@voltro/
|
|
808
|
+
"@voltro/ai": "0.52.0",
|
|
809
|
+
"@voltro/cache": "0.52.0",
|
|
810
|
+
"@voltro/client": "0.52.0",
|
|
811
|
+
"@voltro/data-transfer": "0.52.0",
|
|
812
|
+
"@voltro/database": "0.52.0",
|
|
813
|
+
"@voltro/env": "0.52.0",
|
|
814
|
+
"@voltro/kv": "0.52.0",
|
|
815
|
+
"@voltro/logger": "0.52.0",
|
|
816
|
+
"@voltro/plugin-auth": "0.52.0",
|
|
817
|
+
"@voltro/plugin-broadcast": "0.52.0",
|
|
818
|
+
"@voltro/plugin-mail": "0.52.0",
|
|
819
|
+
"@voltro/plugin-storage": "0.52.0",
|
|
820
|
+
"@voltro/plugin-webhooks": "0.52.0",
|
|
821
|
+
"@voltro/protocol": "0.52.0",
|
|
822
|
+
"@voltro/runtime": "0.52.0",
|
|
823
|
+
"@voltro/serverless": "0.52.0",
|
|
824
|
+
"@voltro/workflow": "0.52.0",
|
|
812
825
|
"chokidar": "^5.0.0",
|
|
813
826
|
"ioredis": "^5.11.1",
|
|
814
827
|
"tinyglobby": "^0.2.17",
|
package/templates/AGENTS.core.md
CHANGED
|
@@ -696,6 +696,17 @@ primitive → just save; the supervised dev loop respawns and regenerates.
|
|
|
696
696
|
- **Don't roll your own session token / ICU/i18n / job runner** — use
|
|
697
697
|
`signSession`/`verifySession`, `@voltro/i18n`, `@effect/workflow`.
|
|
698
698
|
- **Don't add `bullmq`/`temporal`/`react-query`/SWR** — see Mental model.
|
|
699
|
+
- **Don't build a GraphQL layer over the stores.** It would bypass the
|
|
700
|
+
reactivity path (source-based invalidation, per-delivery guards) — a second,
|
|
701
|
+
dead read path. External consumers → REST + OpenAPI (`defineRestRoute` +
|
|
702
|
+
`@voltro/plugin-openapi`); internal clients → RPC + live subscriptions.
|
|
703
|
+
- **Don't write `'use server'` / `'use client'` — there is no RSC.** Islands +
|
|
704
|
+
loaders + streaming SSR are the model; those directives mark a boundary this
|
|
705
|
+
framework does not have.
|
|
706
|
+
- **Don't split the app into microservices with service-to-service RPC.** One
|
|
707
|
+
monolith process, scaled by running more replicas (`@effect/cluster` shards
|
|
708
|
+
durable workflows across instances), is the architecture. An external system
|
|
709
|
+
boundary is REST + OpenAPI; a reliable outbound effect is `ctx.outbox`.
|
|
699
710
|
|
|
700
711
|
## Plugins
|
|
701
712
|
|
package/templates/AGENTS.md
CHANGED
|
@@ -696,6 +696,17 @@ primitive → just save; the supervised dev loop respawns and regenerates.
|
|
|
696
696
|
- **Don't roll your own session token / ICU/i18n / job runner** — use
|
|
697
697
|
`signSession`/`verifySession`, `@voltro/i18n`, `@effect/workflow`.
|
|
698
698
|
- **Don't add `bullmq`/`temporal`/`react-query`/SWR** — see Mental model.
|
|
699
|
+
- **Don't build a GraphQL layer over the stores.** It would bypass the
|
|
700
|
+
reactivity path (source-based invalidation, per-delivery guards) — a second,
|
|
701
|
+
dead read path. External consumers → REST + OpenAPI (`defineRestRoute` +
|
|
702
|
+
`@voltro/plugin-openapi`); internal clients → RPC + live subscriptions.
|
|
703
|
+
- **Don't write `'use server'` / `'use client'` — there is no RSC.** Islands +
|
|
704
|
+
loaders + streaming SSR are the model; those directives mark a boundary this
|
|
705
|
+
framework does not have.
|
|
706
|
+
- **Don't split the app into microservices with service-to-service RPC.** One
|
|
707
|
+
monolith process, scaled by running more replicas (`@effect/cluster` shards
|
|
708
|
+
durable workflows across instances), is the architecture. An external system
|
|
709
|
+
boundary is REST + OpenAPI; a reliable outbound effect is `ctx.outbox`.
|
|
699
710
|
|
|
700
711
|
## Plugins
|
|
701
712
|
|
|
@@ -717,7 +728,7 @@ each plugin's own README.
|
|
|
717
728
|
|
|
718
729
|
| Topic | Open | Summary |
|
|
719
730
|
|---|---|---|
|
|
720
|
-
| **What's new in 0.
|
|
731
|
+
| **What's new in 0.52.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
721
732
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
722
733
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
723
734
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -775,7 +786,7 @@ each plugin's own README.
|
|
|
775
786
|
| auth-workos | `node_modules/@voltro/cli/templates/agent-docs/plugins/auth-workos.md` (or `node_modules/@voltro/plugin-auth-workos/README.md`) | WorkOS AuthStrategy — verifies WorkOS AuthKit / SSO JWTs via JWKS (no API key) and maps org_id → tenantId. |
|
|
776
787
|
| billing | `node_modules/@voltro/cli/templates/agent-docs/plugins/billing.md` (or `node_modules/@voltro/plugin-billing/README.md`) | Subscriptions, plans, entitlements, and usage metering over a pluggable provider (Stripe + mock). Money is integer minor units. |
|
|
777
788
|
| broadcast | `node_modules/@voltro/cli/templates/agent-docs/plugins/broadcast.md` (or `node_modules/@voltro/plugin-broadcast/README.md`) | Cross-replica reactivity over a pub/sub bus (Redis / NATS) for non-postgres dialects — closes the single-instance gap so a write on one pod surfaces on another. |
|
|
778
|
-
| cdc-out | `node_modules/@voltro/cli/templates/agent-docs/plugins/cdc-out.md` (or `node_modules/@voltro/plugin-cdc-out/README.md`) | Declaratively mirror table changes outward to external sinks (webhook
|
|
789
|
+
| cdc-out | `node_modules/@voltro/cli/templates/agent-docs/plugins/cdc-out.md` (or `node_modules/@voltro/plugin-cdc-out/README.md`) | Declaratively mirror table changes outward to external sinks (webhook, plus a CdcSink interface for custom sinks) through a durable outbox — ordered per pipe, at-least-once from enqueue, retried with backoff, dead-lettered. |
|
|
779
790
|
| clickhouse | `node_modules/@voltro/cli/templates/agent-docs/plugins/clickhouse.md` (or `node_modules/@voltro/plugin-clickhouse/README.md`) | Production-grade OLAP AnalyticsSink over ClickHouse — self-hosted or ClickHouse Cloud — for billions of events with millisecond aggregates. |
|
|
780
791
|
| datadog | `node_modules/@voltro/cli/templates/agent-docs/plugins/datadog.md` (or `node_modules/@voltro/plugin-datadog/README.md`) | Agentless Datadog metrics exporter — pushes the unified Metrics-API to Datadog's /api/v2/series HTTP intake. |
|
|
781
792
|
| deactivation | `node_modules/@voltro/cli/templates/agent-docs/plugins/deactivation.md` (or `node_modules/@voltro/plugin-deactivation/README.md`) | A schema mixin that marks a subject as deactivated (can't log in) while keeping its data fully visible — the deliberate opposite of soft-delete. |
|
|
@@ -795,14 +806,14 @@ each plugin's own README.
|
|
|
795
806
|
| prometheus | `node_modules/@voltro/cli/templates/agent-docs/plugins/prometheus.md` (or `node_modules/@voltro/plugin-prometheus/README.md`) | Prometheus exporter — scrapes the unified Metrics-API at GET /metrics in text exposition format. |
|
|
796
807
|
| ratelimit | `node_modules/@voltro/cli/templates/agent-docs/plugins/ratelimit.md` (or `node_modules/@voltro/plugin-ratelimit/README.md`) | Per-endpoint, per-subject and per-tenant request limits via the rpc interceptors. Sliding-window / fixed-window / token-bucket, memory / postgres / redis stores. |
|
|
797
808
|
| rbac | `node_modules/@voltro/cli/templates/agent-docs/plugins/rbac.md` (or `node_modules/@voltro/plugin-rbac/README.md`) | Roles + permissions + the permission() handler guard. Roles compile to scopes. |
|
|
809
|
+
| row-history | `node_modules/@voltro/cli/templates/agent-docs/plugins/row-history.md` (or `node_modules/@voltro/plugin-row-history/README.md`) | Full row history + time-travel. audit() records who/when; row-history records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
798
810
|
| scim | `node_modules/@voltro/cli/templates/agent-docs/plugins/scim.md` (or `node_modules/@voltro/plugin-scim/README.md`) | SCIM 2.0 provisioning — Users + Groups REST endpoints so an enterprise IdP (Okta, Entra, OneLogin) can create / update / deactivate users in your app. |
|
|
799
811
|
| search | `node_modules/@voltro/cli/templates/agent-docs/plugins/search.md` (or `node_modules/@voltro/plugin-search/README.md`) | Keep an external search index (Typesense / Meilisearch / Algolia) in sync with your tables via the ChangeEvent tap, query it tenant-scoped through a typed action + hook. |
|
|
800
812
|
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and opt-in performance traces. |
|
|
801
813
|
| soft-delete | `node_modules/@voltro/cli/templates/agent-docs/plugins/soft-delete.md` (or `node_modules/@voltro/plugin-soft-delete/README.md`) | The softDelete() schema mixin — deletedAt / deletedBy columns, delete() redirected to an UPDATE, default reads filtered, hardDelete() bypass. |
|
|
802
814
|
| sso-saml | `node_modules/@voltro/cli/templates/agent-docs/plugins/sso-saml.md` (or `node_modules/@voltro/plugin-sso-saml/README.md`) | Enterprise SAML 2.0 SSO — SP-initiated login, ACS assertion consumer, SP metadata. Signature verification via @node-saml/node-saml; framework session minting built in. |
|
|
803
|
-
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / R2
|
|
815
|
+
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / MinIO (R2 and GCS via their S3 interop) / Azure / database / filesystem / memory providers, presigned URLs, a dashboard browser. |
|
|
804
816
|
| tinybird | `node_modules/@voltro/cli/templates/agent-docs/plugins/tinybird.md` (or `node_modules/@voltro/plugin-tinybird/README.md`) | Hosted-ClickHouse AnalyticsSink over Tinybird's Events API + Pipes — pay-as-you-go OLAP without operating a cluster. |
|
|
805
|
-
| versioning | `node_modules/@voltro/cli/templates/agent-docs/plugins/versioning.md` (or `node_modules/@voltro/plugin-versioning/README.md`) | Full row history + time-travel. audit() records who/when; versioning records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
806
817
|
| webhooks | `node_modules/@voltro/cli/templates/agent-docs/plugins/webhooks.md` (or `node_modules/@voltro/plugin-webhooks/README.md`) | First-class outgoing + incoming webhooks — declared events with a webhook: block, defineIncomingWebhook in *.webhook.tsx files, runtime subscriptions, durable delivery via @effect/workflow, HMAC signing, provider presets, and idempotency. |
|
|
807
818
|
|
|
808
819
|
|
|
@@ -9,7 +9,7 @@ each plugin's own README.
|
|
|
9
9
|
|
|
10
10
|
| Topic | Open | Summary |
|
|
11
11
|
|---|---|---|
|
|
12
|
-
| **What's new in 0.
|
|
12
|
+
| **What's new in 0.52.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
13
13
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
14
14
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
15
15
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -67,7 +67,7 @@ each plugin's own README.
|
|
|
67
67
|
| auth-workos | `node_modules/@voltro/cli/templates/agent-docs/plugins/auth-workos.md` (or `node_modules/@voltro/plugin-auth-workos/README.md`) | WorkOS AuthStrategy — verifies WorkOS AuthKit / SSO JWTs via JWKS (no API key) and maps org_id → tenantId. |
|
|
68
68
|
| billing | `node_modules/@voltro/cli/templates/agent-docs/plugins/billing.md` (or `node_modules/@voltro/plugin-billing/README.md`) | Subscriptions, plans, entitlements, and usage metering over a pluggable provider (Stripe + mock). Money is integer minor units. |
|
|
69
69
|
| broadcast | `node_modules/@voltro/cli/templates/agent-docs/plugins/broadcast.md` (or `node_modules/@voltro/plugin-broadcast/README.md`) | Cross-replica reactivity over a pub/sub bus (Redis / NATS) for non-postgres dialects — closes the single-instance gap so a write on one pod surfaces on another. |
|
|
70
|
-
| cdc-out | `node_modules/@voltro/cli/templates/agent-docs/plugins/cdc-out.md` (or `node_modules/@voltro/plugin-cdc-out/README.md`) | Declaratively mirror table changes outward to external sinks (webhook
|
|
70
|
+
| cdc-out | `node_modules/@voltro/cli/templates/agent-docs/plugins/cdc-out.md` (or `node_modules/@voltro/plugin-cdc-out/README.md`) | Declaratively mirror table changes outward to external sinks (webhook, plus a CdcSink interface for custom sinks) through a durable outbox — ordered per pipe, at-least-once from enqueue, retried with backoff, dead-lettered. |
|
|
71
71
|
| clickhouse | `node_modules/@voltro/cli/templates/agent-docs/plugins/clickhouse.md` (or `node_modules/@voltro/plugin-clickhouse/README.md`) | Production-grade OLAP AnalyticsSink over ClickHouse — self-hosted or ClickHouse Cloud — for billions of events with millisecond aggregates. |
|
|
72
72
|
| datadog | `node_modules/@voltro/cli/templates/agent-docs/plugins/datadog.md` (or `node_modules/@voltro/plugin-datadog/README.md`) | Agentless Datadog metrics exporter — pushes the unified Metrics-API to Datadog's /api/v2/series HTTP intake. |
|
|
73
73
|
| deactivation | `node_modules/@voltro/cli/templates/agent-docs/plugins/deactivation.md` (or `node_modules/@voltro/plugin-deactivation/README.md`) | A schema mixin that marks a subject as deactivated (can't log in) while keeping its data fully visible — the deliberate opposite of soft-delete. |
|
|
@@ -87,12 +87,12 @@ each plugin's own README.
|
|
|
87
87
|
| prometheus | `node_modules/@voltro/cli/templates/agent-docs/plugins/prometheus.md` (or `node_modules/@voltro/plugin-prometheus/README.md`) | Prometheus exporter — scrapes the unified Metrics-API at GET /metrics in text exposition format. |
|
|
88
88
|
| ratelimit | `node_modules/@voltro/cli/templates/agent-docs/plugins/ratelimit.md` (or `node_modules/@voltro/plugin-ratelimit/README.md`) | Per-endpoint, per-subject and per-tenant request limits via the rpc interceptors. Sliding-window / fixed-window / token-bucket, memory / postgres / redis stores. |
|
|
89
89
|
| rbac | `node_modules/@voltro/cli/templates/agent-docs/plugins/rbac.md` (or `node_modules/@voltro/plugin-rbac/README.md`) | Roles + permissions + the permission() handler guard. Roles compile to scopes. |
|
|
90
|
+
| row-history | `node_modules/@voltro/cli/templates/agent-docs/plugins/row-history.md` (or `node_modules/@voltro/plugin-row-history/README.md`) | Full row history + time-travel. audit() records who/when; row-history records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
90
91
|
| scim | `node_modules/@voltro/cli/templates/agent-docs/plugins/scim.md` (or `node_modules/@voltro/plugin-scim/README.md`) | SCIM 2.0 provisioning — Users + Groups REST endpoints so an enterprise IdP (Okta, Entra, OneLogin) can create / update / deactivate users in your app. |
|
|
91
92
|
| search | `node_modules/@voltro/cli/templates/agent-docs/plugins/search.md` (or `node_modules/@voltro/plugin-search/README.md`) | Keep an external search index (Typesense / Meilisearch / Algolia) in sync with your tables via the ChangeEvent tap, query it tenant-scoped through a typed action + hook. |
|
|
92
93
|
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and opt-in performance traces. |
|
|
93
94
|
| soft-delete | `node_modules/@voltro/cli/templates/agent-docs/plugins/soft-delete.md` (or `node_modules/@voltro/plugin-soft-delete/README.md`) | The softDelete() schema mixin — deletedAt / deletedBy columns, delete() redirected to an UPDATE, default reads filtered, hardDelete() bypass. |
|
|
94
95
|
| sso-saml | `node_modules/@voltro/cli/templates/agent-docs/plugins/sso-saml.md` (or `node_modules/@voltro/plugin-sso-saml/README.md`) | Enterprise SAML 2.0 SSO — SP-initiated login, ACS assertion consumer, SP metadata. Signature verification via @node-saml/node-saml; framework session minting built in. |
|
|
95
|
-
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / R2
|
|
96
|
+
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / MinIO (R2 and GCS via their S3 interop) / Azure / database / filesystem / memory providers, presigned URLs, a dashboard browser. |
|
|
96
97
|
| tinybird | `node_modules/@voltro/cli/templates/agent-docs/plugins/tinybird.md` (or `node_modules/@voltro/plugin-tinybird/README.md`) | Hosted-ClickHouse AnalyticsSink over Tinybird's Events API + Pipes — pay-as-you-go OLAP without operating a cluster. |
|
|
97
|
-
| versioning | `node_modules/@voltro/cli/templates/agent-docs/plugins/versioning.md` (or `node_modules/@voltro/plugin-versioning/README.md`) | Full row history + time-travel. audit() records who/when; versioning records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
98
98
|
| webhooks | `node_modules/@voltro/cli/templates/agent-docs/plugins/webhooks.md` (or `node_modules/@voltro/plugin-webhooks/README.md`) | First-class outgoing + incoming webhooks — declared events with a webhook: block, defineIncomingWebhook in *.webhook.tsx files, runtime subscriptions, durable delivery via @effect/workflow, HMAC signing, provider presets, and idempotency. |
|
|
@@ -460,7 +460,7 @@
|
|
|
460
460
|
{
|
|
461
461
|
"slug": "cdc-out",
|
|
462
462
|
"title": "CDC-out (reverse-ETL)",
|
|
463
|
-
"description": "Declaratively mirror table changes outward to external sinks (webhook
|
|
463
|
+
"description": "Declaratively mirror table changes outward to external sinks (webhook, plus a CdcSink interface for custom sinks) through a durable outbox — ordered per pipe, at-least-once from enqueue, retried with backoff, dead-lettered.",
|
|
464
464
|
"pkg": "@voltro/plugin-cdc-out",
|
|
465
465
|
"doc": "plugins/cdc-out.md",
|
|
466
466
|
"module": "agent-docs/plugins/cdc-out.md"
|
|
@@ -617,6 +617,14 @@
|
|
|
617
617
|
"doc": "plugins/rbac.md",
|
|
618
618
|
"module": "agent-docs/plugins/rbac.md"
|
|
619
619
|
},
|
|
620
|
+
{
|
|
621
|
+
"slug": "row-history",
|
|
622
|
+
"title": "Row history",
|
|
623
|
+
"description": "Full row history + time-travel. audit() records who/when; row-history records what-changed-to-what — a value snapshot of every row on every write, with as-of queries.",
|
|
624
|
+
"pkg": "@voltro/plugin-row-history",
|
|
625
|
+
"doc": "plugins/row-history.md",
|
|
626
|
+
"module": "agent-docs/plugins/row-history.md"
|
|
627
|
+
},
|
|
620
628
|
{
|
|
621
629
|
"slug": "scim",
|
|
622
630
|
"title": "SCIM",
|
|
@@ -660,7 +668,7 @@
|
|
|
660
668
|
{
|
|
661
669
|
"slug": "storage",
|
|
662
670
|
"title": "Storage",
|
|
663
|
-
"description": "File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / R2
|
|
671
|
+
"description": "File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / MinIO (R2 and GCS via their S3 interop) / Azure / database / filesystem / memory providers, presigned URLs, a dashboard browser.",
|
|
664
672
|
"pkg": "@voltro/plugin-storage",
|
|
665
673
|
"doc": "plugins/storage.md",
|
|
666
674
|
"module": "agent-docs/plugins/storage.md"
|
|
@@ -673,14 +681,6 @@
|
|
|
673
681
|
"doc": "plugins/tinybird.md",
|
|
674
682
|
"module": "agent-docs/plugins/tinybird.md"
|
|
675
683
|
},
|
|
676
|
-
{
|
|
677
|
-
"slug": "versioning",
|
|
678
|
-
"title": "Row versioning",
|
|
679
|
-
"description": "Full row history + time-travel. audit() records who/when; versioning records what-changed-to-what — a value snapshot of every row on every write, with as-of queries.",
|
|
680
|
-
"pkg": "@voltro/plugin-versioning",
|
|
681
|
-
"doc": "plugins/versioning.md",
|
|
682
|
-
"module": "agent-docs/plugins/versioning.md"
|
|
683
|
-
},
|
|
684
684
|
{
|
|
685
685
|
"slug": "webhooks",
|
|
686
686
|
"title": "Webhooks",
|
|
@@ -710,9 +710,9 @@
|
|
|
710
710
|
"api-ratelimit": "agent-docs/templates/apibackends.md",
|
|
711
711
|
"api-rbac": "agent-docs/templates/apibackends.md",
|
|
712
712
|
"api-rest": "agent-docs/templates/apibackends.md",
|
|
713
|
+
"api-row-history": "agent-docs/templates/apibackends.md",
|
|
713
714
|
"api-saas": "agent-docs/templates/apibackends.md",
|
|
714
715
|
"api-search": "agent-docs/templates/apibackends.md",
|
|
715
|
-
"api-versioning": "agent-docs/templates/apibackends.md",
|
|
716
716
|
"api-webhooks": "agent-docs/templates/apibackends.md",
|
|
717
717
|
"app": "agent-docs/templates/appshells.md",
|
|
718
718
|
"blank": "agent-docs/templates/appshells.md",
|
|
@@ -142,6 +142,12 @@ config value always winning:
|
|
|
142
142
|
| `VOLTRO_CSP_HTML` | CSP for HTML responses (under `strict` it defaults to the same policy as `VOLTRO_CSP`). `off` drops just this one. |
|
|
143
143
|
| `VOLTRO_HSTS` | `Strict-Transport-Security` value. `off` drops just this one. |
|
|
144
144
|
| `VOLTRO_MAX_RPC_BODY_BYTES` | Cap on the buffered `POST /rpc` JSON body (default 8 MiB) — an oversized body is refused `413` and never buffered past the cap. File uploads ride plugin routes with their own limits. |
|
|
145
|
+
| `VOLTRO_MAX_BODY_BYTES` | Cap on every OTHER body read — plugin HTTP routes, REST routes, incoming webhooks (default 8 MiB, matching the rpc cap). The config-file spelling is `http.maxBodyBytes` in `app.config.ts`; per-route overrides (`defineRestRoute({ maxBodyBytes })`, a webhook handler's `maxBodyBytes`) win over both. Oversize is `413` for `Content-Length` and chunked alike. |
|
|
146
|
+
|
|
147
|
+
Response compression for the buffered non-rpc surfaces (and `voltro start`'s
|
|
148
|
+
HTML) is configured in the same `http:` block — `http.compression.{enabled,minBytes}`
|
|
149
|
+
(default on, 1 KiB threshold; `POST /rpc` is never compressed). Details + the
|
|
150
|
+
BREACH reasoning: [Security → compression](/docs/security/overview#response-compression--and-where-breach-sits).
|
|
145
151
|
|
|
146
152
|
Generate any of the secret vars above with `voltro secret generate <purpose>` (see [`secret`](#command-quick-reference)) — it picks the right length and format. A lower environment's secrets must always differ from production's.
|
|
147
153
|
|
|
@@ -317,36 +323,48 @@ fails to update.
|
|
|
317
323
|
|
|
318
324
|
```
|
|
319
325
|
observed: 12/34 procedures exercised (35%)
|
|
326
|
+
1 declared/observed mismatch among the 12 that ran
|
|
320
327
|
mutation(orders.place) (api/orders/place.mutation.ts)
|
|
321
328
|
writes 'inventory' (update) but declares no target for it
|
|
322
329
|
subscriptions on that table are not invalidated by this mutation
|
|
323
330
|
fix: add { table: 'inventory', op: 'update' } to this procedure's targets
|
|
324
|
-
|
|
331
|
+
20 never ran — no observation exists, so nothing is claimed about them
|
|
332
|
+
2 ran with no table access recorded — indistinguishable from touching nothing, so nothing is claimed about them either
|
|
325
333
|
```
|
|
326
334
|
|
|
327
|
-
|
|
335
|
+
Four things about that output are deliberate:
|
|
328
336
|
|
|
329
337
|
- **Coverage comes first.** Three findings at 8% coverage and three at 95% are
|
|
330
338
|
different claims. Hiding the denominator is how a check starts overstating
|
|
331
339
|
what it knows.
|
|
332
|
-
-
|
|
333
|
-
|
|
334
|
-
|
|
340
|
+
- **Every result line carries the count it is a result about.** `1 mismatch
|
|
341
|
+
among the 12 that ran` — never a bare verdict. A sentence that still reads as
|
|
342
|
+
a conclusion once it is cut out of this block will eventually be cut out of
|
|
343
|
+
it, and quoted as a clean bill of health for a surface nobody measured.
|
|
344
|
+
- **The counts partition the declared set — they add up to the total, always.**
|
|
345
|
+
There are two ways to say nothing about a procedure, and both get a line:
|
|
346
|
+
it never ran, or it ran and no table access was recorded for it. A procedure
|
|
347
|
+
that appeared in no line at all would be indistinguishable from a defect in
|
|
348
|
+
`check` itself, so the two kinds of blindness are named separately and never
|
|
349
|
+
folded into the findings.
|
|
335
350
|
- **Observed diagnostics never fail the build.** An observation is evidence
|
|
336
351
|
about the runs that happened, not a proof about the ones that didn't, and
|
|
337
352
|
`check`'s exit code gates CI. They are always warnings.
|
|
338
353
|
|
|
339
|
-
A
|
|
340
|
-
|
|
354
|
+
A fifth thing is not visible in that output and matters more than any of the
|
|
355
|
+
four: **the recorder only knows what ran.** A boot is not a run. An idle dev
|
|
341
356
|
instance that started, served nothing and stopped produces
|
|
342
357
|
|
|
343
358
|
```
|
|
344
|
-
observed: 0/
|
|
345
|
-
|
|
359
|
+
observed: 0/34 procedures exercised (0%)
|
|
360
|
+
nothing was compared — a declaration is only checked against a procedure that RAN
|
|
361
|
+
34 never ran — no observation exists, so nothing is claimed about them
|
|
346
362
|
```
|
|
347
363
|
|
|
348
|
-
|
|
349
|
-
|
|
364
|
+
Note what that is NOT: it is not "no mismatches found". At zero coverage there
|
|
365
|
+
is no result to report, so the section reports the absence of the comparison
|
|
366
|
+
instead. The honest answer is also a useless one — it says nothing about any of
|
|
367
|
+
the surface. If you want this as a CI gate, the recording pass has
|
|
350
368
|
to be a run that actually *calls* the procedures. `voltro e2e` is one: it spawns
|
|
351
369
|
`voltro dev` for the api, which turns recording on, and then drives the specs. A
|
|
352
370
|
harness of your own that boots the app in its own process needs
|
|
@@ -365,6 +383,29 @@ handlers: a static pass over code that reaches the store through shared helpers,
|
|
|
365
383
|
behind conditionals, has a long tail of both false positives and false negatives
|
|
366
384
|
— and a check that is *sometimes* wrong is one people stop reading.
|
|
367
385
|
|
|
386
|
+
#### Declared vs LIVE — against a running server
|
|
387
|
+
|
|
388
|
+
When `check` runs against a live api (a local `voltro dev`, or a deployed one
|
|
389
|
+
via `--url`), it also diffs the tags your source declares — plugin routes
|
|
390
|
+
included — against the server's actual rpc registry:
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
declared vs live: 2 of 214 source-declared tags are NOT registered on the server
|
|
394
|
+
⚠ presence.heartbeat — a generated client calls this and gets "Unknown request tag"
|
|
395
|
+
⚠ presence.list — a generated client calls this and gets "Unknown request tag"
|
|
396
|
+
fix: if the server runs older code, redeploy; if it is current, plugin route registration was dropped — check the boot line "plugin routes registered"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Only the source→live direction is a finding — a tag the server carries that your
|
|
400
|
+
source does not declare is normal runtime synthesis (agents, undo, approvals).
|
|
401
|
+
This exists because exactly that gap has shipped once: every
|
|
402
|
+
plugin-contributed procedure dead under `voltro serve`, with nothing anywhere
|
|
403
|
+
saying so — the only evidence was a `Defect` frame in the browser console of
|
|
404
|
+
whoever happened to look. (That registration defect is fixed; the diff is the
|
|
405
|
+
runtime backstop for the next one, e.g. a stale deploy.) The server now also
|
|
406
|
+
logs every `Defect` frame it sends (`rpc defect sent to client`), so an unknown
|
|
407
|
+
tag is an operator-visible event rather than a client-only one.
|
|
408
|
+
|
|
368
409
|
The HTTP surface is reachable directly too — e.g. `curl -s localhost:4000/_voltro/inspect/rpc | jq` (there is no `/_voltro/inspect/queries` endpoint; it's `rpc` for procedures, `routes` for the web page tree, `subscriptions` for active subscribers).
|
|
369
410
|
|
|
370
411
|
## Where to read next
|
|
@@ -1364,7 +1405,7 @@ Point the Kubernetes liveness probe at `/internal/liveness` and the readiness pr
|
|
|
1364
1405
|
For WebSocket connections to land on the same backend (required for in-process subscription state):
|
|
1365
1406
|
|
|
1366
1407
|
- Reverse proxy: `lb_policy ip_hash` (Caddy) / `ip_hash` (nginx).
|
|
1367
|
-
-
|
|
1408
|
+
- Cross-instance subscription invalidation is built in on Postgres (LISTEN/NOTIFY) and MySQL/MariaDB (binlog CDC); on any other dialect add [`@voltro/plugin-broadcast`](/docs/plugins/broadcast) (Redis/NATS). With that in place a reconnect may land on any replica and still sees every change — sticky sessions then only keep one live connection pinned, they are not a correctness requirement.
|
|
1368
1409
|
|
|
1369
1410
|
## `voltro build api --target <swift|kotlin>` — native SDK generation
|
|
1370
1411
|
|
|
@@ -1796,6 +1837,47 @@ matching rule lives inside the CLI, so you cannot re-derive the list with your
|
|
|
1796
1837
|
own grep. `--json` prints the complete scan, nothing elided, with no preflight
|
|
1797
1838
|
output mixed in:
|
|
1798
1839
|
|
|
1840
|
+
### Unimported `@voltro/*` dependencies
|
|
1841
|
+
|
|
1842
|
+
A declared framework dependency nobody imports still gets installed, walked on
|
|
1843
|
+
every `voltro update`, and read as evidence the package is in use — its
|
|
1844
|
+
breaking-change notes included. The usual origin is a migration: the app moves
|
|
1845
|
+
off a framework package to a third-party one, and the `package.json` entry
|
|
1846
|
+
stays. `voltro doctor` checks every `@voltro/*` in `dependencies` and
|
|
1847
|
+
`devDependencies` for an import site:
|
|
1848
|
+
|
|
1849
|
+
```
|
|
1850
|
+
unimported deps · 8 @voltro/* package(s) declared, 214 file(s) scanned
|
|
1851
|
+
⚠ @voltro/i18n — declared in dependencies, imported nowhere
|
|
1852
|
+
a dependency nobody imports still gets installed, updated, and read as
|
|
1853
|
+
evidence the package is in use — its breaking-change notes included.
|
|
1854
|
+
Remove it, or if it IS imported through an assembled specifier the scan
|
|
1855
|
+
cannot see, keep it and ignore this line — the rule is advisory.
|
|
1856
|
+
· (2 loaded by the framework itself: @voltro/cli, @voltro/sql-postgres)
|
|
1857
|
+
```
|
|
1858
|
+
|
|
1859
|
+
Scoped to `@voltro/*` deliberately: for third-party packages the same question
|
|
1860
|
+
has a long tail of legitimate no-import shapes, and a rule that is sometimes
|
|
1861
|
+
wrong is one people stop reading. Three states are distinguished, and each is
|
|
1862
|
+
printed:
|
|
1863
|
+
|
|
1864
|
+
- **Exempt, by name** — packages the framework loads on your declaration
|
|
1865
|
+
(`@voltro/cli` is the binary; `@voltro/devtools` is mounted by `voltro dev`;
|
|
1866
|
+
the `@voltro/sql-*` dialect drivers are loaded from your config). An
|
|
1867
|
+
exemption you cannot see is a finding you cannot question.
|
|
1868
|
+
- **Not measurable yet** — `@voltro/client` / `@voltro/web` are normally
|
|
1869
|
+
imported by *generated* code. On a tree where codegen has never run, their
|
|
1870
|
+
absence is a missing measurement, not a dead dependency; the section says so
|
|
1871
|
+
and tells you to run `voltro dev` once.
|
|
1872
|
+
- **Unimported** — advisory, never fatal. A mention in a comment or an error
|
|
1873
|
+
string does not count as an import (a commented-out import is exactly the
|
|
1874
|
+
residue this looks for), and an import assembled at runtime from string
|
|
1875
|
+
pieces is invisible to the scan — the finding text says both.
|
|
1876
|
+
|
|
1877
|
+
The full report is in `voltro doctor --json` under `unimportedDeps`
|
|
1878
|
+
(`null` when there is no `package.json` to read — "could not check" and
|
|
1879
|
+
"checked, clean" never print the same).
|
|
1880
|
+
|
|
1799
1881
|
### Duplicate package instances
|
|
1800
1882
|
|
|
1801
1883
|
`voltro doctor` also reports any identity-sensitive package resolved at more than
|
|
@@ -2850,7 +2932,7 @@ Not every run can take it, and a run that cannot **says why** rather than quietl
|
|
|
2850
2932
|
taking the slower path:
|
|
2851
2933
|
|
|
2852
2934
|
- a store the framework cannot send DDL to (the in-memory store).
|
|
2853
|
-
- a **write recorder** on any table in the set — `
|
|
2935
|
+
- a **write recorder** on any table in the set — `rowHistoryPlugin({ timing:
|
|
2854
2936
|
'in-transaction' })` and friends. A recorder is keyed by table name, so a
|
|
2855
2937
|
staged write would find none and the recorder would silently not run. Its
|
|
2856
2938
|
promise is "if the change committed, the entry is there", so the run keeps the
|
|
@@ -2906,7 +2988,7 @@ ITSELF is not a cycle: one statement carries the whole table.
|
|
|
2906
2988
|
|
|
2907
2989
|
### A `replace` does not write per-row history
|
|
2908
2990
|
|
|
2909
|
-
Write recorders — `
|
|
2991
|
+
Write recorders — `rowHistoryPlugin({ timing: 'in-transaction' })` and anything
|
|
2910
2992
|
else registered through the same seam — are **suspended for a `replace`**. A
|
|
2911
2993
|
replace sets a state; it does not change rows, so a per-row history entry would
|
|
2912
2994
|
describe something that did not happen. On a large bundle that is not a detail:
|