@odla-ai/chapter 0.38.0 → 0.38.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/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +51 -35
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +51 -35
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
package/dist/worker/index.cjs
CHANGED
|
@@ -1225,10 +1225,10 @@ async function syncApplicationToCrm(deps, opts) {
|
|
|
1225
1225
|
return recordId;
|
|
1226
1226
|
}
|
|
1227
1227
|
async function backfillCrm(deps) {
|
|
1228
|
-
const
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1228
|
+
const data = await deps.db.query({
|
|
1229
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } },
|
|
1230
|
+
$users: { $: { limit: 1e3 } }
|
|
1231
|
+
});
|
|
1232
1232
|
const seen = /* @__PURE__ */ new Set();
|
|
1233
1233
|
let synced = 0;
|
|
1234
1234
|
const errors = [];
|
|
@@ -1243,8 +1243,8 @@ async function backfillCrm(deps) {
|
|
|
1243
1243
|
errors.push({ email: key, error: err instanceof Error ? err.message : String(err) });
|
|
1244
1244
|
}
|
|
1245
1245
|
};
|
|
1246
|
-
for (const a of
|
|
1247
|
-
for (const u of
|
|
1246
|
+
for (const a of data.applications ?? []) await run(a, str(a.status));
|
|
1247
|
+
for (const u of data.$users ?? []) {
|
|
1248
1248
|
if (u.deleted === true) continue;
|
|
1249
1249
|
await run({ email: u.email, firstName: str(u.name) });
|
|
1250
1250
|
}
|
|
@@ -4369,14 +4369,16 @@ var handleAdminPeople = async (req, url, env, ctx) => {
|
|
|
4369
4369
|
if (gate9 instanceof Response) return gate9;
|
|
4370
4370
|
const { db } = gate9;
|
|
4371
4371
|
const sk = await getVaultSecret(db, "clerk_secret_key");
|
|
4372
|
-
const [
|
|
4373
|
-
db.query({
|
|
4374
|
-
|
|
4372
|
+
const [data, roleList] = await Promise.all([
|
|
4373
|
+
db.query({
|
|
4374
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 200 } },
|
|
4375
|
+
$users: { $: { limit: 200 } }
|
|
4376
|
+
}),
|
|
4375
4377
|
sk ? clerkListUsers(sk).catch(() => []) : Promise.resolve([])
|
|
4376
4378
|
]);
|
|
4377
4379
|
const clerkByUserId = new Map(roleList.map((u) => [u.id, u]));
|
|
4378
4380
|
const people = /* @__PURE__ */ new Map();
|
|
4379
|
-
for (const u of
|
|
4381
|
+
for (const u of data.$users ?? []) {
|
|
4380
4382
|
if (u.deleted === true) continue;
|
|
4381
4383
|
const email = typeof u.email === "string" ? u.email : "";
|
|
4382
4384
|
if (!email) continue;
|
|
@@ -4391,7 +4393,7 @@ var handleAdminPeople = async (req, url, env, ctx) => {
|
|
|
4391
4393
|
application: null
|
|
4392
4394
|
});
|
|
4393
4395
|
}
|
|
4394
|
-
for (const a of
|
|
4396
|
+
for (const a of data.applications ?? []) {
|
|
4395
4397
|
const key = String(a.email ?? "").toLowerCase();
|
|
4396
4398
|
if (!key) continue;
|
|
4397
4399
|
const name = `${a.firstName ?? ""} ${a.lastName ?? ""}`.trim();
|
|
@@ -4596,13 +4598,19 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4596
4598
|
const now = Date.now();
|
|
4597
4599
|
const d7 = now - 7 * 864e5;
|
|
4598
4600
|
const d30 = now - 30 * 864e5;
|
|
4599
|
-
const
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4601
|
+
const data = await db.query({
|
|
4602
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } },
|
|
4603
|
+
meetings: {
|
|
4604
|
+
$: {
|
|
4605
|
+
where: { status: "scheduled" },
|
|
4606
|
+
order: { startAt: "asc" },
|
|
4607
|
+
limit: 500
|
|
4608
|
+
}
|
|
4609
|
+
},
|
|
4610
|
+
crm_record: { $: { where: { type: "person" }, limit: 1e3 } },
|
|
4611
|
+
groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } }
|
|
4612
|
+
});
|
|
4613
|
+
const apps = rows3(data.applications);
|
|
4606
4614
|
const applications = {
|
|
4607
4615
|
total: apps.length,
|
|
4608
4616
|
last7: apps.filter((a) => a.createdAt >= d7).length,
|
|
@@ -4614,7 +4622,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4614
4622
|
pipeline[s] = 0;
|
|
4615
4623
|
pipelineDelta[s] = 0;
|
|
4616
4624
|
}
|
|
4617
|
-
for (const r of rows3(
|
|
4625
|
+
for (const r of rows3(data.crm_record)) {
|
|
4618
4626
|
const s = r.stage;
|
|
4619
4627
|
if (s in pipeline) {
|
|
4620
4628
|
pipeline[s] = (pipeline[s] ?? 0) + 1;
|
|
@@ -4622,7 +4630,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4622
4630
|
if (Number.isFinite(sc) && sc >= d7) pipelineDelta[s] = (pipelineDelta[s] ?? 0) + 1;
|
|
4623
4631
|
}
|
|
4624
4632
|
}
|
|
4625
|
-
const meetings = rows3(
|
|
4633
|
+
const meetings = rows3(data.meetings);
|
|
4626
4634
|
const appById = new Map(apps.map((a) => [a.id, a]));
|
|
4627
4635
|
const upcoming = meetings.filter((m) => m.startAt >= now - 36e5);
|
|
4628
4636
|
const calls = { upcoming: upcoming.length, needsAttention: meetings.filter((m) => m.drift && m.drift !== "none").length };
|
|
@@ -4638,7 +4646,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4638
4646
|
email: a?.email ?? null
|
|
4639
4647
|
};
|
|
4640
4648
|
});
|
|
4641
|
-
const group =
|
|
4649
|
+
const group = data.groups?.[0];
|
|
4642
4650
|
const timezone = resolveScheduling(group?.schedulingJson).timezone;
|
|
4643
4651
|
let revenue = { billingReady: false };
|
|
4644
4652
|
let revenueSeries = null;
|
|
@@ -4672,16 +4680,18 @@ var handleAdminBilling = async (req, url, env, ctx) => {
|
|
|
4672
4680
|
const db = got;
|
|
4673
4681
|
const sk = await getVaultSecret(db, "stripe_secret_key");
|
|
4674
4682
|
if (!sk) return json({ billingReady: false, rows: [], summary: null });
|
|
4675
|
-
const [
|
|
4676
|
-
db.query({
|
|
4677
|
-
|
|
4678
|
-
|
|
4683
|
+
const [data, subsRes] = await Promise.all([
|
|
4684
|
+
db.query({
|
|
4685
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 200 } },
|
|
4686
|
+
groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } }
|
|
4687
|
+
}),
|
|
4688
|
+
stripeCall(sk, "GET", "/v1/subscriptions", { limit: 100, status: "all" })
|
|
4679
4689
|
]);
|
|
4680
|
-
const testMode = String(
|
|
4690
|
+
const testMode = String(data.groups?.[0]?.stripePublishableKey ?? "").startsWith("pk_test");
|
|
4681
4691
|
if (!subsRes.ok) return json({ error: "billing lookup failed upstream" }, 502);
|
|
4682
4692
|
const subById = new Map(rows3(subsRes.body.data).map((s) => [s.id, s]));
|
|
4683
4693
|
const billingRows = [];
|
|
4684
|
-
for (const a of rows3(
|
|
4694
|
+
for (const a of rows3(data.applications)) {
|
|
4685
4695
|
if (!a.stripeCustomerId && !a.stripeSubscriptionId) continue;
|
|
4686
4696
|
const sub = a.stripeSubscriptionId ? subById.get(a.stripeSubscriptionId) : void 0;
|
|
4687
4697
|
const items = sub?.items?.data ?? [];
|
|
@@ -5021,21 +5031,27 @@ var handleAdminComms = async (req, url, env, ctx) => {
|
|
|
5021
5031
|
if (got instanceof Response) return got;
|
|
5022
5032
|
const db = got;
|
|
5023
5033
|
const appId = m[1];
|
|
5024
|
-
const
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5034
|
+
const data = await db.query({
|
|
5035
|
+
emailLog: {
|
|
5036
|
+
$: {
|
|
5037
|
+
where: { applicationId: appId },
|
|
5038
|
+
order: { sentAt: "desc" },
|
|
5039
|
+
limit: 100
|
|
5040
|
+
}
|
|
5041
|
+
},
|
|
5042
|
+
meetings: { $: { where: { applicationId: appId } } },
|
|
5043
|
+
applications: { $: { where: { id: appId }, limit: 1 } }
|
|
5044
|
+
});
|
|
5045
|
+
const app = data.applications?.[0] ?? null;
|
|
5030
5046
|
const group = await loadGroup2(db, str2(app?.groupId, ctx.chapter.id));
|
|
5031
5047
|
const vars = app ? { firstName: str2(app.firstName), lastName: str2(app.lastName), email: str2(app.email), phone: str2(app.phone), state: str2(app.state), adminUrl: `${url.origin}/admin/`, membersUrl: `${url.origin}/members/` } : null;
|
|
5032
|
-
const emails = (
|
|
5048
|
+
const emails = (data.emailLog ?? []).filter((r) => r.template !== "adminNotification").map((r) => {
|
|
5033
5049
|
let mailBody = typeof r.body === "string" ? r.body : null;
|
|
5034
5050
|
if (!mailBody && group && vars) mailBody = renderTemplateBody(emailGroupFrom(group), String(r.template), vars);
|
|
5035
5051
|
const channel = r.error ? "email (failed)" : r.redirected ? "email (dev-redirected)" : r.transport === "log-only" ? "email (not delivered)" : "email";
|
|
5036
5052
|
return { kind: "email", channel, label: String(r.template), subject: str2(r.subject), to: r.to ?? null, body: mailBody, at: r.sentAt, error: r.error ?? null };
|
|
5037
5053
|
});
|
|
5038
|
-
const calendar = (
|
|
5054
|
+
const calendar = (data.meetings ?? []).map((m2) => ({
|
|
5039
5055
|
kind: "calendar",
|
|
5040
5056
|
channel: "Google Calendar",
|
|
5041
5057
|
label: m2.status === "cancelled" ? "Invitation (call later cancelled)" : "Meeting invitation",
|