@coopenomics/docs-factory 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +194 -2
- package/dist/index.cjs +10614 -0
- package/dist/index.d.cts +2285 -0
- package/dist/index.d.mts +2285 -0
- package/dist/index.d.ts +2285 -0
- package/dist/index.mjs +10460 -0
- package/package.json +88 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Anthony Fu <https://github.com/antfu>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,195 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 📄 @coopenomics/factory
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Фабрика документов кооператива — библиотека для генерации юридически значимых документов (PDF). Объединяет шаблоны из блокчейна, приватные данные из хранилища и рендерит HTML через Handlebars/Nunjucks с последующей генерацией PDF через WeasyPrint.
|
|
4
|
+
|
|
5
|
+
## Основные возможности
|
|
6
|
+
|
|
7
|
+
- Более 60 шаблонов юридических документов (заявления, протоколы, решения, договоры, акты)
|
|
8
|
+
- Рендеринг HTML из шаблонов Handlebars и Nunjucks
|
|
9
|
+
- Генерация PDF через WeasyPrint
|
|
10
|
+
- Валидация данных по JSON Schema
|
|
11
|
+
- Электронная подпись документов через EOSIO-ключи
|
|
12
|
+
- Хранение документов и метаданных в MongoDB
|
|
13
|
+
- Сборка как ES-модуль и CommonJS (unbuild)
|
|
14
|
+
|
|
15
|
+
## Установка
|
|
16
|
+
|
|
17
|
+
Компонент является частью монорепозитория. Установка зависимостей из корня проекта:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Или только для этого компонента:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm install --filter @coopenomics/factory
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Системные зависимости
|
|
30
|
+
|
|
31
|
+
Для генерации PDF необходим [WeasyPrint](https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#installation).
|
|
32
|
+
|
|
33
|
+
## Скрипты
|
|
34
|
+
|
|
35
|
+
| Скрипт | Команда | Описание |
|
|
36
|
+
|--------|---------|----------|
|
|
37
|
+
| `build` | `pnpm run build` | Сборка библиотеки (unbuild) |
|
|
38
|
+
| `dev` | `pnpm run dev` | Режим разработки с автопересборкой (nodemon) |
|
|
39
|
+
| `test` | `pnpm run test` | Запуск тестов (Vitest) |
|
|
40
|
+
| `lint` | `pnpm run lint` | Проверка кода (ESLint) |
|
|
41
|
+
| `typecheck` | `pnpm run typecheck` | Проверка типов TypeScript |
|
|
42
|
+
| `setup-indexes` | `pnpm run setup-indexes` | Настройка индексов MongoDB |
|
|
43
|
+
|
|
44
|
+
Из корня монорепозитория:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm run build:lib # Сборка factory + cooptypes
|
|
48
|
+
pnpm run dev:lib # Режим разработки factory + cooptypes
|
|
49
|
+
pnpm run test:component # Компонентные тесты factory
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Конфигурация
|
|
53
|
+
|
|
54
|
+
Хранилище фабрики — порт `IFactoryStorage`; реализации — PostgreSQL (`PostgresFactoryStorage`) и память. Для набора тестов нужен PostgreSQL. Переменные окружения:
|
|
55
|
+
|
|
56
|
+
- `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_USERNAME`, `POSTGRES_PASSWORD`, `POSTGRES_DATABASE` — база набора тестов
|
|
57
|
+
- `SOURCE` — источник данных (`local` для тестов)
|
|
58
|
+
|
|
59
|
+
Подробное описание переменных — в файле `.env-example`.
|
|
60
|
+
|
|
61
|
+
## Тестирование
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
SOURCE=local NODE_ENV=test pnpm --filter @coopenomics/factory run test
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Тестовый набор покрывает генерацию документов различных типов. Тесты требуют запущенный MongoDB и используют таймаут 240 секунд.
|
|
68
|
+
|
|
69
|
+
Файлы тестов:
|
|
70
|
+
|
|
71
|
+
| Файл | Описание |
|
|
72
|
+
|------|----------|
|
|
73
|
+
| `test/index.test.ts` | Основные тесты генерации документов |
|
|
74
|
+
| `test/wallet.test.ts` | Тесты документов кошелька |
|
|
75
|
+
| `test/meet.test.ts` | Тесты документов собраний |
|
|
76
|
+
| `test/blagorost.test.ts` | Тесты документов программы «Благорост» |
|
|
77
|
+
| `test/market.test.ts` | Тесты документов маркетплейса |
|
|
78
|
+
| `test/search.test.ts` | Тесты поиска документов |
|
|
79
|
+
| `test/udata.test.ts` | Тесты пользовательских данных |
|
|
80
|
+
| `test/documents-1000-plus.test.ts` | Тесты документов с registry_id > 1000 |
|
|
81
|
+
|
|
82
|
+
## Архитектура
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
src/
|
|
86
|
+
├── index.ts # Точка входа библиотеки
|
|
87
|
+
├── config.ts # Конфигурация подключений
|
|
88
|
+
├── Actions/ # Генераторы документов (по registry_id)
|
|
89
|
+
│ ├── 1.WalletAgreement.ts
|
|
90
|
+
│ ├── 100.ParticipantApplication.ts
|
|
91
|
+
│ ├── 300.AnnualGeneralMeetingAgenda.ts
|
|
92
|
+
│ ├── 600.FreeDecision.ts
|
|
93
|
+
│ ├── 1001.GenerationContract.ts
|
|
94
|
+
│ └── ... # Более 60 шаблонов
|
|
95
|
+
├── Factory/ # Ядро фабрики документов
|
|
96
|
+
├── Models/ # Модели данных MongoDB
|
|
97
|
+
│ ├── Cooperative.ts
|
|
98
|
+
│ ├── Individual.ts
|
|
99
|
+
│ ├── Organization.ts
|
|
100
|
+
│ ├── Document.ts
|
|
101
|
+
│ └── ...
|
|
102
|
+
└── templates/ # HTML-шаблоны (Nunjucks/Handlebars)
|
|
103
|
+
test/ # Тесты (Vitest)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Процесс генерации документа
|
|
107
|
+
|
|
108
|
+
1. Загрузка шаблона и JSON Schema из блокчейна
|
|
109
|
+
2. Получение приватных данных из хранилища (MongoDB)
|
|
110
|
+
3. Валидация данных по JSON Schema (Ajv)
|
|
111
|
+
4. Конструирование контекста для шаблона
|
|
112
|
+
5. Рендеринг HTML из Nunjucks/Handlebars-шаблона
|
|
113
|
+
6. Подпись хеша документа EOSIO-ключом
|
|
114
|
+
7. Генерация PDF через WeasyPrint
|
|
115
|
+
|
|
116
|
+
## Приватные данные документа: `doc_data`
|
|
117
|
+
|
|
118
|
+
Зарезервированный механизм для документов, содержащих персональные данные (ФИО экспедитора, паспорт, госномер, телефон и т.п.), которые **не должны попадать в блокчейн**.
|
|
119
|
+
|
|
120
|
+
### Поток
|
|
121
|
+
|
|
122
|
+
1. Контроллер собирает приватный payload и вызывает `generator.saveDocData(payload, registry_id)` — возвращается `{ hash }` (sha256, идемпотентный).
|
|
123
|
+
2. `hash` передаётся on-chain в Action под зарезервированным именем `doc_data_hash`.
|
|
124
|
+
3. При генерации/регенерации фабрика подгружает payload из `doc_private_data` через `generator.getDocData(hash)` и подставляет в `combinedData.doc_data`.
|
|
125
|
+
4. Шаблон документа использует приватные поля как `{{ doc_data.<field> }}`.
|
|
126
|
+
|
|
127
|
+
### Пример
|
|
128
|
+
|
|
129
|
+
Контроллер:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const { hash } = await generator.saveDocData({
|
|
133
|
+
expeditor_full_name: 'Иванов Иван Иванович',
|
|
134
|
+
passport: '4509 123456',
|
|
135
|
+
phone: '+79991234567',
|
|
136
|
+
vehicle_registration_number: 'А123ВВ77',
|
|
137
|
+
}, 1103)
|
|
138
|
+
|
|
139
|
+
// в Action документа 1103 (MarketplaceTransportNote):
|
|
140
|
+
await generator.generate({
|
|
141
|
+
registry_id: 1103,
|
|
142
|
+
coopname: 'voskhod',
|
|
143
|
+
username: operatorAccount,
|
|
144
|
+
shipment_id,
|
|
145
|
+
doc_data_hash: hash,
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Фабрика (`src/Actions/1103.MarketplaceTransportNote.ts`):
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
const doc_data = await this.loadDocData<TransportNoteDocData>(data)
|
|
153
|
+
const combinedData = { ...base, doc_data }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Шаблон (`Templates/1103.MarketplaceTransportNote/index.ts`):
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<tr><th>Экспедитор</th><td>{{ doc_data.expeditor_full_name }}</td></tr>
|
|
160
|
+
<tr><th>Госномер</th><td>{{ doc_data.vehicle_registration_number }}</td></tr>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Зарезервированные имена шаблона
|
|
164
|
+
|
|
165
|
+
| Имя | Источник | Применение |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `meta` | factory | заголовки, дата, lang, hash |
|
|
168
|
+
| `coop` | factory | реквизиты кооператива |
|
|
169
|
+
| `vars` | factory | переменные кооператива |
|
|
170
|
+
| `user` | factory | подписант (по сертификату) |
|
|
171
|
+
| `request` / `program` / `decision` | factory | контекст ЦПП |
|
|
172
|
+
| `branch` | factory | данные КУ |
|
|
173
|
+
| **`doc_data`** | **DocDataService** | **приватные данные документа** |
|
|
174
|
+
|
|
175
|
+
### Graceful degradation
|
|
176
|
+
|
|
177
|
+
Если запись в `doc_private_data` удалена (например, по запросу пайщика), документ остаётся **верифицируемым по хэшу подписи** (хэш зафиксирован on-chain), но не регенерируется. Это явное архитектурное решение: ценность блокчейн-подписи сохраняется; восстановление PDF — обратимо deprecated.
|
|
178
|
+
|
|
179
|
+
### Когда применять
|
|
180
|
+
|
|
181
|
+
- **Новые документы** с персональными данными — сразу через `doc_data`.
|
|
182
|
+
- **Существующие документы** (700-1099, 300-304 и т.д.) — остаются без изменений. Паттерн прогрессивный, переводить старые документы при отсутствии необходимости не нужно.
|
|
183
|
+
|
|
184
|
+
## Ключевые зависимости
|
|
185
|
+
|
|
186
|
+
- **nunjucks / handlebars** — шаблонизаторы
|
|
187
|
+
- **ajv** — валидация JSON Schema
|
|
188
|
+
- **mongodb** — хранилище данных
|
|
189
|
+
- **eosjs-ecc** — криптографические операции EOSIO
|
|
190
|
+
- **pdf-lib** — работа с PDF
|
|
191
|
+
- **unbuild** — сборка библиотеки
|
|
192
|
+
|
|
193
|
+
## Лицензия
|
|
194
|
+
|
|
195
|
+
[BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.ru)
|