vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Мультитенантный аналитический сервис: синхронизирует данные YClients в PostgreSQL, отдаёт портал и продуктовые отчёты через FastAPI и обслуживает Vite-интерфейс. • Общий: положительные оплаты услуг завершённых визитов, товаров и пополнений личных счетов, делённые на сумму уникальных клиентов завершённых визитов, завершённых записей без клиента и уникальных товарных документов. • По услугам: оплаченные услуги / завершённые записи. • По товарам: оплаченные товары / количество проданных товарных единиц. • По допуслугам: оплаченные допуслуги / количество оказанных допуслуг.README 전문 보기 ↗
Мультитенантный аналитический сервис: синхронизирует данные YClients в PostgreSQL, отдаёт портал и продуктовые отчёты через FastAPI и обслуживает Vite-интерфейс.
Доход общего среднего чека относится к дате платежа, клиентская часть знаменателя — к дате визита. До подтверждённой синхронизации детализированных финансовых транзакций API возвращает average_check.source_status = "partial".
visit_metrics.opz_qty показывает количество ОПЗ, а opz_pct — долю от завершённых визитов. При одинаковых фильтрах итоговые opz_qty и opz_pct совпадают с фактом ОПЗ в «План/факт»; наличие плана у отдельных сотрудников не влияет на итог филиала или сети. Факт выбранного сотрудника также совпадает с его строкой в полном списке филиала: распределение ОПЗ между администраторами выполняется до применения фильтра сотрудника. Исключение — фильтр по администратору: расчётные ОПЗ в обзоре отнесены к барберу визита, а ручная добавка при фильтре по сотруднику не подмешивается ни в обзоре, ни в годовых фактах отчётов, поэтому строку администратора целиком показывает только «План/факт». Дневные поля opz_qty и opz_pct доступны в revenue_daily.POST /dashboard/plan/opz_fact) вводятся администраторам по месяцу и прибавляются к расчётным ОПЗ в обзоре, План/факте и годовых фактах отчётов; дневные opz_qty/opz_pct в revenue_daily остаются чисто расчётными, поэтому сумма дневного графика меньше плитки обзора на величину добавок. Месячная добавка засчитывается в периоде, который покрывает месяц целиком, либо доходит до сегодня, начинаясь не позже 1-го числа текущего месяца — одинаково в обзоре и в План/факте; прошедшая неделя и день в середине месяца идут по чистому расчёту.AGENTS.md.1–100; в PostgreSQL они продолжают храниться как доли 0–1.PATCH /dashboard/services: при ошибке любого элемента весь пакет откатывается.api.py - FastAPI-приложение: подключает роутеры портала и дашборда, health-пробы, постановка sync в очередь и статусauth_*.py - аутентификация, сессии, роли и скоуп доступа по филиаламonboarding_routes.py / yclients_credentials.py - онбординг и зашифрованные credentials YClientssync_pipeline.py - ETL pipeline YClients -> PostgreSQLsync_worker.py - worker, который обрабатывает queued sync jobsmain.py - ручной CLI-запуск синхронизацииmigrate.py - применение Alembic миграцийdashboard_service.py / dashboard_routes.py / dashboard_reports.py — агрегаты и отчёты продуктового дашборда (JSON)web/ - Vite MPA: дашборд, отчёты, auth, onboarding, settings и admindeploy/nginx/ - nginx на VM: таблица маршрутов API (routes.mjs), из неё scripts/nginx-allowlist.mjs генерирует api-allowlist.conf; static-headers.conf - заголовки безопасности статикиdocker-compose.yml - запуск api, worker и PostgreSQL (на VM); локальная разработка идёт без Dockersync.sh - ручной запуск one-shot sync через Docker ComposeКаталог web/ содержит Vite MPA: основной Chart.js dashboard/reports и отдельные страницы auth, onboarding, settings и admin. В локальной разработке Vite проксирует запросы в FastAPI; production-сборка раздаётся nginx на VM и ходит в API тем же origin под /api.
Ниже — запуск через Docker Compose. Повседневная локальная разработка идёт на полной копии
production-БД (./scripts/local-db-refresh.sh, PostgreSQL на 127.0.0.1:5433, без Docker) —
порядок описан в AGENTS.md, раздел «Локальная разработка на копии прода».
cp .env.example .env
Заполните минимум:
APP_ENV=local для локального запускаDB_PASSWORDSYNC_API_TOKENAUTH_JWT_SECRET длиной не менее 32 символовPORTAL_CREDENTIALS_ENCRYPTION_KEY длиной не менее 32 символовAUTH_COOKIE_SECURE=false и AUTH_CONSOLE_EMAIL=true для локального HTTP без SMTPУчётные данные YClients в .env не задаются: они сохраняются в зашифрованном виде через onboarding/admin.
docker compose run --rm migrate
docker compose up -d postgres api worker
После запуска будут доступны:
http://127.0.0.1:8000source scripts/dev-env.sh
cd web
npm ci
npm run dev
Frontend будет доступен на http://127.0.0.1:5173. Зарегистрируйте владельца через register.html; при локальном AUTH_CONSOLE_EMAIL=true ссылка подтверждения появится в логах API. Затем onboarding сохранит credentials, предложит выбрать филиалы и поставит начальную синхронизацию в очередь.
Проверка контейнеров:
docker compose ps
Ручной one-shot sync:
./sync.sh incremental manual cli
./sync.sh refresh manual cli # перечитать последние SYNC_REFRESH_DAYS с очисткой окна
./sync.sh full manual cli # то же по всей истории
Логи worker:
docker compose logs -f worker
Smoke check local API:
curl http://127.0.0.1:8000/health
Общий read-only демо-стенд с синтетическими данными — чтобы показывать дашборд
потенциальным клиентам без реальных данных YClients. Кнопка «View demo» на странице
входа делает беспарольный вход (POST /auth/demo-login) и открывает дашборд с
демо-баннером; любой запрос на запись под демо-сессией возвращает 403. Если стенд
не провижинен, /auth/demo-login отвечает 503 — кнопка показывает ошибку.
Демо живёт в основной базе как отдельный portal tenant:
PortalAccount(is_demo=True) с синтетическими филиалами source_type='demo'.
Это не отдельный сайт и не отдельная БД.
Создать или переиспользовать встроенный read-only демо-тенант:
python -m scripts.seed_demo
Скрипт можно запускать рядом с реальными tenant'ами: он создаёт только demo account, demo owner и demo companies. Реальные компании не удаляются и не перезаписываются.
source_type='demo' и активностью (клиенты, услуги, записи, продажи);PortalAccount(is_demo=True) и по одному PortalBranch на компанию;[email protected] (is_demo=True).Флаги seed_demo: --companies, --days, --seed, --clients-per-company,
--staff-per-company, --goods-per-company,
--appointments-per-day-min/--appointments-per-day-max.
Скрипт идемпотентен: повторный запуск переиспользует стенд и не перегенерирует данные.
seed_demo при наличии демо-данных пропускает генерацию, поэтому повторный запуск
не сдвигает даты. Чтобы обновить, удалите старые demo data в отдельной
maintenance-задаче и затем снова выполните python -m scripts.seed_demo.
Локальное окружение проекта уже содержит Python tooling и Node.js в .venv/bin
(dev-инструменты — pytest, ruff и т. д. — ставятся из requirements-dev.txt;
requirements.txt — только то, что нужно рантайму и Docker-образу).
Для ручных команд в текущем shell:
source scripts/dev-env.sh
node --version
npm --version
pytest --version
Быстрый гейт перед коммитом (ruff + syntax + fast pytest + gitleaks):
./scripts/preflight.sh
Security checks для CI и ручного triage:
./scripts/security-check.sh
./scripts/security-check.sh --strict
В .github/workflows/deploy-vm.yml перед деплоем обязательно проходят ruff check ., pytest
и frontend-проверки (npm test, scan:auth-tokens, build, scan:auth-build).
В CI отдельный workflow .github/workflows/security.yml запускает:
gitleaks остаётся в deploy workflow как full-history secrets gate;pip-audit и npm audit --audit-level=high делают коммит красным при известных уязвимостях, но деплой не блокируют:
deploy-vm.yml от security.yml не зависит;Semgrep и Checkov пока работают как report/SARIF checks для triage, чтобы не блокировать deploy на существующих IaC findings без явного suppressions review.pip-audit падает на любой известной Python vulnerability: у Python advisory
severity доступна не всегда, поэтому high/critical threshold применяется явно
только к npm audit.
Frontend audit — штатный npm audit --audit-level=high: любой high/critical в зависимостях
(включая dev) делает проверку красной. Allowlist исключений не ведётся; если понадобится первая suppression,
добавлять её отдельным решением после risk review.
Локальный ./scripts/security-check.sh --strict делает Semgrep/Checkov blocking намеренно:
это режим для ручной подготовки к ужесточению CI после triage.
Краткий разбор последнего sync-лога (top slowest шаги + ошибки):
python scripts/sync-log-summary.py # последний лог
python scripts/sync-log-summary.py --last 5 # сводка по последним 5 запускам
Постановка sync-джобы без ручного curl (авто-читает .env):
python scripts/enqueue-sync.py --tenant 1 --mode incremental
python scripts/enqueue-sync.py --tenant 1 --mode refresh # перечитать последние SYNC_REFRESH_DAYS
python scripts/enqueue-sync.py --global --mode full --dry-run # печатает curl
python scripts/enqueue-sync.py --status # текущий статус
Полная проверка backend + frontend build:
./scripts/check.sh
Локальные unit/API тесты:
./scripts/check.sh tests/test_sync_parsing.py tests/test_api.py tests/test_dashboard_api.py
Postgres integration tests:
TEST_DATABASE_URL=postgresql+psycopg2://postgres:[email protected]:5432/yclients_test \
./scripts/check.sh tests/test_postgres_integration.py
system.* таблицы состояния и истории запусков сохраняются отдельно