@palbase/backend 39.1.0 → 39.1.2

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/docs/README.md CHANGED
@@ -265,6 +265,35 @@ group these into namespaced calls — `pb.todos.list()`, `pb.todos.create(...)`,
265
265
  `pb.todos.get(id:)`. Rename the class or the method and the operationId (and the
266
266
  generated client surface) changes; the verb/path do not affect it.
267
267
 
268
+ ### What the CLI writes into your repository
269
+
270
+ ONE directory, and everything in it is committed:
271
+
272
+ ```text
273
+ palbase/
274
+ project.json which project this checkout is bound to
275
+ palbase-env.d.ts generated from your db/*.ts — types Database.public.*
276
+ .gitattributes marks the generated files so they stay out of review diffs
277
+ environments/
278
+ local/ the stack `palbase start` runs on this machine
279
+ openapi.json the contract
280
+ roles.json the role definitions
281
+ main/ the deployed environment, same shape
282
+ ```
283
+
284
+ There is nothing to ignore. Anything that belongs to YOUR MACHINE rather than to
285
+ the project — the stack `palbase start` put in front of you, and the measurement
286
+ `palbase plan` made — lives outside the checkout, beside your credentials in
287
+ `~/.palbase/checkouts/<hash>/`. A repository that had to carry ignore rules for
288
+ generated files is a repository where nobody can see those files drift.
289
+
290
+ A checkout still holding the retired layout (`.palbase/`, or a `palbase/` with
291
+ `Generated/`, `Config/` or a root `openapi.json` in it) is REFUSED by
292
+ `palbase link`, which names what it found. There is no migration: a tree holding
293
+ both layouts carries two contracts and two clients, and nothing can say which one
294
+ a build read. Delete the old files, commit that deletion, and link again —
295
+ everything there is regenerated from the project.
296
+
268
297
  ### CLI workflow
269
298
 
270
299
  - `palbase build` — validate the tree locally exactly the way a deploy would
package/docs/auth.md CHANGED
@@ -5,6 +5,26 @@ unless it opts out with `auth: false`. Client SDKs attach the user's token
5
5
  automatically, so on the backend you declare what a route needs and inject the
6
6
  user.
7
7
 
8
+ ## Temporary verification failures
9
+
10
+ An absent or invalid access token produces `401 unauthorized` on a protected
11
+ route. If the runtime cannot retrieve a usable signing keyset, it instead
12
+ returns `503 auth_unavailable`. A network failure, an unsuccessful JWKS response,
13
+ or a keyset with no usable signing keys is an availability failure, not evidence
14
+ that the caller's token is invalid. Keep the session and retry after the service
15
+ recovers; signing in again is not required while the token remains valid.
16
+
17
+ The same rule applies to upload authorization. Requests that cannot be verified
18
+ do not reach the handler or the database, and uploads receive no grant. Public
19
+ requests without credentials continue to work.
20
+
21
+ Known signing keys remain usable within their trust TTL (five minutes by
22
+ default). Expired keysets are not trusted during an outage. Concurrent refreshes
23
+ share one request, and failed refreshes and unknown key IDs share a one-second
24
+ retry interval so recovery and key rotation do not wait for the entire TTL.
25
+
26
+ ## Declaring authentication
27
+
8
28
  ```ts
9
29
  import { Controller, Get, Post, Body, User, OptionalUser } from "@palbase/backend";
10
30
  import type { UserT } from "@palbase/backend";
@@ -273,6 +273,35 @@ group these into namespaced calls — `pb.todos.list()`, `pb.todos.create(...)`,
273
273
  `pb.todos.get(id:)`. Rename the class or the method and the operationId (and the
274
274
  generated client surface) changes; the verb/path do not affect it.
275
275
 
276
+ ### What the CLI writes into your repository
277
+
278
+ ONE directory, and everything in it is committed:
279
+
280
+ ```text
281
+ palbase/
282
+ project.json which project this checkout is bound to
283
+ palbase-env.d.ts generated from your db/*.ts — types Database.public.*
284
+ .gitattributes marks the generated files so they stay out of review diffs
285
+ environments/
286
+ local/ the stack `palbase start` runs on this machine
287
+ openapi.json the contract
288
+ roles.json the role definitions
289
+ main/ the deployed environment, same shape
290
+ ```
291
+
292
+ There is nothing to ignore. Anything that belongs to YOUR MACHINE rather than to
293
+ the project — the stack `palbase start` put in front of you, and the measurement
294
+ `palbase plan` made — lives outside the checkout, beside your credentials in
295
+ `~/.palbase/checkouts/<hash>/`. A repository that had to carry ignore rules for
296
+ generated files is a repository where nobody can see those files drift.
297
+
298
+ A checkout still holding the retired layout (`.palbase/`, or a `palbase/` with
299
+ `Generated/`, `Config/` or a root `openapi.json` in it) is REFUSED by
300
+ `palbase link`, which names what it found. There is no migration: a tree holding
301
+ both layouts carries two contracts and two clients, and nothing can say which one
302
+ a build read. Delete the old files, commit that deletion, and link again —
303
+ everything there is regenerated from the project.
304
+
276
305
  ### CLI workflow
277
306
 
278
307
  - `palbase build` — validate the tree locally exactly the way a deploy would
@@ -795,6 +824,26 @@ unless it opts out with `auth: false`. Client SDKs attach the user's token
795
824
  automatically, so on the backend you declare what a route needs and inject the
796
825
  user.
797
826
 
827
+ ## Temporary verification failures
828
+
829
+ An absent or invalid access token produces `401 unauthorized` on a protected
830
+ route. If the runtime cannot retrieve a usable signing keyset, it instead
831
+ returns `503 auth_unavailable`. A network failure, an unsuccessful JWKS response,
832
+ or a keyset with no usable signing keys is an availability failure, not evidence
833
+ that the caller's token is invalid. Keep the session and retry after the service
834
+ recovers; signing in again is not required while the token remains valid.
835
+
836
+ The same rule applies to upload authorization. Requests that cannot be verified
837
+ do not reach the handler or the database, and uploads receive no grant. Public
838
+ requests without credentials continue to work.
839
+
840
+ Known signing keys remain usable within their trust TTL (five minutes by
841
+ default). Expired keysets are not trusted during an outage. Concurrent refreshes
842
+ share one request, and failed refreshes and unknown key IDs share a one-second
843
+ retry interval so recovery and key rotation do not wait for the entire TTL.
844
+
845
+ ## Declaring authentication
846
+
798
847
  ```ts
799
848
  import { Controller, Get, Post, Body, User, OptionalUser } from "@palbase/backend";
800
849
  import type { UserT } from "@palbase/backend";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palbase/backend",
3
- "version": "39.1.0",
3
+ "version": "39.1.2",
4
4
  "description": "Palbase Backend SDK — class controllers (@Controller/@Get/@Post + @Body/@QueryParams/@Param), error classes, schema DSL",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -110,7 +110,7 @@
110
110
  "typescript": "^5.7.0",
111
111
  "unplugin-swc": "^1.5.11",
112
112
  "vitest": "^3.0.0",
113
- "@palbase/core": "^2.4.1"
113
+ "@palbase/core": "^2.4.2"
114
114
  },
115
115
  "publishConfig": {
116
116
  "access": "public",