test(coach): repository, streak and rhythm suites

Covers what the coach interfaces promise before anything builds on them:
goal and habit ownership and limits, one check-in per habit, goal and day
dated in the user's time zone, streaks across weekends and weeks, and a
rhythm that keeps exactly one main-bot routine per check-in and is
idempotent when set again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
Claude 2026-10-03 13:15:06 +00:00
parent 7d7af8f3e9
commit e1ce6f4090
No known key found for this signature in database
4 changed files with 577 additions and 0 deletions

View File

@ -0,0 +1,182 @@
import { randomUUID } from "node:crypto";
import { routineJobKey } from "@rakazo/adapter-kit";
import type { PrismaClient } from "@rakazo/db";
import { bootstrapUserSpace, createDb, ensureMainConversation } from "@rakazo/db";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { COACH_ROUTINES, getCoachRhythm, setCoachRhythm } from "./coach-rhythm.js";
const databaseUrl = process.env.DATABASE_URL;
const describePostgres =
process.env.VERIFY_DATABASE && databaseUrl ? describe.sequential : describe.skip;
const signupEnv = { signupsEnabled: "true", signupAllowlist: "" };
describePostgres("coach rhythm (PostgreSQL)", () => {
let prisma: PrismaClient;
let close: () => Promise<void>;
const userIds: string[] = [];
async function newUser(timeZone: string | null = "Europe/Vienna") {
const id = `cr${randomUUID().replaceAll("-", "")}`;
userIds.push(id);
await prisma.user.create({ data: { id, name: "Ada", email: `${id}@rakazo.test` } });
await bootstrapUserSpace(prisma, { id }, signupEnv, { claimDeploymentOwner: false });
if (timeZone) await prisma.userProfile.create({ data: { userId: id, timeZone } });
return id;
}
function fakeJobs() {
return { enqueue: vi.fn(async () => undefined), cancel: vi.fn(async () => undefined) };
}
function coachRoutines(userId: string) {
return prisma.routine.findMany({
where: { userId, coachKey: { not: null } },
orderBy: { coachKey: "asc" },
});
}
beforeAll(() => {
const db = createDb(databaseUrl!);
prisma = db.prisma;
close = async () => {
await db.prisma.$disconnect();
await db.pool.end();
};
});
afterAll(async () => {
if (!prisma) return;
const memberships = await prisma.member.findMany({
where: { userId: { in: userIds } },
select: { organizationId: true },
});
await prisma.organization.deleteMany({
where: { id: { in: memberships.map((member) => member.organizationId) } },
});
await prisma.user.deleteMany({ where: { id: { in: userIds } } });
await close();
});
it("keeps one main-bot routine per check-in in the main conversation and user's time zone", async () => {
const userId = await newUser("Europe/Vienna");
const jobs = fakeJobs();
const rhythm = { morning: "07:30", evening: null, weekly: { day: 0, time: "18:00" } };
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm })).toEqual(rhythm);
const conversation = await ensureMainConversation(prisma, userId);
const created = await coachRoutines(userId);
expect(
created.map(
({ coachKey, botId, threadId, spaceId, crons, timezone, active, notify, name }) => ({
coachKey,
botId,
threadId,
spaceId,
crons,
timezone,
active,
notify,
name,
}),
),
).toEqual([
{
coachKey: "morning",
botId: conversation.leadBotId,
threadId: conversation.threadId,
spaceId: conversation.spaceId,
crons: ["30 7 * * *"],
timezone: "Europe/Vienna",
active: true,
notify: true,
name: COACH_ROUTINES.morning.name,
},
{
coachKey: "weekly",
botId: conversation.leadBotId,
threadId: conversation.threadId,
spaceId: conversation.spaceId,
crons: ["0 18 * * 0"],
timezone: "Europe/Vienna",
active: true,
notify: true,
name: COACH_ROUTINES.weekly.name,
},
]);
for (const routine of created) {
expect(routine.nextRunAt!.getTime()).toBeGreaterThan(Date.now());
expect(jobs.enqueue).toHaveBeenCalledWith(
expect.objectContaining({
name: "routine.wakeup",
replaceKey: routineJobKey(routine.id),
availableAt: routine.nextRunAt,
}),
);
}
expect(created[0]?.prompt).toBe(COACH_ROUTINES.morning.prompt);
// The same rhythm again changes nothing.
jobs.enqueue.mockClear();
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm })).toEqual(rhythm);
expect(jobs.enqueue).not.toHaveBeenCalled();
expect(await coachRoutines(userId)).toEqual(created);
// Moving, adding and turning off check-ins.
const next = { morning: "06:45", evening: "21:00", weekly: null };
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm: next })).toEqual(next);
const updated = await coachRoutines(userId);
expect(updated.map((routine) => [routine.coachKey, routine.crons[0]])).toEqual([
["evening", "0 21 * * *"],
["morning", "45 6 * * *"],
]);
expect(updated.find((routine) => routine.coachKey === "morning")?.id).toBe(created[0]?.id);
expect(jobs.cancel).toHaveBeenCalledWith(routineJobKey(created[1]!.id));
expect(await getCoachRhythm(prisma, userId)).toEqual(next);
});
it("reads paused or reshaped routines as off and turns them back on", async () => {
const userId = await newUser("UTC");
const jobs = fakeJobs();
await setCoachRhythm(
{ prisma, jobs },
{ userId, rhythm: { morning: "08:00", evening: "20:00", weekly: null } },
);
const routines = await coachRoutines(userId);
await prisma.routine.update({ where: { id: routines[0]!.id }, data: { active: false } });
await prisma.routine.update({
where: { id: routines[1]!.id },
data: { crons: ["0 8 * * 1-5"] },
});
expect(await getCoachRhythm(prisma, userId)).toEqual({
morning: null,
evening: null,
weekly: null,
});
const rhythm = { morning: "08:00", evening: "20:00", weekly: null };
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm })).toEqual(rhythm);
expect((await coachRoutines(userId)).map((routine) => routine.id)).toEqual(
routines.map((routine) => routine.id),
);
});
it("turning everything off removes the routines and never creates a main bot", async () => {
const userId = await newUser(null);
const jobs = fakeJobs();
const off = { morning: null, evening: null, weekly: null };
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm: off })).toEqual(off);
expect(await prisma.bot.count({ where: { userId, kind: "main" } })).toBe(0);
expect(await getCoachRhythm(prisma, userId)).toEqual(off);
await setCoachRhythm(
{ prisma, jobs },
{ userId, rhythm: { morning: "09:15", evening: null, weekly: null } },
);
const [routine] = await coachRoutines(userId);
expect(routine).toMatchObject({ timezone: "UTC", crons: ["15 9 * * *"] });
expect(await setCoachRhythm({ prisma, jobs }, { userId, rhythm: off })).toEqual(off);
expect(await coachRoutines(userId)).toEqual([]);
expect(jobs.cancel).toHaveBeenCalledWith(routineJobKey(routine!.id));
});
});

