fix(sources): stop listing a source whose readings were all deleted

The in-use probe matched tombstoned readings, so a source stayed marked
on the priority ladder after every reading from it was deleted. Both
the read and the save response of the source-priority route go through
this one probe.
This commit is contained in:
Marc-André Bombeck committed 2026-10-08 22:57:47 +02:00
1 parent 27dfc6a617
commit dcbd564962
3 files changed
+84 -2

No files matched your search

@@ -38,6 +38,21 @@ describe("getSourcesInUse", () => {
expect(await getSourcesInUse("u1")).toEqual(["MANUAL"]);
});
it("does not count a source whose readings were all deleted", async () => {
// The probe answers like the database: a MANUAL row exists, but it is a
// tombstone, so only a probe that admits deleted rows finds it.
vi.mocked(prisma.measurement.findFirst).mockImplementation(((args: {
where: { source: string; deletedAt?: null };
}) =>
Promise.resolve(
args.where.source === "MANUAL" && !("deletedAt" in args.where)
? { id: "m-deleted" }
: null,
)) as never);
expect(await getSourcesInUse("u1")).toEqual([]);
});
it("lists a connected integration that has not delivered yet", async () => {
vi.mocked(prisma.measurement.findFirst).mockResolvedValue(null);
vi.mocked(prisma.withingsConnection.findUnique).mockResolvedValue({
+8 -2
View File
@@ -17,7 +17,8 @@ export const RANKABLE_SOURCES: readonly MeasurementSource[] = Array.from(
* one measurement from, or an integration it has connected that has not
* delivered yet.
*
* The Settings ladder lists only these. Ranking a source the person has never
* Deleted (tombstoned) readings do not count. The Settings ladder lists only
* these. Ranking a source the person has never
* used decides nothing, and ten of them per metric buried the two that do.
* The ladders themselves stay whole: hidden sources keep their slot, so a
* source that starts delivering later lands where the ladder already put it.
@@ -33,7 +34,12 @@ export async function getSourcesInUse(
Promise.all(
RANKABLE_SOURCES.map((source) =>
prisma.measurement
.findFirst({ where: { userId, source }, select: { id: true } })
.findFirst({
// A deleted reading is not data: a source whose readings were
// all deleted is no longer in use.
where: { userId, source, deletedAt: null },
select: { id: true },
})
.then((row) => (row ? source : null)),
),
),