Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ The module enable / disable hooks were always mutations, so nothing changes in y

The gateway still answers the old `GET` on these paths for now (it logs a deprecation warning) and will drop it after gateway 0.2, so upgrade the core SDK before then. The scheduler switch moved to `PUT` earlier (core SDK 4.6.0). The code module (`hub.code`) has no hooks in this package yet; call `useNorbix().hub.code.enableCode(...)` directly.

### Bulk record writes (core SDK 4.11.0)

`useUpdateManyRecordsMutation` / `useDeleteManyRecordsMutation` (Hub) and `useUpdateManyMutation` / `useDeleteManyMutation` (Api) take a new optional `allRecords` argument. An empty filter (`{}`, or no filter on update) matches the whole collection and the gateway refuses it with `CM-ERRORS-DATABASE-037` unless you pass `allRecords: true`:

```ts
const [deleteMany] = useDeleteManyRecordsMutation();
await deleteMany({ collectionName: 'orders', filter: '{}', allRecords: true });
```

Other gateway rules that now show up as errors from these hooks: an update body with `$` operators (`$inc`, `$set`, …) is refused with `CM-ERRORS-DATABASE-035` (send the plain fields to set); a broken insert or replace document answers `CM-ERRORS-DATABASE-036`; soft-deleted records are "not found" for update, replace and change-owner, and a bulk update skips them. A caller with only own-record rights may now use the bulk hooks; they touch only that caller's records.

### Schemas per environment

`useGetDatabaseSchemasQuery` returns only the schemas of the environment the request targets: the `env` argument, or else the client's environment (`norbix.setEnvironment(...)`, sent as the `norbix-env` header), or `PROD` when neither is set. Each row carries `env`. The schema list settings (`useGetDatabaseSchemaListSettingsQuery` / `useUpdateDatabaseSchemaListSettingsMutation`) are stored per environment too.
Expand Down
39 changes: 39 additions & 0 deletions docs/tasks/database-last-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Database last wave — react-redux on @norbix.ai/ts 4.11.0

## Goal

Move `@norbix.ai/react-redux` onto `@norbix.ai/ts` 4.11.0, the core SDK release that follows the last gateway Database wave.

Not in scope: new hooks (4.11.0 adds no SDK method), the follow-up aggregate field `JoinedCollections` (not in any SDK yet).

## Plan

1. chore(deps): require @norbix.ai/ts 4.11.0 — done, `package.json`, `package-lock.json`
2. test(database): `allRecords` reaches the wire for update many / delete many — done, `tests/database.test.ts`
3. docs(readme): bulk record writes, `allRecords` and the new database errors — done, `README.md`
4. chore(hooks): regenerate hooks — dropped: no hook generator exists in this repo, and 4.11.0 has the same method list as 4.10.0 (compared the `.d.ts` method names of both npm packages), so no hook is added or removed. The hook-per-SDK-method guards (`has one hook per hub.database method …`, `reaches every api.database method …`) pass.

## Changes

| file | what changed | plan step # |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| `package.json`, `package-lock.json` | `@norbix.ai/ts` peer `>=4.11.0`, dev `^4.11.0` | 1 |
| `tests/database.test.ts` | two real-SDK tests: `updateManyRecords` sends `PUT …/orders/many` with `allRecords: true`; `deleteManyRecords` sends `DELETE …/orders/many` with `allRecords` | 2 |
| `README.md` | "Bulk record writes (core SDK 4.11.0)" section | 3 |

## Findings

- What 4.11.0 changes for this package: types only. New `allRecords?: boolean` on the update-many / delete-many requests (Hub and Api); `TaxonomyListProjection.dependencyRefs` (a `TaxonomyRef { id, name? }` list) replaces `dependencyNames`; trigger rows carry `env`; `RenameDatabaseSchemaRequest.renameUniqueName` removed. No hook or test here used the removed fields. Left as is.
- `npx prettier --check .` reports 20 files with style issues that are already on `main` (docs, examples, `tests/provider.test.tsx`). Not touched here; left open.

## Rejected / moved out

- None.

## Needs you

- Nothing.

## Open questions

- None.
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"prepublishOnly": "npm run build"
},
"peerDependencies": {
"@norbix.ai/ts": ">=4.10.0",
"@norbix.ai/ts": ">=4.11.0",
"@reduxjs/toolkit": ">=2.0.0",
"react": ">=18.0.0",
"react-redux": ">=9.0.0"
Expand All @@ -68,7 +68,7 @@
"@commitlint/cli": "^21.2.2",
"@commitlint/config-conventional": "^21.2.2",
"@eslint/js": "^10.0.1",
"@norbix.ai/ts": "^4.10.0",
"@norbix.ai/ts": "^4.11.0",
"@reduxjs/toolkit": "^2.12.0",
"@semantic-release/commit-analyzer": "^13.0.1",
"@semantic-release/github": "^12.0.9",
Expand Down
34 changes: 34 additions & 0 deletions tests/database.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,40 @@ describe('hub records through the real SDK (fake fetch)', () => {
expect(out.data?.result).toBe('r2');
});

it('updateManyRecords sends PUT /many with allRecords for an empty filter', async () => {
const { seen, result } = run(
'updateManyRecords',
{ collectionName: 'orders', filter: '{}', update: '{"status":"archived"}', allRecords: true },
200,
{ result: { matchedCount: 3, modifiedCount: 3 } },
);

const out = (await result) as { error?: unknown };

expect(out.error).toBeUndefined();
expect(seen[0].method).toBe('PUT');
expect(seen[0].url).toBe('https://hub.norbix.io/v2/database/collections/orders/many');
expect(seen[0].body).toMatchObject({ filter: '{}', allRecords: true });
});

it('deleteManyRecords sends DELETE /many with allRecords for an empty filter', async () => {
const { seen, result } = run(
'deleteManyRecords',
{ collectionName: 'orders', filter: '{}', allRecords: true },
200,
{ result: { deletedCount: 3 } },
);

const out = (await result) as { error?: unknown };

expect(out.error).toBeUndefined();
expect(seen[0].method).toBe('DELETE');
const url = new globalThis.URL(seen[0].url);
expect(url.pathname).toBe('/v2/database/collections/orders/many');
const sent = { ...Object.fromEntries(url.searchParams), ...(seen[0].body as object) };
expect(String(sent.allRecords)).toBe('true');
});

it('a gateway error ResponseStatus comes back as the usual serialized error', async () => {
const { result } = run('findRecords', { collectionName: 'orders' }, 403, {
responseStatus: { errorCode: 'Forbidden', message: 'Missing permission database:read' },
Expand Down
Loading