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 <cursoragent@cursor.com>
46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
import { Router } from 'express'
|
|
import { getDb } from '../db.js'
|
|
import { rowToVps } from './vps.js'
|
|
import { rowToSettings } from './settings.js'
|
|
import { sanitizeAccount, rowToActiveTariff, rowToTariffSyncOptions } from '../utils/row-mappers.js'
|
|
|
|
const router = Router()
|
|
|
|
router.get('/', (req, res) => {
|
|
try {
|
|
const db = getDb()
|
|
const vps = db.prepare('SELECT * FROM vps ORDER BY createdAt DESC').all()
|
|
const providers = db.prepare('SELECT * FROM providers ORDER BY name').all()
|
|
const providerAccounts = db.prepare('SELECT * FROM provider_accounts ORDER BY name').all()
|
|
const payments = db.prepare('SELECT * FROM payments ORDER BY date DESC').all()
|
|
const balanceLedger = db.prepare('SELECT * FROM balance_ledger ORDER BY date DESC').all()
|
|
const settingsRows = db.prepare('SELECT * FROM settings ORDER BY id').all()
|
|
const activeTariffs = db.prepare('SELECT * FROM active_tariffs ORDER BY name').all()
|
|
const tariffSyncOptions = db.prepare('SELECT * FROM tariff_sync_options').all()
|
|
let serverProjects = []
|
|
try {
|
|
serverProjects = db
|
|
.prepare('SELECT id, name, color, sortOrder, notes, createdAt FROM server_projects ORDER BY name')
|
|
.all()
|
|
} catch {
|
|
serverProjects = []
|
|
}
|
|
|
|
res.json({
|
|
vps: vps.map(rowToVps),
|
|
serverProjects,
|
|
providers,
|
|
providerAccounts: providerAccounts.map(sanitizeAccount),
|
|
payments,
|
|
balanceLedger,
|
|
settings: settingsRows.map(rowToSettings),
|
|
activeTariffs: activeTariffs.map(rowToActiveTariff),
|
|
tariffSyncOptions: tariffSyncOptions.map(rowToTariffSyncOptions),
|
|
})
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message })
|
|
}
|
|
})
|
|
|
|
export default router
|