f27eb3a102
PR #27 включил transpileOnly через "ts-node" блок в tsconfig.json для ускорения cold-start dev. Это сломало TypeORM на старте: DataTypeNotSupportedError: Data type "Object" in "TokenEntity.type" is not supported by "postgres" database. Корень: transpileOnly режим ts-node использует ts.transpileModule, один файл за раз без TypeChecker. Cross-file type aliases — типа `import type { TokenType } from '~/types/token.types'` где `TokenType = (typeof tokenTypes)[keyof typeof tokenTypes]` — без type-checker'а **не резолвятся**. design:type metadata для `@Column() type!: TokenType` записывается как `Object` вместо `String`. TypeORM пытается создать колонку Object → unsupported. Проблема структурная: множество TypeORM Entity в controller'е используют `import type {SomeAlias}` + `@Column() field: SomeAlias`, полагаясь на полный type-resolve в metadata-emit. Без явного `type:` в каждом @Column переход на transpileOnly / SWC невозможен. Возвращаемся к полному ts-node (cold-start 60+ сек, как было до PR #27). @swc/core / @swc-node/register остаются в devDeps — безвредны, не используются. Smoke-suite tests/unit/_swc-readiness/ остаётся как regression-net для будущих попыток (тестирует emitDecoratorMetadata инвариант). Будущий путь к ускорению (отдельная задача): 1. Пройтись по всем TypeORM Entity, добавить explicit type: в каждый @Column — снимет зависимость от cross-file metadata. 2. ИЛИ перевести TokenType-подобные type-aliases в enum (value- import) — runtime binding позволит metadata эмититься корректно. 3. Тогда transpileOnly / SWC заработают без regressions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🎛️ @coopenomics/controller
Основной бэкенд-сервис платформы «Цифровой Кооператив». GraphQL API на NestJS с чистой архитектурой — обрабатывает все запросы от рабочего стола, управляет кооперативными процессами, генерирует документы и взаимодействует с блокчейном EOSIO.
Основные возможности
- GraphQL API для всех операций платформы
- Чистая архитектура: domain → infrastructure → modules
- Управление пайщиками, кошельками и финансовыми операциями
- Электронный документооборот с ЭП через блокчейн
- Система расширений (extensions) для модульного подключения функциональности
- Платёжный шлюз с поддержкой нескольких провайдеров
- JWT-аутентификация и авторизация
- Миграции данных через TypeORM
- Интеграция с Novu для уведомлений и LiveKit для видеоконференций
Установка
Компонент является частью монорепозитория. Установка зависимостей из корня проекта:
pnpm install
Или только для этого компонента:
pnpm install --filter @coopenomics/controller
Скрипты
| Скрипт | Команда | Описание |
|---|---|---|
dev |
pnpm run dev |
Запуск в режиме разработки (nodemon + ts-node) |
start |
pnpm run start |
Запуск в production-режиме |
lint |
pnpm run lint |
Проверка кода (ESLint) |
lint:fix |
pnpm run lint:fix |
Автоисправление lint-ошибок |
typecheck |
pnpm run typecheck |
Проверка типов TypeScript |
migration:generate |
pnpm run migration:generate |
Генерация новой миграции |
migration:run |
pnpm run migration:run |
Применение всех миграций |
migration:status |
pnpm run migration:status |
Текущий статус миграций |
migration:rollback |
pnpm run migration:rollback |
Откат миграций |
migration:list |
pnpm run migration:list |
Список всех миграций |
docs |
pnpm run docs |
Генерация документации API (SpectaQL) |
Конфигурация
Скопируйте .env-example в .env и настройте переменные окружения:
- Строки подключения к MongoDB, реляционной БД, Redis
- Endpoint блокчейн-ноды и
CHAIN_ID VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY— ключи для push-уведомлений- Настройки JWT-аутентификации
- Конфигурация платёжных провайдеров
- Настройки Sentry для мониторинга ошибок
Подробное описание переменных — в файле .env-example.
Тестирование
Интеграционные тесты выполняются через компонент @coopenomics/boot, который разворачивает полную инфраструктуру:
pnpm --filter @coopenomics/boot run test
Архитектура
Проект следует принципам чистой архитектуры с направлением зависимостей внутрь (к домену):
src/
├── domain/ # Доменный слой (бизнес-логика)
│ ├── account/ # Аккаунты пользователей
│ ├── agreement/ # Соглашения
│ ├── auth/ # Аутентификация
│ ├── blockchain/ # Интерфейсы блокчейна
│ ├── branch/ # Кооперативные участки
│ ├── capital/ # Паевые взносы
│ ├── cooplace/ # Маркетплейс
│ ├── document/ # Документооборот
│ ├── extension/ # Расширения
│ ├── gateway/ # Платёжный шлюз
│ ├── ledger/ # Бухгалтерский учёт
│ ├── meet/ # Собрания
│ ├── participant/ # Участники кооператива
│ ├── registration/ # Регистрация
│ ├── wallet/ # Кошельки
│ └── common/ # Общие порты и репозитории
├── infrastructure/ # Инфраструктурный слой (адаптеры)
│ ├── blockchain/ # Адаптер блокчейна EOSIO
│ ├── database/ # Адаптеры БД (Mongoose, TypeORM)
│ └── external/ # Внешние сервисы
├── modules/ # Прикладной слой (NestJS-модули)
│ ├── auth/ # Модуль аутентификации
│ ├── cooperative/ # Модуль кооператива
│ └── ... # Остальные модули
└── extensions/ # Система подключаемых расширений
├── extensions.registry.ts
└── base.extension.module.ts
migrations/ # Миграции данных (TypeORM)
Поток данных
- Резолвер принимает входные данные и передаёт в сервис
- Сервис вызывает интерактор домена, передавая DTO (реализующие доменный интерфейс)
- Интерактор выполняет бизнес-логику и взаимодействует с портами
- Адаптеры (инфраструктура) преобразуют доменные объекты в формат внешних систем
- Результаты возвращаются обратно по цепочке
Ключевые зависимости
- @nestjs/* — фреймворк бэкенда
- graphql / @nestjs/graphql — GraphQL API
- mongoose — MongoDB ODM
- typeorm — реляционный ORM с миграциями
- eosjs — взаимодействие с блокчейном EOSIO
- ioredis — Redis-клиент
- @novu/api — сервис уведомлений
- livekit-server-sdk — видеоконференции
- winston — логирование