feat: add app_config table with runtime log level control and POS structured logging
- New app_config key-value table for system settings, with in-memory cache (mirrors ModuleService pattern) - GET/PATCH /v1/config endpoints for reading and updating config (settings.view/settings.edit permissions) - Runtime log level: PATCH /v1/config/log_level applies immediately, persists across restarts - Startup loads log level from DB in onReady hook (env var is default, DB overrides) - Add structured request.log.info() to POS routes: transaction create/complete/void, drawer open/close, discount create/update/delete Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
46
packages/backend/src/services/config.service.ts
Normal file
46
packages/backend/src/services/config.service.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
|
||||
import { appConfig } from '../db/schema/stores.js'
|
||||
|
||||
let configCache: Map<string, string | null> | null = null
|
||||
|
||||
export const AppConfigService = {
|
||||
async getAll(db: PostgresJsDatabase<any>) {
|
||||
return db.select().from(appConfig)
|
||||
},
|
||||
|
||||
async get(db: PostgresJsDatabase<any>, key: string): Promise<string | null> {
|
||||
if (!configCache) await this.refreshCache(db)
|
||||
return configCache!.get(key) ?? null
|
||||
},
|
||||
|
||||
async set(db: PostgresJsDatabase<any>, key: string, value: string | null, description?: string) {
|
||||
const [existing] = await db.select().from(appConfig).where(eq(appConfig.key, key)).limit(1)
|
||||
|
||||
if (existing) {
|
||||
const [updated] = await db
|
||||
.update(appConfig)
|
||||
.set({ value, updatedAt: new Date(), ...(description !== undefined ? { description } : {}) })
|
||||
.where(eq(appConfig.key, key))
|
||||
.returning()
|
||||
configCache = null
|
||||
return updated
|
||||
}
|
||||
|
||||
const [inserted] = await db
|
||||
.insert(appConfig)
|
||||
.values({ key, value, description, updatedAt: new Date() })
|
||||
.returning()
|
||||
configCache = null
|
||||
return inserted
|
||||
},
|
||||
|
||||
async refreshCache(db: PostgresJsDatabase<any>) {
|
||||
const rows = await db.select({ key: appConfig.key, value: appConfig.value }).from(appConfig)
|
||||
configCache = new Map(rows.map((r) => [r.key, r.value]))
|
||||
},
|
||||
|
||||
invalidateCache() {
|
||||
configCache = null
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user