mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(mood): one spelling on the wire, one day-key helper, one written decision
Three small things the audit named together. The mood reads spread the whole row, so adding the wire keys shipped every level-A value twice — once as the column name and once as the key the write path accepts. A client would have picked one and been stuck with it. The column spelling is stripped now, and the create response's key set is asserted so it stays stripped. The published contract is unaffected either way; these routes are not in it. The dimension series carried its own copy of the day-key subtraction that the freshness module already exports. One copy now. And the reason a stale dimension ships with a notice instead of being dropped the way the status surfaces drop one is written at the builder: a one-line card has nothing left to say about a value it cannot narrate, while an open conversation can say when the value is from — and silence there would leave no way to tell an unanswered dimension from one nobody has looked at in a week.
This commit is contained in:
1 parent
4db0f3a62a
commit
3dd79ec734
6 files changed
+83
-34
No files matched your search
@@ -103,9 +103,11 @@ describe("mood writers agree on the derived level-A value", () => {
|
||||
);
|
||||
expect(single.status).toBe(201);
|
||||
|
||||
// 2 — bulk backfill. The request shape carries no level-A field; the
|
||||
// server derives it, which is the whole point of this phase being
|
||||
// invisible on the wire.
|
||||
// 2 — bulk backfill. The request shape carries no level-A field and the
|
||||
// server derives it, which is why the published contract does not move:
|
||||
// this batch path is the one in `docs/api/openapi.yaml`, and it is
|
||||
// byte-identical. The unpublished single routes DO answer five new keys
|
||||
// on their reads, which is additive and which the client ignores.
|
||||
const bulk = await postBulk(
|
||||
jsonRequest("/api/mood-entries/bulk", {
|
||||
entries: [
|
||||
@@ -370,12 +372,27 @@ describe("mood writers agree on the derived level-A value", () => {
|
||||
);
|
||||
expect(res.status).toBe(201);
|
||||
const json = (await res.json()) as {
|
||||
data: { a1: number; a2: number; a3: number; a4: null; a5: null };
|
||||
data: Record<string, unknown> & {
|
||||
a1: number;
|
||||
a2: number;
|
||||
a3: number;
|
||||
a4: null;
|
||||
a5: null;
|
||||
};
|
||||
};
|
||||
// The response echoes the values under the keys the request used.
|
||||
expect(json.data.a1).toBe(4);
|
||||
expect(json.data.a2).toBe(9);
|
||||
expect(json.data.a5).toBeNull();
|
||||
// And under those keys ONLY. The routes spread the whole row, so simply
|
||||
// adding the wire keys shipped every value twice under two spellings; a
|
||||
// client would then have picked one and been stuck with it.
|
||||
const keys = Object.keys(json.data as Record<string, unknown>);
|
||||
expect(keys).not.toContain("moodA1");
|
||||
expect(keys).not.toContain("stressA2");
|
||||
expect(keys).not.toContain("energyA3");
|
||||
expect(keys).not.toContain("connectionA4");
|
||||
expect(keys).not.toContain("stabilityA5");
|
||||
|
||||
const row = await getPrismaClient().moodEntry.findFirstOrThrow({
|
||||
where: { userId: USER },
|
||||
|
||||
Reference in new issue
Block a user