@odla-ai/chapter 0.10.1 → 0.11.0
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/README.md +21 -3
- package/dist/index.cjs +12 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +17 -3
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +7 -0
- package/dist/worker/index.d.ts +7 -0
- package/dist/worker/index.js +17 -3
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
package/dist/worker/index.d.cts
CHANGED
|
@@ -154,6 +154,12 @@ interface ChapterApplication {
|
|
|
154
154
|
defaultMaxLen?: number;
|
|
155
155
|
/** Max JSON request body in bytes. Default 32768. */
|
|
156
156
|
bodyCap?: number;
|
|
157
|
+
/** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
|
|
158
|
+
* writing a row with no consent record. Default `false` for back-compat —
|
|
159
|
+
* but turn it on if the disclaimer is a compliance record: a missing ack is
|
|
160
|
+
* otherwise silent, permanent and unreconstructible. Failure is deterministic
|
|
161
|
+
* and surfaces on the first test submit, not intermittently in production. */
|
|
162
|
+
requireDisclaimerAck?: boolean;
|
|
157
163
|
}
|
|
158
164
|
/** The fully-resolved application config carried on the {@link Chapter}. */
|
|
159
165
|
interface ResolvedApplication {
|
|
@@ -162,6 +168,7 @@ interface ResolvedApplication {
|
|
|
162
168
|
maxLen: Record<string, number>;
|
|
163
169
|
defaultMaxLen: number;
|
|
164
170
|
bodyCap: number;
|
|
171
|
+
requireDisclaimerAck: boolean;
|
|
165
172
|
}
|
|
166
173
|
/** The `defineChapter()` config a site fills in. */
|
|
167
174
|
interface ChapterConfig {
|
package/dist/worker/index.d.ts
CHANGED
|
@@ -154,6 +154,12 @@ interface ChapterApplication {
|
|
|
154
154
|
defaultMaxLen?: number;
|
|
155
155
|
/** Max JSON request body in bytes. Default 32768. */
|
|
156
156
|
bodyCap?: number;
|
|
157
|
+
/** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
|
|
158
|
+
* writing a row with no consent record. Default `false` for back-compat —
|
|
159
|
+
* but turn it on if the disclaimer is a compliance record: a missing ack is
|
|
160
|
+
* otherwise silent, permanent and unreconstructible. Failure is deterministic
|
|
161
|
+
* and surfaces on the first test submit, not intermittently in production. */
|
|
162
|
+
requireDisclaimerAck?: boolean;
|
|
157
163
|
}
|
|
158
164
|
/** The fully-resolved application config carried on the {@link Chapter}. */
|
|
159
165
|
interface ResolvedApplication {
|
|
@@ -162,6 +168,7 @@ interface ResolvedApplication {
|
|
|
162
168
|
maxLen: Record<string, number>;
|
|
163
169
|
defaultMaxLen: number;
|
|
164
170
|
bodyCap: number;
|
|
171
|
+
requireDisclaimerAck: boolean;
|
|
165
172
|
}
|
|
166
173
|
/** The `defineChapter()` config a site fills in. */
|
|
167
174
|
interface ChapterConfig {
|
package/dist/worker/index.js
CHANGED
|
@@ -157,6 +157,9 @@ async function createClerkUser(secretKey, input, fetchImpl = fetch) {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
// src/member.ts
|
|
160
|
+
function hasDisclaimerAck(fields) {
|
|
161
|
+
return fields.disclaimerAck === true || fields.disclaimerAck === "true";
|
|
162
|
+
}
|
|
160
163
|
var IDENTITY_FIELDS = /* @__PURE__ */ new Set(["email", "firstName", "lastName"]);
|
|
161
164
|
function applicantProfile(chapter, fields) {
|
|
162
165
|
const profile = {};
|
|
@@ -179,6 +182,10 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
179
182
|
const cap = app.maxLen[f] ?? app.defaultMaxLen;
|
|
180
183
|
if (typeof v === "string" && v.length > cap) return { ok: false, error: `${f} exceeds ${cap} characters` };
|
|
181
184
|
}
|
|
185
|
+
const acked = hasDisclaimerAck(fields);
|
|
186
|
+
if (app.requireDisclaimerAck && !acked) {
|
|
187
|
+
return { ok: false, error: "disclaimerAck is required" };
|
|
188
|
+
}
|
|
182
189
|
const id = opts.newId();
|
|
183
190
|
const row = { id, status: chapter.pipeline.initial, createdAt: opts.now };
|
|
184
191
|
for (const f of [...app.required, ...app.optional]) {
|
|
@@ -186,12 +193,12 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
186
193
|
}
|
|
187
194
|
if (fields.focus !== void 0) row.focus = fields.focus;
|
|
188
195
|
if (opts.groupId) row.groupId = opts.groupId;
|
|
189
|
-
if (
|
|
196
|
+
if (acked) row.disclaimerAckAt = opts.now;
|
|
190
197
|
const { duplicate } = await db.transact(
|
|
191
198
|
[{ t: "update", ns: "applications", id, attrs: row }],
|
|
192
199
|
opts.submissionId ? { mutationId: `join:${opts.submissionId}` } : void 0
|
|
193
200
|
);
|
|
194
|
-
return { ok: true, id, duplicate, status: chapter.pipeline.initial };
|
|
201
|
+
return { ok: true, id, duplicate, status: chapter.pipeline.initial, disclaimerAckAt: acked ? opts.now : null };
|
|
195
202
|
}
|
|
196
203
|
function joinConfig(group, paymentsReady) {
|
|
197
204
|
return {
|
|
@@ -647,7 +654,14 @@ var handleMember = async (req, url, env, ctx) => {
|
|
|
647
654
|
}
|
|
648
655
|
await provisionApplicant(db, chapter, result.id, parsed);
|
|
649
656
|
}
|
|
650
|
-
return json({
|
|
657
|
+
return json({
|
|
658
|
+
id: result.id,
|
|
659
|
+
duplicate: result.duplicate,
|
|
660
|
+
status: result.status,
|
|
661
|
+
// Echoed so a site can see (and assert in an integration test) whether its
|
|
662
|
+
// join page actually posted the ack. Absent consent is otherwise invisible.
|
|
663
|
+
disclaimerAckAt: result.disclaimerAckAt
|
|
664
|
+
});
|
|
651
665
|
}
|
|
652
666
|
return null;
|
|
653
667
|
};
|