@odla-ai/chapter 0.25.2 → 0.25.4
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 +35 -6
- package/dist/{chunk-AWBRQH7E.js → chunk-5SWVMJZN.js} +1 -1
- package/dist/chunk-5SWVMJZN.js.map +1 -0
- package/dist/{chunk-GMGTJIY3.js → chunk-WHA3MUDQ.js} +4 -3
- package/dist/chunk-WHA3MUDQ.js.map +1 -0
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +5 -1
- package/dist/ui/admin/index.js +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/member/index.d.ts +2 -1
- package/dist/ui/member/index.js +1 -1
- package/dist/worker/index.cjs +12 -1
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +12 -1
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/runbooks/adopt-existing.md +19 -3
- package/runbooks/greenfield.md +6 -6
- package/dist/chunk-AWBRQH7E.js.map +0 -1
- package/dist/chunk-GMGTJIY3.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -903,8 +903,10 @@ type SubmitResult = {
|
|
|
903
903
|
* fields + max lengths, writes the `applications` row at the pipeline's initial
|
|
904
904
|
* status, and — when the client supplies a `submissionId` — stamps it as the
|
|
905
905
|
* transaction's mutationId (`join:${submissionId}`) so a double-tap can never
|
|
906
|
-
* create two applications
|
|
907
|
-
*
|
|
906
|
+
* create two applications. The application id is derived from that same stable
|
|
907
|
+
* input, so the duplicate response returns the first request's canonical id
|
|
908
|
+
* rather than a fresh, nonexistent one. Idempotency is package-enforced.
|
|
909
|
+
* `now`/`newId` are injected (deterministic in tests).
|
|
908
910
|
*/
|
|
909
911
|
declare function submitApplication(db: ChapterDb, chapter: Chapter, fields: Record<string, unknown>, opts: {
|
|
910
912
|
submissionId?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -903,8 +903,10 @@ type SubmitResult = {
|
|
|
903
903
|
* fields + max lengths, writes the `applications` row at the pipeline's initial
|
|
904
904
|
* status, and — when the client supplies a `submissionId` — stamps it as the
|
|
905
905
|
* transaction's mutationId (`join:${submissionId}`) so a double-tap can never
|
|
906
|
-
* create two applications
|
|
907
|
-
*
|
|
906
|
+
* create two applications. The application id is derived from that same stable
|
|
907
|
+
* input, so the duplicate response returns the first request's canonical id
|
|
908
|
+
* rather than a fresh, nonexistent one. Idempotency is package-enforced.
|
|
909
|
+
* `now`/`newId` are injected (deterministic in tests).
|
|
908
910
|
*/
|
|
909
911
|
declare function submitApplication(db: ChapterDb, chapter: Chapter, fields: Record<string, unknown>, opts: {
|
|
910
912
|
submissionId?: string;
|
package/dist/index.js
CHANGED
|
@@ -382,6 +382,17 @@ function canApprove(status, p) {
|
|
|
382
382
|
return p.approvableFrom.includes(status);
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
// src/application-id.ts
|
|
386
|
+
var APPLICATION_ID_DOMAIN = "odla-ai/chapter/application/v1:";
|
|
387
|
+
async function applicationIdForSubmission(submissionId) {
|
|
388
|
+
const input = new TextEncoder().encode(`${APPLICATION_ID_DOMAIN}${submissionId}`);
|
|
389
|
+
const bytes = new Uint8Array(await crypto.subtle.digest("SHA-256", input)).slice(0, 16);
|
|
390
|
+
bytes[6] = bytes[6] & 15 | 128;
|
|
391
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
392
|
+
const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
393
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
394
|
+
}
|
|
395
|
+
|
|
385
396
|
// src/member.ts
|
|
386
397
|
var DEFAULT_REQUIRED = ["firstName", "lastName", "email", "referral", "whoYouAre", "message"];
|
|
387
398
|
var DEFAULT_OPTIONAL = ["referralName", "linkedin", "phone", "state"];
|
|
@@ -454,7 +465,7 @@ async function submitApplication(db, chapter, fields, opts) {
|
|
|
454
465
|
if (app.requireDisclaimerAck && !acked) {
|
|
455
466
|
return { ok: false, error: "disclaimerAck is required" };
|
|
456
467
|
}
|
|
457
|
-
const id2 = opts.newId();
|
|
468
|
+
const id2 = opts.submissionId ? await applicationIdForSubmission(opts.submissionId) : opts.newId();
|
|
458
469
|
const row = { id: id2, status: chapter.pipeline.initial, createdAt: opts.now };
|
|
459
470
|
for (const f of [...app.required, ...app.optional]) {
|
|
460
471
|
if (typeof fields[f] === "string") row[f] = fields[f].trim();
|