feat(api): /api/lead с SQLite и миграциями
db/: better-sqlite3 по DB_PATH (WAL, foreign_keys), миграции через PRAGMA user_version, схема leads и lead_clarifications по плану. createApp(deps) с инъекцией базы, часов и notifier (пока no-op, зовётся после ответа). POST /api/lead: только JSON (415), тело до 16 КБ (413), validateLead → 400, запись → 201. index.ts: env и graceful shutdown.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import type { ValidLead } from '@kvarta/shared/lead';
|
||||
import type { Db } from './db/index.js';
|
||||
import type { LeadEvent } from './notifier.js';
|
||||
|
||||
export type SaveMeta = { now: Date; userAgent: string | null };
|
||||
|
||||
export type SaveResult = { kind: 'created'; event: LeadEvent };
|
||||
|
||||
export function saveLead(db: Db, lead: ValidLead, meta: SaveMeta): SaveResult {
|
||||
const { lastInsertRowid } = db
|
||||
.prepare(
|
||||
`INSERT INTO leads (created_at, phone, name, interest, comment, first_touch, last_touch, user_agent)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.run(
|
||||
meta.now.toISOString(),
|
||||
lead.phone,
|
||||
lead.name,
|
||||
lead.interest,
|
||||
lead.comment,
|
||||
lead.firstTouch ? JSON.stringify(lead.firstTouch) : null,
|
||||
JSON.stringify(lead.lastTouch),
|
||||
meta.userAgent,
|
||||
);
|
||||
return { kind: 'created', event: { kind: 'lead', leadId: Number(lastInsertRowid) } };
|
||||
}
|
||||
Reference in New Issue
Block a user