Add the database schema and repository layer
The per-calendar JSON blob is gone. v1 kept every calendar's colour, every visibility toggle and a custom palette inside one calendar_colors TEXT column, so hiding one calendar rewrote the whole document -- which is where "Fix calendar visibility preservation during event updates" came from. Those are rows now, and set_visible touches visibility alone. Foreign keys are switched on. v1 declared external_calendars.user_id as INTEGER against a TEXT users.id; SQLite enforces neither the type nor the constraint unless asked, so it was decorative and could never match. Session tokens are stored as SHA-256, never in the clear, so a copy of the database cannot be used to impersonate anyone. The CalDAV password is the one secret that cannot be hashed -- it has to be replayed to the server -- so it gets an encrypted column with the algorithm recorded alongside, and one way in and one way out instead of v1's eight localStorage reads. Preferences are one column each with CHECK constraints, so a bad view or a nonsense time increment is refused whatever route it arrives by. A NULL display timezone means "follow the browser", which is a state v1 could not express -- as with a NULL calendar colour meaning "defer to the server", which is why it hashed paths to invent one. Feed caching stores a content hash beside the ETag, because a published Outlook feed sends neither ETag nor Last-Modified and staleness has to be detectable anyway. Thirty tests against real in-memory SQLite, not mocks. One caught that create() returned nanosecond timestamps while the column stores microseconds, so a session never compared equal to itself read back.
This commit is contained in:
@@ -40,6 +40,9 @@ uuid = { version = "1", features = ["v4", "serde"] }
|
||||
icalendar = "0.17"
|
||||
rrule = "0.14"
|
||||
|
||||
# Crypto
|
||||
sha2 = "0.10"
|
||||
|
||||
# Errors + logging
|
||||
thiserror = "2"
|
||||
tracing = "0.1"
|
||||
|
||||
Reference in New Issue
Block a user