fix: store work entry dates as ISO strings instead of epoch milliseconds#747
fix: store work entry dates as ISO strings instead of epoch milliseconds#747devin-ai-integration[bot] wants to merge 1 commit into
Conversation
- Changed Joi date validation from date().iso() (which converts to Date objects) to string().pattern() (which preserves the YYYY-MM-DD string) - This fixes CSV/PDF exports showing dates as epoch timestamps like 1778544000000 instead of readable dates like 2026-05-12 - Also enabled PRAGMA foreign_keys in SQLite init to fix cascade deletes - Added ROOT_CAUSE_ANALYSIS.md documenting the bug and fix
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
| date: Joi.string().pattern(/^\d{4}-\d{2}-\d{2}$/).required().messages({ | ||
| 'string.pattern.base': '"date" must be a valid ISO date (YYYY-MM-DD)' | ||
| }) |
There was a problem hiding this comment.
🟡 Date regex accepts semantically invalid dates (e.g., month 13, day 32)
The regex /^\d{4}-\d{2}-\d{2}$/ only validates the YYYY-MM-DD format but does not validate that the date is semantically valid. It will accept strings like "2026-13-32", "2026-00-00", "2026-02-30" (Feb 30), etc., and store them in the database. The previous Joi.date().iso() would reject these because it parsed the string into a JavaScript Date object and verified validity. The error message '"date" must be a valid ISO date (YYYY-MM-DD)' is also misleading since the check doesn't verify it's actually a valid date. This applies to both workEntrySchema and updateWorkEntrySchema.
Prompt for agents
The regex /^\d{4}-\d{2}-\d{2}$/ only checks YYYY-MM-DD format but accepts impossible dates like 2026-13-32 or 2026-02-30. The fix correctly avoids Joi.date().iso() (which converts strings to Date objects), but should add a .custom() validator to verify the date is semantically valid. For example, after the pattern check, add a Joi .custom() call that parses the string with new Date(value + 'T00:00:00Z') and verifies the result is not NaN and round-trips back to the same string. This should be applied to both workEntrySchema (line 14) and updateWorkEntrySchema (line 23) in backend/src/validation/schemas.js.
Was this helpful? React with 👍 or 👎 to provide feedback.



Summary
Work entry dates were being stored in SQLite as epoch milliseconds (e.g.,
1778544000000) instead of ISO date strings (e.g.,"2026-05-12"). This corrupted CSV/PDF exports and API responses.Root cause: Joi's
date().iso()validator converts date strings to JavaScriptDateobjects. When sqlite3 binds aDateobject, it calls.valueOf()producing an epoch timestamp in milliseconds.Fix: Changed the Joi validation schema from
Joi.date().iso()toJoi.string().pattern(/^\d{4}-\d{2}-\d{2}$/), which validates the YYYY-MM-DD format without converting to a Date object.Additional fix: Enabled
PRAGMA foreign_keys = ONin the database initialization so thatON DELETE CASCADEconstraints actually work (SQLite has foreign keys OFF by default).Before
CSV exports showed epoch timestamps instead of dates:

After
CSV exports now show proper ISO dates:

Review & Testing Checklist for Human
"2026-05-12"(not a number)YYYY-MM-DD05/12/2026) and confirm it's rejected with a clear errorNotes
ROOT_CAUSE_ANALYSIS.mdfor detailed bug documentationLink to Devin session: https://partner-workshops.devinenterprise.com/sessions/608e673002f14154a9c03740d66cd851