@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.
@@ -1225,10 +1225,10 @@ async function syncApplicationToCrm(deps, opts) {
1225
1225
  return recordId;
1226
1226
  }
1227
1227
  async function backfillCrm(deps) {
1228
- const [appsRes, usersRes] = await Promise.all([
1229
- deps.db.query({ applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } } }),
1230
- deps.db.query({ $users: { $: { limit: 1e3 } } })
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 appsRes.applications ?? []) await run(a, str(a.status));
1247
- for (const u of usersRes.$users ?? []) {
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 [appsRes, usersRes, roleList] = await Promise.all([
4373
- db.query({ applications: { $: { order: { createdAt: "desc" }, limit: 200 } } }),
4374
- db.query({ $users: { $: { limit: 200 } } }),
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 usersRes.$users ?? []) {
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 appsRes.applications ?? []) {
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 [appsRes, meetingsRes, recsRes, groupRes] = await Promise.all([
4600
- db.query({ applications: { $: { order: { createdAt: "desc" }, limit: 1e3 } } }),
4601
- db.query({ meetings: { $: { where: { status: "scheduled" }, order: { startAt: "asc" }, limit: 500 } } }),
4602
- db.query({ crm_record: { $: { where: { type: "person" }, limit: 1e3 } } }),
4603
- db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })
4604
- ]);
4605
- const apps = rows3(appsRes.applications);
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(recsRes.crm_record)) {
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(meetingsRes.meetings);
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 = groupRes.groups?.[0];
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 [appsRes, subsRes, groupRes] = await Promise.all([
4676
- db.query({ applications: { $: { order: { createdAt: "desc" }, limit: 200 } } }),
4677
- stripeCall(sk, "GET", "/v1/subscriptions", { limit: 100, status: "all" }),
4678
- db.query({ groups: { $: { where: { id: ctx.chapter.id }, limit: 1 } } })
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(groupRes.groups?.[0]?.stripePublishableKey ?? "").startsWith("pk_test");
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(appsRes.applications)) {
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 [emailRes, meetingRes, appRes] = await Promise.all([
5025
- db.query({ emailLog: { $: { where: { applicationId: appId }, order: { sentAt: "desc" }, limit: 100 } } }),
5026
- db.query({ meetings: { $: { where: { applicationId: appId } } } }),
5027
- db.query({ applications: { $: { where: { id: appId }, limit: 1 } } })
5028
- ]);
5029
- const app = appRes.applications?.[0] ?? null;
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 = (emailRes.emailLog ?? []).filter((r) => r.template !== "adminNotification").map((r) => {
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 = (meetingRes.meetings ?? []).map((m2) => ({
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",