import { beforeEach, describe, expect, it } from "vitest"; import { appLogs, type Db } from "@parking/db"; import { createTestDb } from "@parking/db/testing"; import { LogService, pinoDbStream } from "./log-service.js"; // pinoDbStream feeds backend warn+ lines into app_logs. Since 2026-07-04 the logger // emits level NAMES ("warn") instead of pino's numeric codes (40) — for human-readable // container logs — and the stream must accept BOTH encodings (numeric covers any // default-configured pino). A level the tee can't resolve falls back to info → not // persisted, never a crash. let db: Db; let stream: { write: (line: string) => void }; let teed: string[]; beforeEach(() => { ({ db } = createTestDb()); teed = []; stream = pinoDbStream(new LogService(db), { write: (line: string) => { teed.push(line); return true; }, } as unknown as NodeJS.WritableStream); }); const rows = () => db.select().from(appLogs).all(); describe("pinoDbStream level encodings", () => { it("persists a LABEL-level warn line (the current logger format)", () => { stream.write(`{"level":"warn","time":"2026-07-04T18:14:11.453Z","msg":"label warn"}\n`); expect(rows()).toHaveLength(1); expect(rows()[0]).toMatchObject({ level: "warn", source: "backend", message: "label warn" }); }); it("still persists a NUMERIC-level error line (legacy/default pino)", () => { stream.write(`{"level":50,"time":1783179038453,"msg":"numeric error"}\n`); expect(rows()[0]).toMatchObject({ level: "error", message: "numeric error" }); }); it("info stays stdout-only in both encodings (teed, not persisted)", () => { stream.write(`{"level":"info","msg":"label info"}\n`); stream.write(`{"level":30,"msg":"numeric info"}\n`); expect(rows()).toHaveLength(0); expect(teed).toHaveLength(2); // stdout tee always happens }); it("an unresolvable level falls back to info (dropped), never throws", () => { stream.write(`{"level":"loud","msg":"weird"}\n`); stream.write(`not json at all\n`); expect(rows()).toHaveLength(0); expect(teed).toHaveLength(2); }); });