@odla-ai/chapter 0.20.2 → 0.21.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 +78 -32
- package/dist/chunk-3JG5X2LT.js +80 -0
- package/dist/chunk-3JG5X2LT.js.map +1 -0
- package/dist/chunk-AOTWFOH4.js +1481 -0
- package/dist/chunk-AOTWFOH4.js.map +1 -0
- package/dist/{chunk-LME2IHY5.js → chunk-ILGUJXSB.js} +1 -1
- package/dist/chunk-ILGUJXSB.js.map +1 -0
- package/dist/index.cjs +61 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -19
- package/dist/index.d.ts +64 -19
- package/dist/index.js +61 -6
- package/dist/index.js.map +1 -1
- package/dist/{types-D2fGiNG8.d.ts → types-CXDiDj_s.d.ts} +36 -8
- package/dist/ui/admin/index.d.ts +85 -84
- package/dist/ui/admin/index.js +8 -2
- package/dist/ui/index.d.ts +3 -2
- package/dist/ui/index.js +9 -3
- package/dist/ui/member/index.d.ts +3 -1
- package/dist/ui/member/index.js +2 -2
- package/dist/worker/index.cjs +28 -16
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +36 -8
- package/dist/worker/index.d.ts +36 -8
- package/dist/worker/index.js +28 -16
- package/dist/worker/index.js.map +1 -1
- package/package.json +3 -3
- package/runbooks/adopt-existing.md +13 -4
- package/runbooks/greenfield.md +19 -9
- package/dist/chunk-LME2IHY5.js.map +0 -1
- package/dist/chunk-MKXHZMAP.js +0 -51
- package/dist/chunk-MKXHZMAP.js.map +0 -1
- package/dist/chunk-UIWFEESI.js +0 -922
- package/dist/chunk-UIWFEESI.js.map +0 -1
package/dist/worker/index.d.cts
CHANGED
|
@@ -32,8 +32,36 @@ interface Rule {
|
|
|
32
32
|
}
|
|
33
33
|
/** Namespace → rule set. */
|
|
34
34
|
type DbRules = Record<string, Rule>;
|
|
35
|
-
/**
|
|
35
|
+
/** Typed semantic roles shared by the public site and application surfaces. */
|
|
36
|
+
interface ChapterBrandTokens {
|
|
37
|
+
background?: string;
|
|
38
|
+
surface?: string;
|
|
39
|
+
surface2?: string;
|
|
40
|
+
text?: string;
|
|
41
|
+
textMuted?: string;
|
|
42
|
+
textFaint?: string;
|
|
43
|
+
border?: string;
|
|
44
|
+
borderStrong?: string;
|
|
45
|
+
accent?: string;
|
|
46
|
+
accentStrong?: string;
|
|
47
|
+
accentSoft?: string;
|
|
48
|
+
onAccent?: string;
|
|
49
|
+
good?: string;
|
|
50
|
+
warn?: string;
|
|
51
|
+
danger?: string;
|
|
52
|
+
chart1?: string;
|
|
53
|
+
chart2?: string;
|
|
54
|
+
chartPositive?: string;
|
|
55
|
+
chartNegative?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Brand tokens that theme the site: theme, semantic roles, fonts, and logos. */
|
|
36
58
|
interface ChapterBrand {
|
|
59
|
+
/** Preloaded @odla-ai/ui theme name used by ThemeScope. */
|
|
60
|
+
theme?: string;
|
|
61
|
+
/** Admin/application color mode. Explicit light is the safe default. */
|
|
62
|
+
colorScheme?: "light" | "dark" | "system";
|
|
63
|
+
tokens?: ChapterBrandTokens;
|
|
64
|
+
tokensDark?: ChapterBrandTokens;
|
|
37
65
|
/** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
|
|
38
66
|
* or `--ui-*` token names). Applies in BOTH light and dark unless overridden
|
|
39
67
|
* by {@link paletteDark}. */
|
|
@@ -67,7 +95,7 @@ interface ChapterNetworkTarget {
|
|
|
67
95
|
id: string;
|
|
68
96
|
/** Human-facing site name. Defaults to `id`. */
|
|
69
97
|
name?: string;
|
|
70
|
-
/** Absolute follower origin, e.g. `https://
|
|
98
|
+
/** Absolute follower origin, e.g. `https://chapter.example.com`. */
|
|
71
99
|
url: string;
|
|
72
100
|
/** Leader-vault key holding this follower's share secret. Defaults to
|
|
73
101
|
* `network_share_<id-with-underscores>`. */
|
|
@@ -138,10 +166,10 @@ interface ChapterScheduling {
|
|
|
138
166
|
}
|
|
139
167
|
/** How a signed-in user's role is determined.
|
|
140
168
|
*
|
|
141
|
-
* - `"claim"` reads a role ladder from a JWT claim (
|
|
169
|
+
* - `"claim"` reads a role ladder from a JWT claim (the member-site model:
|
|
142
170
|
* `provisional → member → admin`). Admin is the last (highest) rung; the
|
|
143
171
|
* read-only `superAdmins` tier sits above it.
|
|
144
|
-
* - `"table"` gates on the deny-all `admins` allowlist (
|
|
172
|
+
* - `"table"` gates on the deny-all `admins` allowlist (the hub model):
|
|
145
173
|
* a binary "email is an admin or isn't", set only in odla Studio.
|
|
146
174
|
*
|
|
147
175
|
* Defaults: `"claim"` in `chapter` mode, `"table"` in `hub` mode. */
|
|
@@ -168,7 +196,7 @@ interface ResolvedAuth {
|
|
|
168
196
|
}
|
|
169
197
|
/** The application status pipeline. Which statuses exist, and the subsets a site
|
|
170
198
|
* allows a call to be booked from / an application approved from. Defaults to
|
|
171
|
-
*
|
|
199
|
+
* the reference pipeline. Status never moves backwards (package-enforced). */
|
|
172
200
|
interface ChapterPipeline {
|
|
173
201
|
stages?: readonly string[];
|
|
174
202
|
bookableFrom?: readonly string[];
|
|
@@ -185,8 +213,8 @@ interface ResolvedPipeline {
|
|
|
185
213
|
}
|
|
186
214
|
/** The application (join form) validation surface — which string fields are
|
|
187
215
|
* required vs accepted, their max lengths, and the request body cap. Drives
|
|
188
|
-
* submit validation + the CRM slot projection; defaults to
|
|
189
|
-
* The `applications` schema attrs stay fixed
|
|
216
|
+
* submit validation + the CRM slot projection; defaults to the reference form.
|
|
217
|
+
* The `applications` schema attrs stay fixed; this is
|
|
190
218
|
* validation config, not schema generation. */
|
|
191
219
|
interface ChapterApplication {
|
|
192
220
|
required?: readonly string[];
|
|
@@ -258,7 +286,7 @@ interface ChapterConfig {
|
|
|
258
286
|
/** `notificationEmail` required in `chapter` mode. */
|
|
259
287
|
emails?: ChapterEmails;
|
|
260
288
|
scheduling?: ChapterScheduling;
|
|
261
|
-
/** Application status pipeline (stages + bookable/approvable subsets).
|
|
289
|
+
/** Application status pipeline (stages + bookable/approvable subsets). */
|
|
262
290
|
pipeline?: ChapterPipeline;
|
|
263
291
|
/** Join-form validation (required/optional fields, max lengths, body cap). */
|
|
264
292
|
application?: ChapterApplication;
|
package/dist/worker/index.d.ts
CHANGED
|
@@ -32,8 +32,36 @@ interface Rule {
|
|
|
32
32
|
}
|
|
33
33
|
/** Namespace → rule set. */
|
|
34
34
|
type DbRules = Record<string, Rule>;
|
|
35
|
-
/**
|
|
35
|
+
/** Typed semantic roles shared by the public site and application surfaces. */
|
|
36
|
+
interface ChapterBrandTokens {
|
|
37
|
+
background?: string;
|
|
38
|
+
surface?: string;
|
|
39
|
+
surface2?: string;
|
|
40
|
+
text?: string;
|
|
41
|
+
textMuted?: string;
|
|
42
|
+
textFaint?: string;
|
|
43
|
+
border?: string;
|
|
44
|
+
borderStrong?: string;
|
|
45
|
+
accent?: string;
|
|
46
|
+
accentStrong?: string;
|
|
47
|
+
accentSoft?: string;
|
|
48
|
+
onAccent?: string;
|
|
49
|
+
good?: string;
|
|
50
|
+
warn?: string;
|
|
51
|
+
danger?: string;
|
|
52
|
+
chart1?: string;
|
|
53
|
+
chart2?: string;
|
|
54
|
+
chartPositive?: string;
|
|
55
|
+
chartNegative?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Brand tokens that theme the site: theme, semantic roles, fonts, and logos. */
|
|
36
58
|
interface ChapterBrand {
|
|
59
|
+
/** Preloaded @odla-ai/ui theme name used by ThemeScope. */
|
|
60
|
+
theme?: string;
|
|
61
|
+
/** Admin/application color mode. Explicit light is the safe default. */
|
|
62
|
+
colorScheme?: "light" | "dark" | "system";
|
|
63
|
+
tokens?: ChapterBrandTokens;
|
|
64
|
+
tokensDark?: ChapterBrandTokens;
|
|
37
65
|
/** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
|
|
38
66
|
* or `--ui-*` token names). Applies in BOTH light and dark unless overridden
|
|
39
67
|
* by {@link paletteDark}. */
|
|
@@ -67,7 +95,7 @@ interface ChapterNetworkTarget {
|
|
|
67
95
|
id: string;
|
|
68
96
|
/** Human-facing site name. Defaults to `id`. */
|
|
69
97
|
name?: string;
|
|
70
|
-
/** Absolute follower origin, e.g. `https://
|
|
98
|
+
/** Absolute follower origin, e.g. `https://chapter.example.com`. */
|
|
71
99
|
url: string;
|
|
72
100
|
/** Leader-vault key holding this follower's share secret. Defaults to
|
|
73
101
|
* `network_share_<id-with-underscores>`. */
|
|
@@ -138,10 +166,10 @@ interface ChapterScheduling {
|
|
|
138
166
|
}
|
|
139
167
|
/** How a signed-in user's role is determined.
|
|
140
168
|
*
|
|
141
|
-
* - `"claim"` reads a role ladder from a JWT claim (
|
|
169
|
+
* - `"claim"` reads a role ladder from a JWT claim (the member-site model:
|
|
142
170
|
* `provisional → member → admin`). Admin is the last (highest) rung; the
|
|
143
171
|
* read-only `superAdmins` tier sits above it.
|
|
144
|
-
* - `"table"` gates on the deny-all `admins` allowlist (
|
|
172
|
+
* - `"table"` gates on the deny-all `admins` allowlist (the hub model):
|
|
145
173
|
* a binary "email is an admin or isn't", set only in odla Studio.
|
|
146
174
|
*
|
|
147
175
|
* Defaults: `"claim"` in `chapter` mode, `"table"` in `hub` mode. */
|
|
@@ -168,7 +196,7 @@ interface ResolvedAuth {
|
|
|
168
196
|
}
|
|
169
197
|
/** The application status pipeline. Which statuses exist, and the subsets a site
|
|
170
198
|
* allows a call to be booked from / an application approved from. Defaults to
|
|
171
|
-
*
|
|
199
|
+
* the reference pipeline. Status never moves backwards (package-enforced). */
|
|
172
200
|
interface ChapterPipeline {
|
|
173
201
|
stages?: readonly string[];
|
|
174
202
|
bookableFrom?: readonly string[];
|
|
@@ -185,8 +213,8 @@ interface ResolvedPipeline {
|
|
|
185
213
|
}
|
|
186
214
|
/** The application (join form) validation surface — which string fields are
|
|
187
215
|
* required vs accepted, their max lengths, and the request body cap. Drives
|
|
188
|
-
* submit validation + the CRM slot projection; defaults to
|
|
189
|
-
* The `applications` schema attrs stay fixed
|
|
216
|
+
* submit validation + the CRM slot projection; defaults to the reference form.
|
|
217
|
+
* The `applications` schema attrs stay fixed; this is
|
|
190
218
|
* validation config, not schema generation. */
|
|
191
219
|
interface ChapterApplication {
|
|
192
220
|
required?: readonly string[];
|
|
@@ -258,7 +286,7 @@ interface ChapterConfig {
|
|
|
258
286
|
/** `notificationEmail` required in `chapter` mode. */
|
|
259
287
|
emails?: ChapterEmails;
|
|
260
288
|
scheduling?: ChapterScheduling;
|
|
261
|
-
/** Application status pipeline (stages + bookable/approvable subsets).
|
|
289
|
+
/** Application status pipeline (stages + bookable/approvable subsets). */
|
|
262
290
|
pipeline?: ChapterPipeline;
|
|
263
291
|
/** Join-form validation (required/optional fields, max lengths, body cap). */
|
|
264
292
|
application?: ChapterApplication;
|
package/dist/worker/index.js
CHANGED
|
@@ -1138,7 +1138,7 @@ function createStripeProvider(config) {
|
|
|
1138
1138
|
"expand[0]": "latest_invoice.confirmation_secret",
|
|
1139
1139
|
metadata: meta
|
|
1140
1140
|
},
|
|
1141
|
-
//
|
|
1141
|
+
// Hardening: one subscription per application, so a client
|
|
1142
1142
|
// retry between create and the db write can't orphan a second one.
|
|
1143
1143
|
`sub:${input.applicationId}`
|
|
1144
1144
|
);
|
|
@@ -1709,18 +1709,30 @@ var handleAdminPeopleRole = async (req, url, env, ctx) => {
|
|
|
1709
1709
|
};
|
|
1710
1710
|
|
|
1711
1711
|
// src/series.ts
|
|
1712
|
-
function
|
|
1713
|
-
const
|
|
1714
|
-
const
|
|
1715
|
-
const
|
|
1716
|
-
const
|
|
1717
|
-
for (const
|
|
1718
|
-
if (!Number.isFinite(
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1712
|
+
function periodSeries(points, now, count, periodMs) {
|
|
1713
|
+
const start = now - count * periodMs;
|
|
1714
|
+
const previousStart = start - count * periodMs;
|
|
1715
|
+
const current = Array.from({ length: count }, () => 0);
|
|
1716
|
+
const previous = Array.from({ length: count }, () => 0);
|
|
1717
|
+
for (const point of points) {
|
|
1718
|
+
if (!Number.isFinite(point.t) || !Number.isFinite(point.v)) continue;
|
|
1719
|
+
if (point.t >= start && point.t <= now) {
|
|
1720
|
+
const index = Math.min(count - 1, Math.floor((point.t - start) / periodMs));
|
|
1721
|
+
current[index] = (current[index] ?? 0) + point.v;
|
|
1722
|
+
} else if (point.t >= previousStart && point.t < start) {
|
|
1723
|
+
const index = Math.min(count - 1, Math.floor((point.t - previousStart) / periodMs));
|
|
1724
|
+
previous[index] = (previous[index] ?? 0) + point.v;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
const labels = current.map((_, index) => new Date(start + index * periodMs).toISOString().slice(5, 10));
|
|
1728
|
+
return { labels, current, previous };
|
|
1729
|
+
}
|
|
1730
|
+
function dashboardMetricData(points, now) {
|
|
1731
|
+
const DAY = 864e5;
|
|
1732
|
+
return {
|
|
1733
|
+
wow: periodSeries(points, now, 7, DAY),
|
|
1734
|
+
mom: periodSeries(points, now, 4, 7 * DAY)
|
|
1735
|
+
};
|
|
1724
1736
|
}
|
|
1725
1737
|
function subAnnualCents(sub) {
|
|
1726
1738
|
const items = sub.items?.data ?? [];
|
|
@@ -1803,8 +1815,8 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
1803
1815
|
if (subsRes.ok) {
|
|
1804
1816
|
const subs = rows(subsRes.body.data);
|
|
1805
1817
|
const subMs = (s) => (s.created ?? 0) * 1e3;
|
|
1806
|
-
membersSeries =
|
|
1807
|
-
revenueSeries =
|
|
1818
|
+
membersSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: 1 })), now);
|
|
1819
|
+
revenueSeries = dashboardMetricData(subs.map((s) => ({ t: subMs(s), v: subAnnualCents(s) })), now);
|
|
1808
1820
|
const active = subs.filter((s) => s.status === "active");
|
|
1809
1821
|
revenue = {
|
|
1810
1822
|
billingReady: true,
|
|
@@ -1816,7 +1828,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
1816
1828
|
};
|
|
1817
1829
|
}
|
|
1818
1830
|
}
|
|
1819
|
-
const applicationsSeries =
|
|
1831
|
+
const applicationsSeries = dashboardMetricData(apps.map((a) => ({ t: a.createdAt || 0, v: 1 })), now);
|
|
1820
1832
|
return json({ applications, applicationsSeries, pipeline, pipelineDelta, calls, agenda, timezone, revenue, revenueSeries, membersSeries });
|
|
1821
1833
|
};
|
|
1822
1834
|
var handleAdminBilling = async (req, url, env, ctx) => {
|