@neetru/sdk 1.2.0 → 2.1.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +336 -244
  2. package/README.md +194 -194
  3. package/dist/auth.cjs +3762 -345
  4. package/dist/auth.cjs.map +1 -1
  5. package/dist/auth.d.cts +5 -1
  6. package/dist/auth.d.ts +5 -1
  7. package/dist/auth.mjs +3762 -345
  8. package/dist/auth.mjs.map +1 -1
  9. package/dist/catalog.cjs.map +1 -1
  10. package/dist/catalog.d.cts +5 -1
  11. package/dist/catalog.d.ts +5 -1
  12. package/dist/catalog.mjs.map +1 -1
  13. package/dist/checkout.cjs.map +1 -1
  14. package/dist/checkout.d.cts +5 -1
  15. package/dist/checkout.d.ts +5 -1
  16. package/dist/checkout.mjs.map +1 -1
  17. package/dist/collection-ref-DqAAhuhX.d.cts +472 -0
  18. package/dist/collection-ref-DqAAhuhX.d.ts +472 -0
  19. package/dist/db-react.cjs +136 -0
  20. package/dist/db-react.cjs.map +1 -0
  21. package/dist/db-react.d.cts +99 -0
  22. package/dist/db-react.d.ts +99 -0
  23. package/dist/db-react.mjs +112 -0
  24. package/dist/db-react.mjs.map +1 -0
  25. package/dist/db.cjs +3621 -131
  26. package/dist/db.cjs.map +1 -1
  27. package/dist/db.d.cts +5 -8
  28. package/dist/db.d.ts +5 -8
  29. package/dist/db.mjs +3618 -131
  30. package/dist/db.mjs.map +1 -1
  31. package/dist/entitlements.cjs.map +1 -1
  32. package/dist/entitlements.d.cts +5 -1
  33. package/dist/entitlements.d.ts +5 -1
  34. package/dist/entitlements.mjs.map +1 -1
  35. package/dist/errors.cjs.map +1 -1
  36. package/dist/errors.mjs.map +1 -1
  37. package/dist/index.cjs +3984 -341
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +13 -6
  40. package/dist/index.d.ts +13 -6
  41. package/dist/index.mjs +3904 -262
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/mocks.cjs +189 -7
  44. package/dist/mocks.cjs.map +1 -1
  45. package/dist/mocks.d.cts +18 -5
  46. package/dist/mocks.d.ts +18 -5
  47. package/dist/mocks.mjs +189 -7
  48. package/dist/mocks.mjs.map +1 -1
  49. package/dist/notifications.cjs.map +1 -1
  50. package/dist/notifications.d.cts +5 -1
  51. package/dist/notifications.d.ts +5 -1
  52. package/dist/notifications.mjs.map +1 -1
  53. package/dist/react.cjs.map +1 -1
  54. package/dist/react.d.cts +5 -1
  55. package/dist/react.d.ts +5 -1
  56. package/dist/react.mjs.map +1 -1
  57. package/dist/support.cjs.map +1 -1
  58. package/dist/support.d.cts +5 -1
  59. package/dist/support.d.ts +5 -1
  60. package/dist/support.mjs.map +1 -1
  61. package/dist/telemetry.cjs.map +1 -1
  62. package/dist/telemetry.d.cts +5 -1
  63. package/dist/telemetry.d.ts +5 -1
  64. package/dist/telemetry.mjs.map +1 -1
  65. package/dist/types-Cfb-qeDg.d.cts +1364 -0
  66. package/dist/types-V1EfjR1p.d.ts +1364 -0
  67. package/dist/usage.cjs.map +1 -1
  68. package/dist/usage.d.cts +5 -1
  69. package/dist/usage.d.ts +5 -1
  70. package/dist/usage.mjs.map +1 -1
  71. package/dist/webhooks.cjs.map +1 -1
  72. package/dist/webhooks.d.cts +5 -1
  73. package/dist/webhooks.d.ts +5 -1
  74. package/dist/webhooks.mjs.map +1 -1
  75. package/package.json +133 -111
  76. package/dist/types-CQAfwqUS.d.cts +0 -654
  77. package/dist/types-CQAfwqUS.d.ts +0 -654
