This commit is contained in:
Alex Ant
2025-09-27 17:58:04 +05:00
parent 007836f52e
commit 26b818c9a6
182 changed files with 5172 additions and 217 deletions
@@ -28,7 +28,7 @@ void capital::approvereg(eosio::name coopname, checksum256 contributor_hash, doc
eosio::check(contributor != contributors.end(), "Пайщик не зарегистрирован в контракте");
// Обновляем пайщика и устанавливаем принятый договор УХД
contributors.modify(contributor, coopname, [&](auto &c){
contributors.modify(contributor, payer, [&](auto &c){
c.status = Capital::Contributors::Status::ACTIVE;
c.contract = contract;
});
@@ -0,0 +1,247 @@
---
description: Правила работы с пагинацией в контроллере
alwaysApply: false
---
# Правила работы с пагинацией в Controller
## Общие принципы
**Всегда используйте доменные интерфейсы пагинации** вместо примитивных типов (`skip`, `take`, `limit`, `offset`).
Расчет общего количества записей **всегда** производится через `count()` в репозитории.
## Архитектурные слои и интерфейсы
### 1. DTO слой (GraphQL)
```typescript
// Входные параметры от клиента
PaginationInputDTO {
page: number; // Номер страницы (начиная с 1)
limit: number; // Количество элементов на странице
sortBy?: string; // Поле сортировки
sortOrder: 'ASC' | 'DESC'; // Направление сортировки
}
// Результат для клиента
PaginationResult<T> {
items: T[]; // Элементы текущей страницы
totalCount: number; // Общее количество элементов
totalPages: number; // Общее количество страниц
currentPage: number; // Текущая страница
}
```
### 2. Домен слой
```typescript
// Входные параметры для домена
PaginationInputDomainInterface {
page: number;
limit: number;
sortBy?: string;
sortOrder: 'ASC' | 'DESC';
}
// Результат из домена
PaginationResultDomainInterface<T> {
items: T[];
totalCount: number;
totalPages: number;
currentPage: number;
}
```
## Поток данных
### В Resolver (GraphQL слой)
```typescript
// Создание GraphQL типа для пагинированного результата
const paginatedEntitiesResult = createPaginationResult(EntityDTO, 'PaginatedEntities');
@Query(() => paginatedEntitiesResult)
async getEntities(
@Args('filter') filter?: FilterDTO,
@Args('options') options?: PaginationInputDTO
): Promise<PaginationResult<EntityDTO>> {
// Преобразование в доменный интерфейс
const domainOptions: PaginationInputDomainInterface | undefined = options
? {
page: options.page,
limit: options.limit,
sortBy: options.sortBy,
sortOrder: options.sortOrder,
}
: undefined;
// Вызов сервиса
const result = await this.service.getEntities(filter, domainOptions);
// DTO готовится в сервисе, резолвер проксирует результат
return result;
}
```
### В Service (Прикладной слой)
```typescript
async getEntities(
filter?: FilterDTO,
options?: PaginationInputDomainInterface
): Promise<PaginationResult<EntityDTO>> {
// Получение результата из домена
const domainResult = await this.interactor.getEntities(filter, options);
// Преобразование доменных сущностей в DTO
const items = domainResult.items.map(item => this.mapToDTO(item));
// Возврат полного пагинированного результата с DTO
return {
items,
totalCount: domainResult.totalCount,
totalPages: domainResult.totalPages,
currentPage: domainResult.currentPage,
};
}
```
### В Interactor/UseCase (Домен слой)
```typescript
async getEntities(
filter?: DomainFilter,
options?: PaginationInputDomainInterface
): Promise<PaginationResultDomainInterface<DomainEntity>> {
// Вызов репозитория
return await this.repository.findAllPaginated(filter, options);
}
```
### В Repository (Инфраструктурный слой)
```typescript
async findAllPaginated(
filter?: Filter,
options?: PaginationInputDomainInterface
): Promise<PaginationResultDomainInterface<Entity>> {
// 1. Валидация параметров
const validatedOptions = options
? PaginationUtils.validatePaginationOptions(options)
: { page: 1, limit: 10, sortOrder: 'ASC' };
// 2. Получение SQL параметров
const { limit, offset } = PaginationUtils.getSqlPaginationParams(validatedOptions);
// 3. Подсчет общего количества (ОБЯЗАТЕЛЬНО!)
const totalCount = await this.repository.count({ where });
// 4. Получение данных с пагинацией
const entities = await this.repository.find({
where,
skip: offset,
take: limit,
order: orderBy,
});
// 5. Преобразование в доменные сущности
const items = entities.map(entity => this.mapper.toDomain(entity));
// 6. Создание результата через утилиту
return PaginationUtils.createPaginationResult(items, totalCount, validatedOptions);
}
```
## GraphQL типы пагинации
Для создания GraphQL типов пагинированных результатов используйте `createPaginationResult`:
```typescript
import { createPaginationResult } from '~/application/common/dto/pagination.dto';
// Создание GraphQL типа для пагинированного результата
const paginatedEntitiesResult = createPaginationResult(EntityDTO, 'PaginatedEntities');
// Использование в резолвере
@Query(() => paginatedEntitiesResult)
async getEntities(...) : Promise<PaginationResult<EntityDTO>>
```
Функция `createPaginationResult` создает GraphQL DTO тип для пагинированного ответа, но не готовит сами данные.
## Утилиты пагинации
Используйте `PaginationUtils` для стандартных операций:
```typescript
import { PaginationUtils } from '~/shared/utils/pagination.utils';
// Валидация параметров
const validatedOptions = PaginationUtils.validatePaginationOptions(options);
// Получение SQL параметров (limit, offset)
const { limit, offset } = PaginationUtils.getSqlPaginationParams(options);
// Создание результата пагинации
const result = PaginationUtils.createPaginationResult(items, totalCount, options);
```
## Валидация параметров
- `page >= 1` - номер страницы должен быть положительным
- `1 <= limit <= 1000` - ограничение на количество элементов
- `sortOrder` должен быть `'ASC'` или `'DESC'`
## Запрещенные паттерны
❌ **НЕ ПРАВИЛЬНО:**
```typescript
// Не используйте примитивные типы
async getApprovals(filter?: Filter, skip = 0, take = 50)
// Не рассчитывайте пагинацию вручную
const totalPages = Math.ceil(totalCount / limit); // Делайте это в утилите
// Не возвращайте сырые данные без пагинации
return await this.repository.findAll(); // Всегда используйте пагинацию
```
✅ **ПРАВИЛЬНО:**
```typescript
// Сервис возвращает полный пагинированный результат с DTO
async getApprovals(
filter?: ApprovalFilterInput,
options?: PaginationInputDomainInterface
): Promise<PaginationResult<ApprovalDTO>> {
// Получение доменного результата
const domainResult = await this.repository.findAllPaginated(filter, options);
// Преобразование в DTO
const items = domainResult.items.map(item => this.toDTO(item));
// Возврат полного результата
return {
items,
totalCount: domainResult.totalCount,
totalPages: domainResult.totalPages,
currentPage: domainResult.currentPage,
};
}
// Резолвер проксирует результат от сервиса
@Query(() => paginatedApprovalsResult)
async getApprovals(filter, options): Promise<PaginationResult<ApprovalDTO>> {
return await this.service.getApprovals(filter, domainOptions);
}
```
## Ключевые моменты
1. **DTO готовится в Service** - сервис получает доменные сущности и преобразует их в DTO перед возвратом
2. **GraphQL типы создаются через createPaginationResult** - это создает схему GraphQL, а не данные
3. **Резолвер проксирует результат** - резолвер просто вызывает сервис и возвращает результат
4. **Полный пагинированный результат** - всегда возвращается PaginationResult<T> с items, totalCount, totalPages, currentPage
## Примеры из кода
- ✅ `ApprovalService` - правильная реализация с полным PaginationResult
- ✅ `InvestsManagementService` - прямое преобразование Domain → DTO в сервисе
- ✅ `TimeTrackingService` - явное преобразование полей в DTO
- ✅ `InvestTypeormRepository` - полная реализация с валидацией через PaginationUtils
@@ -1,6 +1,6 @@
---
alwaysApply: true
globs: **/desktop/**
alwaysApply: false
---
# DESKTOP
@@ -0,0 +1,30 @@
---
alwaysApply: false
globs: **/controller/**/*.resolver.ts
---
## 📋 Правила формирования агрегатов документов
### 📝 **В сервисах**
1. **Инжект DocumentAggregationService** в конструктор сервиса
2. **Создай async метод toDTO** для преобразования доменных сущностей в DTO
3. **Вызывай buildDocumentAggregate()** для поля документа:
```typescript
const document = await this.documentAggregationService.buildDocumentAggregate(entity.documentField);
```
4. **Добавь поле document в возвращаемый объект**
### 🎯 **В DTO**
1. **Импорт DocumentAggregateDTO**
2. **Добавь поле document** с типом `DocumentAggregateDTO | null`
3. **nullable: true** в GraphQL декораторе
### 🔄 **В резолверах**
- **Ничего не меняй** - резолверы автоматически получают DTO с полем document
### ⚡ **Чек-лист**
- ✅ DocumentAggregationService инжектирован
- ✅ Метод toDTO стал async
- ✅ Все вызовы toDTO стали await
- ✅ Поле document добавлено в DTO
- ✅ Импорт DocumentAggregateDTO добавлен
- ✅ Тип поля корректный (DocumentAggregateDTO | null)
@@ -0,0 +1,112 @@
---
description: Правила работы с двойными подписями документов
globs:
alwaysApply: true
---
# Правила работы с двойными подписями документов
## Общая концепция
Двойная подпись означает, что документ подписывается двумя разными участниками процесса. Каждая подпись имеет свой уникальный идентификатор (`signatureId`).
## Типы документов
### IDocumentAggregate
Структура агрегата документа, содержащая:
- `document`: `SignedDigitalDocument` - подписанный документ с подписями
- `hash`: `string` - хеш документа
- `rawDocument`: `GeneratedDocument` - сырой (неподписанный) документ, необходимый для генерации новых подписей
### SignedDigitalDocument
Подписанный документ, содержащий:
- `doc_hash`: хеш содержимого
- `hash`: общий хеш
- `meta`: метаданные документа
- `meta_hash`: хеш метаданных
- `signatures`: массив подписей
- `version`: версия стандарта
### ZGeneratedDocument (из cooptypes)
Базовый документ для подписи:
- `full_title`: полное название
- `html`: HTML содержимое
- `hash`: хеш документа
- `meta`: метаданные
- `binary`: бинарные данные (Uint8Array или string)
## Процесс двойной подписи
### 1. Подготовка данных
Для добавления второй подписи к документу необходимо иметь:
- `rawDocument` (ZGeneratedDocument) - базовый документ без подписей
- `existingSignedDocuments` - массив уже существующих подписанных документов
### 2. Вызов signDocument
```typescript
const doubleSignedDocument = await signDocument(
rawDocument, // ZGeneratedDocument - базовый документ
username, // string - имя пользователя, подписывающего документ
2, // signatureId - идентификатор подписи (2 для второй)
[existingDocument] // existingSignedDocuments - массив существующих подписей
);
```
### 3. Параметры signDocument
- **document**: `ZGeneratedDocument` - базовый документ (обязательно `rawDocument` из `IDocumentAggregate`)
- **account**: `string` - имя аккаунта подписанта
- **signatureId**: `number` - идентификатор подписи:
- `1` - первая подпись
- `2` - вторая подпись
- `3` - третья подпись (если необходимо)
- **existingSignedDocuments**: `ISignedDocument2[]` - массив документов с существующими подписями
## Пример реализации
```typescript
export function useConfirmApproval() {
const { signDocument } = useSignDocument();
const { username } = useSessionStore();
const confirmApproval = async (
coopname: string,
approved_document: IDocumentAggregate
): Promise<IConfirmApprovalOutput> => {
if (!approved_document.rawDocument) {
throw new Error('Документ не найден');
}
// Подписываем документ второй подписью
const doubleSignedDocument = await signDocument(
approved_document.rawDocument, // ZGeneratedDocument
username, // string
2, // signatureId для второй подписи
[approved_document.document], // existingSignedDocuments
);
// Отправляем документ с двойной подписью
return await api.confirmApproval({
coopname,
approval_hash: approved_document.hash,
approved_document: doubleSignedDocument,
});
};
return { confirmApproval };
}
```
## Важные замечания
1. **rawDocument обязателен** - без него невозможно добавить новую подпись
2. **signatureId должен быть уникальным** - каждая подпись имеет свой идентификатор
3. **existingSignedDocuments** - содержит все предыдущие подписи документа
4. **Типизация** - строго следить за типами `IDocumentAggregate`, `ZGeneratedDocument`, `SignedDigitalDocument`
5. **Session Store** - использовать `useSessionStore().username` для получения имени подписанта
## Распространенные ошибки
- Попытка подписать `SignedDigitalDocument` напрямую (нужен `ZGeneratedDocument`)
- Отсутствие `rawDocument` в `IDocumentAggregate`
- Неправильный `signatureId` (не уникальный)
- Отсутствие `existingSignedDocuments` при добавлении второй подписи
@@ -0,0 +1,130 @@
---
description: Правила работы с одинарными подписями документов
globs:
alwaysApply: true
---
# Правила работы с одинарными подписями документов
## Общая концепция
Одинарная подпись означает, что документ подписывается одним участником процесса. Подпись имеет идентификатор `signatureId = 1` (по умолчанию).
## Типы документов
### ZGeneratedDocument (из cooptypes)
Базовый документ для подписи:
- `full_title`: полное название
- `html`: HTML содержимое
- `hash`: хеш документа
- `meta`: метаданные
- `binary`: бинарные данные (Uint8Array или string)
### SignedDigitalDocument
Подписанный документ, содержащий:
- `doc_hash`: хеш содержимого
- `hash`: общий хеш
- `meta`: метаданные документа
- `meta_hash`: хеш метаданных
- `signatures`: массив подписей
- `version`: версия стандарта
## Способ подписания документа
### Использование useSignDocument
```typescript
const { signDocument } = useSignDocument();
const signedDocument = await signDocument(
document, // ZGeneratedDocument - базовый документ
account, // string - имя пользователя, подписывающего документ
1, // signatureId - идентификатор подписи (1 для первой/единственной)
);
```
## Параметры для подписания
- **document**: `ZGeneratedDocument` - базовый документ, полученный после генерации
- **account**: `string` - имя аккаунта подписанта (обычно `useSessionStore().username`)
- **signatureId**: `number` - идентификатор подписи (для одинарной подписи всегда `1`)
## Примеры реализации
### Пример 1: Голосование на собрании
```typescript
export const useVoteOnMeet = () => {
const { signDocument } = useSignDocument();
const sessionStore = useSessionStore();
const vote = async (input: IVoteOnMeetInput): Promise<void> => {
// Генерируем бюллетень для голосования
const generatedBallot = await generateBallot({
coopname: input.coopname,
username: sessionStore.username,
meet_hash: input.meetHash,
answers: input.answers,
});
// Подписываем бюллетень одинарной подписью
const signedBallot = await signDocument(
generatedBallot, // ZGeneratedDocument
sessionStore.username, // string
1, // signatureId = 1
);
// Отправляем подписанный бюллетень
await api.voteOnMeet({
...input,
ballot: signedBallot,
});
};
return { vote };
};
```
### Пример 2: Подписание соглашения
```typescript
export const useSignAgreement = () => {
const { signDocument } = useSignDocument();
const { info } = useSystemStore();
const { username } = useSessionStore();
const signAgreement = async (agreement_type: string, agreement: ZGeneratedDocument) => {
// Подписываем документ одинарной подписью
const signedDocument = await signDocument(
agreement, // ZGeneratedDocument
username, // string
1, // signatureId = 1
);
// Отправляем подписанное соглашение
await api.sendAgreement({
coopname: info.coopname,
administrator: info.coopname,
username,
agreement_type,
document: {...signedDocument, meta: JSON.stringify(signedDocument.meta)}
});
};
return { signAgreement };
};
```
## Важные замечания
1. **Генерация документа обязательна** - перед подписью документ должен быть сгенерирован через фабрику документов
2. **signatureId = 1** - для одинарной подписи всегда используется идентификатор `1`
3. **Session Store** - использовать `useSessionStore().username` для получения имени подписанта
4. **Ключ подписи** - должен быть установлен в Global Store (`wif` ключ)
## Распространенные ошибки
- Попытка подписать документ без предварительной генерации
- Использование неправильного `signatureId` (не 1 для одинарной подписи)
- Отсутствие приватного ключа в Global Store
- Попытка подписать уже подписанный документ (для одинарной подписи использовать только свежесгенерированные документы)
+151 -19
View File
@@ -690,6 +690,88 @@ input AnswerInput {
vote: String!
}
"""Одобрение документа председателем совета"""
type Approval {
"""Дата создания записи"""
_created_at: DateTime!
"""Внутренний ID базы данных"""
_id: String!
"""Дата последнего обновления записи"""
_updated_at: DateTime!
"""Хеш одобрения для идентификации"""
approval_hash: String!
"""Одобренный документ (заполняется при подтверждении одобрения)"""
approved_document: DocumentAggregate
"""Номер блока крайней синхронизации с блокчейном"""
block_num: Float
"""Действие обратного вызова при одобрении"""
callback_action_approve: String!
"""Действие обратного вызова при отклонении"""
callback_action_decline: String!
"""Контракт обратного вызова для обработки результата"""
callback_contract: String!
"""Название кооператива"""
coopname: String!
"""Дата создания одобрения"""
created_at: DateTime!
"""Документ, требующий одобрения"""
document: DocumentAggregate
"""ID одобрения в блокчейне"""
id: Float
"""Метаданные одобрения в формате JSON"""
meta: String!
"""Флаг присутствия записи в блокчейне"""
present: Boolean!
"""Статус одобрения"""
status: ApprovalStatus!
"""Имя пользователя, запросившего одобрение"""
username: String!
}
"""Фильтр для поиска одобрений"""
input ApprovalFilter {
"""Поиск по хешу одобрения"""
approval_hash: String
"""Фильтр по названию кооператива"""
coopname: String
"""Фильтр по дате создания (от)"""
created_from: DateTime
"""Фильтр по дате создания (до)"""
created_to: DateTime
"""Фильтр по статусам одобрений"""
statuses: [ApprovalStatus!]
"""Фильтр по имени пользователя"""
username: String
}
"""Статус одобрения в системе CHAIRMAN"""
enum ApprovalStatus {
APPROVED
DECLINED
PENDING
}
input AssetContributionActGenerateDocumentInput {
"""Идентификатор акта"""
act_id: String!
@@ -1379,70 +1461,70 @@ type CapitalContributor {
_updated_at: DateTime!
"""Приложения к контракту"""
appendixes: [String!]
appendixes: [String!]!
"""Номер блока последнего обновления"""
block_num: Int
"""Номер блока крайней синхронизации с блокчейном"""
block_num: Float
"""Статус из блокчейна"""
blockchain_status: String
blockchain_status: String!
"""Контракт вкладчика"""
contract: DocumentAggregate
"""Вклад как автор"""
contributed_as_author: Float
contributed_as_author: String!
"""Вклад как вкладчик"""
contributed_as_contributor: Float
contributed_as_contributor: String!
"""Вклад как координатор"""
contributed_as_coordinator: Float
contributed_as_coordinator: String!
"""Вклад как создатель"""
contributed_as_creator: Float
contributed_as_creator: String!
"""Вклад как инвестор"""
contributed_as_investor: Float
contributed_as_investor: String!
"""Вклад как собственник имущества"""
contributed_as_propertor: Float
contributed_as_propertor: String!
"""Хеш вкладчика"""
contributor_hash: String!
"""Название кооператива"""
coopname: String
coopname: String!
"""Дата создания"""
created_at: String
created_at: String!
"""Сумма долга"""
debt_amount: Float
debt_amount: String!
"""Отображаемое имя"""
display_name: String
display_name: String!
"""ID в блокчейне"""
id: Int
id: Int!
"""Является ли внешним контрактом"""
is_external_contract: Boolean
is_external_contract: Boolean!
"""Мемо/комментарий"""
memo: String
"""Существует ли запись в блокчейне"""
"""Флаг присутствия записи в блокчейне"""
present: Boolean!
"""Ставка за час работы"""
rate_per_hour: Float
rate_per_hour: String!
"""Статус вкладчика"""
status: ContributorStatus!
"""Имя пользователя"""
username: String
username: String!
}
"""Параметры фильтрации для запросов вкладчиков CAPITAL"""
@@ -2723,6 +2805,18 @@ input ConfigInput {
voting_period_in_days: Float!
}
"""Входные данные для подтверждения одобрения документа"""
input ConfirmApproveInput {
"""Хеш одобрения для идентификации"""
approval_hash: String!
"""Одобренный документ в формате JSON"""
approved_document: SignedDigitalDocumentInput!
"""Название кооператива"""
coopname: String!
}
"""
Подтвердить получение имущества Уполномоченным лицом от Заказчика по новации и акту приёмки-передачи
"""
@@ -3522,6 +3616,18 @@ type DecisionDetailAggregate {
votes_for: [ExtendedBlockchainAction!]!
}
"""Входные данные для отклонения одобрения документа"""
input DeclineApproveInput {
"""Хеш одобрения для идентификации"""
approval_hash: String!
"""Название кооператива"""
coopname: String!
"""Причина отклонения"""
reason: String!
}
input DeclineRequestInput {
"""Имя аккаунта кооператива"""
coopname: String!
@@ -5114,6 +5220,12 @@ type Mutation {
"""Обновление истории в CAPITAL контракте"""
capitalUpdateStory(data: UpdateStoryInput!): CapitalStory!
"""Подтверждение одобрения документа председателем совета"""
chairmanConfirmApprove(data: ConfirmApproveInput!): Approval!
"""Отклонение одобрения документа председателем совета"""
chairmanDeclineApprove(data: DeclineApproveInput!): Approval!
"""Завершить заявку по истечению гарантийного срока"""
completeRequest(data: CompleteRequestInput!): Transaction!
@@ -5686,6 +5798,20 @@ type PaginatedCapitalVotesPaginationResult {
totalPages: Int!
}
type PaginatedChairmanApprovalsPaginationResult {
"""Текущая страница"""
currentPage: Int!
"""Элементы текущей страницы"""
items: [Approval!]!
"""Общее количество элементов"""
totalCount: Int!
"""Общее количество страниц"""
totalPages: Int!
}
type PaginatedCurrentTableStatesPaginationResult {
"""Текущая страница"""
currentPage: Int!
@@ -6376,6 +6502,12 @@ type Query {
"""Получение списка голосов кооператива с фильтрацией"""
capitalVotes(filter: VoteFilter, options: PaginationInput): PaginatedCapitalVotesPaginationResult!
"""Получение одобрения по внутреннему ID базы данных"""
chairmanApproval(id: String!): Approval
"""Получение списка одобрений председателя совета с фильтрацией"""
chairmanApprovals(filter: ApprovalFilter, options: PaginationInput): PaginatedChairmanApprovalsPaginationResult!
"""Получить сводную информацию о аккаунте"""
getAccount(data: GetAccountInput!): Account!
-8
View File
@@ -1,8 +0,0 @@
# TEST
testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest
test
st
test
st
@@ -15,17 +15,6 @@ export class ContributorOutputDTO extends BaseOutputDTO {
})
id!: number;
@Field(() => Int, {
description: 'Номер блока последнего обновления',
})
block_num!: number;
@Field(() => Boolean, {
description: 'Существует ли запись в блокчейне',
defaultValue: false,
})
present!: boolean;
@Field(() => ContributorStatus, {
description: 'Статус вкладчика',
})
@@ -52,6 +52,7 @@ export class ParticipationManagementInteractor {
// Создаем вкладчика в репозитории (данные базы данных)
const contributor = new ContributorDomainEntity({
_id: '', // будет сгенерирован автоматически
block_num: 0,
present: true,
contributor_hash: data.contributor_hash,
status: ContributorStatus.PENDING,
@@ -79,6 +80,7 @@ export class ParticipationManagementInteractor {
// Создаем базовые данные вкладчика для базы данных
const databaseData = {
_id: '', // будет сгенерирован автоматически
block_num: 0,
present: false,
contributor_hash: generateRandomHash(),
status: ContributorStatus.PENDING,
@@ -3,7 +3,7 @@ import type { IAppendixDatabaseData } from '../interfaces/appendix-database.inte
import type { IAppendixBlockchainData } from '../interfaces/appendix-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность приложения
@@ -1,5 +1,5 @@
import type { ICommentDatabaseData } from '../interfaces/comment-database.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность комментария
@@ -2,7 +2,7 @@ import { CommitStatus } from '../enums/commit-status.enum';
import type { ICommitDatabaseData } from '../interfaces/commit-database.interface';
import type { ICommitBlockchainData } from '../interfaces/commit-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность коммита
@@ -3,7 +3,7 @@ import type { IContributorDatabaseData } from '../interfaces/contributor-databas
import type { IContributorBlockchainData } from '../interfaces/contributor-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность вкладчика
@@ -1,6 +1,6 @@
import { CycleStatus } from '../enums/cycle-status.enum';
import type { ICycleDatabaseData } from '../interfaces/cycle-database.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность цикла разработки
@@ -3,7 +3,7 @@ import type { IDebtDatabaseData } from '../interfaces/debt-database.interface';
import type { IDebtBlockchainData } from '../interfaces/debt-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность долга
@@ -3,7 +3,7 @@ import type { IExpenseDatabaseData } from '../interfaces/expense-database.interf
import type { IExpenseBlockchainData } from '../interfaces/expense-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность расхода
@@ -2,7 +2,7 @@ import { InvestStatus } from '../enums/invest-status.enum';
import type { IInvestDatabaseData } from '../interfaces/invest-database.interface';
import type { IInvestBlockchainData } from '../interfaces/invest-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность инвестиции
@@ -1,7 +1,7 @@
import { IssuePriority } from '../enums/issue-priority.enum';
import { IssueStatus } from '../enums/issue-status.enum';
import type { IIssueDatabaseData } from '../interfaces/issue-database.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность задачи
@@ -3,7 +3,7 @@ import type { IProgramInvestDatabaseData } from '../interfaces/program-invest-da
import type { IProgramInvestBlockchainData } from '../interfaces/program-invest-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность программной инвестиции
@@ -4,7 +4,7 @@ import type { IProgramPropertyBlockchainData } from '../interfaces/program-prope
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { randomUUID } from 'crypto';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность программного имущественного взноса
@@ -2,7 +2,7 @@ import type { IProgramWalletDatabaseData } from '../interfaces/program-wallet-da
import type { IProgramWalletBlockchainData } from '../interfaces/program-wallet-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { randomUUID } from 'crypto';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность программного кошелька
@@ -3,7 +3,7 @@ import type { IProgramWithdrawDatabaseData } from '../interfaces/program-withdra
import type { IProgramWithdrawBlockchainData } from '../interfaces/program-withdraw-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность возврата из программы
*
@@ -2,7 +2,7 @@ import { ProjectPropertyStatus } from '../enums/project-property-status.enum';
import type { IProjectPropertyDatabaseData } from '../interfaces/project-property-database.interface';
import type { IProjectPropertyBlockchainData } from '../interfaces/project-property-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность проектного имущественного взноса
*
@@ -1,7 +1,7 @@
import type { IProjectWalletDatabaseData } from '../interfaces/project-wallet-database.interface';
import type { IProjectWalletBlockchainData } from '../interfaces/project-wallet-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность проектного кошелька
*
@@ -2,7 +2,7 @@ import { ProjectStatus } from '../enums/project-status.enum';
import type { IProjectDomainInterfaceDatabaseData } from '../interfaces/project-database.interface';
import type { IProjectDomainInterfaceBlockchainData } from '../interfaces/project-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
import { IssueIdGenerationService } from '../services/issue-id-generation.service';
/**
* Доменная сущность проекта
@@ -3,7 +3,7 @@ import type { IResultDatabaseData } from '../interfaces/result-database.interfac
import type { IResultBlockchainData } from '../interfaces/result-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность результата
*
@@ -1,7 +1,7 @@
import type { IStateDatabaseData } from '../interfaces/state-database.interface';
import type { IStateBlockchainData } from '../interfaces/state-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность состояния кооператива
*
@@ -1,6 +1,6 @@
import { StoryStatus } from '../enums/story-status.enum';
import type { IStoryDatabaseData } from '../interfaces/story-database.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность истории (критерия выполнения)
@@ -1,4 +1,4 @@
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
import type { ITimeEntryDatabaseData } from '../interfaces/time-entry-database.interface';
/**
@@ -1,7 +1,7 @@
import type { IVoteDatabaseData } from '../interfaces/vote-database.interface';
import type { IVoteBlockchainData } from '../interfaces/vote-blockchain.interface';
import type { IBlockchainSynchronizable } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseDomainEntity } from './base.entity';
import { BaseDomainEntity } from '~/shared/sync/entities/base-domain.entity';
/**
* Доменная сущность голоса
*
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных приложения из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных комментария из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных коммита из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных вкладчика из базы данных
*/
@@ -1,5 +1,5 @@
import type { CycleStatus } from '../enums/cycle-status.enum';
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных цикла из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных долга из базы данных
*/
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных расхода из базы данных
*/
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных инвестиции из базы данных
*/
@@ -1,6 +1,6 @@
import type { IssuePriority } from '../enums/issue-priority.enum';
import type { IssueStatus } from '../enums/issue-status.enum';
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных задачи из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных программной инвестиции из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных программного имущественного взноса из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных программного кошелька из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных возврата из программы из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных проекта из базы данных
*/
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных проектного имущественного взноса из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных проектного кошелька из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных результата из базы данных
*/
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных состояния из базы данных
*/
@@ -1,5 +1,5 @@
import type { StoryStatus } from '../enums/story-status.enum';
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных истории из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных записи времени из базы данных
@@ -1,4 +1,4 @@
import type { IBaseDatabaseData } from './base-database.interface';
import type { IBaseDatabaseData } from '~/shared/sync/interfaces/base-database.interface';
/**
* Интерфейс данных голоса из базы данных
*/
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { AppendixStatus } from '../../domain/enums/appendix-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_appendixes';
@Entity(EntityName)
@@ -1,6 +1,6 @@
import { Entity, Column, Index, ManyToOne, JoinColumn } from 'typeorm';
import { IssueTypeormEntity } from './issue.typeorm-entity';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_comments';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { CommitStatus } from '../../domain/enums/commit-status.enum';
import type { ICommitBlockchainData } from '../../domain/interfaces/commit-blockchain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_commits';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, CreateDateColumn, Index, ManyToMany } from 'typeorm';
import { ContributorStatus } from '../../domain/enums/contributor-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
import { IssueTypeormEntity } from './issue.typeorm-entity';
const EntityName = 'capital_contributors';
@@ -1,7 +1,7 @@
import { Entity, Column, CreateDateColumn, Index, OneToMany } from 'typeorm';
import { CycleStatus } from '../../domain/enums/cycle-status.enum';
import { IssueTypeormEntity } from './issue.typeorm-entity';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_cycles';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { DebtStatus } from '../../domain/enums/debt-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_debts';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { ExpenseStatus } from '../../domain/enums/expense-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_expenses';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { InvestStatus } from '../../domain/enums/invest-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_invests';
@Entity(EntityName)
@@ -6,7 +6,7 @@ import { CycleTypeormEntity } from './cycle.typeorm-entity';
import { CommentTypeormEntity } from './comment.typeorm-entity';
import { StoryTypeormEntity } from './story.typeorm-entity';
import { ContributorTypeormEntity } from './contributor.typeorm-entity';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_issues';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { ProgramInvestStatus } from '../../domain/enums/program-invest-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_program_invests';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { ProgramPropertyStatus } from '../../domain/enums/program-property-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_program_properties';
@Entity(EntityName)
@@ -1,5 +1,5 @@
import { Entity, Column, Index } from 'typeorm';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_program_wallets';
@Entity(EntityName)
@@ -1,7 +1,7 @@
import { Entity, Column, Index } from 'typeorm';
import { ProgramWithdrawStatus } from '../../domain/enums/program-withdraw-status.enum';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_program_withdraws';
@Entity(EntityName)
@@ -1,6 +1,6 @@
import { Entity, Column, Index } from 'typeorm';
import { ProjectPropertyStatus } from '../../domain/enums/project-property-status.enum';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_project_properties';
@Entity(EntityName)
@@ -1,5 +1,5 @@
import { Entity, Column, Index } from 'typeorm';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_project_wallets';
@Entity(EntityName)
@@ -3,7 +3,7 @@ import { ProjectStatus } from '../../domain/enums/project-status.enum';
import { IProjectDomainInterfaceBlockchainData } from '../../domain/interfaces/project-blockchain.interface';
import { IssueTypeormEntity } from './issue.typeorm-entity';
import { StoryTypeormEntity } from './story.typeorm-entity';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_projects';
@Entity(EntityName)
@@ -2,7 +2,7 @@ import { Entity, Column, Index } from 'typeorm';
import { ResultStatus } from '../../domain/enums/result-status.enum';
import { IResultBlockchainData } from '../../domain/interfaces/result-blockchain.interface';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_results';
@Entity(EntityName)
@@ -1,6 +1,6 @@
import { Entity, Column, Index } from 'typeorm';
import type { IStateBlockchainData } from '../../domain/interfaces/state-blockchain.interface';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_state';
@Entity(EntityName)
@@ -2,7 +2,7 @@ import { Entity, Column, Index, ManyToOne, JoinColumn } from 'typeorm';
import { StoryStatus } from '../../domain/enums/story-status.enum';
import { ProjectTypeormEntity } from './project.typeorm-entity';
import { IssueTypeormEntity } from './issue.typeorm-entity';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_stories';
@Entity(EntityName)
@@ -1,5 +1,5 @@
import { Entity, Column, Index } from 'typeorm';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
/**
* Сущность для хранения записей времени работы над задачами
@@ -1,5 +1,5 @@
import { Entity, Column, Index } from 'typeorm';
import { BaseTypeormEntity } from './base.typeorm-entity';
import { BaseTypeormEntity } from '~/shared/sync/entities/base-typeorm.entity';
const EntityName = 'capital_votes';
@Entity(EntityName)
@@ -12,6 +12,7 @@ export class CommentMapper {
static toDomain(entity: CommentTypeormEntity): CommentDomainEntity {
const databaseData: ICommentDatabaseData = {
_id: entity._id,
block_num: entity.block_num,
content: entity.content,
commentor_id: entity.commentor_id,
issue_id: entity.issue_id,
@@ -12,6 +12,7 @@ export class CycleMapper {
static toDomain(entity: CycleTypeormEntity): CycleDomainEntity {
const databaseData: ICycleDatabaseData = {
_id: entity._id,
block_num: entity.block_num,
name: entity.name,
start_date: entity.start_date,
end_date: entity.end_date,
@@ -13,6 +13,7 @@ export class IssueMapper {
const databaseData: IIssueDatabaseData = {
_id: entity._id,
id: entity.id,
block_num: entity.block_num,
issue_hash: entity.issue_hash,
coopname: entity.coopname,
title: entity.title,
@@ -6,7 +6,7 @@ import { AppendixTypeormEntity } from '../entities/appendix.typeorm-entity';
import { AppendixMapper } from '../mappers/appendix.mapper';
import type { AppendixRepository } from '../../domain/repositories/appendix.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IAppendixDatabaseData } from '../../domain/interfaces/appendix-database.interface';
import type { IAppendixBlockchainData } from '../../domain/interfaces/appendix-blockchain.interface';
@@ -8,7 +8,7 @@ import { CommitMapper } from '../mappers/commit.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import type { ICommitBlockchainData } from '../../domain/interfaces/commit-blockchain.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { ICommitDatabaseData } from '../../domain/interfaces/commit-database.interface';
import type {
PaginationInputDomainInterface,
@@ -7,7 +7,7 @@ import { ContributorTypeormEntity } from '../entities/contributor.typeorm-entity
import { ContributorMapper } from '../mappers/contributor.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import { IContributorDatabaseData } from '../../domain/interfaces/contributor-database.interface';
import type {
PaginationInputDomainInterface,
@@ -7,7 +7,7 @@ import { DebtTypeormEntity } from '../entities/debt.typeorm-entity';
import { DebtMapper } from '../mappers/debt.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IDebtDatabaseData } from '../../domain/interfaces/debt-database.interface';
import type { IDebtBlockchainData } from '../../domain/interfaces/debt-blockchain.interface';
@@ -7,7 +7,7 @@ import { ExpenseTypeormEntity } from '../entities/expense.typeorm-entity';
import { ExpenseMapper } from '../mappers/expense.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IExpenseBlockchainData } from '../../domain/interfaces/expense-blockchain.interface';
import type { IExpenseDatabaseData } from '../../domain/interfaces/expense-database.interface';
import type { ExpenseFilterInputDTO } from '../../application/dto/expenses_management/expense-filter.input';
@@ -7,7 +7,7 @@ import { InvestTypeormEntity } from '../entities/invest.typeorm-entity';
import { InvestMapper } from '../mappers/invest.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IInvestDatabaseData } from '../../domain/interfaces/invest-database.interface';
import type { IInvestBlockchainData } from '../../domain/interfaces/invest-blockchain.interface';
import type {
@@ -6,7 +6,7 @@ import { ProgramInvestTypeormEntity } from '../entities/program-invest.typeorm-e
import { ProgramInvestMapper } from '../mappers/program-invest.mapper';
import type { ProgramInvestRepository } from '../../domain/repositories/program-invest.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProgramInvestDatabaseData } from '../../domain/interfaces/program-invest-database.interface';
import type { IProgramInvestBlockchainData } from '../../domain/interfaces/program-invest-blockchain.interface';
import type {
@@ -6,7 +6,7 @@ import { ProgramPropertyTypeormEntity } from '../entities/program-property.typeo
import { ProgramPropertyMapper } from '../mappers/program-property.mapper';
import type { ProgramPropertyRepository } from '../../domain/repositories/program-property.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProgramPropertyDatabaseData } from '../../domain/interfaces/program-property-database.interface';
import type { IProgramPropertyBlockchainData } from '../../domain/interfaces/program-property-blockchain.interface';
@@ -6,7 +6,7 @@ import { ProgramWalletTypeormEntity } from '../entities/program-wallet.typeorm-e
import { ProgramWalletMapper } from '../mappers/program-wallet.mapper';
import type { ProgramWalletRepository } from '../../domain/repositories/program-wallet.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProgramWalletDatabaseData } from '../../domain/interfaces/program-wallet-database.interface';
import type { IProgramWalletBlockchainData } from '../../domain/interfaces/program-wallet-blockchain.interface';
@@ -6,7 +6,7 @@ import { ProgramWithdrawTypeormEntity } from '../entities/program-withdraw.typeo
import { ProgramWithdrawMapper } from '../mappers/program-withdraw.mapper';
import type { ProgramWithdrawRepository } from '../../domain/repositories/program-withdraw.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProgramWithdrawDatabaseData } from '../../domain/interfaces/program-withdraw-database.interface';
import type { IProgramWithdrawBlockchainData } from '../../domain/interfaces/program-withdraw-blockchain.interface';
@@ -6,7 +6,7 @@ import { ProjectPropertyTypeormEntity } from '../entities/project-property.typeo
import { ProjectPropertyMapper } from '../mappers/project-property.mapper';
import type { ProjectPropertyRepository } from '../../domain/repositories/project-property.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProjectPropertyBlockchainData } from '../../domain/interfaces/project-property-blockchain.interface';
import type { IProjectPropertyDatabaseData } from '../../domain/interfaces/project-property-database.interface';
@@ -6,7 +6,7 @@ import { ProjectWalletTypeormEntity } from '../entities/project-wallet.typeorm-e
import { ProjectWalletMapper } from '../mappers/project-wallet.mapper';
import type { ProjectWalletRepository } from '../../domain/repositories/project-wallet.repository';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IProjectWalletBlockchainData } from '../../domain/interfaces/project-wallet-blockchain.interface';
import type { IProjectWalletDatabaseData } from '../../domain/interfaces/project-wallet-database.interface';
@@ -7,7 +7,7 @@ import { ProjectTypeormEntity } from '../entities/project.typeorm-entity';
import { ProjectMapper } from '../mappers/project.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import { DomainToBlockchainUtils } from '~/shared/utils/domain-to-blockchain.utils';
import type { IProjectDomainInterfaceBlockchainData } from '../../domain/interfaces/project-blockchain.interface';
import type { IProjectDomainInterfaceDatabaseData } from '../../domain/interfaces/project-database.interface';
@@ -7,7 +7,7 @@ import { ResultTypeormEntity } from '../entities/result.typeorm-entity';
import { ResultMapper } from '../mappers/result.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IResultBlockchainData } from '../../domain/interfaces/result-blockchain.interface';
import type { IResultDatabaseData } from '../../domain/interfaces/result-database.interface';
@@ -7,7 +7,7 @@ import { StateTypeormEntity } from '../entities/state.typeorm-entity';
import { StateMapper } from '../mappers/state.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IStateBlockchainData } from '../../domain/interfaces/state-blockchain.interface';
import type { IStateDatabaseData } from '../../domain/interfaces/state-database.interface';
@@ -7,7 +7,7 @@ import { VoteTypeormEntity } from '../entities/vote.typeorm-entity';
import { VoteMapper } from '../mappers/vote.mapper';
import { CAPITAL_DATABASE_CONNECTION } from '../database/capital-database.module';
import type { IBlockchainSyncRepository } from '~/shared/interfaces/blockchain-sync.interface';
import { BaseBlockchainRepository } from './base-blockchain.repository';
import { BaseBlockchainRepository } from '~/shared/sync/repositories/base-blockchain.repository';
import type { IVoteDatabaseData } from '../../domain/interfaces/vote-database.interface';
import type { IVoteBlockchainData } from '../../domain/interfaces/vote-blockchain.interface';
import type {
@@ -0,0 +1,46 @@
import { InputType, Field } from '@nestjs/graphql';
import { ApprovalStatus } from '../../domain/enums/approval-status.enum';
/**
* GraphQL Input DTO для фильтрации списка одобрений
*/
@InputType('ApprovalFilter', {
description: 'Фильтр для поиска одобрений',
})
export class ApprovalFilterInput {
@Field(() => String, {
nullable: true,
description: 'Фильтр по названию кооператива',
})
coopname?: string;
@Field(() => String, {
nullable: true,
description: 'Фильтр по имени пользователя',
})
username?: string;
@Field(() => [ApprovalStatus], {
nullable: true,
description: 'Фильтр по статусам одобрений',
})
statuses?: ApprovalStatus[];
@Field(() => Date, {
nullable: true,
description: 'Фильтр по дате создания (от)',
})
created_from?: Date;
@Field(() => Date, {
nullable: true,
description: 'Фильтр по дате создания (до)',
})
created_to?: Date;
@Field(() => String, {
nullable: true,
description: 'Поиск по хешу одобрения',
})
approval_hash?: string;
}
@@ -0,0 +1,75 @@
import { ObjectType, Field } from '@nestjs/graphql';
import { BaseOutputDTO } from './base.dto';
import { ApprovalStatus } from '../../domain/enums/approval-status.enum';
import { DocumentAggregateDTO } from '~/application/document/dto/document-aggregate.dto';
/**
* GraphQL Output DTO для сущности одобрения (Approval)
*/
@ObjectType('Approval', {
description: 'Одобрение документа председателем совета',
})
export class ApprovalDTO extends BaseOutputDTO {
@Field(() => Number, {
nullable: true,
description: 'ID одобрения в блокчейне',
})
id?: number;
@Field(() => String, {
description: 'Название кооператива',
})
coopname!: string;
@Field(() => String, {
description: 'Имя пользователя, запросившего одобрение',
})
username!: string;
@Field(() => String, {
description: 'Хеш одобрения для идентификации',
})
approval_hash!: string;
@Field(() => String, {
description: 'Контракт обратного вызова для обработки результата',
})
callback_contract!: string;
@Field(() => String, {
description: 'Действие обратного вызова при одобрении',
})
callback_action_approve!: string;
@Field(() => String, {
description: 'Действие обратного вызова при отклонении',
})
callback_action_decline!: string;
@Field(() => String, {
description: 'Метаданные одобрения в формате JSON',
})
meta!: string;
@Field(() => Date, {
description: 'Дата создания одобрения',
})
created_at!: Date;
@Field(() => ApprovalStatus, {
description: 'Статус одобрения',
})
status!: ApprovalStatus;
@Field(() => DocumentAggregateDTO, {
description: 'Документ, требующий одобрения',
nullable: true,
})
document?: DocumentAggregateDTO | null;
@Field(() => DocumentAggregateDTO, {
description: 'Одобренный документ (заполняется при подтверждении одобрения)',
nullable: true,
})
approved_document?: DocumentAggregateDTO | null;
}
@@ -0,0 +1,35 @@
import { ObjectType, Field } from '@nestjs/graphql';
/**
* Базовый GraphQL Output DTO для сущностей CHAIRMAN
*/
@ObjectType('ChairmanBaseEntity', {
description: 'Базовые поля сущности CHAIRMAN',
})
export class BaseOutputDTO {
@Field(() => String, {
description: 'Внутренний ID базы данных',
})
_id!: string;
@Field(() => Boolean, {
description: 'Флаг присутствия записи в блокчейне',
})
present!: boolean;
@Field(() => Number, {
nullable: true,
description: 'Номер блока крайней синхронизации с блокчейном',
})
block_num?: number;
@Field(() => Date, {
description: 'Дата создания записи',
})
_created_at!: Date;
@Field(() => Date, {
description: 'Дата последнего обновления записи',
})
_updated_at!: Date;
}
@@ -0,0 +1,33 @@
import { InputType, Field } from '@nestjs/graphql';
import { IsString, IsNotEmpty, ValidateNested } from 'class-validator';
import { SignedDigitalDocumentInputDTO } from '~/application/document/dto/signed-digital-document-input.dto';
import type { ISignedDocumentDomainInterface } from '~/domain/document/interfaces/signed-document-domain.interface';
/**
* GraphQL Input DTO для мутации подтверждения одобрения
*/
@InputType('ConfirmApproveInput', {
description: 'Входные данные для подтверждения одобрения документа',
})
export class ConfirmApproveInputDTO {
@Field(() => String, {
description: 'Название кооператива',
})
@IsString()
@IsNotEmpty()
coopname!: string;
@Field(() => String, {
description: 'Хеш одобрения для идентификации',
})
@IsString()
@IsNotEmpty()
approval_hash!: string;
@Field(() => SignedDigitalDocumentInputDTO, {
description: 'Одобренный документ в формате JSON',
})
@IsNotEmpty()
@ValidateNested()
approved_document!: ISignedDocumentDomainInterface;
}
@@ -0,0 +1,31 @@
import { InputType, Field } from '@nestjs/graphql';
import { IsString, IsNotEmpty } from 'class-validator';
/**
* GraphQL Input DTO для мутации отклонения одобрения
*/
@InputType('DeclineApproveInput', {
description: 'Входные данные для отклонения одобрения документа',
})
export class DeclineApproveInputDTO {
@Field(() => String, {
description: 'Название кооператива',
})
@IsString()
@IsNotEmpty()
coopname!: string;
@Field(() => String, {
description: 'Хеш одобрения для идентификации',
})
@IsString()
@IsNotEmpty()
approval_hash!: string;
@Field(() => String, {
description: 'Причина отклонения',
})
@IsString()
@IsNotEmpty()
reason!: string;
}
@@ -0,0 +1,5 @@
export * from './approval.dto';
export * from './approval-filter.input';
export * from './base.dto';
export * from './confirm-approve-input.dto';
export * from './decline-approve-input.dto';

Some files were not shown because too many files have changed in this diff Show More