View File

@ -0,0 +1,66 @@
import { describe, expect, it } from "vitest";
import {
addDays,
habitDoneInPeriod,
habitStreak,
localDateIn,
weekdayOf,
weekStartOf,
} from "./coach.js";
const dates = (...values: string[]) => new Set(values);
describe("calendar dates", () => {
it("reads the date in the user's time zone, not the server's", () => {
const instant = new Date("2026-10-03T23:30:00Z");
expect(localDateIn("UTC", instant)).toBe("2026-10-03");
expect(localDateIn("Europe/Vienna", instant)).toBe("2026-10-04");
expect(localDateIn("America/Los_Angeles", instant)).toBe("2026-10-03");
expect(localDateIn("Pacific/Kiritimati", new Date("2026-10-03T10:30:00Z"))).toBe("2026-10-04");
});
it("moves across months, years and daylight saving changes by whole days", () => {
expect(addDays("2026-10-31", 1)).toBe("2026-11-01");
expect(addDays("2027-01-01", -1)).toBe("2026-12-31");
expect(addDays("2026-03-28", 2)).toBe("2026-03-30");
expect(weekdayOf("2026-10-03")).toBe(6);
expect(weekStartOf("2026-10-03")).toBe("2026-09-28");
expect(weekStartOf("2026-10-04")).toBe("2026-09-28");
expect(weekStartOf("2026-10-05")).toBe("2026-10-05");
});
});
describe("habit streaks", () => {
const saturday = "2026-10-03";
it("counts consecutive days and keeps today open until it is done", () => {
const done = dates("2026-09-30", "2026-10-01", "2026-10-02");
expect(habitStreak("daily", done, saturday)).toBe(3);
expect(habitStreak("daily", new Set([...done, saturday]), saturday)).toBe(4);
expect(habitStreak("daily", dates("2026-09-30", "2026-10-01"), saturday)).toBe(0);
expect(habitStreak("daily", dates(), saturday)).toBe(0);
});
it("skips weekends for weekday habits", () => {
const monday = "2026-10-05";
const done = dates("2026-10-01", "2026-10-02");
expect(habitStreak("weekdays", done, saturday)).toBe(2);
expect(habitStreak("weekdays", done, monday)).toBe(2);
expect(habitStreak("weekdays", new Set([...done, monday]), monday)).toBe(3);
expect(habitStreak("weekdays", dates("2026-10-01"), monday)).toBe(0);
});
it("counts weeks with at least one done day for weekly habits", () => {
const done = dates("2026-09-15", "2026-09-26", "2026-09-29");
expect(habitStreak("weekly", done, saturday)).toBe(3);
expect(habitStreak("weekly", dates("2026-09-15", "2026-09-26"), saturday)).toBe(2);
expect(habitStreak("weekly", dates("2026-09-15"), saturday)).toBe(0);
});
it("reads a weekly habit as done for the rest of the week", () => {
expect(habitDoneInPeriod("weekly", dates("2026-09-29"), saturday)).toBe(true);
expect(habitDoneInPeriod("weekly", dates("2026-09-27"), saturday)).toBe(false);
expect(habitDoneInPeriod("daily", dates("2026-10-02"), saturday)).toBe(false);
expect(habitDoneInPeriod("daily", dates(saturday), saturday)).toBe(true);
});
});

