docs: add implementation plan; fix session cap and genre seed in spec

Session validation now also checks created_at so the 12-hour cap holds
while expires_at is still in the future. Genre seed avoids ON CONFLICT,
which burns SMALLSERIAL values on every startup.
This commit is contained in:
2026-10-02 13:59:50 -05:00
parent de38590f46
commit 02d4598697
+5 -2
View File
@@ -22,10 +22,13 @@ Store sessions in PostgreSQL, keyed by the SHA-256 of an opaque random token.
```sql
UPDATE sessions
SET expires_at = LEAST(now() + interval '30 minutes', created_at + interval '12 hours')
WHERE token_hash = %s AND expires_at > now()
WHERE token_hash = %s
AND expires_at > now()
AND created_at > now() - interval '12 hours'
RETURNING user_id;
```
This gives a 30-minute idle timeout and a 12-hour absolute cap. No row → 401.
This gives a 30-minute idle timeout and a 12-hour absolute cap. The `created_at` predicate is required:
`expires_at` can still be up to 30 minutes in the future when the 12-hour cap passes. No row → 401.
- **Revoke:** logout deletes the row. Deleting a user cascades to their sessions.
- **Cleanup:** a user's expired rows are deleted when they log in; no scheduled job.