7ef332999e
The dashboard had generic BI views but nothing parking-shaped. Added: - Occupancy step-area over the range with the configured capacity as a red reference line. occupancyStart folds the ENTIRE prior ledger (voided entries excluded, clamped ≥0); each series point carries occupancyEnd. Answers "when are we near full". - Entries heatmap hour × day-of-week (7×24, row 0 = Monday, site tz) as a pure CSS-grid intensity map — weekday-vs-weekend at a glance, the direct evidence for tariff windows. Replaces the flat hour histogram (strictly contains it). - Stay-duration histogram at tariff-shaped edges (30m/1h/2h/4h/8h/24h/ tail): where ladder/up-to breakpoints should sit. - Voids + anomalies KPIs (accented when >0) — the look-closer counters the signed chain exists for; peak-occupancy KPI (peak / capacity). - Revenue bars stacked cash vs card (the drawer's money vs the bank's); CSV export gains cash, card, occupancy_end columns. Internals: localParts caches its Intl formatter per tz (was one new formatter per ledger row); @parking/db re-exports lt/gt. 5 new tests. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
23 lines
908 B
TypeScript
23 lines
908 B
TypeScript
import Database from "better-sqlite3";
|
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
import * as schema from "./schema.js";
|
|
|
|
export * from "./schema.js";
|
|
// Re-export the query helpers consumers need, so they don't depend on
|
|
// drizzle-orm directly (it's an implementation detail of this package).
|
|
export { eq, ne, and, or, asc, desc, gt, gte, lt, lte, isNull, isNotNull, inArray, sql } from "drizzle-orm";
|
|
|
|
/**
|
|
* Open the local SQLite database in WAL mode. WAL allows many concurrent readers
|
|
* plus one writer — a parking workload never approaches SQLite's single-writer
|
|
* limit. See wiki/entities/sqlite.md.
|
|
*/
|
|
export function createDb(url = process.env.DATABASE_URL ?? "./parking.sqlite") {
|
|
const sqlite = new Database(url);
|
|
sqlite.pragma("journal_mode = WAL");
|
|
sqlite.pragma("foreign_keys = ON");
|
|
return drizzle(sqlite, { schema });
|
|
}
|
|
|
|
export type Db = ReturnType<typeof createDb>;
|