Mirrors the node:sqlite sub-backend structure with full migration support.
Uses native pg types (UUID, JSONB, TIMESTAMPTZ) and $1/$2 parameterisation
via internal ? placeholders converted at execution time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fills in all 7 previously-unimplemented note methods in SqliteInterface
and ApiInterface, adds cast/query helpers for notes, and fixes the
apirouter (missing updatenote validator, two /user/ → /users/ typos that
were also bypassing auth middleware).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/auth/logout previously only cleared the client's cookie, leaving the
session token valid in the sessions table — a stolen cookie captured
before logout would still work afterwards. Add BackendDbInterface#deleteSession
(implemented in SqliteInterface) and call it from the logout route using
the session token from the cookie. Caught by the new auth-http.test.ts
integration test, updated to assert the session is actually invalidated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds 215 tests across three tiers using node:test + node:assert/strict
(no new test framework dependencies):
- test/tools/ — middleware and utility tests (token, hash, authenticate,
jsonBody, convertError, validators)
- test/shared/ — DbInterface/BackendDbInterface contract suites reusable
across backends (users, abodes, residents, apikeys, sessions, auth)
- test/backends/sqlite/ — SQLite-private tests (sql builder, WrappedDb,
migrator) + shared suites via SqliteInterface
- test/backends/api/ — ApiInterface unit tests + shared suites via a
live Koa server backed by SQLite
Also fixes four bugs uncovered by the tests:
- ApiInterface: path params leaked into query string (slice(1) fix)
- ApiInterface: calling res.json() on 204 No Content responses
- SqliteInterface.updateResident: missing comma in SET clause
- WrappedBetterSqlite3Db: readonly:undefined rejected by better-sqlite3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>