refactor(repo): переход на pnpm monorepo с shadcn/ui и Fastify+Drizzle
Frontend:
- apps/web (Vite+TS, TanStack Router/Query, shadcn/ui @cfdm/ui base-nova)
- 10 страниц в routes/_auth/, Recharts через shadcn Chart, lucide-react
- формы на RHF + Zod (FormSheet/FormField)
- удалены Tabler, Chart.js, react-router-dom
Backend (параллельный трек):
- apps/api (Fastify 5 + Drizzle + better-sqlite3)
- packages/db: Drizzle-схема и repositories по сущностям
- packages/shared: Zod-контракты
- роуты с валидацией и единым форматом ошибок { error: { code, message } }
- sync/backup — заглушки 501 (billmanager-адаптеры переносятся отдельно)
- legacy Express оставлен как runtime по умолчанию (RUNTIME=express)
Infra:
- Dockerfile multi-stage под pnpm workspaces
- .dockerignore и docker-compose обновлены под monorepo
Rules:
- удалены нерелевантные правила (rust, cloudflare, server/frontend-conventions)
- project-structure.mdc и AGENTS.md переписаны под monorepo
- frontend-shadcn.mdc, shadcn-ui-production.mdc, sqlite.mdc обновлены
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Запуск синхронизации BILLmanager с записью в sync_log (для API и планировщика)
|
||||
*/
|
||||
|
||||
import { getDb } from './db.js'
|
||||
import { syncFromBillmanager } from './adapters/billmanager/index.js'
|
||||
|
||||
/**
|
||||
* @param {object} account - строка provider_accounts
|
||||
* @param {object} [opts] - { skipTariffs, skipVpsPayments }
|
||||
* @returns {Promise<object>} результат syncFromBillmanager + ok, logId
|
||||
*/
|
||||
export async function runBillmanagerAccountSync(account, opts = {}) {
|
||||
const db = getDb()
|
||||
const logId = `sync-${account.id}-${Date.now()}`
|
||||
db.prepare(`
|
||||
INSERT INTO sync_log (id, accountId, startedAt, status)
|
||||
VALUES (?, ?, ?, ?)
|
||||
`).run(logId, account.id, new Date().toISOString(), 'running')
|
||||
|
||||
try {
|
||||
const result = await syncFromBillmanager(account, db, opts)
|
||||
const summaryPayload = {
|
||||
...(result.syncSummary || {}),
|
||||
vpsCount: result.vpsCount,
|
||||
paymentsCount: result.paymentsCount,
|
||||
tariffsCount: result.tariffsCount ?? 0,
|
||||
}
|
||||
db.prepare(`
|
||||
UPDATE sync_log SET finishedAt=?, status=?, vpsCount=?, paymentsCount=?, summary=?
|
||||
WHERE id=?
|
||||
`).run(
|
||||
new Date().toISOString(),
|
||||
'ok',
|
||||
result.vpsCount,
|
||||
result.paymentsCount,
|
||||
JSON.stringify(summaryPayload),
|
||||
logId,
|
||||
)
|
||||
return { ok: true, logId, ...result }
|
||||
} catch (err) {
|
||||
db.prepare(`
|
||||
UPDATE sync_log SET finishedAt=?, status=?, error=?, summary=?
|
||||
WHERE id=?
|
||||
`).run(
|
||||
new Date().toISOString(),
|
||||
'error',
|
||||
err.message || 'Unknown error',
|
||||
JSON.stringify({ error: err.message || 'Unknown error' }),
|
||||
logId,
|
||||
)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user