SQLite best practices for Node.js with better-sqlite3 — WAL mode, pragmas, foreign keys, STRICT tables, transactions, migrations, graceful shutdown, and query patterns
97
98%
Does it follow best practices?
Impact
96%
1.65xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent applies SQLite best practices for a task management app. The task mentions bulk import (should trigger transaction wrapping), multiple FK relationships (should trigger FK indexing), enum-like columns (should trigger CHECK constraints), and date queries (should trigger proper TEXT/ISO date storage). None of these patterns are prescribed in the task.",
"type": "weighted_checklist",
"checklist": [
{
"name": "WAL mode enabled",
"description": "db.ts sets PRAGMA journal_mode = WAL",
"max_score": 8
},
{
"name": "Foreign keys ON",
"description": "db.ts sets PRAGMA foreign_keys = ON",
"max_score": 8
},
{
"name": "Busy timeout set",
"description": "db.ts sets PRAGMA busy_timeout to a positive value",
"max_score": 6
},
{
"name": "Graceful shutdown",
"description": "db.close() called on SIGTERM/SIGINT",
"max_score": 6
},
{
"name": "Bulk import uses transaction",
"description": "The bulk task import wraps all inserts in a single db.transaction() call, NOT individual inserts without a transaction",
"max_score": 14
},
{
"name": "Prepared statement reuse in bulk",
"description": "The bulk import prepares the INSERT statement once and reuses it in the loop, not calling db.prepare() for each row",
"max_score": 8
},
{
"name": "Indexes on all foreign keys",
"description": "Explicit CREATE INDEX on tasks.project_id, tasks.assigned_to, and any other FK columns",
"max_score": 10
},
{
"name": "CHECK constraints on priority and status",
"description": "Priority column has CHECK (priority IN ('low','medium','high','urgent')) and status column has CHECK constraint",
"max_score": 7
},
{
"name": "Dates as TEXT ISO 8601",
"description": "Due dates and timestamps stored as TEXT, using datetime() or date() functions for defaults and queries",
"max_score": 7
},
{
"name": "Migration pattern",
"description": "Sequential migration pattern with tracking table",
"max_score": 6
},
{
"name": "Prepared statements throughout",
"description": "All queries use db.prepare() with ? placeholders, no string interpolation",
"max_score": 10
},
{
"name": "STRICT tables",
"description": "Tables created with STRICT keyword",
"max_score": 5
},
{
"name": "Money as INTEGER",
"description": "Estimated hours stored as INTEGER (minutes) or REAL if fractional hours are needed -- not as TEXT",
"max_score": 5
}
]
}