@terreno/mcp 57.21.0 → 58.0.0-beta.1
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 +43 -0
- package/README.md +57 -3
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +17 -16
- package/dist/bootstrap.js.map +1 -1
- package/dist/docs/guidelines/admin-frontend/guidelines/core.md +6 -5
- package/dist/docs/guidelines/ui/guidelines/core.md +1 -1
- package/dist/docs/prompts/debug.md +6 -4
- package/dist/docs/prompts/screen.md +11 -17
- package/dist/docs/resources/overview.md +5 -3
- package/dist/docs/resources/patterns.md +157 -238
- package/dist/docs/resources/syncdb.md +44 -16
- package/dist/docs/templates/bootstrap/CLAUDE.template.md +2 -2
- package/dist/docs/templates/bootstrap/cursorrules.template.md +7 -5
- package/dist/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +8 -12
- package/dist/docs/templates/bootstrap/frontend/app/_layout.template.tsx +75 -52
- package/dist/docs/templates/bootstrap/frontend/app/login.template.tsx +46 -108
- package/dist/docs/templates/bootstrap/frontend/app/signup.template.tsx +53 -0
- package/dist/docs/templates/bootstrap/frontend/lib/betterAuth.template.md +18 -0
- package/dist/docs/templates/bootstrap/frontend/store/apiClient.template.md +33 -0
- package/dist/docs/templates/bootstrap/frontend/store/apiSdk.template.md +76 -0
- package/dist/docs/templates/bootstrap/frontend/store/syncdb.template.md +56 -0
- package/dist/docs/templates/bootstrap/frontend/utils/index.template.md +0 -4
- package/dist/docs/upgrades/58.0.0-beta.1.md +504 -0
- package/dist/docs/upgrades/58.0.0.md +495 -4
- package/dist/docs/versioned/next/README.md +2 -2
- package/dist/docs/versioned/next/approval-rubric.md +2 -2
- package/dist/docs/versioned/next/explanation/admin-interface.md +6 -5
- package/dist/docs/versioned/next/explanation/admin-plugin-frontend.md +1 -1
- package/dist/docs/versioned/next/explanation/ai-workflows.md +5 -3
- package/dist/docs/versioned/next/explanation/announcements/rtk-deprecation.md +16 -11
- package/dist/docs/versioned/next/explanation/authentication.md +62 -43
- package/dist/docs/versioned/next/explanation/dependency-management.md +1 -1
- package/dist/docs/versioned/next/explanation/deployment-baseline.md +1 -1
- package/dist/docs/versioned/next/explanation/example-coverage.md +2 -2
- package/dist/docs/versioned/next/explanation/explicit-any-policy.md +5 -6
- package/dist/docs/versioned/next/explanation/gcp-hosting-architecture.md +1 -1
- package/dist/docs/versioned/next/explanation/local-first-data.md +11 -9
- package/dist/docs/versioned/next/explanation/model-router-actions.md +1 -1
- package/dist/docs/versioned/next/explanation/modular-api-design.md +2 -2
- package/dist/docs/versioned/next/explanation/no-barrel-imports.md +5 -5
- package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +4 -3
- package/dist/docs/versioned/next/explanation/source-rules.md +2 -2
- package/dist/docs/versioned/next/explanation/typescript-configuration.md +2 -4
- package/dist/docs/versioned/next/explanation/versioning-policy.md +3 -3
- package/dist/docs/versioned/next/how-to/README.md +3 -2
- package/dist/docs/versioned/next/how-to/add-feature-flags.md +50 -25
- package/dist/docs/versioned/next/how-to/add-organizations.md +2 -1
- package/dist/docs/versioned/next/how-to/admin-custom-home.md +8 -2
- package/dist/docs/versioned/next/how-to/admin-custom-widget.md +0 -1
- package/dist/docs/versioned/next/how-to/agent-ui-asks.md +6 -6
- package/dist/docs/versioned/next/how-to/build-admin-screens.md +10 -8
- package/dist/docs/versioned/next/how-to/build-for-web.md +1 -1
- package/dist/docs/versioned/next/how-to/call-external-apis.md +2 -2
- package/dist/docs/versioned/next/how-to/circleci.md +12 -6
- package/dist/docs/versioned/next/how-to/configure-better-auth.md +114 -60
- package/dist/docs/versioned/next/how-to/connect-mcp-service-token.md +10 -4
- package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +14 -2
- package/dist/docs/versioned/next/how-to/debug-with-mcp.md +8 -13
- package/dist/docs/versioned/next/how-to/expose-mcp-tools.md +15 -4
- package/dist/docs/versioned/next/how-to/generate-the-client-sdk.md +33 -0
- package/dist/docs/versioned/next/how-to/github-actions-ci.md +2 -2
- package/dist/docs/versioned/next/how-to/in-app-notifications.md +1 -1
- package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +318 -447
- package/dist/docs/versioned/next/how-to/password-reset.md +1 -1
- package/dist/docs/versioned/next/how-to/product-announcements.md +6 -3
- package/dist/docs/versioned/next/how-to/rate-limiting.md +38 -16
- package/dist/docs/versioned/next/how-to/run-mongodb-migrations.md +19 -0
- package/dist/docs/versioned/next/how-to/run-tests-locally.md +2 -3
- package/dist/docs/versioned/next/how-to/set-up-social-login.md +1 -1
- package/dist/docs/versioned/next/how-to/set-up-terreno-mcp.md +2 -2
- package/dist/docs/versioned/next/how-to/track-upstream-expo.md +1 -1
- package/dist/docs/versioned/next/how-to/upgrade-banner.md +5 -3
- package/dist/docs/versioned/next/how-to/upgrade-terreno.md +5 -5
- package/dist/docs/versioned/next/how-to/use-syncdb-correctly.md +1 -1
- package/dist/docs/versioned/next/how-to/websocket-integration.md +113 -402
- package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
- package/dist/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +5 -0
- package/dist/docs/versioned/next/implementationPlans/native-module-baseline.md +29 -5
- package/dist/docs/versioned/next/implementationPlans/remove-legacy-realtime.md +1 -1
- package/dist/docs/versioned/next/implementationPlans/remove-rtk.md +185 -0
- package/dist/docs/versioned/next/reference/README.md +1 -1
- package/dist/docs/versioned/next/reference/admin-frontend.md +85 -70
- package/dist/docs/versioned/next/reference/admin-spa.md +10 -4
- package/dist/docs/versioned/next/reference/ai.md +36 -4
- package/dist/docs/versioned/next/reference/announcements.md +3 -3
- package/dist/docs/versioned/next/reference/api.md +39 -24
- package/dist/docs/versioned/next/reference/cli.md +3 -4
- package/dist/docs/versioned/next/reference/environment-variables.md +16 -16
- package/dist/docs/versioned/next/reference/feature-flags.md +48 -7
- package/dist/docs/versioned/next/reference/jobs.md +2 -2
- package/dist/docs/versioned/next/reference/legacy/rtk.md +25 -600
- package/dist/docs/versioned/next/reference/mcp-server.md +441 -1158
- package/dist/docs/versioned/next/reference/syncdb.md +426 -16
- package/dist/docs/versioned/next/reference/test.md +28 -3
- package/dist/docs/versioned/next/reference/ui.md +132 -19
- package/dist/docs/versioned/next/tasks/native-module-baseline.md +8 -4
- package/dist/docs/versioned/next/tasks/rate-limiting.md +9 -2
- package/dist/docs/versioned/next/tasks/remove-legacy-realtime.md +5 -5
- package/dist/docs/versioned/next/tasks/remove-rtk.md +155 -0
- package/dist/local/localTools.d.ts.map +1 -1
- package/dist/local/localTools.js +3 -54
- package/dist/local/localTools.js.map +1 -1
- package/dist/local/tools/runtime.d.ts +0 -21
- package/dist/local/tools/runtime.d.ts.map +1 -1
- package/dist/local/tools/runtime.js +0 -176
- package/dist/local/tools/runtime.js.map +1 -1
- package/dist/local/tools/syncDb.d.ts +0 -11
- package/dist/local/tools/syncDb.d.ts.map +1 -1
- package/dist/local/tools/syncDb.js +1 -5
- package/dist/local/tools/syncDb.js.map +1 -1
- package/dist/packageGuidelines.d.ts +3 -2
- package/dist/packageGuidelines.d.ts.map +1 -1
- package/dist/packageGuidelines.js +4 -11
- package/dist/packageGuidelines.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +17 -18
- package/dist/prompts.js.map +1 -1
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +1 -8
- package/dist/resources.js.map +1 -1
- package/dist/search/chunker.d.ts +1 -1
- package/dist/search/chunker.d.ts.map +1 -1
- package/dist/search/inferPackages.d.ts +1 -1
- package/dist/search/inferPackages.js +5 -5
- package/dist/search/inferPackages.js.map +1 -1
- package/dist/tools.d.ts +6 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +126 -119
- package/dist/tools.js.map +1 -1
- package/package.json +6 -6
- package/src/docs/guidelines/admin-frontend/guidelines/core.md +6 -5
- package/src/docs/guidelines/ui/guidelines/core.md +1 -1
- package/src/docs/prompts/debug.md +6 -4
- package/src/docs/prompts/screen.md +11 -17
- package/src/docs/resources/overview.md +5 -3
- package/src/docs/resources/patterns.md +157 -238
- package/src/docs/resources/syncdb.md +44 -16
- package/src/docs/templates/bootstrap/CLAUDE.template.md +2 -2
- package/src/docs/templates/bootstrap/cursorrules.template.md +7 -5
- package/src/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +8 -12
- package/src/docs/templates/bootstrap/frontend/app/_layout.template.tsx +75 -52
- package/src/docs/templates/bootstrap/frontend/app/login.template.tsx +46 -108
- package/src/docs/templates/bootstrap/frontend/app/signup.template.tsx +53 -0
- package/src/docs/templates/bootstrap/frontend/lib/betterAuth.template.md +18 -0
- package/src/docs/templates/bootstrap/frontend/store/apiClient.template.md +33 -0
- package/src/docs/templates/bootstrap/frontend/store/apiSdk.template.md +76 -0
- package/src/docs/templates/bootstrap/frontend/store/syncdb.template.md +56 -0
- package/src/docs/templates/bootstrap/frontend/utils/index.template.md +0 -4
- package/src/docs/upgrades/58.0.0-beta.1.md +504 -0
- package/src/docs/upgrades/58.0.0.md +495 -4
- package/src/docs/versioned/next/README.md +2 -2
- package/src/docs/versioned/next/approval-rubric.md +2 -2
- package/src/docs/versioned/next/explanation/admin-interface.md +6 -5
- package/src/docs/versioned/next/explanation/admin-plugin-frontend.md +1 -1
- package/src/docs/versioned/next/explanation/ai-workflows.md +5 -3
- package/src/docs/versioned/next/explanation/announcements/rtk-deprecation.md +16 -11
- package/src/docs/versioned/next/explanation/authentication.md +62 -43
- package/src/docs/versioned/next/explanation/dependency-management.md +1 -1
- package/src/docs/versioned/next/explanation/deployment-baseline.md +1 -1
- package/src/docs/versioned/next/explanation/example-coverage.md +2 -2
- package/src/docs/versioned/next/explanation/explicit-any-policy.md +5 -6
- package/src/docs/versioned/next/explanation/gcp-hosting-architecture.md +1 -1
- package/src/docs/versioned/next/explanation/local-first-data.md +11 -9
- package/src/docs/versioned/next/explanation/model-router-actions.md +1 -1
- package/src/docs/versioned/next/explanation/modular-api-design.md +2 -2
- package/src/docs/versioned/next/explanation/no-barrel-imports.md +5 -5
- package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +4 -3
- package/src/docs/versioned/next/explanation/source-rules.md +2 -2
- package/src/docs/versioned/next/explanation/typescript-configuration.md +2 -4
- package/src/docs/versioned/next/explanation/versioning-policy.md +3 -3
- package/src/docs/versioned/next/how-to/README.md +3 -2
- package/src/docs/versioned/next/how-to/add-feature-flags.md +50 -25
- package/src/docs/versioned/next/how-to/add-organizations.md +2 -1
- package/src/docs/versioned/next/how-to/admin-custom-home.md +8 -2
- package/src/docs/versioned/next/how-to/admin-custom-widget.md +0 -1
- package/src/docs/versioned/next/how-to/agent-ui-asks.md +6 -6
- package/src/docs/versioned/next/how-to/build-admin-screens.md +10 -8
- package/src/docs/versioned/next/how-to/build-for-web.md +1 -1
- package/src/docs/versioned/next/how-to/call-external-apis.md +2 -2
- package/src/docs/versioned/next/how-to/circleci.md +12 -6
- package/src/docs/versioned/next/how-to/configure-better-auth.md +114 -60
- package/src/docs/versioned/next/how-to/connect-mcp-service-token.md +10 -4
- package/src/docs/versioned/next/how-to/create-a-terreno-app.md +14 -2
- package/src/docs/versioned/next/how-to/debug-with-mcp.md +8 -13
- package/src/docs/versioned/next/how-to/expose-mcp-tools.md +15 -4
- package/src/docs/versioned/next/how-to/generate-the-client-sdk.md +33 -0
- package/src/docs/versioned/next/how-to/github-actions-ci.md +2 -2
- package/src/docs/versioned/next/how-to/in-app-notifications.md +1 -1
- package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +318 -447
- package/src/docs/versioned/next/how-to/password-reset.md +1 -1
- package/src/docs/versioned/next/how-to/product-announcements.md +6 -3
- package/src/docs/versioned/next/how-to/rate-limiting.md +38 -16
- package/src/docs/versioned/next/how-to/run-mongodb-migrations.md +19 -0
- package/src/docs/versioned/next/how-to/run-tests-locally.md +2 -3
- package/src/docs/versioned/next/how-to/set-up-social-login.md +1 -1
- package/src/docs/versioned/next/how-to/set-up-terreno-mcp.md +2 -2
- package/src/docs/versioned/next/how-to/track-upstream-expo.md +1 -1
- package/src/docs/versioned/next/how-to/upgrade-banner.md +5 -3
- package/src/docs/versioned/next/how-to/upgrade-terreno.md +5 -5
- package/src/docs/versioned/next/how-to/use-syncdb-correctly.md +1 -1
- package/src/docs/versioned/next/how-to/websocket-integration.md +113 -402
- package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +1 -1
- package/src/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +5 -0
- package/src/docs/versioned/next/implementationPlans/native-module-baseline.md +29 -5
- package/src/docs/versioned/next/implementationPlans/remove-legacy-realtime.md +1 -1
- package/src/docs/versioned/next/implementationPlans/remove-rtk.md +185 -0
- package/src/docs/versioned/next/reference/README.md +1 -1
- package/src/docs/versioned/next/reference/admin-frontend.md +85 -70
- package/src/docs/versioned/next/reference/admin-spa.md +10 -4
- package/src/docs/versioned/next/reference/ai.md +36 -4
- package/src/docs/versioned/next/reference/announcements.md +3 -3
- package/src/docs/versioned/next/reference/api.md +39 -24
- package/src/docs/versioned/next/reference/cli.md +3 -4
- package/src/docs/versioned/next/reference/environment-variables.md +16 -16
- package/src/docs/versioned/next/reference/feature-flags.md +48 -7
- package/src/docs/versioned/next/reference/jobs.md +2 -2
- package/src/docs/versioned/next/reference/legacy/rtk.md +25 -600
- package/src/docs/versioned/next/reference/mcp-server.md +441 -1158
- package/src/docs/versioned/next/reference/syncdb.md +426 -16
- package/src/docs/versioned/next/reference/test.md +28 -3
- package/src/docs/versioned/next/reference/ui.md +132 -19
- package/src/docs/versioned/next/tasks/native-module-baseline.md +8 -4
- package/src/docs/versioned/next/tasks/rate-limiting.md +9 -2
- package/src/docs/versioned/next/tasks/remove-legacy-realtime.md +5 -5
- package/src/docs/versioned/next/tasks/remove-rtk.md +155 -0
- package/dist/docs/guidelines/rtk/guidelines/core.md +0 -26
- package/dist/docs/resources/rtk.md +0 -181
- package/dist/docs/templates/bootstrap/frontend/openapi-config.template.md +0 -16
- package/dist/docs/templates/bootstrap/frontend/scripts/generate-sdk.template.md +0 -49
- package/dist/docs/templates/bootstrap/frontend/store/appState.template.md +0 -45
- package/dist/docs/templates/bootstrap/frontend/store/errors.template.md +0 -51
- package/dist/docs/templates/bootstrap/frontend/store/index.template.md +0 -86
- package/dist/docs/templates/bootstrap/frontend/store/openApiSdk.template.md +0 -49
- package/dist/docs/templates/bootstrap/frontend/store/sdk.template.md +0 -80
- package/src/docs/guidelines/rtk/guidelines/core.md +0 -26
- package/src/docs/resources/rtk.md +0 -181
- package/src/docs/templates/bootstrap/frontend/openapi-config.template.md +0 -16
- package/src/docs/templates/bootstrap/frontend/scripts/generate-sdk.template.md +0 -49
- package/src/docs/templates/bootstrap/frontend/store/appState.template.md +0 -45
- package/src/docs/templates/bootstrap/frontend/store/errors.template.md +0 -51
- package/src/docs/templates/bootstrap/frontend/store/index.template.md +0 -86
- package/src/docs/templates/bootstrap/frontend/store/openApiSdk.template.md +0 -49
- package/src/docs/templates/bootstrap/frontend/store/sdk.template.md +0 -80
|
@@ -54,49 +54,66 @@ After adding the backend routes, regenerate the SDK so the frontend can call the
|
|
|
54
54
|
cd your-frontend && bun run sdk
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
Regeneration may emit a hook for `/feature-flags/flagConfiguration`; prefer **`useTerrenoFeatureFlags`** / **`useFeatureFlags`** from `@terreno/
|
|
57
|
+
Regeneration may emit a hook for `/feature-flags/flagConfiguration`; prefer **`useTerrenoFeatureFlags`** / **`useFeatureFlags`** from `@terreno/syncdb/flags` so the OpenFeature domain, per-user refetch, and socket refresh stay consistent.
|
|
58
58
|
|
|
59
59
|
### 4. Use feature flags in the frontend
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
Add `@openfeature/web-sdk` and `@openfeature/react-sdk` to the app (`catalog:` versions). Both
|
|
62
|
+
hooks come from `@terreno/syncdb/flags`, fetch through the request client from
|
|
63
|
+
`ApiClientProvider`, and refetch when the server pushes `featureFlagsChanged` on the syncdb
|
|
64
|
+
socket.
|
|
62
65
|
|
|
63
|
-
**
|
|
66
|
+
**Recommended (OpenFeature):** wrap the tree that reads flags in
|
|
67
|
+
`<OpenFeatureProvider domain="feature-flags">` and call `useTerrenoFeatureFlags` once after
|
|
68
|
+
auth. Pass your `syncDb` as `socket` when this component sits above `SyncDbProvider`. Then read
|
|
69
|
+
values with `useBooleanFlagValue` / `useStringFlagValue` / `FeatureFlag`.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import {OpenFeatureProvider} from "@openfeature/react-sdk";
|
|
73
|
+
import {useTerrenoFeatureFlags} from "@terreno/syncdb/flags";
|
|
74
|
+
import {syncDb} from "@/store/syncdb";
|
|
75
|
+
|
|
76
|
+
const FlagsBridge: React.FC<{children: React.ReactNode; userId?: string}> = ({
|
|
77
|
+
children,
|
|
78
|
+
userId,
|
|
79
|
+
}) => {
|
|
80
|
+
useTerrenoFeatureFlags({skip: !userId, socket: syncDb, userId});
|
|
81
|
+
return <OpenFeatureProvider domain="feature-flags">{children}</OpenFeatureProvider>;
|
|
82
|
+
};
|
|
83
|
+
```
|
|
64
84
|
|
|
65
85
|
```typescript
|
|
66
86
|
import {useBooleanFlagValue} from "@openfeature/react-sdk";
|
|
67
|
-
import {useTerrenoFeatureFlags, useSelectCurrentUserId} from "@terreno/rtk";
|
|
68
|
-
import {terrenoApi} from "@/store/sdk";
|
|
69
87
|
|
|
70
88
|
const GatedBanner: React.FC = () => {
|
|
71
|
-
const userId = useSelectCurrentUserId();
|
|
72
|
-
useTerrenoFeatureFlags(terrenoApi, {userId, skip: !userId});
|
|
73
89
|
const showBanner = useBooleanFlagValue("new-ui", false);
|
|
74
90
|
return showBanner ? <NewUI /> : null;
|
|
75
91
|
};
|
|
76
92
|
```
|
|
77
93
|
|
|
94
|
+
**Flat accessors:** `useFeatureFlags` returns `{flags, getFlag, getVariant, isLoading, error,
|
|
95
|
+
refetch}`. Screens below the bridge can pass `socket: null` — they share the bridge's cached
|
|
96
|
+
query, so its refetch updates them too.
|
|
97
|
+
|
|
78
98
|
```typescript
|
|
79
|
-
import {useFeatureFlags} from "@terreno/
|
|
80
|
-
import {terrenoApi} from "@/store/sdk";
|
|
99
|
+
import {useFeatureFlags} from "@terreno/syncdb/flags";
|
|
81
100
|
|
|
82
|
-
const LegacyStyle: React.FC = () => {
|
|
83
|
-
const {getFlag, isLoading} = useFeatureFlags(
|
|
101
|
+
const LegacyStyle: React.FC<{userId?: string}> = ({userId}) => {
|
|
102
|
+
const {getFlag, isLoading} = useFeatureFlags({skip: !userId, socket: null, userId});
|
|
84
103
|
|
|
85
104
|
if (isLoading) {
|
|
86
105
|
return <Spinner />;
|
|
87
106
|
}
|
|
88
107
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return showNewUI ? <NewUI /> : <OldUI />;
|
|
108
|
+
return getFlag("new-ui") ? <NewUI /> : <OldUI />;
|
|
92
109
|
};
|
|
93
110
|
```
|
|
94
111
|
|
|
95
112
|
### 4b. Live updates (optional)
|
|
96
113
|
|
|
97
|
-
To push flag changes to open clients without a refresh, pass **`liveUpdates`** when constructing `FeatureFlagsApp` (see `example-backend/src/server.ts`): Mongoose **`FeatureFlag.watch()`** drives a Socket.io broadcast. **MongoDB must run as a replica set** (a single-node replica set is enough); standalone instances cannot use change streams, and the plugin logs a warning if `watch()` fails.
|
|
114
|
+
To push flag changes to open clients without a refresh, pass **`liveUpdates`** when constructing `FeatureFlagsApp` (see `example-backend/src/server.ts`): Mongoose **`FeatureFlag.watch()`** drives a Socket.io broadcast. Point `socketIoServer` at `() => realtimeApp.getIo()` so the push goes out on the socket the syncdb client already holds. **MongoDB must run as a replica set** (a single-node replica set is enough); standalone instances cannot use change streams, and the plugin logs a warning if `watch()` fails.
|
|
98
115
|
|
|
99
|
-
On the client
|
|
116
|
+
On the client there is nothing extra to wire: `useTerrenoFeatureFlags` listens for `featureFlagsChanged` (or `socketEventName`) through `syncDb.onSocketEvent` and refetches `/flagConfiguration`. The app opens no second socket. The event payload is only `{ key: string }` — the same flag keys are already returned to every authenticated user in `/flagConfiguration`, so this is not considered a new exposure.
|
|
100
117
|
|
|
101
118
|
### 5. Create flags via the admin panel
|
|
102
119
|
|
|
@@ -111,23 +128,31 @@ Navigate to the admin panel in your app. The "Feature Flags" card appears automa
|
|
|
111
128
|
|
|
112
129
|
## Migrating from `GET …/evaluate` (OpenFeature)
|
|
113
130
|
|
|
114
|
-
Terreno's feature-flag stack uses **OpenFeature** (`@terreno/feature-flags` on the server, `@terreno/
|
|
131
|
+
Terreno's feature-flag stack uses **OpenFeature** (`@terreno/feature-flags` on the server, `@terreno/syncdb/flags` on the client). Use this checklist if you upgrade from a Terreno release that only documented `GET …/evaluate`.
|
|
115
132
|
|
|
116
133
|
### Backend (`@terreno/feature-flags`)
|
|
117
134
|
|
|
118
135
|
1. Keep **`FeatureFlagsApp`** registered as before; admin CRUD is unchanged.
|
|
119
136
|
2. Prefer authenticated clients calling **`GET {basePath}/flagConfiguration`** — the JSON body matches OpenFeature's static configuration shape (for `TypedInMemoryProvider` on the client).
|
|
120
|
-
3. **`GET {basePath}/evaluate`** still returns the legacy `Record<key, boolean | string | null>` map but is **deprecated** (`Deprecation: true`, `Sunset` header). Migrate direct HTTP or hand-written clients to `/flagConfiguration`, or rely on `@terreno/
|
|
137
|
+
3. **`GET {basePath}/evaluate`** still returns the legacy `Record<key, boolean | string | null>` map but is **deprecated** (`Deprecation: true`, `Sunset` header). Migrate direct HTTP or hand-written clients to `/flagConfiguration`, or rely on the `@terreno/syncdb/flags` hooks below.
|
|
121
138
|
4. **`FeatureFlag`** documents gain optional **`defaultVariant`** (boolean: `"on"` / `"off"`; variant: a key from `variants`). Omitted values are filled on save. For existing databases, run a one-off backfill or reuse the pattern in `example-backend/src/scripts/seed-feature-flags.ts`.
|
|
122
139
|
5. **Live updates (optional):** pass `liveUpdates: { socketIoServer: io | () => io }` to `FeatureFlagsApp`. MongoDB must run as a **replica set** (a single-node replica set is enough) so Mongoose change streams work.
|
|
123
140
|
|
|
124
|
-
### Frontend (`@terreno/
|
|
125
|
-
|
|
126
|
-
1.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
141
|
+
### Frontend (`@terreno/syncdb/flags` + OpenFeature)
|
|
142
|
+
|
|
143
|
+
1. Replace the Terreno 57 `useFeatureFlags(terrenoApi, options)` with
|
|
144
|
+
`useFeatureFlags(options)` from `@terreno/syncdb/flags`. The result shape is unchanged:
|
|
145
|
+
`{flags, getFlag, getVariant, isLoading, error, refetch}`. The legacy string `basePath`
|
|
146
|
+
argument is gone; pass `{basePath}`.
|
|
147
|
+
2. Replace `useTerrenoFeatureFlags(terrenoApi, {socket, ...})` with
|
|
148
|
+
`useTerrenoFeatureFlags({socket: syncDb, ...})`. `socket` is now your `SyncDb` client, not a
|
|
149
|
+
Socket.io client, and defaults to the `SyncDbProvider` client.
|
|
150
|
+
3. Drop `useSocketConnection` and `useRealtimeDebug`. Listen for other server events with
|
|
151
|
+
`useSocketEvent` from `@terreno/syncdb/react` (see
|
|
152
|
+
[WebSocket integration](./websocket-integration.md)).
|
|
153
|
+
4. Keep `@openfeature/web-sdk` and `@openfeature/react-sdk` in the app (`catalog:` versions) and
|
|
154
|
+
wrap the UI that reads flags in `<OpenFeatureProvider domain="feature-flags">`.
|
|
155
|
+
5. Mount the hooks under `ApiClientProvider`, or pass `client`.
|
|
131
156
|
|
|
132
157
|
### Further reading
|
|
133
158
|
|
|
@@ -173,7 +173,8 @@ exactly one administered organization may omit it; Terreno infers that org.
|
|
|
173
173
|
Operators and superadmins must select an org.
|
|
174
174
|
|
|
175
175
|
Frontend admin hosts use `OrgContextProvider` + `OrgSwitcher`.
|
|
176
|
-
`
|
|
176
|
+
`useAdminModelApi` and the built-in admin screens add the selected organization
|
|
177
|
+
header automatically.
|
|
177
178
|
|
|
178
179
|
Disabled organizations are excluded from `/orgs/mine` and cannot be selected as
|
|
179
180
|
tenant context. Operators re-enable them from the organization directory UI or
|
|
@@ -25,8 +25,14 @@ Built-in IDs include `modelStats`, `modelsGrid`, `scriptRunner`, `versionConfig`
|
|
|
25
25
|
For an app-specific widget, implement `AdminHomeWidgetProps` and register it:
|
|
26
26
|
|
|
27
27
|
```tsx
|
|
28
|
-
<AdminProvider
|
|
29
|
-
|
|
28
|
+
<AdminProvider
|
|
29
|
+
apiBase="/admin"
|
|
30
|
+
apiOrigin={baseUrl}
|
|
31
|
+
getAuthHeaders={getAdminAuthHeaders}
|
|
32
|
+
routeBase="/admin"
|
|
33
|
+
widgets={{home: {operationsSummary: OperationsSummary}}}
|
|
34
|
+
>
|
|
35
|
+
<AdminHome />
|
|
30
36
|
</AdminProvider>
|
|
31
37
|
```
|
|
32
38
|
|
|
@@ -248,9 +248,9 @@ use uploads, or lower the per-file cap with `asks: {maxFileSizeBytes: 5_000_000}
|
|
|
248
248
|
<GPTChat resolveAskFiles={resolveAskFiles} {...chatProps} />;
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
`
|
|
252
|
-
`FormData` with a `file` part; the
|
|
253
|
-
|
|
251
|
+
`usePostFilesUploadMutation` is a generated hook in `example-frontend/store/apiSdk.ts` whose
|
|
252
|
+
body is a `FormData` with a `file` part; the request client sends it with the session token.
|
|
253
|
+
`/files/*` exists only on a server with a bucket.
|
|
254
254
|
`createAskFileUploader` (in `gptAsks.ts`) returns `undefined` on 404, the upload's `id` and
|
|
255
255
|
`size` on success, and throws with the server's detail otherwise (such as 401 when the session
|
|
256
256
|
has ended), so the ask stays open. See `example-frontend/app/(tabs)/ai.tsx`.
|
|
@@ -297,9 +297,9 @@ answer as two rows, and ratings are sent by message index.
|
|
|
297
297
|
|
|
298
298
|
A turn can stream only `{done}`, for example when the server cancels a second ask because one is
|
|
299
299
|
already pending. Reload the conversation with `GET /gpt/histories/:id` when a turn streamed nothing
|
|
300
|
-
visible, or when `done.pendingAsk` names an ask the stream did not send. The `@terreno/
|
|
301
|
-
|
|
302
|
-
the history itself, not `{data}` (see [
|
|
300
|
+
visible, or when `done.pendingAsk` names an ask the stream did not send. The `@terreno/syncdb/api`
|
|
301
|
+
request client unwraps the `data` of single-document responses, so `apiClient.request` for that
|
|
302
|
+
route resolves to the history itself, not `{data}` (see [API client](../reference/syncdb.md#api-client)).
|
|
303
303
|
|
|
304
304
|
Refetch the history list after a turn that streams ask events or reloads the conversation. The
|
|
305
305
|
example app reopens a conversation from the list's cached rows, which still hold the pending ask.
|
|
@@ -25,7 +25,6 @@ Embedded app (`example-frontend`):
|
|
|
25
25
|
const syncConflicts = useConflicts();
|
|
26
26
|
|
|
27
27
|
<AdminProvider
|
|
28
|
-
api={api}
|
|
29
28
|
apiBase="/admin"
|
|
30
29
|
apiOrigin={baseUrl}
|
|
31
30
|
getAuthHeaders={getAdminAuthHeaders}
|
|
@@ -35,7 +34,6 @@ const syncConflicts = useConflicts();
|
|
|
35
34
|
widgets={{screens: {"sync-lab": SyncLabScreen}}}
|
|
36
35
|
>
|
|
37
36
|
<AdminShellLayout
|
|
38
|
-
api={api}
|
|
39
37
|
apiBase="/admin"
|
|
40
38
|
configurationPath="/admin/configuration"
|
|
41
39
|
rolesPath="/roles"
|
|
@@ -53,8 +51,8 @@ store name and `windowCollections` set; do not mix admin rows into the owner/ten
|
|
|
53
51
|
product store. Start that client after `canOpenAdminPage` succeeds, block the admin
|
|
54
52
|
shell until `start()` resolves, and call `stop()` when the admin layout unmounts.
|
|
55
53
|
|
|
56
|
-
Gate entry with `canOpenAdminPage` from `@terreno/
|
|
57
|
-
rely on `user.admin` alone when RBAC is on. Import `baseUrl` from `@terreno/
|
|
54
|
+
Gate entry with `canOpenAdminPage` from `@terreno/syncdb/app` (`admin:access`). Do not
|
|
55
|
+
rely on `user.admin` alone when RBAC is on. Import `baseUrl` from `@terreno/syncdb/config`
|
|
58
56
|
and pass it as `apiOrigin` so admin RPC (`GET /admin/config`, `/rbac/roles`, …)
|
|
59
57
|
hits the API instead of the Expo web origin.
|
|
60
58
|
|
|
@@ -123,11 +121,15 @@ for those paths. Otherwise `[model]/[id]` treats the id as a generic document.
|
|
|
123
121
|
|
|
124
122
|
## 5. Fetch data the admin way
|
|
125
123
|
|
|
124
|
+
- Every admin request goes through the `AdminProvider` fetch client. Admin
|
|
125
|
+
components take no `api` prop.
|
|
126
126
|
- String-`_id` collections configured with `adminBroadcast` use windowed syncdb
|
|
127
|
-
when the host passes `syncDb
|
|
128
|
-
- ObjectId
|
|
129
|
-
|
|
130
|
-
-
|
|
127
|
+
when the host passes `syncDb`.
|
|
128
|
+
- ObjectId and API-only models use fetch CRUD. Custom screens call
|
|
129
|
+
`useAdminModelApi(routePath, modelName)` for list/read/create/update/delete.
|
|
130
|
+
- Bulk patch stays server-side at `{routePath}/bulk-patch` for every model.
|
|
131
|
+
- Custom admin RPC uses `useAdminRpc` + `useAdminRpcQuery` / `useAdminRpcMutation`.
|
|
132
|
+
Do not add axios or a second request client.
|
|
131
133
|
|
|
132
134
|
## 6. Sidebar and grouping
|
|
133
135
|
|
|
@@ -26,7 +26,7 @@ bun expo export --platform web
|
|
|
26
26
|
|
|
27
27
|
### Alternative: `app.json` `extra.BASE_URL`
|
|
28
28
|
|
|
29
|
-
`@terreno/
|
|
29
|
+
`@terreno/syncdb/config` resolves the API base from `expo-constants` `extra.BASE_URL` and `EXPO_PUBLIC_API_URL` (see `syncdb/src/config/resolveBaseUrls.ts`). Priority in **production** builds:
|
|
30
30
|
|
|
31
31
|
1. `EXPO_PUBLIC_API_URL` environment variable (set before export)
|
|
32
32
|
2. `extra.BASE_URL` in app config (when env var is unset)
|
|
@@ -10,7 +10,7 @@ How to talk to third-party HTTP APIs (payment processors, health integrations, m
|
|
|
10
10
|
| Calling an external service through its own SDK (Twilio, Google APIs, Stripe) | `withApiErrorHandling` around the SDK calls — the SDK owns transport, you standardize failures |
|
|
11
11
|
| Logging or classifying a caught error from any external call | `normalizeApiError` |
|
|
12
12
|
| Surfacing an external failure to your API's consumers from a route handler | `withApiErrorHandling` with `rethrowAs: "apiError"` |
|
|
13
|
-
| Making internal requests to your own `@terreno/api` backend | None of these — use `@terreno/
|
|
13
|
+
| Making internal requests to your own `@terreno/api` backend | None of these — use the generated `store/apiSdk.ts` hooks (`@terreno/syncdb/api` request client) or syncdb collection hooks on the frontend, or direct function calls on the backend |
|
|
14
14
|
|
|
15
15
|
**Rule of thumb:** any file that would otherwise contain `axios.create(...)` plus a token variable plus a `try/catch → axios.isAxiosError → log → throw` block should use these utilities instead.
|
|
16
16
|
|
|
@@ -92,7 +92,7 @@ Note the hook's output classification also feeds the client's retry decision —
|
|
|
92
92
|
|
|
93
93
|
## When not to use this
|
|
94
94
|
|
|
95
|
-
- **Your own backend's routes** — use the generated
|
|
95
|
+
- **Your own backend's routes** — use syncdb collection hooks or the generated `store/apiSdk.ts` hooks (frontend) or call the function directly (backend).
|
|
96
96
|
- **SDK-managed transport** (Twilio, googleapis) — don't fight the SDK's HTTP layer; adopt only `normalizeApiError`/`withApiErrorHandling` for consistent failure handling.
|
|
97
97
|
- **Webhook notifiers** — `sendToSlack`/`sendToGoogleChat`/`sendToZoom` post to a fixed webhook. Slack channel creation, invites, and bot posts use `createSlackPrivateChannel`, `inviteSlackUsersToChannel`, and `postSlackMessage` with `SLACK_BOT_TOKEN`. See [Webhooks & Notifications](../reference/api.md#webhooks--notifications).
|
|
98
98
|
|
|
@@ -47,6 +47,13 @@ list pipelines on the slug above.
|
|
|
47
47
|
| `.circleci/config.yml` | Setup workflow + `path-filtering` (this is the live config) |
|
|
48
48
|
| `.circleci/continue-config.yml` | Real jobs/workflows gated by those params |
|
|
49
49
|
|
|
50
|
+
## Bun version is pinned
|
|
51
|
+
|
|
52
|
+
`install_bun_and_deps` pins Bun with `node/install-bun` `version`. Bun 1.4.4 reports
|
|
53
|
+
lower line coverage than 1.4.2 for the same tests, which fails the 95% package
|
|
54
|
+
coverage gates. Bump the pin together with the local toolchain and re-run
|
|
55
|
+
`bun run test:coverage` in each package first.
|
|
56
|
+
|
|
50
57
|
## Bun install is uncached
|
|
51
58
|
|
|
52
59
|
`install_bun_and_deps` runs `bun install --frozen-lockfile` with
|
|
@@ -87,8 +94,8 @@ The example-backend Docker job runs only when its image recipe changes
|
|
|
87
94
|
(`Dockerfile`, `.dockerignore`, package manifests, or `bun.lock`). API/source
|
|
88
95
|
changes are covered by preview CD builds and do not start a duplicate image job.
|
|
89
96
|
|
|
90
|
-
UI,
|
|
91
|
-
Those packages are covered by `ui-ci` / `
|
|
97
|
+
UI, syncdb, and admin-frontend changes do **not** start `example-backend-ci`.
|
|
98
|
+
Those packages are covered by `ui-ci` / `syncdb-ci` / `packages-ci` plus e2e and
|
|
92
99
|
admin-spa. `new-file-coverage` starts on package `src/` (and example app
|
|
93
100
|
runtime paths including `example-frontend/components/`), not on every `*.ts`
|
|
94
101
|
file in the repo (Playwright specs no longer compile the world). Package CI
|
|
@@ -169,13 +176,13 @@ non-PR branch builds.
|
|
|
169
176
|
| Path (examples) | Parameter | PR job | `master` job |
|
|
170
177
|
| --- | --- | --- | --- |
|
|
171
178
|
| `demo/**`, `ui/**` | `run-deploy-demo` | `deploy-demo-preview` | `deploy-demo` |
|
|
172
|
-
| `example-frontend/**`, `admin-frontend/**`, `
|
|
179
|
+
| `example-frontend/**`, `admin-frontend/**`, `ui/**`, `ai/**`, `blocks/**`, `syncdb/**`, `bun.lock` | `run-deploy-frontend` | `deploy-frontend-preview` | `deploy-frontend` |
|
|
173
180
|
| `docs/**`, `website/**` | `run-deploy-docs` | `deploy-docs-preview` | `deploy-docs` |
|
|
174
181
|
| `example-backend/**`, `api/**`, `comms/**`, `jobs/**`, `admin-spa/**`, `feature-flags/**`, `announcements/**`, plus every frontend path above | `run-cd-backend` | `gcp-cd-preview` | `gcp-cd-prod` |
|
|
175
182
|
| `terraform/**`, `infra/**` | `run-cd-terraform` | `gcp-cd-preview` | `gcp-cd-prod` |
|
|
176
183
|
| `mcp-server/**`, `ui/**` | `run-cd-mcp` | _(none)_ | `gcp-cd-prod` (runs `mcp-server` `test:ci` first) |
|
|
177
184
|
|
|
178
|
-
The backend image bundles the admin SPA (ui,
|
|
185
|
+
The backend image bundles the admin SPA (ui, admin-frontend, syncdb), so
|
|
179
186
|
those paths redeploy the backend too. Every frontend PR preview therefore gets
|
|
180
187
|
an isolated `pr-N` backend: `deploy-frontend-preview` always points
|
|
181
188
|
`EXPO_PUBLIC_API_URL` at it (the prod backend rejects preview CORS) and waits
|
|
@@ -283,7 +290,7 @@ ambient OIDC token for GCP impersonation.
|
|
|
283
290
|
Branch protection must require the CircleCI job names below. Remove disabled
|
|
284
291
|
GitHub check names or pull requests will wait for checks that can no longer run.
|
|
285
292
|
|
|
286
|
-
Dedicated package jobs (`api-ci`, `ai-ci`, `blocks-ci`, `
|
|
293
|
+
Dedicated package jobs (`api-ci`, `ai-ci`, `blocks-ci`, `ui-ci`, `syncdb-ci`,
|
|
287
294
|
`comms-ci`, `mcp-server-ci`, `admin-spa-ci`) run `bun run test:coverage`
|
|
288
295
|
(`scripts/check-coverage.ts`, 95% functions and lines). Isolated `syncdb` tests
|
|
289
296
|
are included by that script. Published packages without a dedicated workflow
|
|
@@ -305,7 +312,6 @@ the same commands through the parameterized `packages-ci` job, gated by
|
|
|
305
312
|
| Admin frontend lint, compile, coverage | `packages-ci` (`admin-frontend`) |
|
|
306
313
|
| Run all tests (AI CI) | `ai-ci` |
|
|
307
314
|
| Lint, compile, and test blocks | `blocks-ci` |
|
|
308
|
-
| RTK Lint and Build | `rtk-ci` |
|
|
309
315
|
| Syncdb Lint, Build, and Tests | `syncdb-ci` |
|
|
310
316
|
| UI Lint, Build, Types, and Tests + demo typecheck | `ui-ci` |
|
|
311
317
|
| Demo Lint and TypeScript Check | `ui-demo-ci` (demo-only PRs) |
|