@fitzzero/quickdraw-skills 5.0.0 → 5.0.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/package.json
CHANGED
|
@@ -88,7 +88,7 @@ compile time.
|
|
|
88
88
|
| `members({ model, entry, user, level, levels? })` | a membership table row |
|
|
89
89
|
| `inherit({ from: projectContract, via: "projectId" })` | the level on the parent row in another service |
|
|
90
90
|
| `anyOf(policyA, policyB)` | the highest level any of them gives |
|
|
91
|
-
| `resolver({ levelsFor, where
|
|
91
|
+
| `resolver({ levelsFor, where?, reads })` | your code, one batched read for all ids |
|
|
92
92
|
| `everyone("Read")` | every signed-in user, on every row; no read |
|
|
93
93
|
|
|
94
94
|
- `entry` forms need a policy and `scope` forms a `model`; a service without
|
|
@@ -100,6 +100,17 @@ compile time.
|
|
|
100
100
|
`anyOf(owner("id"), everyone("Read"))`, never a hand-written `resolver`
|
|
101
101
|
answering `Read` for every id: `rowless: true` covers one method, not
|
|
102
102
|
subscriptions.
|
|
103
|
+
- A `resolver` declares what its levels depend on, or nothing re-checks it
|
|
104
|
+
and a removed member keeps their live rows:
|
|
105
|
+
`reads: { columns: ["visibility"], memberships: [{ model: "teamMember", entry: "projectId", user: "userId", level: "role" }] }`
|
|
106
|
+
(columns of the service's model; membership tables as `members` takes
|
|
107
|
+
them, `entry` holding this service's row id). Tracked writes to them then
|
|
108
|
+
revoke and re-check as for the other policies, and `tools.rows(ids)` reads
|
|
109
|
+
the declared columns. `reads: "none"` only when nothing a tracked write
|
|
110
|
+
changes can change a level (the principal's grants alone). Without either
|
|
111
|
+
the server warns `[quickdraw:resolver-without-reads]` and a strict test
|
|
112
|
+
app fails to start. A level from another service's row is `inherit`'s
|
|
113
|
+
job, alone or in `anyOf`.
|
|
103
114
|
- Lookups are batched per call: checking 60 ids costs what one does.
|
|
104
115
|
`createServer({ access: { cacheMs } })` keeps them across calls; tracked
|
|
105
116
|
writes to the columns and tables a policy reads evict them.
|
|
@@ -186,6 +186,11 @@ Contract halves come from `@fitzzero/quickdraw-core`, handlers from
|
|
|
186
186
|
- `sharing.contract({ mode: "acl" | "members" })` with `sharing.handlers(project)`,
|
|
187
187
|
on a service whose policy has a `jsonAcl` or `members`.
|
|
188
188
|
- `admin.contract({ entity })` with `admin.handlers(task)` (`{ service: "Admin" }` by default).
|
|
189
|
+
Name what an admin may change with `editable: ["title", "status"]` (on
|
|
190
|
+
`admin.contract` too, so the input schemas and MCP tools name only those):
|
|
191
|
+
every other field is read-only, and a write naming one is `VALIDATION`.
|
|
192
|
+
Without it the kit writes every field it shows but `id` and the
|
|
193
|
+
timestamps, owner and foreign-key columns included.
|
|
189
194
|
On a users service, `admin.handlers(user, { grants: true })` lets the admin
|
|
190
195
|
screen edit `serviceAccess` through `adminUpdate` (service-wide Admins
|
|
191
196
|
only); never hand-write a `setServiceAccess` method for it. `adminMeta`
|
|
@@ -122,9 +122,10 @@ test that caused it (an oversized reply fails an in-process `app.as(...)`
|
|
|
122
122
|
call; over a socket or HTTP the reply was already sent, so it is logged, not
|
|
123
123
|
thrown). Warnings outside its calls (an `ambient-write` while seeding) are
|
|
124
124
|
logged, and `app.close()` ends it. `tiered-field-in-output` (a method's own
|
|
125
|
-
output schema declares a tiered field, at any depth)
|
|
126
|
-
`
|
|
127
|
-
|
|
125
|
+
output schema declares a tiered field, at any depth) and
|
|
126
|
+
`resolver-without-reads` (a `resolver` policy declares no `reads`) are
|
|
127
|
+
thrown by `createTestApp` itself: answer `"entity"` from that method, or
|
|
128
|
+
declare the resolver's `reads`, rather than turning strictness off.
|
|
128
129
|
Turn it on for service suites.
|
|
129
130
|
`createRecordingSink()` passed as `flushSink` records what each flush wrote.
|
|
130
131
|
|