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,51 @@
|
||||
import { desc, eq } from 'drizzle-orm'
|
||||
import { getDb, schema } from '../index.js'
|
||||
import { generateId } from './utils.js'
|
||||
|
||||
type Row = typeof schema.balanceLedger.$inferSelect
|
||||
type Insert = Partial<typeof schema.balanceLedger.$inferInsert> & {
|
||||
type: string
|
||||
date: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
function normalize(input: Partial<Row>) {
|
||||
return {
|
||||
type: input.type ?? '',
|
||||
date: input.date ?? '',
|
||||
amount: Number(input.amount) || 0,
|
||||
currency: input.currency ?? '',
|
||||
direction: input.direction ?? '',
|
||||
providerAccountId: input.providerAccountId ?? '',
|
||||
vpsId: input.vpsId ?? '',
|
||||
note: input.note ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export const balanceLedgerRepository = {
|
||||
list(): Row[] {
|
||||
return getDb().select().from(schema.balanceLedger).orderBy(desc(schema.balanceLedger.date)).all()
|
||||
},
|
||||
get(id: string): Row | undefined {
|
||||
return getDb().select().from(schema.balanceLedger).where(eq(schema.balanceLedger.id, id)).get()
|
||||
},
|
||||
create(input: Insert, id?: string): Row {
|
||||
const finalId = id ?? input.id ?? generateId('ledger')
|
||||
getDb().insert(schema.balanceLedger).values({ id: finalId, ...normalize(input) }).run()
|
||||
return this.get(finalId)!
|
||||
},
|
||||
update(id: string, input: Partial<Row>): Row | undefined {
|
||||
const existing = this.get(id)
|
||||
if (!existing) return undefined
|
||||
getDb()
|
||||
.update(schema.balanceLedger)
|
||||
.set(normalize({ ...existing, ...input }))
|
||||
.where(eq(schema.balanceLedger.id, id))
|
||||
.run()
|
||||
return this.get(id)
|
||||
},
|
||||
delete(id: string): boolean {
|
||||
const r = getDb().delete(schema.balanceLedger).where(eq(schema.balanceLedger.id, id)).run()
|
||||
return r.changes > 0
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user