View File

@ -0,0 +1,327 @@
import { randomUUID } from "node:crypto";
import { COACH_ACTIVE_GOAL_LIMIT, COACH_ACTIVE_HABIT_LIMIT } from "@rakazo/contracts";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { bootstrapUserSpace } from "./bootstrap-user.js";
import type { PrismaClient } from "./client.js";
import { createDb } from "./client.js";
import {
CoachNotFoundError,
createGoal,
createHabit,
InvalidCoachInputError,
listCheckIns,
listGoals,
listHabits,
loadCoachSummary,
loadCoachToday,
logCheckIn,
removeGoal,
removeHabit,
updateGoal,
updateHabit,
upsertDailyBrief,
} from "./coach.js";
const databaseUrl = process.env.DATABASE_URL;
const describePostgres =
process.env.VERIFY_DATABASE && databaseUrl ? describe.sequential : describe.skip;
const signupEnv = { signupsEnabled: "true", signupAllowlist: "" };
/** Saturday 2026-10-03, 23:30 UTC: already Sunday in Vienna. */
const NOW = new Date("2026-10-03T23:30:00Z");
describePostgres("coach repository (PostgreSQL)", () => {
let prisma: PrismaClient;
let close: () => Promise<void>;
const userIds: string[] = [];
async function newUser(timeZone: string | null = "Europe/Vienna") {
const id = `co${randomUUID().replaceAll("-", "")}`;
userIds.push(id);
await prisma.user.create({ data: { id, name: "Ada", email: `${id}@rakazo.test` } });
const { spaceId } = await bootstrapUserSpace(prisma, { id }, signupEnv, {
claimDeploymentOwner: false,
});
if (timeZone) await prisma.userProfile.create({ data: { userId: id, timeZone } });
return { userId: id, spaceId };
}
beforeAll(() => {
const db = createDb(databaseUrl!);
prisma = db.prisma;
close = async () => {
await db.prisma.$disconnect();
await db.pool.end();
};
});
afterAll(async () => {
if (!prisma) return;
const memberships = await prisma.member.findMany({
where: { userId: { in: userIds } },
select: { organizationId: true },
});
await prisma.organization.deleteMany({
where: { id: { in: memberships.map((member) => member.organizationId) } },
});
await prisma.user.deleteMany({ where: { id: { in: userIds } } });
await close();
});
it("creates, completes, reopens and removes goals, scoped to their owner", async () => {
const { userId, spaceId } = await newUser();
const other = await newUser();
const goal = await createGoal(prisma, userId, {
title: " Ship the beta ",
detail: "Invite ten testers",
targetDate: "2026-11-01",
spaceId,
source: "onboarding",
});
expect(goal).toMatchObject({
title: "Ship the beta",
detail: "Invite ten testers",
status: "active",
targetDate: "2026-11-01",
spaceId,
source: "onboarding",
createdByBotId: null,
completedAt: null,
});
const done = await updateGoal(prisma, userId, goal.id, { status: "done" });
expect(done.status).toBe("done");
expect(done.completedAt).not.toBeNull();
const reopened = await updateGoal(prisma, userId, goal.id, {
status: "active",
targetDate: null,
});
expect(reopened).toMatchObject({ status: "active", completedAt: null, targetDate: null });
await expect(updateGoal(prisma, other.userId, goal.id, { title: "Mine" })).rejects.toThrow(
CoachNotFoundError,
);
await expect(removeGoal(prisma, other.userId, goal.id)).rejects.toThrow(CoachNotFoundError);
await expect(
createGoal(prisma, other.userId, { title: "Theirs", spaceId, source: "user" }),
).rejects.toThrow("Space not found");
expect(await listGoals(prisma, other.userId)).toEqual([]);
expect((await listGoals(prisma, userId, { status: "active" })).map((g) => g.id)).toEqual([
goal.id,
]);
await removeGoal(prisma, userId, goal.id);
expect(await listGoals(prisma, userId)).toEqual([]);
});
it("validates titles, dates and the active limits", async () => {
const { userId } = await newUser();
await expect(createGoal(prisma, userId, { title: " ", source: "user" })).rejects.toThrow(
InvalidCoachInputError,
);
await expect(
createGoal(prisma, userId, { title: "x".repeat(201), source: "user" }),
).rejects.toThrow("longer than 200");
await expect(
createGoal(prisma, userId, { title: "Bad date", targetDate: "2026-02-30", source: "user" }),
).rejects.toThrow("YYYY-MM-DD");
await prisma.userGoal.createMany({
data: Array.from({ length: COACH_ACTIVE_GOAL_LIMIT }, (_, index) => ({
userId,
title: `Goal ${index}`,
source: "user",
})),
});
await expect(createGoal(prisma, userId, { title: "One more", source: "user" })).rejects.toThrow(
`at most ${COACH_ACTIVE_GOAL_LIMIT} active goals`,
);
const [first] = await listGoals(prisma, userId);
await updateGoal(prisma, userId, first!.id, { status: "dropped" });
await createGoal(prisma, userId, { title: "One more", source: "user" });
await expect(updateGoal(prisma, userId, first!.id, { status: "active" })).rejects.toThrow(
"active goals",
);
await prisma.habit.createMany({
data: Array.from({ length: COACH_ACTIVE_HABIT_LIMIT }, (_, index) => ({
userId,
title: `Habit ${index}`,
source: "user",
})),
});
await expect(
createHabit(prisma, userId, { title: "One more", source: "user" }),
).rejects.toThrow(`at most ${COACH_ACTIVE_HABIT_LIMIT} active habits`);
});
it("links habits to goals, pauses them and keeps their history", async () => {
const { userId } = await newUser();
const other = await newUser();
const goal = await createGoal(prisma, userId, { title: "Run a 10k", source: "chat" });
const habit = await createHabit(prisma, userId, {
title: "Run",
cadence: "weekdays",
goalId: goal.id,
source: "chat",
createdByBotId: "bot-1",
});
expect(habit).toMatchObject({ cadence: "weekdays", goalId: goal.id, active: true });
await expect(
createHabit(prisma, other.userId, { title: "Steal", goalId: goal.id, source: "user" }),
).rejects.toThrow(CoachNotFoundError);
const paused = await updateHabit(prisma, userId, habit.id, { active: false, title: "Jog" });
expect(paused).toMatchObject({ active: false, title: "Jog" });
expect(await listHabits(prisma, userId)).toEqual([]);
expect((await listHabits(prisma, userId, { includeInactive: true })).length).toBe(1);
// Removing the goal keeps the habit, unlinked.
await removeGoal(prisma, userId, goal.id);
expect((await listHabits(prisma, userId, { includeInactive: true }))[0]?.goalId).toBeNull();
await expect(removeHabit(prisma, other.userId, habit.id)).rejects.toThrow(CoachNotFoundError);
await removeHabit(prisma, userId, habit.id);
expect(await listHabits(prisma, userId, { includeInactive: true })).toEqual([]);
});
it("keeps one check-in per habit, goal and day, dated in the user's time zone", async () => {
const { userId } = await newUser("Europe/Vienna");
const other = await newUser();
const habit = await createHabit(prisma, userId, { title: "Stretch", source: "user" });
const goal = await createGoal(prisma, userId, { title: "Learn Spanish", source: "user" });
const first = await logCheckIn(
prisma,
userId,
{ kind: "habit", habitId: habit.id, done: true },
NOW,
);
// 23:30 UTC on Saturday is Sunday in Vienna.
expect(first).toMatchObject({ kind: "habit", date: "2026-10-04", done: true, note: "" });
const again = await logCheckIn(
prisma,
userId,
{ kind: "habit", habitId: habit.id, note: "10 minutes", createdByBotId: "bot-1" },
NOW,
);
expect(again).toMatchObject({ id: first.id, done: true, note: "10 minutes" });
// Who created the row stays as it was.
expect(again.createdByBotId).toBeNull();
const daily = await logCheckIn(prisma, userId, { kind: "daily", mood: 4 }, NOW);
const dailyAgain = await logCheckIn(prisma, userId, { kind: "daily", energy: 2 }, NOW);
expect(dailyAgain).toMatchObject({ id: daily.id, mood: 4, energy: 2 });
const goalCheckIn = await logCheckIn(
prisma,
userId,
{ kind: "goal", goalId: goal.id, note: "Finished unit 3", date: "2026-10-02" },
NOW,
);
expect(goalCheckIn.date).toBe("2026-10-02");
await expect(
logCheckIn(prisma, userId, { kind: "daily", date: "2026-10-05" }, NOW),
).rejects.toThrow("future");
await expect(
logCheckIn(prisma, userId, { kind: "daily", date: "2025-01-01" }, NOW),
).rejects.toThrow("go back at most");
await expect(logCheckIn(prisma, userId, { kind: "daily", mood: 6 }, NOW)).rejects.toThrow(
"1 to 5",
);
await expect(
logCheckIn(prisma, userId, { kind: "habit", goalId: goal.id }, NOW),
).rejects.toThrow(InvalidCoachInputError);
await expect(
logCheckIn(prisma, other.userId, { kind: "habit", habitId: habit.id, done: true }, NOW),
).rejects.toThrow(CoachNotFoundError);
expect((await listCheckIns(prisma, userId)).map((row) => row.kind).sort()).toEqual([
"daily",
"goal",
"habit",
]);
expect(await listCheckIns(prisma, userId, { from: "2026-10-03" })).toHaveLength(2);
expect(await listCheckIns(prisma, userId, { goalId: goal.id })).toHaveLength(1);
expect(await listCheckIns(prisma, other.userId)).toEqual([]);
});
it("reports today's brief, goals, habits with streaks and the daily check-in", async () => {
const { userId } = await newUser("Europe/Vienna");
const daily = await createHabit(prisma, userId, { title: "Walk", source: "user" });
const weekly = await createHabit(prisma, userId, {
title: "Long run",
cadence: "weekly",
source: "user",
});
const later = await createGoal(prisma, userId, { title: "Later", source: "user" });
const soon = await createGoal(prisma, userId, {
title: "Soon",
targetDate: "2026-10-10",
source: "user",
});
await createGoal(prisma, userId, { title: "Old", source: "user" }).then((goal) =>
updateGoal(prisma, userId, goal.id, { status: "done" }),
);
for (const date of ["2026-10-01", "2026-10-02", "2026-10-03"]) {
await logCheckIn(prisma, userId, { kind: "habit", habitId: daily.id, date, done: true }, NOW);
}
await logCheckIn(
prisma,
userId,
{ kind: "habit", habitId: weekly.id, date: "2026-09-30", done: true },
NOW,
);
let today = await loadCoachToday(prisma, userId, NOW);
expect(today).toMatchObject({ date: "2026-10-04", timeZone: "Europe/Vienna", brief: null });
expect(today.checkIn).toBeNull();
expect(today.goals.map((goal) => goal.id)).toEqual([soon.id, later.id]);
expect(
today.habits.map(({ title, doneToday, streak }) => ({ title, doneToday, streak })),
).toEqual([
{ title: "Walk", doneToday: false, streak: 3 },
{ title: "Long run", doneToday: true, streak: 1 },
]);
const brief = await upsertDailyBrief(
prisma,
userId,
{ text: "Rest day. Plan the week.", botId: "bot-1" },
NOW,
);
expect(brief).toMatchObject({ date: "2026-10-04", botId: "bot-1" });
const rewritten = await upsertDailyBrief(prisma, userId, { text: "Rest day." }, NOW);
expect(rewritten).toMatchObject({ id: brief.id, text: "Rest day.", botId: null });
await expect(
upsertDailyBrief(prisma, userId, { text: "Far ahead", date: "2026-10-20" }, NOW),
).rejects.toThrow("today or tomorrow");
await expect(upsertDailyBrief(prisma, userId, { text: " " }, NOW)).rejects.toThrow("empty");
await logCheckIn(prisma, userId, { kind: "habit", habitId: daily.id, done: true }, NOW);
await logCheckIn(prisma, userId, { kind: "daily", mood: 5 }, NOW);
// Unchecking a weekly habit clears it for the whole week.
await logCheckIn(prisma, userId, { kind: "habit", habitId: weekly.id, done: false }, NOW);
today = await loadCoachToday(prisma, userId, NOW);
expect(today.brief?.text).toBe("Rest day.");
expect(today.checkIn).toMatchObject({ kind: "daily", mood: 5 });
expect(today.habits.map(({ doneToday, streak }) => ({ doneToday, streak }))).toEqual([
{ doneToday: true, streak: 4 },
{ doneToday: false, streak: 0 },
]);
const summary = await loadCoachSummary(prisma, userId, NOW);
expect(summary).toMatchObject({ date: "2026-10-04", timeZone: "Europe/Vienna" });
expect(summary.habits).toEqual(today.habits);
expect(summary.goals).toEqual(today.goals);
});
it("uses UTC dates when the user has no time zone", async () => {
const { userId } = await newUser(null);
expect(await loadCoachToday(prisma, userId, NOW)).toMatchObject({
date: "2026-10-03",
timeZone: "UTC",
goals: [],
habits: [],
});
});
});

