Grouped low-severity findings in packages/data-ops.
UpdateNotificationSourceInput allows type/config mismatch & cannot null topicId — zod-schema/notification-source.ts:31-38. config is z.any(); a {type:"birthday"} PUT over a waste source persists incoherent config. Test: reject type change without matching config; accept topicId:null.
initDatabase does not URL-encode credentials & ignores re-init — database/setup.ts:14-21. A password with @///# breaks the connection string; if(db)return db silently keeps the first client. Test: connection string for p@ss/w#rd contains p%40ss%2Fw%23rd.
- Drizzle configs reference a nonexistent
relations.ts — drizzle-{dev,stage,prod}.config.ts:9; tests/drizzle-config.test.ts:22 asserts the string, not the file. Test: every schema path exists on disk.
seed.ts raw-SQL interpolation, non-transactional, no ON CONFLICT — scripts/seed.ts:42-103. Breaks on an apostrophe in a value; partial state on mid-run failure.
- All
timestamp columns are WITHOUT time zone — schema.ts, auth-schema.ts. Correct only while every writer agrees on UTC; timestamptz is the cheap fix now.
email_whitelist lookup normalized but storage is not — queries/email-whitelist.ts:9-17, schema.ts:162-167. A mixed-case stored row never matches → user locked out. Test: insert mixed-case, assert lookup matches.
- Unbounded queries —
queries/delivery.ts:13-20,63-70 (getDeliveryLogs/getDeliveryFailures) and leads.ts:17-20 (listLeadsForAdmin) have no LIMIT/pagination.
SourceFormInput omits householdId — zod-schema/source-form-schema.ts:21-35 → forces an unvalidated cast at the worker call site.
Grouped low-severity findings in
packages/data-ops.UpdateNotificationSourceInputallows type/config mismatch & cannot nulltopicId—zod-schema/notification-source.ts:31-38.configisz.any(); a{type:"birthday"}PUT over a waste source persists incoherent config. Test: reject type change without matching config; accepttopicId:null.initDatabasedoes not URL-encode credentials & ignores re-init —database/setup.ts:14-21. A password with@///#breaks the connection string;if(db)return dbsilently keeps the first client. Test: connection string forp@ss/w#rdcontainsp%40ss%2Fw%23rd.relations.ts—drizzle-{dev,stage,prod}.config.ts:9;tests/drizzle-config.test.ts:22asserts the string, not the file. Test: every schema path exists on disk.seed.tsraw-SQL interpolation, non-transactional, no ON CONFLICT —scripts/seed.ts:42-103. Breaks on an apostrophe in a value; partial state on mid-run failure.timestampcolumns are WITHOUT time zone —schema.ts,auth-schema.ts. Correct only while every writer agrees on UTC;timestamptzis the cheap fix now.email_whitelistlookup normalized but storage is not —queries/email-whitelist.ts:9-17,schema.ts:162-167. A mixed-case stored row never matches → user locked out. Test: insert mixed-case, assert lookup matches.queries/delivery.ts:13-20,63-70(getDeliveryLogs/getDeliveryFailures) andleads.ts:17-20(listLeadsForAdmin) have no LIMIT/pagination.SourceFormInputomitshouseholdId—zod-schema/source-form-schema.ts:21-35→ forces an unvalidated cast at the worker call site.