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 <cursoragent@cursor.com>
This commit is contained in:
1 parent
8408155be6
commit
6fbd1a9113
202 files changed
+16734
-12145
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import { queryClient } from '../lib/queryClient'
|
||||
import { api } from '../lib/api-client'
|
||||
|
||||
export const snapshotKeys = {
|
||||
all: ['snapshot'] as const,
|
||||
}
|
||||
|
||||
export const snapshotQueryOptions = () => ({
|
||||
queryKey: snapshotKeys.all,
|
||||
queryFn: () => api.fetchData(),
|
||||
staleTime: 30_000,
|
||||
})
|
||||
|
||||
export const ratesKeys = {
|
||||
all: ['rates'] as const,
|
||||
}
|
||||
|
||||
export const ratesQueryOptions = (ratesUrl?: string) => ({
|
||||
queryKey: ratesKeys.all,
|
||||
queryFn: async () => {
|
||||
if (!ratesUrl) return null
|
||||
const proxyUrl = `/api/rates-proxy?url=${encodeURIComponent(ratesUrl)}`
|
||||
try {
|
||||
const res = await fetch(proxyUrl)
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
||||
return await res.json()
|
||||
} catch {
|
||||
const direct = await fetch(ratesUrl)
|
||||
if (!direct.ok) throw new Error(`HTTP ${direct.status}`)
|
||||
return await direct.json()
|
||||
}
|
||||
},
|
||||
enabled: Boolean(ratesUrl),
|
||||
})
|
||||
|
||||
export const projectsKeys = {
|
||||
suggest: (q: string) => ['projects', 'suggest', q] as const,
|
||||
}
|
||||
|
||||
export const projectsSuggestQueryOptions = (q: string) => ({
|
||||
queryKey: projectsKeys.suggest(q),
|
||||
queryFn: () => api.fetchProjectSuggestions(q),
|
||||
enabled: q.length >= 2,
|
||||
})
|
||||
|
||||
export type SnapshotFromQuery = Awaited<ReturnType<typeof api.fetchData>>
|
||||
export { queryClient }
|
||||
Reference in new issue
Block a user