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>
30 lines
1.3 KiB
JavaScript
30 lines
1.3 KiB
JavaScript
/**
|
|
* BILLmanager: URL и тип API задаются на хостере (providers), учётные данные — на аккаунте.
|
|
* Поддержка fallback на поля аккаунта для старых данных до миграции.
|
|
*/
|
|
|
|
/**
|
|
* @param {object|null|undefined} accountRow
|
|
* @param {object|null|undefined} providerRow
|
|
* @returns {{ apiType: string, apiBaseUrl: string }}
|
|
*/
|
|
export function resolveBillmanagerApi(accountRow, providerRow) {
|
|
const apiType = String(providerRow?.apiType || accountRow?.apiType || '').trim()
|
|
const apiBaseUrl = String(providerRow?.apiBaseUrl || accountRow?.apiBaseUrl || '').trim()
|
|
return { apiType, apiBaseUrl }
|
|
}
|
|
|
|
/**
|
|
* Объект аккаунта с подставленным URL для syncFromBillmanager / balance.
|
|
* @param {object} accountRow
|
|
* @param {object|null|undefined} providerRow
|
|
* @returns {object|null} null если не готово к запросам API
|
|
*/
|
|
export function billmanagerAccountRowForSync(accountRow, providerRow) {
|
|
if (!accountRow) return null
|
|
const { apiType, apiBaseUrl } = resolveBillmanagerApi(accountRow, providerRow)
|
|
const cred = String(accountRow.apiCredentials || '').trim()
|
|
if (apiType !== 'billmanager' || !apiBaseUrl || !cred) return null
|
|
return { ...accountRow, apiType: 'billmanager', apiBaseUrl }
|
|
}
|