@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.js
CHANGED
|
@@ -1198,10 +1198,10 @@ async function syncApplicationToCrm(deps, opts) {
|
|
|
1198
1198
|
return recordId;
|
|
1199
1199
|
}
|
|
1200
1200
|
async function backfillCrm(deps) {
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1201
|
+
const data = await deps.db.query({
|
|
1202
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } },
|
|
1203
|
+
$users: { $: { limit: 1e3 } }
|
|
1204
|
+
});
|
|
1205
1205
|
const seen = /* @__PURE__ */ new Set();
|
|
1206
1206
|
let synced = 0;
|
|
1207
1207
|
const errors = [];
|
|
@@ -1216,8 +1216,8 @@ async function backfillCrm(deps) {
|
|
|
1216
1216
|
errors.push({ email: key, error: err instanceof Error ? err.message : String(err) });
|
|
1217
1217
|
}
|
|
1218
1218
|
};
|
|
1219
|
-
for (const a of
|
|
1220
|
-
for (const u of
|
|
1219
|
+
for (const a of data.applications ?? []) await run(a, str(a.status));
|
|
1220
|
+
for (const u of data.$users ?? []) {
|
|
1221
1221
|
if (u.deleted === true) continue;
|
|
1222
1222
|
await run({ email: u.email, firstName: str(u.name) });
|
|
1223
1223
|
}
|
|
@@ -4342,14 +4342,16 @@ var handleAdminPeople = async (req, url, env, ctx) => {
|
|
|
4342
4342
|
if (gate9 instanceof Response) return gate9;
|
|
4343
4343
|
const { db } = gate9;
|
|
4344
4344
|
const sk = await getVaultSecret(db, "clerk_secret_key");
|
|
4345
|
-
const [
|
|
4346
|
-
db.query({
|
|
4347
|
-
|
|
4345
|
+
const [data, roleList] = await Promise.all([
|
|
4346
|
+
db.query({
|
|
4347
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 200 } },
|
|
4348
|
+
$users: { $: { limit: 200 } }
|
|
4349
|
+
}),
|
|
4348
4350
|
sk ? clerkListUsers(sk).catch(() => []) : Promise.resolve([])
|
|
4349
4351
|
]);
|
|
4350
4352
|
const clerkByUserId = new Map(roleList.map((u) => [u.id, u]));
|
|
4351
4353
|
const people = /* @__PURE__ */ new Map();
|
|
4352
|
-
for (const u of
|
|
4354
|
+
for (const u of data.$users ?? []) {
|
|
4353
4355
|
if (u.deleted === true) continue;
|
|
4354
4356
|
const email = typeof u.email === "string" ? u.email : "";
|
|
4355
4357
|
if (!email) continue;
|
|
@@ -4364,7 +4366,7 @@ var handleAdminPeople = async (req, url, env, ctx) => {
|
|
|
4364
4366
|
application: null
|
|
4365
4367
|
});
|
|
4366
4368
|
}
|
|
4367
|
-
for (const a of
|
|
4369
|
+
for (const a of data.applications ?? []) {
|
|
4368
4370
|
const key = String(a.email ?? "").toLowerCase();
|
|
4369
4371
|
if (!key) continue;
|
|
4370
4372
|
const name = `${a.firstName ?? ""} ${a.lastName ?? ""}`.trim();
|
|
@@ -4569,13 +4571,19 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4569
4571
|
const now = Date.now();
|
|
4570
4572
|
const d7 = now - 7 * 864e5;
|
|
4571
4573
|
const d30 = now - 30 * 864e5;
|
|
4572
|
-
const
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4574
|
+
const data = await db.query({
|
|
4575
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } },
|
|
4576
|
+
meetings: {
|
|
4577
|
+
$: {
|
|
4578
|
+
where: { status: "scheduled" },
|
|
4579
|
+
order: { startAt: "asc" },
|
|
4580
|
+
limit: 500
|
|
4581
|
+
}
|
|
4582
|
+
},
|
|
4583
|
+
crm_record: { $: { where: { type: "person" }, limit: 1e3 } },
|
|
4584
|
+
groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } }
|
|
4585
|
+
});
|
|
4586
|
+
const apps = rows3(data.applications);
|
|
4579
4587
|
const applications = {
|
|
4580
4588
|
total: apps.length,
|
|
4581
4589
|
last7: apps.filter((a) => a.createdAt >= d7).length,
|
|
@@ -4587,7 +4595,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4587
4595
|
pipeline[s] = 0;
|
|
4588
4596
|
pipelineDelta[s] = 0;
|
|
4589
4597
|
}
|
|
4590
|
-
for (const r of rows3(
|
|
4598
|
+
for (const r of rows3(data.crm_record)) {
|
|
4591
4599
|
const s = r.stage;
|
|
4592
4600
|
if (s in pipeline) {
|
|
4593
4601
|
pipeline[s] = (pipeline[s] ?? 0) + 1;
|
|
@@ -4595,7 +4603,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4595
4603
|
if (Number.isFinite(sc) && sc >= d7) pipelineDelta[s] = (pipelineDelta[s] ?? 0) + 1;
|
|
4596
4604
|
}
|
|
4597
4605
|
}
|
|
4598
|
-
const meetings = rows3(
|
|
4606
|
+
const meetings = rows3(data.meetings);
|
|
4599
4607
|
const appById = new Map(apps.map((a) => [a.id, a]));
|
|
4600
4608
|
const upcoming = meetings.filter((m) => m.startAt >= now - 36e5);
|
|
4601
4609
|
const calls = { upcoming: upcoming.length, needsAttention: meetings.filter((m) => m.drift && m.drift !== "none").length };
|
|
@@ -4611,7 +4619,7 @@ var handleAdminDashboard = async (req, url, env, ctx) => {
|
|
|
4611
4619
|
email: a?.email ?? null
|
|
4612
4620
|
};
|
|
4613
4621
|
});
|
|
4614
|
-
const group =
|
|
4622
|
+
const group = data.groups?.[0];
|
|
4615
4623
|
const timezone = resolveScheduling(group?.schedulingJson).timezone;
|
|
4616
4624
|
let revenue = { billingReady: false };
|
|
4617
4625
|
let revenueSeries = null;
|
|
@@ -4645,16 +4653,18 @@ var handleAdminBilling = async (req, url, env, ctx) => {
|
|
|
4645
4653
|
const db = got;
|
|
4646
4654
|
const sk = await getVaultSecret(db, "stripe_secret_key");
|
|
4647
4655
|
if (!sk) return json({ billingReady: false, rows: [], summary: null });
|
|
4648
|
-
const [
|
|
4649
|
-
db.query({
|
|
4650
|
-
|
|
4651
|
-
|
|
4656
|
+
const [data, subsRes] = await Promise.all([
|
|
4657
|
+
db.query({
|
|
4658
|
+
applications: { $: { order: { createdAt: "desc" }, limit: 200 } },
|
|
4659
|
+
groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } }
|
|
4660
|
+
}),
|
|
4661
|
+
stripeCall(sk, "GET", "/v1/subscriptions", { limit: 100, status: "all" })
|
|
4652
4662
|
]);
|
|
4653
|
-
const testMode = String(
|
|
4663
|
+
const testMode = String(data.groups?.[0]?.stripePublishableKey ?? "").startsWith("pk_test");
|
|
4654
4664
|
if (!subsRes.ok) return json({ error: "billing lookup failed upstream" }, 502);
|
|
4655
4665
|
const subById = new Map(rows3(subsRes.body.data).map((s) => [s.id, s]));
|
|
4656
4666
|
const billingRows = [];
|
|
4657
|
-
for (const a of rows3(
|
|
4667
|
+
for (const a of rows3(data.applications)) {
|
|
4658
4668
|
if (!a.stripeCustomerId && !a.stripeSubscriptionId) continue;
|
|
4659
4669
|
const sub = a.stripeSubscriptionId ? subById.get(a.stripeSubscriptionId) : void 0;
|
|
4660
4670
|
const items = sub?.items?.data ?? [];
|
|
@@ -4994,21 +5004,27 @@ var handleAdminComms = async (req, url, env, ctx) => {
|
|
|
4994
5004
|
if (got instanceof Response) return got;
|
|
4995
5005
|
const db = got;
|
|
4996
5006
|
const appId = m[1];
|
|
4997
|
-
const
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5007
|
+
const data = await db.query({
|
|
5008
|
+
emailLog: {
|
|
5009
|
+
$: {
|
|
5010
|
+
where: { applicationId: appId },
|
|
5011
|
+
order: { sentAt: "desc" },
|
|
5012
|
+
limit: 100
|
|
5013
|
+
}
|
|
5014
|
+
},
|
|
5015
|
+
meetings: { $: { where: { applicationId: appId } } },
|
|
5016
|
+
applications: { $: { where: { id: appId }, limit: 1 } }
|
|
5017
|
+
});
|
|
5018
|
+
const app = data.applications?.[0] ?? null;
|
|
5003
5019
|
const group = await loadGroup2(db, str2(app?.groupId, ctx.chapter.id));
|
|
5004
5020
|
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;
|
|
5005
|
-
const emails = (
|
|
5021
|
+
const emails = (data.emailLog ?? []).filter((r) => r.template !== "adminNotification").map((r) => {
|
|
5006
5022
|
let mailBody = typeof r.body === "string" ? r.body : null;
|
|
5007
5023
|
if (!mailBody && group && vars) mailBody = renderTemplateBody(emailGroupFrom(group), String(r.template), vars);
|
|
5008
5024
|
const channel = r.error ? "email (failed)" : r.redirected ? "email (dev-redirected)" : r.transport === "log-only" ? "email (not delivered)" : "email";
|
|
5009
5025
|
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 };
|
|
5010
5026
|
});
|
|
5011
|
-
const calendar = (
|
|
5027
|
+
const calendar = (data.meetings ?? []).map((m2) => ({
|
|
5012
5028
|
kind: "calendar",
|
|
5013
5029
|
channel: "Google Calendar",
|
|
5014
5030
|
label: m2.status === "cancelled" ? "Invitation (call later cancelled)" : "Meeting invitation",
|