package/CHANGELOG.md CHANGED
@@ -1,244 +1,336 @@
1
- # Changelog
2
-
3
- All notable changes to `@neetru/sdk` will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- ### Planned (post-1.2)
11
- - size-limit budget no CI (<12KB gz core com db namespace).
12
- - CDN distribution (`cdn.neetru.com/sdk/v1/`).
13
- - Endpoint batch `/api/v1/sdk/telemetry/batch` (substitui drenagem N×1 do `track()` por 1 request).
14
-
15
- ## [1.2.0] - 2026-05-19 — **Webhooks + Notifications + DX (cache, retry, batch)**
16
-
17
- Release de qualidade fechando 3 CRITICAL + 6 IMPORTANT do code review interno + 4 melhorias de DX. Adiciona `webhooks` + `notifications` no `NeetruClient`.
18
-
19
- ### Added
20
- - **`client.webhooks`** — `register`/`list`/`unregister`/`test` pra endpoints HTTP do produto receberem eventos do Core (subscription.activated, usage.quota_exceeded, etc).
21
- - **`verifyWebhookSignature(payload, signature, secret)`** — util pura (HMAC SHA-256 constant-time compare via `node:crypto`) pra consumidor validar payloads recebidos.
22
- - **`client.notifications`** `send`/`list`/`markRead`/`dismiss` pra produto integrar com a bandeja in-app do Neetru.
23
- - **`client.telemetry.track(input)`** + `client.telemetry.flush()` fire-and-forget batch (500ms debounce). Ideal pra alta frequência (page-views, cliques). `event()` segue como single-shot com `eventId` ack.
24
- - **`client.entitlements.check(..., { cacheBust })`** cache LRU em memória (60s TTL, 100 entries). Corta 90%+ requests em renders repetidos do `<EntitlementGate>`. `cacheBust: true` força ida ao servidor.
25
- - **httpRequest retry/backoff** — 2 retries default em `rate_limited` (429), `server_error` (5xx), `network_error`. Honra `Retry-After` header. Caller opt-out com `opts.retries: 0`.
26
- - **Subpaths novos**: `@neetru/sdk/webhooks`, `@neetru/sdk/notifications`.
27
-
28
- ### Changed
29
- - **`client.catalog.list()` / `get()`** agora consomem `/api/sdk/v1/catalog` (público, sem Bearer) em vez de `/api/v1/cli/catalog` (staff). Consumidor não precisa mais de chave staff só pra ler catálogo. `includeDrafts` é ignorado — rascunhos só via CLI.
30
- - **`auth.signOut()`** revoga token em `auth.neetru.com/api/v1/oauth/revoke` (canônico), não mais `api.neetru.com/oauth/revoke` (404 em prod).
31
- - **`<EntitlementGate>`** passa `tenantId` (do `client.config.tenantId`) pra `usage.check`. Sem tenantId, cai pra `entitlements.check` em vez de chamar `usage.check` e travar em `validation_failed` silencioso.
32
- - **`engines.node`** subiu pra `>=20` (alinha com `target: node20` do tsup; Node 18 EOL).
33
-
34
- ### Fixed
35
- - **CRITICAL** — `webhooks` e `notifications` lançavam `'invalid_input'`, código ausente da union `NeetruErrorCode`. Todas as 17 ocorrências viraram `'validation_failed'`.
36
- - **CRITICAL** `telemetry.log()` chamava `/sdk/v1/telemetry/log` (404). Corrigido pra `/api/sdk/v1/telemetry/log`.
37
- - **CRITICAL** `db` namespace tinha o mesmo bug em 6 paths (`/sdk/v1/datastore/...`). Corrigido em massa pra `/api/sdk/v1/datastore/...`.
38
- - **CRITICAL** 8 `httpRequest` calls em `webhooks` e `notifications` não passavam `requireAuth: true` todos hits em prod retornavam 401. Corrigido.
39
- - **`MockSupport.mockTicketSeq`** virou instance field (era module-level, poluía tests entre suites).
40
- - **`db.list()`** removeu variável `query` dead code (refactor incompleto de pre-1.1).
41
-
42
- ### Internal
43
- - 51 testes novos (webhooks: 22, notifications: 20, react: 9). Total: 215 testes (16 files), 100% passing. tsc clean.
44
- - `api-surface-stability.test.ts` agora lock `webhooks` + `notifications` no `NeetruClient`.
45
-
46
- ## [1.1.0] - 2026-05-08 — **Checkout namespace + React helpers**
47
-
48
- Adiciona o namespace `client.checkout` (start/get/cancel intent) com auto-redirect
49
- em browser. Suporte ao fluxo Sprint 13 onde produtos SaaS delegam checkout pro
50
- portal `minhaconta.neetru.com` via `POST /api/v1/checkout/intents`.
51
-
52
- ### Added
53
- - **`client.checkout.start({productId, planId, callbackUrl, tenantType?, tenantId?})`** — cria
54
- `checkout_intents/{intentId}` no Core e (em browser) redireciona automaticamente
55
- pra `minhaconta.neetru.com/portal/checkout/{intentId}`. Em Node/SSR retorna
56
- `{intentId, redirectUrl}` sem efeito colateral.
57
- - **`client.checkout.get(intentId)`** — lê estado atual do intent.
58
- - **`client.checkout.cancel(intentId)`** — marca intent como `cancelled`.
59
- - **Subpath `@neetru/sdk/react`** — componente `<CheckoutLink>` (wrapper de `<a>`
60
- que dispara `start()` no click) + `<EntitlementGate mode="block|readonly">`
61
- + hook `useEntitlementContext()` pra desabilitar escritas quando free tier
62
- estoura limite (decisão CEO §5 read-only sempre, não hard-block).
63
- - **`MockCheckout`** implementação dev (`NEETRU_ENV=dev`) sem network. Retorna
64
- URL fake `https://localhost:9003/portal/checkout/{intentId}` pra dev externo
65
- testar UI sem provisionar conta Neetru.
66
- - **Peer dep `react ^18 || ^19`** marcado opcional (só carregado se import `/react`).
67
-
68
- ### Changed
69
- - `VERSION` const bump `1.0.0 1.1.0`.
70
- - `NeetruClient.checkout` adicionado — backward-compatible (caller que não usa
71
- o namespace não é afetado).
72
-
73
- ### Notes
74
- - API stability test (`api-surface-stability.test.ts`) atualizado pra incluir
75
- `checkout` no inventário canônico.
76
-
77
- ## [1.0.0] - 2026-05-06 **GA (General Availability)**
78
-
79
- Marco de estabilidade. A partir desta versão, **a superfície pública do SDK
80
- está congelada** breaking changes em majors (semver estrito).
81
-
82
- ### Added
83
- - **API stability lock** — todos os contratos (`createNeetruClient`,
84
- `NeetruClient`, namespaces `auth`/`catalog`/`entitlements`/`telemetry`/
85
- `usage`/`support`/`db`, `NeetruError`) ficam estáveis em v1.x. Coberto
86
- por `api-surface-stability.test.ts` que falha o build se algum método
87
- muda forma.
88
- - **JSDoc completo** em toda função/método público — base pra `npm run docs:gen`
89
- (typedoc `sdk/docs-html/`).
90
- - **`docs:gen` script** + `scripts/typedoc.config.json` gera HTML
91
- navigable das APIs.
92
- - **`engines.node`** relaxado de `>=20` `>=18` (suporta runtimes Node 18 LTS
93
- ainda em uso por consumers).
94
-
95
- ### Changed
96
- - `VERSION` bump `0.3.0` `1.0.0`.
97
- - README atualizado com seção de migração v0.3 v1.0 (no breaking changes
98
- upgrade transparente).
99
-
100
- ### Migration v0.3 → v1.0
101
- - **Sem breaking changes.** Upgrade direto via `npm install @neetru/sdk@1.0.0`.
102
- - `initNeetru` continua deprecated mas funcional. **Será removido em v2.0.0.**
103
- - `NeetruConfig` continua deprecated. Use `NeetruClientConfig`.
104
-
105
- ### Stability promise (v1.x)
106
- A partir de v1.0:
107
- - Métodos novos podem ser adicionados a namespaces existentes (minor bump).
108
- - Métodos podem ser marcados `@deprecated` em qualquer minor — só removidos
109
- em major.
110
- - Tipos nunca ganham campos required em minor (só optional ou via union).
111
- - `NeetruErrorCode` é union fechado em v1.0 — qualquer novo código bumpa minor.
112
-
113
- ### Notes
114
- - Pacote ainda **privado** (`private: true`). Publicação no npm é
115
- responsabilidade do ownergate no CHANGELOG continua trancado até decisão.
116
-
117
- ## [0.3.0] - 2026-05-06
118
-
119
- ### Added
120
- - Namespace `client.db` (v0.3) — wrapper minimalista pra coleções tenant-scoped:
121
- - `client.db.collection(name).list({ limit? })`
122
- - `client.db.collection(name).get(id)` (retorna null em not_found)
123
- - `client.db.collection(name).set(id, data)` upsert
124
- - `client.db.collection(name).remove(id)` delete
125
- - Endpoints: `/sdk/v1/datastore/{collection}/{id?}` (placeholder REST — Sprint 9
126
- finaliza; SDK já expõe interface estável).
127
- - `MockDb` (in-memory) ativo em `NEETRU_ENV=dev`.
128
- - Namespace `client.usage` ganhou `report()` e `check()`:
129
- - `usage.report(resource, qty?)` `POST /sdk/v1/usage/record` canônico
130
- (Sprint 7)incrementa atomicamente `usage_counters/{tid}_{pid}_{r}_{yyyymm}`.
131
- - `usage.check(resource)` `GET /sdk/v1/entitlements?productId&tenantId&feature`
132
- retorna `{allowed, reason, remaining, limit, planId, planFeatures}`.
133
- - `NeetruClientConfig.productId` / `.tenantId` — defaults pra `usage.report` /
134
- `usage.check` / `db.collection` quando não passado em options.
135
- - Mock helpers: `MockDb`, `MockUsage.report()`, `MockUsage.check()`.
136
-
137
- ### Changed
138
- - `VERSION` bump `0.2.0` `0.3.0`.
139
- - `NeetruClient` agora expõe `.db` além dos antigos.
140
- - `ResolvedConfig` ganhou `productId` + `tenantId` opcionais.
141
-
142
- ### Backend (acompanha esta release)
143
- - Novos endpoints (Sprint 7):
144
- - `POST /sdk/v1/usage/record` — atomic increment + 80%/100% notifications + audit.
145
- - `GET /sdk/v1/entitlements` lookup canônico subscription→plan→counter.
146
- - `POST /sdk/v1/telemetry/log` batch logger pra `logs/{productId}/{yyyymmdd}/`.
147
-
148
- ## [0.2.0] - 2026-05-06
149
-
150
- ### Added
151
- - Namespace `client.auth` (v0.2 OIDC + dev mocks):
152
- - `signIn(options?)` redireciona pra auth.neetru.com authorize endpoint
153
- (browser) ou retorna mock user em dev (`NEETRU_ENV=dev`).
154
- - `signOut()`limpa `localStorage.neetru_id_token` + revoga refresh
155
- server-side (best-effort).
156
- - `getUser()` decodifica id_token cached e retorna `NeetruUser` ou null.
157
- - `onAuthStateChanged(listener)` sub a mudanças, dispatcha sync no subscribe.
158
- - Namespace `client.usage` (v0.2 meter):
159
- - `track(event, props?)` → `POST /sdk/v1/usage/record` com Bearer.
160
- - `getQuota(metric)` → `GET /sdk/v1/usage/quota?metric=` returns
161
- `{ metric, used, limit, plan, resetsAt? }`.
162
- - Namespace `client.support` (v0.2tickets):
163
- - `createTicket({subject, message, severity?, productSlug?})` →
164
- `POST /api/v1/products/{slug}/tickets` (default `_default`).
165
- - `listMyTickets()` → `GET ...` retorna array (aceita envelope `{tickets:[]}`).
166
- - `mocks` module (`@neetru/sdk/mocks`):
167
- - `MockAuth`, `MockUsage`, `MockSupport`, `MockEntitlements` — overridáveis
168
- via `createNeetruClient({ mocks: { auth: MockAuth(...), ... } })`.
169
- - `DEV_FIXTURE_USER` constante exportada.
170
- - `NEETRU_ENV` resolution chain: config arg > `process.env.NEETRU_ENV` >
171
- `globalThis.NEETRU_ENV` > default `prod`. `dev` ativa mocks automáticos.
172
- - Subpath exports adicionais: `@neetru/sdk/{auth,usage,support,mocks}`.
173
- - Tipos novos: `NeetruUser`, `AuthNamespace`, `UsageNamespace`,
174
- `SupportNamespace`, `SignInOptions`, `SupportTicket`, `UsageQuota`,
175
- `NeetruEnv`, `CreateTicketInput`.
176
-
177
- ### Changed
178
- - `VERSION` bump `0.1.0` `0.2.0`.
179
- - `NeetruClientConfig` ganhou campos `env` + `mocks`.
180
- - `ResolvedConfig` ganhou `env` resolved.
181
- - `NeetruClient` agora expõe `.auth`, `.usage`, `.support` além dos antigos.
182
-
183
- ### Backend (acompanha esta release — endpoints documentados em `docs/SDK_OPENAPI.md`)
184
- - `POST /sdk/v1/usage/record` record event meterado.
185
- - `GET /sdk/v1/usage/quota?metric=` ler quota atual.
186
- - `POST /api/v1/products/{slug}/tickets` — criar ticket.
187
- - `GET /api/v1/products/{slug}/tickets` — listar meus tickets.
188
- - (auth) `auth.neetru.com/oauth/authorize` já live (Sprint 1 OIDC).
189
- - (auth) `auth.neetru.com/oauth/revoke` revoga refresh token.
190
-
191
- ### Notes
192
- - Pacote ainda **privado** (`private: true`) — não publicado no npm.
193
- - Carry-over: integração OIDC live aguarda owner habilitar redirect_uri pro
194
- domain do consumer (configurar em `oidc_clients/{client_id}.redirect_uris`).
195
- - TODO: `support.listMyTickets` precisa parametrizar productSlug (fixed
196
- `_default` na v0.2).
197
-
198
- ## [0.1.0] - 2026-05-05
199
-
200
- ### Added
201
- - `createNeetruClient(config)` factory — entry point principal.
202
- - Resolve `apiKey` (arg explícito > `NEETRU_API_KEY` env em Node).
203
- - Resolve `baseUrl` (default `https://api.neetru.com`).
204
- - Resolve `fetch` (arg > `globalThis.fetch`).
205
- - Namespace `client.catalog`:
206
- - `list(opts?)` `GET /api/v1/cli/catalog`. Aceita `includeDrafts`.
207
- - `get(slug)` `GET /api/v1/cli/catalog/{slug}`.
208
- - Namespace `client.entitlements`:
209
- - `check(slug, feature)` → boolean.
210
- - `checkDetailed(slug, feature)` → `EntitlementCheck` com `reason`.
211
- - Backed por `GET /api/v1/sdk/entitlements/check`.
212
- - Namespace `client.telemetry`:
213
- - `event({ name, properties?, timestamp? })` → `POST /api/v1/sdk/telemetry/event`.
214
- - Subpath exports map: `@neetru/sdk/{catalog,entitlements,telemetry,errors}`.
215
- - HTTP transport com mapeamento status → `NeetruError.code` estável.
216
- - Tipos exportados: `NeetruClient`, `NeetruClientConfig`, `Product`, `ProductPlan`,
217
- `EntitlementCheck`, `TelemetryEventInput`, `TelemetryEventAck`, `NeetruErrorCode`.
218
- - Compat alias `initNeetru` (deprecated, será removido em v1.0).
219
-
220
- ### Changed
221
- - `VERSION` bump `0.0.1` → `0.1.0`.
222
- - tsup config multi-entry pra subpath imports.
223
-
224
- ### Backend (acompanha esta release)
225
- - `GET /api/v1/cli/catalog/{slug}` — produto único.
226
- - `GET /api/v1/sdk/entitlements/check?slug=&feature=` verificação por user.
227
- - `POST /api/v1/sdk/telemetry/event` — persiste em `usage_events`.
228
-
229
- ### Notes
230
- - Pacote ainda **privado** (`private: true`). Publicação no npm é
231
- responsabilidade do owner em Sprint 6.
232
- - API instável; pré-1.0 segue regra "breaking allowed em qualquer minor".
233
-
234
- ## [0.0.1] - 2026-05-04
235
-
236
- ### Added
237
- - Scaffold inicial do pacote `@neetru/sdk` (private, não publicado no npm ainda).
238
- - `initNeetru(config)` com validação de `apiUrl` e injeção opcional de `fetch`.
239
- - `NeetruError` com `code`, `status` e `requestId` opcionais.
240
- - `NeetruConfig` e `NeetruClient` types públicos.
241
- - `VERSION` const exportada.
242
- - Build pipeline com tsup (dual ESM + CJS + `.d.ts`).
243
- - README + CHANGELOG.
244
- - `tsconfig.json` strict ES2022 ESNext.
1
+ # Changelog
2
+
3
+ All notable changes to `@neetru/sdk` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Planned (post-2.1)
11
+ - size-limit budget no CI (<12KB gz core com db namespace).
12
+ - CDN distribution (`cdn.neetru.com/sdk/v2/`).
13
+ - Endpoint batch `/api/v1/sdk/telemetry/batch` (substitui drenagem N×1 do `track()` por 1 request).
14
+
15
+ ## [2.1.1] - 2026-05-25 — **DbDocRef identity + DbBatchOp discriminated union [patch]**
16
+
17
+ Dois fixes LOW reportados por pdv-agiliza (tickets `bug_97b3f0488d1c49cf8c5f94e5d544289b` + `bug_6aab9adc182640218652a65cdcb71b63`).
18
+ Sem breaking changes — todos os usos de `doc()` existentes continuam funcionando.
19
+
20
+ ### Fixed
21
+
22
+ - **`DbDocRef.id / .path / .collection`** (fix #13, ticket `bug_97b3f0488d1c49cf8c5f94e5d544289b`):
23
+ `DbDocRef` agora expõe três propriedades readonly de identidade:
24
+ - `id: string`ID do documento dentro da coleção.
25
+ - `path: string` Caminho completo `"colecao/docId"`.
26
+ - `collection: string` Nome da coleção parent.
27
+ Análogo ao `DocumentReference.id/.path` do Firestore Web SDK. Elimina a necessidade
28
+ de adaptadores externos que reattachavam `collection + id` manualmente.
29
+ Implementado em `DbCollectionRefImpl.doc()` (offline), `createLazyCollectionRef.doc()`
30
+ (client-db) e `MockDb.doc()` (mocks).
31
+
32
+ - **`DbBatchOp` discriminated union** (fix #14, ticket `bug_6aab9adc182640218652a65cdcb71b63`):
33
+ `DbBatchOp` foi convertido de `interface` opaca (campo `op: 'add'|'set'|'update'|'remove'`
34
+ com `id?`/`data?` opcionais) para **discriminated union** pelo campo `kind`:
35
+ ```ts
36
+ type DbBatchOp<T = Record<string, unknown>> =
37
+ | { kind: 'add'; data: Omit<T, 'id'> }
38
+ | { kind: 'set'; id: string; data: Omit<T, 'id'> }
39
+ | { kind: 'update'; id: string; data: Partial<Omit<T, 'id'>> }
40
+ | { kind: 'remove'; id: string };
41
+ ```
42
+ O `.d.ts` público agora expõe claramente quais campos são obrigatórios por variante.
43
+ O campo `collection` foi removido da operação (sempre opera na coleção do `DbCollectionRef`).
44
+
45
+ ### Migration (2.0.0 → 2.1.1)
46
+
47
+ Callers que usavam `batch()` devem trocar `op` por `kind` e remover o campo `collection`:
48
+
49
+ ```ts
50
+ // antes (2.0.0)
51
+ col.batch([
52
+ { op: 'add', collection: 'orders', data: { total: 10 } },
53
+ { op: 'set', collection: 'orders', id: 'x', data: { total: 20 } },
54
+ { op: 'update', collection: 'orders', id: 'y', data: { total: 30 } },
55
+ { op: 'remove', collection: 'orders', id: 'z' },
56
+ ]);
57
+
58
+ // depois (2.1.1)
59
+ col.batch([
60
+ { kind: 'add', data: { total: 10 } },
61
+ { kind: 'set', id: 'x', data: { total: 20 } },
62
+ { kind: 'update', id: 'y', data: { total: 30 } },
63
+ { kind: 'remove', id: 'z' },
64
+ ]);
65
+ ```
66
+
67
+ ## [2.0.0] - 2026-05-22 — **client.db NeetruDb (Documentos engine-aware + SQL) [M2]**
68
+
69
+ Major bump breaking changes no namespace `db`. Liga todos os building blocks M2 na superfície pública.
70
+
71
+ ### Breaking Changes
72
+
73
+ - **`client.db`** troca de `DbNamespace` (v0.3 REST simples) para `NeetruDb` (v2.0 offline-first engine-aware).
74
+ - `collection().list()` agora retorna `DbListResult<T>` (com `docs`, `nextCursor`, `fromCache`, `stale`, `hasPendingWrites`, `changes`) em vez de `T[]`.
75
+ - `collection().get(id)` retorna `DbGetResult<T> | null` em vez de `T | null`.
76
+ - `db_unavailable` não significa mais "sem rede" — só ciclo de vida do banco. Offline é transparente.
77
+ - Novos métodos obrigatórios na superfície: `sql()`, `syncState`, `flush()`, `clearCache()`, `getConflicts()`, `onSyncStateChanged()`, `batch()`, `onDoc()`, `onSnapshot()`, `doc()`.
78
+ - **`db.sql(schema)` lança `NeetruDbError('db_unavailable')` em `NEETRU_ENV=dev`** — sem Postgres local, sem acesso SQL. Use `neetru dev` para subir o container.
79
+ - **`initNeetru`** mantido como stub funcional mas não mapeia mais `apiUrl → baseUrl`. Remover em v3.0.
80
+ - **`MockDb`** foi atualizado para implementar `NeetruDb` (v2.0) em vez de `DbNamespace` (v0.3).
81
+
82
+ ### Added
83
+
84
+ - **`client.db.collection<T>(name)`** — retorna `DbCollectionRef<T>` offline-first, engine-aware. Funciona sem rede. Sync automático quando conectado.
85
+ - CRUD: `add`, `set`, `update`, `remove`, `get`, `list` (com query, cursor, orderBy, where, limit).
86
+ - Batch: `batch(ops)` operações atômicas (client-side).
87
+ - Realtime: `onSnapshot(query, cb)`, `onDoc(id, cb)` — subscriptions permanentes, delivery imediato do cache.
88
+ - Doc ref: `doc(id).get()`, `.set()`, `.update()`, `.remove()`, `.onSnapshot()`.
89
+ - **`client.db.sql<TSchema>(schema)`** lease SQL. Retorna `NeetruSqlClient<TSchema>` com `orm` (Drizzle `NodePgDatabase`) + `transaction()` + `close()`.
90
+ - **`client.db.syncState`** estado de sincronização observável (`status`, `pendingWrites`, `lastSyncedAt`, `isLeaderTab`).
91
+ - **`client.db.onSyncStateChanged(cb)`** — subscrição de mudanças de sync state.
92
+ - **`client.db.flush()`** força ciclo de sync imediato.
93
+ - **`client.db.clearCache(collections?)`** limpa o cache local (IndexedDB).
94
+ - **`client.db.getConflicts(collection?)`** — lista conflitos LWW pendentes.
95
+ - **Engine detection** via `NeetruDbOptions.engine`: `'firestore'` | `'nosql-vm'` | `'rest'` (default MVP).
96
+ - **Subpath `@neetru/sdk/db/react`** — hooks React: `useCollection`, `useDoc` (exporta via `dist/db-react.{mjs,cjs}`).
97
+ - **Novos tipos públicos exportados**: `NeetruDb`, `NeetruDbEngine`, `NeetruDbOptions`, `NeetruSqlClient`, `DbSqlLease`, `DbCollectionRef`, `DbDocRef`, `DbQuery`, `DbDoc`, `DbListResult`, `DbGetResult`, `DbBatchOp`, `DbChangeType`, `NeetruDbError`, `NeetruDbErrorCode`.
98
+ - **`createNeetruDb(config, opts)`** — factory async (para uso fora do `createNeetruClient`).
99
+ - **`createNeetruDbSync(config, opts)`** — factory sync com lazy init IndexedDB (usada internamente em `createNeetruClient`).
100
+
101
+ ### Changed
102
+
103
+ - **`NeetruClientConfig.db`** — aceita `NeetruDbOptions` (engine, dbId, collections, dbName, etc.).
104
+ - **`client.config.mocks.db`** — agora é `NeetruDb` em vez de `DbNamespace`.
105
+ - **`VERSION`** bumped para `'2.0.0'`.
106
+
107
+ ## [1.2.0] - 2026-05-19 **Webhooks + Notifications + DX (cache, retry, batch)**
108
+
109
+ Release de qualidade fechando 3 CRITICAL + 6 IMPORTANT do code review interno + 4 melhorias de DX. Adiciona `webhooks` + `notifications` no `NeetruClient`.
110
+
111
+ ### Added
112
+ - **`client.webhooks`** — `register`/`list`/`unregister`/`test` pra endpoints HTTP do produto receberem eventos do Core (subscription.activated, usage.quota_exceeded, etc).
113
+ - **`verifyWebhookSignature(payload, signature, secret)`** — util pura (HMAC SHA-256 constant-time compare via `node:crypto`) pra consumidor validar payloads recebidos.
114
+ - **`client.notifications`** `send`/`list`/`markRead`/`dismiss` pra produto integrar com a bandeja in-app do Neetru.
115
+ - **`client.telemetry.track(input)`** + `client.telemetry.flush()` fire-and-forget batch (500ms debounce). Ideal pra alta frequência (page-views, cliques). `event()` segue como single-shot com `eventId` ack.
116
+ - **`client.entitlements.check(..., { cacheBust })`** — cache LRU em memória (60s TTL, 100 entries). Corta 90%+ requests em renders repetidos do `<EntitlementGate>`. `cacheBust: true` força ida ao servidor.
117
+ - **httpRequest retry/backoff** — 2 retries default em `rate_limited` (429), `server_error` (5xx), `network_error`. Honra `Retry-After` header. Caller opt-out com `opts.retries: 0`.
118
+ - **Subpaths novos**: `@neetru/sdk/webhooks`, `@neetru/sdk/notifications`.
119
+
120
+ ### Changed
121
+ - **`client.catalog.list()` / `get()`** agora consomem `/api/sdk/v1/catalog` (público, sem Bearer) em vez de `/api/v1/cli/catalog` (staff). Consumidor não precisa mais de chave staff só pra ler catálogo. `includeDrafts` é ignorado — rascunhos só via CLI.
122
+ - **`auth.signOut()`** revoga token em `auth.neetru.com/api/v1/oauth/revoke` (canônico), não mais `api.neetru.com/oauth/revoke` (404 em prod).
123
+ - **`<EntitlementGate>`** passa `tenantId` (do `client.config.tenantId`) pra `usage.check`. Sem tenantId, cai pra `entitlements.check` em vez de chamar `usage.check` e travar em `validation_failed` silencioso.
124
+ - **`engines.node`** subiu pra `>=20` (alinha com `target: node20` do tsup; Node 18 EOL).
125
+
126
+ ### Fixed
127
+ - **CRITICAL** — `webhooks` e `notifications` lançavam `'invalid_input'`, código ausente da union `NeetruErrorCode`. Todas as 17 ocorrências viraram `'validation_failed'`.
128
+ - **CRITICAL** `telemetry.log()` chamava `/sdk/v1/telemetry/log` (404). Corrigido pra `/api/sdk/v1/telemetry/log`.
129
+ - **CRITICAL** — `db` namespace tinha o mesmo bug em 6 paths (`/sdk/v1/datastore/...`). Corrigido em massa pra `/api/sdk/v1/datastore/...`.
130
+ - **CRITICAL**8 `httpRequest` calls em `webhooks` e `notifications` não passavam `requireAuth: true` — todos hits em prod retornavam 401. Corrigido.
131
+ - **`MockSupport.mockTicketSeq`** virou instance field (era module-level, poluía tests entre suites).
132
+ - **`db.list()`** removeu variável `query` dead code (refactor incompleto de pre-1.1).
133
+
134
+ ### Internal
135
+ - 51 testes novos (webhooks: 22, notifications: 20, react: 9). Total: 215 testes (16 files), 100% passing. tsc clean.
136
+ - `api-surface-stability.test.ts` agora lock `webhooks` + `notifications` no `NeetruClient`.
137
+
138
+ ## [1.1.0] - 2026-05-08 — **Checkout namespace + React helpers**
139
+
140
+ Adiciona o namespace `client.checkout` (start/get/cancel intent) com auto-redirect
141
+ em browser. Suporte ao fluxo Sprint 13 onde produtos SaaS delegam checkout pro
142
+ portal `minhaconta.neetru.com` via `POST /api/v1/checkout/intents`.
143
+
144
+ ### Added
145
+ - **`client.checkout.start({productId, planId, callbackUrl, tenantType?, tenantId?})`** — cria
146
+ `checkout_intents/{intentId}` no Core e (em browser) redireciona automaticamente
147
+ pra `minhaconta.neetru.com/portal/checkout/{intentId}`. Em Node/SSR retorna
148
+ `{intentId, redirectUrl}` sem efeito colateral.
149
+ - **`client.checkout.get(intentId)`** — lê estado atual do intent.
150
+ - **`client.checkout.cancel(intentId)`** — marca intent como `cancelled`.
151
+ - **Subpath `@neetru/sdk/react`**componente `<CheckoutLink>` (wrapper de `<a>`
152
+ que dispara `start()` no click) + `<EntitlementGate mode="block|readonly">`
153
+ + hook `useEntitlementContext()` pra desabilitar escritas quando free tier
154
+ estoura limite (decisão CEO §5 read-only sempre, não hard-block).
155
+ - **`MockCheckout`** — implementação dev (`NEETRU_ENV=dev`) sem network. Retorna
156
+ URL fake `https://localhost:9003/portal/checkout/{intentId}` pra dev externo
157
+ testar UI sem provisionar conta Neetru.
158
+ - **Peer dep `react ^18 || ^19`** marcado opcional ( carregado se import `/react`).
159
+
160
+ ### Changed
161
+ - `VERSION` const bump `1.0.0 1.1.0`.
162
+ - `NeetruClient.checkout` adicionadobackward-compatible (caller que não usa
163
+ o namespace não é afetado).
164
+
165
+ ### Notes
166
+ - API stability test (`api-surface-stability.test.ts`) atualizado pra incluir
167
+ `checkout` no inventário canônico.
168
+
169
+ ## [1.0.0] - 2026-05-06 **GA (General Availability)**
170
+
171
+ Marco de estabilidade. A partir desta versão, **a superfície pública do SDK
172
+ está congelada** breaking changes só em majors (semver estrito).
173
+
174
+ ### Added
175
+ - **API stability lock** — todos os contratos (`createNeetruClient`,
176
+ `NeetruClient`, namespaces `auth`/`catalog`/`entitlements`/`telemetry`/
177
+ `usage`/`support`/`db`, `NeetruError`) ficam estáveis em v1.x. Coberto
178
+ por `api-surface-stability.test.ts` que falha o build se algum método
179
+ muda forma.
180
+ - **JSDoc completo** em toda função/método público — base pra `npm run docs:gen`
181
+ (typedoc `sdk/docs-html/`).
182
+ - **`docs:gen` script** + `scripts/typedoc.config.json` — gera HTML
183
+ navigable das APIs.
184
+ - **`engines.node`** relaxado de `>=20` → `>=18` (suporta runtimes Node 18 LTS
185
+ ainda em uso por consumers).
186
+
187
+ ### Changed
188
+ - `VERSION` bump `0.3.0` `1.0.0`.
189
+ - README atualizado com seção de migração v0.3 → v1.0 (no breaking changes
190
+ upgrade transparente).
191
+
192
+ ### Migration v0.3 v1.0
193
+ - **Sem breaking changes.** Upgrade direto via `npm install @neetru/sdk@1.0.0`.
194
+ - `initNeetru` continua deprecated mas funcional. **Será removido em v2.0.0.**
195
+ - `NeetruConfig` continua deprecated. Use `NeetruClientConfig`.
196
+
197
+ ### Stability promise (v1.x)
198
+ A partir de v1.0:
199
+ - Métodos novos podem ser adicionados a namespaces existentes (minor bump).
200
+ - Métodos podem ser marcados `@deprecated` em qualquer minor — só removidos
201
+ em major.
202
+ - Tipos nunca ganham campos required em minor (só optional ou via union).
203
+ - `NeetruErrorCode` é union fechado em v1.0 — qualquer novo código bumpa minor.
204
+
205
+ ### Notes
206
+ - Pacote ainda **privado** (`private: true`). Publicação no npm é
207
+ responsabilidade do owner gate no CHANGELOG continua trancado até decisão.
208
+
209
+ ## [0.3.0] - 2026-05-06
210
+
211
+ ### Added
212
+ - Namespace `client.db` (v0.3) — wrapper minimalista pra coleções tenant-scoped:
213
+ - `client.db.collection(name).list({ limit? })`
214
+ - `client.db.collection(name).get(id)` (retorna null em not_found)
215
+ - `client.db.collection(name).set(id, data)` upsert
216
+ - `client.db.collection(name).remove(id)` delete
217
+ - Endpoints: `/sdk/v1/datastore/{collection}/{id?}` (placeholder REST — Sprint 9
218
+ finaliza; SDK expõe interface estável).
219
+ - `MockDb` (in-memory) ativo em `NEETRU_ENV=dev`.
220
+ - Namespace `client.usage` ganhou `report()` e `check()`:
221
+ - `usage.report(resource, qty?)` `POST /sdk/v1/usage/record` canônico
222
+ (Sprint 7) incrementa atomicamente `usage_counters/{tid}_{pid}_{r}_{yyyymm}`.
223
+ - `usage.check(resource)` → `GET /sdk/v1/entitlements?productId&tenantId&feature` —
224
+ retorna `{allowed, reason, remaining, limit, planId, planFeatures}`.
225
+ - `NeetruClientConfig.productId` / `.tenantId` — defaults pra `usage.report` /
226
+ `usage.check` / `db.collection` quando não passado em options.
227
+ - Mock helpers: `MockDb`, `MockUsage.report()`, `MockUsage.check()`.
228
+
229
+ ### Changed
230
+ - `VERSION` bump `0.2.0` `0.3.0`.
231
+ - `NeetruClient` agora expõe `.db` além dos antigos.
232
+ - `ResolvedConfig` ganhou `productId` + `tenantId` opcionais.
233
+
234
+ ### Backend (acompanha esta release)
235
+ - Novos endpoints (Sprint 7):
236
+ - `POST /sdk/v1/usage/record` — atomic increment + 80%/100% notifications + audit.
237
+ - `GET /sdk/v1/entitlements` lookup canônico subscription→plan→counter.
238
+ - `POST /sdk/v1/telemetry/log` batch logger pra `logs/{productId}/{yyyymmdd}/`.
239
+
240
+ ## [0.2.0] - 2026-05-06
241
+
242
+ ### Added
243
+ - Namespace `client.auth` (v0.2 — OIDC + dev mocks):
244
+ - `signIn(options?)` redireciona pra auth.neetru.com authorize endpoint
245
+ (browser) ou retorna mock user em dev (`NEETRU_ENV=dev`).
246
+ - `signOut()` — limpa `localStorage.neetru_id_token` + revoga refresh
247
+ server-side (best-effort).
248
+ - `getUser()` — decodifica id_token cached e retorna `NeetruUser` ou null.
249
+ - `onAuthStateChanged(listener)` — sub a mudanças, dispatcha sync no subscribe.
250
+ - Namespace `client.usage` (v0.2 — meter):
251
+ - `track(event, props?)` → `POST /sdk/v1/usage/record` com Bearer.
252
+ - `getQuota(metric)` → `GET /sdk/v1/usage/quota?metric=` returns
253
+ `{ metric, used, limit, plan, resetsAt? }`.
254
+ - Namespace `client.support` (v0.2 — tickets):
255
+ - `createTicket({subject, message, severity?, productSlug?})` →
256
+ `POST /api/v1/products/{slug}/tickets` (default `_default`).
257
+ - `listMyTickets()` → `GET ...` retorna array (aceita envelope `{tickets:[]}`).
258
+ - `mocks` module (`@neetru/sdk/mocks`):
259
+ - `MockAuth`, `MockUsage`, `MockSupport`, `MockEntitlements` — overridáveis
260
+ via `createNeetruClient({ mocks: { auth: MockAuth(...), ... } })`.
261
+ - `DEV_FIXTURE_USER` constante exportada.
262
+ - `NEETRU_ENV` resolution chain: config arg > `process.env.NEETRU_ENV` >
263
+ `globalThis.NEETRU_ENV` > default `prod`. `dev` ativa mocks automáticos.
264
+ - Subpath exports adicionais: `@neetru/sdk/{auth,usage,support,mocks}`.
265
+ - Tipos novos: `NeetruUser`, `AuthNamespace`, `UsageNamespace`,
266
+ `SupportNamespace`, `SignInOptions`, `SupportTicket`, `UsageQuota`,
267
+ `NeetruEnv`, `CreateTicketInput`.
268
+
269
+ ### Changed
270
+ - `VERSION` bump `0.1.0` → `0.2.0`.
271
+ - `NeetruClientConfig` ganhou campos `env` + `mocks`.
272
+ - `ResolvedConfig` ganhou `env` resolved.
273
+ - `NeetruClient` agora expõe `.auth`, `.usage`, `.support` além dos antigos.
274
+
275
+ ### Backend (acompanha esta release — endpoints documentados em `docs/SDK_OPENAPI.md`)
276
+ - `POST /sdk/v1/usage/record` — record event meterado.
277
+ - `GET /sdk/v1/usage/quota?metric=` — ler quota atual.
278
+ - `POST /api/v1/products/{slug}/tickets` — criar ticket.
279
+ - `GET /api/v1/products/{slug}/tickets` — listar meus tickets.
280
+ - (auth) `auth.neetru.com/oauth/authorize` — já live (Sprint 1 OIDC).
281
+ - (auth) `auth.neetru.com/oauth/revoke` — revoga refresh token.
282
+
283
+ ### Notes
284
+ - Pacote ainda **privado** (`private: true`) — não publicado no npm.
285
+ - Carry-over: integração OIDC live aguarda owner habilitar redirect_uri pro
286
+ domain do consumer (configurar em `oidc_clients/{client_id}.redirect_uris`).
287
+ - TODO: `support.listMyTickets` precisa parametrizar productSlug (fixed
288
+ `_default` na v0.2).
289
+
290
+ ## [0.1.0] - 2026-05-05
291
+
292
+ ### Added
293
+ - `createNeetruClient(config)` factory — entry point principal.
294
+ - Resolve `apiKey` (arg explícito > `NEETRU_API_KEY` env em Node).
295
+ - Resolve `baseUrl` (default `https://api.neetru.com`).
296
+ - Resolve `fetch` (arg > `globalThis.fetch`).
297
+ - Namespace `client.catalog`:
298
+ - `list(opts?)` → `GET /api/v1/cli/catalog`. Aceita `includeDrafts`.
299
+ - `get(slug)` → `GET /api/v1/cli/catalog/{slug}`.
300
+ - Namespace `client.entitlements`:
301
+ - `check(slug, feature)` → boolean.
302
+ - `checkDetailed(slug, feature)` → `EntitlementCheck` com `reason`.
303
+ - Backed por `GET /api/v1/sdk/entitlements/check`.
304
+ - Namespace `client.telemetry`:
305
+ - `event({ name, properties?, timestamp? })` → `POST /api/v1/sdk/telemetry/event`.
306
+ - Subpath exports map: `@neetru/sdk/{catalog,entitlements,telemetry,errors}`.
307
+ - HTTP transport com mapeamento status → `NeetruError.code` estável.
308
+ - Tipos exportados: `NeetruClient`, `NeetruClientConfig`, `Product`, `ProductPlan`,
309
+ `EntitlementCheck`, `TelemetryEventInput`, `TelemetryEventAck`, `NeetruErrorCode`.
310
+ - Compat alias `initNeetru` (deprecated, será removido em v1.0).
311
+
312
+ ### Changed
313
+ - `VERSION` bump `0.0.1` → `0.1.0`.
314
+ - tsup config multi-entry pra subpath imports.
315
+
316
+ ### Backend (acompanha esta release)
317
+ - `GET /api/v1/cli/catalog/{slug}` — produto único.
318
+ - `GET /api/v1/sdk/entitlements/check?slug=&feature=` — verificação por user.
319
+ - `POST /api/v1/sdk/telemetry/event` — persiste em `usage_events`.
320
+
321
+ ### Notes
322
+ - Pacote ainda **privado** (`private: true`). Publicação no npm é
323
+ responsabilidade do owner em Sprint 6.
324
+ - API instável; pré-1.0 segue regra "breaking allowed em qualquer minor".
325
+
326
+ ## [0.0.1] - 2026-05-04
327
+
328
+ ### Added
329
+ - Scaffold inicial do pacote `@neetru/sdk` (private, não publicado no npm ainda).
330
+ - `initNeetru(config)` com validação de `apiUrl` e injeção opcional de `fetch`.
331
+ - `NeetruError` com `code`, `status` e `requestId` opcionais.
332
+ - `NeetruConfig` e `NeetruClient` types públicos.
333
+ - `VERSION` const exportada.
334
+ - Build pipeline com tsup (dual ESM + CJS + `.d.ts`).
335
+ - README + CHANGELOG.
336
+ - `tsconfig.json` strict ES2022 ESNext.