View File

@ -109,6 +109,7 @@ async function main() {
"packages/db/src/space-membership.postgres.test.ts", "packages/db/src/space-membership.postgres.test.ts",
"packages/db/src/main-agent.postgres.test.ts", "packages/db/src/main-agent.postgres.test.ts",
"packages/db/src/user-profile.postgres.test.ts", "packages/db/src/user-profile.postgres.test.ts",
"packages/db/src/coach.postgres.test.ts",
"packages/db/src/messaging.postgres.test.ts", "packages/db/src/messaging.postgres.test.ts",
"packages/memory/src/commit.postgres.test.ts", "packages/memory/src/commit.postgres.test.ts",
"packages/adapters/src/wakeup.postgres.test.ts", "packages/adapters/src/wakeup.postgres.test.ts",
@ -117,6 +118,7 @@ async function main() {
"packages/adapters/src/cloud-agent.postgres.test.ts", "packages/adapters/src/cloud-agent.postgres.test.ts",
"packages/adapters/src/builtin-memory-provider.postgres.test.ts", "packages/adapters/src/builtin-memory-provider.postgres.test.ts",
"packages/adapters/src/profile-consolidation.postgres.test.ts", "packages/adapters/src/profile-consolidation.postgres.test.ts",
"packages/adapters/src/coach-rhythm.postgres.test.ts",
]; ];
// Each app reconciles all durable work in its database, including intentionally // Each app reconciles all durable work in its database, including intentionally
// unfinished fixture runs. Clone the pristine migrated schema so one suite // unfinished fixture runs. Clone the pristine migrated schema so one suite