Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/src/components/QuickLogDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ export default function QuickLogDialog({ category, onClose, onLogged }: QuickLog
>
<MenuItem value="oz">oz</MenuItem>
<MenuItem value="ml">ml</MenuItem>
<MenuItem value="cc">cc</MenuItem>
<MenuItem value="g">g</MenuItem>
</TextField>
</Box>
Expand Down
1 change: 1 addition & 0 deletions client/src/pages/FeedingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ export default function FeedingsPage() {
>
<MenuItem value="oz">oz</MenuItem>
<MenuItem value="ml">ml</MenuItem>
<MenuItem value="cc">cc</MenuItem>
<MenuItem value="g">g</MenuItem>
</TextField>
</Box>
Expand Down
2 changes: 1 addition & 1 deletion client/src/types/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface Feeding {
start_time: string;
end_time: string | null;
amount: number | null;
amount_unit: "ml" | "oz" | "g" | null;
amount_unit: "ml" | "oz" | "g" | "cc" | null;
notes: string | null;
created_at: string;
updated_at: string;
Expand Down
25 changes: 25 additions & 0 deletions server/migrations/0010_add_cc_feeding_unit.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Allow 'cc' as a feeding amount unit alongside ml, oz and g.
-- SQLite can't alter a CHECK constraint in place, so the table is rebuilt.
CREATE TABLE feedings_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
child_id INTEGER NOT NULL REFERENCES children(id) ON DELETE CASCADE,
type TEXT NOT NULL CHECK(type IN ('breast_left', 'breast_right', 'both_breasts', 'bottle_breast_milk', 'bottle_formula', 'solid', 'fortified_breast_milk')),
start_time TEXT NOT NULL,
end_time TEXT,
amount REAL,
amount_unit TEXT CHECK(amount_unit IN ('ml', 'oz', 'g', 'cc')),
notes TEXT,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
created_by_user_id INTEGER REFERENCES users(id) ON DELETE SET NULL
);

INSERT INTO feedings_new (id, child_id, type, start_time, end_time, amount, amount_unit, notes, created_at, updated_at, created_by_user_id)
SELECT id, child_id, type, start_time, end_time, amount, amount_unit, notes, created_at, updated_at, created_by_user_id
FROM feedings;

DROP TABLE feedings;
ALTER TABLE feedings_new RENAME TO feedings;

CREATE INDEX idx_feedings_child_id ON feedings(child_id);
CREATE INDEX idx_feedings_start_time ON feedings(start_time);
14 changes: 14 additions & 0 deletions server/test/feedings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ describe("Feedings API", () => {
expect(feeding.notes).toBe("Morning bottle");
});

it("POST /api/feedings accepts cc as an amount unit", async () => {
const res = await api.post("/api/feedings", {
child_id: childId,
type: "bottle_breast_milk",
start_time: "2024-12-01T08:00:00Z",
amount: 120,
amount_unit: "cc",
});
expect(res.status).toBe(201);
const feeding = (await res.json()) as Record<string, unknown>;
expect(feeding.amount).toBe(120);
expect(feeding.amount_unit).toBe("cc");
});

it("GET /api/feedings lists feedings for a child", async () => {
await api.post("/api/feedings", {
child_id: childId,
Expand Down
3 changes: 2 additions & 1 deletion server/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import migration0006 from "../migrations/0006_add_created_by_user_id.sql?raw";
import migration0007 from "../migrations/0007_add_todos.sql?raw";
import migration0008 from "../migrations/0008_split_bottle_feeding_type.sql?raw";
import migration0009 from "../migrations/0009_add_pumping_side.sql?raw";
import migration0010 from "../migrations/0010_add_cc_feeding_unit.sql?raw";

type AppEnv = { Bindings: Env; Variables: { userId: number; userEmail: string; userName: string } };

Expand Down Expand Up @@ -101,7 +102,7 @@ export async function applyMigrations(db: D1Database) {
`;

// Execute the real migration files in order to keep test schema in sync
const migrations = [migration0001, migration0002, migration0003, migration0004, migration0005, migration0006, migration0007, migration0008, migration0009];
const migrations = [migration0001, migration0002, migration0003, migration0004, migration0005, migration0006, migration0007, migration0008, migration0009, migration0010];

// D1 batch doesn't support multi-statement, so split and execute individually
const allSQL = dropSQL + migrations.join("\n");
Expand Down