Compare commits

...

47 Commits

Author SHA1 Message Date
Alex Ant 0aed10eb8b chore(release): publish
- coopback@1.7.37-alpha.1
 - coopdoc-generator-ts@1.0.11-alpha.1
 - cooptypes@1.0.22-alpha.6
 - coop-notificator@0.0.28-alpha.0
 - terminal@0.1.41-alpha.0
2024-09-16 11:37:13 +05:00
Alex Ant d84d687eee update 2024-09-16 11:36:50 +05:00
Alex Ant d046f56832 update 2024-09-16 11:34:07 +05:00
Alex Ant 0af1fbf313 update 2024-09-16 11:24:50 +05:00
Alex Ant e9aaf4309e chore(release): publish
- cooparser-ts@1.0.20-alpha.0
 - coopback@1.7.37-alpha.0
 - coopdoc-generator-ts@1.0.11-alpha.0
 - cooptypes@1.0.22-alpha.6
 - coop-notificator@0.0.27
 - terminal@0.1.40
2024-09-16 11:19:45 +05:00
Alex Ant 80fa1085d2 FUCK 2024-09-16 11:13:22 +05:00
Alex Ant 88195291fd update 2024-09-16 11:09:40 +05:00
Alex Ant 39ad600d00 update 2024-09-16 10:58:59 +05:00
Alex Ant c63a3aba6b update 2024-09-16 10:41:15 +05:00
Alex Ant 782ecbe307 dfdf 2024-09-16 10:36:54 +05:00
Alex Ant f75bbfa048 fix 2024-09-16 10:15:16 +05:00
Alex Ant 3a772cc983 herna 2024-09-16 10:00:29 +05:00
Alex Ant 807113523e documents update 2024-09-16 09:52:00 +05:00
Alex Ant 7df2af8611 update 2024-09-15 17:28:33 +05:00
Alex Ant 10c1697b00 update 2024-09-15 17:23:58 +05:00
Alex Ant 742e5d38ab chore(release): publish
- coopback@1.7.35-alpha.5
 - coopdoc-generator-ts@1.0.79-alpha.5
 - cooptypes@1.0.22-alpha.5
 - coop-notificator@0.0.26-alpha.5
 - terminal@0.1.39-alpha.5
2024-09-15 17:20:44 +05:00
Alex Ant 1d3e7f8af0 update 2024-09-15 17:19:13 +05:00
Alex Ant c99bacab64 before update 2024-09-15 10:40:18 +05:00
Alex Ant 95d7555ebc ssr & covars -> vars 2024-09-15 09:38:02 +05:00
Alex Ant 5854e0a23c chore(release): publish
- coopback@1.7.35-alpha.4
 - coopdoc-generator-ts@1.0.79-alpha.4
 - cooptypes@1.0.22-alpha.4
 - coop-notificator@0.0.26-alpha.4
 - terminal@0.1.39-alpha.4
2024-09-14 17:02:55 +05:00
Alex Ant 81f7f32767 fix 2024-09-14 17:02:33 +05:00
Alex Ant c0374a7da1 chore(release): publish
- coopback@1.7.35-alpha.3
 - coopdoc-generator-ts@1.0.79-alpha.3
 - cooptypes@1.0.22-alpha.3
 - coop-notificator@0.0.26-alpha.3
 - terminal@0.1.39-alpha.3
2024-09-14 16:44:32 +05:00
Alex Ant ed65e655b9 update 2024-09-14 16:43:06 +05:00
Alex Ant d250e516b5 update document models 2024-09-14 12:43:06 +05:00
Alex Ant e4f404b2c7 documents update 2024-09-13 20:41:00 +05:00
Alex Ant 86571331f8 update registry 2024-09-12 15:05:11 +05:00
Alex Ant 163d420af9 request agreements 2024-09-11 16:12:05 +05:00
Alex Ant 4925ea4af0 chore(release): publish
- cooparser-ts@1.0.19-alpha.1
 - coopback@1.7.35-alpha.2
 - coopdoc-generator-ts@1.0.79-alpha.2
 - cooptypes@1.0.22-alpha.2
 - coop-notificator@0.0.26-alpha.2
 - terminal@0.1.39-alpha.2
2024-09-11 10:04:46 +05:00
Alex Ant 57b05ce348 registration agreements 2024-09-11 10:01:09 +05:00
Alex Ant 427b53fcbd chore(release): publish
- coopback@1.7.35-alpha.1
 - coopdoc-generator-ts@1.0.79-alpha.1
 - cooptypes@1.0.22-alpha.1
 - coop-notificator@0.0.26-alpha.1
 - terminal@0.1.39-alpha.1
2024-09-10 10:06:12 +05:00
Alex Ant 2ac7a31be6 промежуточный результат добавления кооперативных соглашений 2024-09-10 10:05:17 +05:00
Alex Ant 4baed6409f chore(release): publish
- cooparser-ts@1.0.19-alpha.0
 - coopback@1.7.35-alpha.0
 - coopdoc-generator-ts@1.0.79-alpha.0
 - cooptypes@1.0.22-alpha.0
 - coop-notificator@0.0.26-alpha.0
 - terminal@0.1.39-alpha.0
2024-09-06 16:39:34 +05:00
Alex Ant 2ea0ff0965 big update 2024-09-06 16:29:18 +05:00
Alex Ant 88b9a7edce small letters 2024-09-05 19:27:23 +05:00
Alex Ant 538066b960 ufff template or Template ??? always should be small letters 2024-09-05 19:25:37 +05:00
Alex Ant b10dd1d75a update generator with new type of document 2024-09-04 20:57:59 +05:00
Alex Ant f743580b55 fix signature collection name 2024-09-03 20:33:30 +05:00
Alex Ant 0688467302 update 2024-09-03 20:11:17 +05:00
Alex Ant 29e972dbf2 fix is_paid 2024-08-27 18:47:39 +05:00
Alex Ant bd99697c5b chore(release): publish
- coopback@1.7.34
 - coopdoc-generator-ts@1.0.78
 - cooptypes@1.0.21
 - coop-notificator@0.0.25
 - terminal@0.1.38
2024-08-25 11:39:35 +05:00
Alex Ant 1d5c431ff6 update types 2024-08-25 11:38:40 +05:00
Alex Ant 3736c510ff chore(release): publish
- cooparser-ts@1.0.18
 - coopback@1.7.33
 - coopdoc-generator-ts@1.0.77
 - terminal@0.1.37
2024-08-25 11:27:44 +05:00
Alex Ant 26c12c3a85 update 2024-08-25 11:25:28 +05:00
Alex Ant 10bb08e5e6 chore(release): publish
- coopback@1.7.32
 - coopdoc-generator-ts@1.0.76
 - terminal@0.1.36
2024-08-25 11:19:13 +05:00
Alex Ant b50d5b6121 publish 2024-08-25 11:07:57 +05:00
Alex Ant 38b28752e1 chore(release): publish
- coopback@1.7.31
 - coopdoc-generator-ts@1.0.75
 - cooptypes@1.0.20
 - coop-notificator@0.0.24
 - terminal@0.1.35
2024-08-25 11:02:44 +05:00
Alex Ant 87c51009de ProgramProvision | ЦПП Цифровой Кошелёк 2024-08-25 10:59:57 +05:00
218 changed files with 17149 additions and 19840 deletions
+3
View File
@@ -0,0 +1,3 @@
node_modules
dist
+14
View File
@@ -0,0 +1,14 @@
{
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true,
"editor.formatOnSave": true,
"editor.tabCompletion": "onlySnippets",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
"eslint.validate": ["javascript", "typescript", "vue"],
"typescript.tsdk": "node_modules/typescript/lib",
"i18n-ally.localesPaths": ["src/i18n"],
"typescript.format.enable": true,
"typescript.format.indentSwitchCase": false,
"typescript.validate.enable": true,
}
+10
View File
@@ -0,0 +1,10 @@
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install -g pnpm lerna
RUN pnpm install
RUN lerna run build
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.18](https://github.com/copenomics/cooparser/compare/cooparser-ts@1.0.17...cooparser-ts@1.0.18) (2024-08-25)
**Note:** Version bump only for package cooparser-ts
## [1.0.17](https://github.com/copenomics/cooparser/compare/cooparser-ts@1.0.17-alpha.2...cooparser-ts@1.0.17) (2024-07-25)
**Note:** Version bump only for package cooparser-ts
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "pkg-placeholder",
"version": "1.0.17",
"version": "1.0.20-alpha.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pkg-placeholder",
"version": "1.0.17",
"version": "1.0.20-alpha.0",
"license": "MIT",
"devDependencies": {
"@antfu/eslint-config": "^2.16.0",
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "cooparser-ts",
"type": "module",
"version": "1.0.17",
"private": true,
"version": "1.0.20-alpha.0",
"private": false,
"packageManager": "pnpm@9.0.6",
"description": "",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
+19 -225
View File
@@ -69,9 +69,6 @@ importers:
esno:
specifier: ^4.7.0
version: 4.7.0
lint-staged:
specifier: ^15.2.2
version: 15.2.2
nodemon:
specifier: ^3.1.4
version: 3.1.4
@@ -1039,10 +1036,6 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ansi-escapes@6.2.1:
resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==}
engines: {node: '>=14.16'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@@ -1233,14 +1226,6 @@ packages:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
cli-truncate@4.0.0:
resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
engines: {node: '>=18'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -1271,9 +1256,6 @@ packages:
colord@2.9.3:
resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
colorspace@1.1.4:
resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==}
@@ -1281,10 +1263,6 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
commander@11.1.0:
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
engines: {node: '>=16'}
commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
@@ -1506,9 +1484,6 @@ packages:
elliptic@6.5.4:
resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
emoji-regex@10.3.0:
resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -1770,9 +1745,6 @@ packages:
eventemitter3@4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
execa@8.0.1:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
@@ -1893,10 +1865,6 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-east-asian-width@1.2.0:
resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
engines: {node: '>=18'}
get-func-name@2.0.2:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
@@ -2083,14 +2051,6 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-fullwidth-code-point@4.0.0:
resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
engines: {node: '>=12'}
is-fullwidth-code-point@5.0.0:
resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
engines: {node: '>=18'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -2200,10 +2160,6 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
lilconfig@3.0.0:
resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
engines: {node: '>=14'}
lilconfig@3.1.1:
resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==}
engines: {node: '>=14'}
@@ -2211,15 +2167,6 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
lint-staged@15.2.2:
resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==}
engines: {node: '>=18.12.0'}
hasBin: true
listr2@8.0.1:
resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==}
engines: {node: '>=18.0.0'}
local-pkg@0.5.0:
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
engines: {node: '>=14'}
@@ -2257,10 +2204,6 @@ packages:
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
log-update@6.0.0:
resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==}
engines: {node: '>=18'}
logform@2.6.0:
resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==}
engines: {node: '>= 12.0.0'}
@@ -2346,10 +2289,6 @@ packages:
engines: {node: '>=4'}
hasBin: true
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
mimic-fn@4.0.0:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
@@ -2546,10 +2485,6 @@ packages:
one-time@1.0.0:
resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==}
onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
@@ -2682,11 +2617,6 @@ packages:
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
engines: {node: '>=12'}
pidtree@0.6.0:
resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
engines: {node: '>=0.10'}
hasBin: true
pkg-types@1.1.0:
resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==}
@@ -2976,17 +2906,10 @@ packages:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rfdc@1.3.1:
resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==}
rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
hasBin: true
@@ -3085,9 +3008,6 @@ packages:
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
@@ -3118,14 +3038,6 @@ packages:
resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
engines: {node: '>=14.16'}
slice-ansi@5.0.0:
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
engines: {node: '>=12'}
slice-ansi@7.1.0:
resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
engines: {node: '>=18'}
source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
@@ -3179,10 +3091,6 @@ packages:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
string-width@7.1.0:
resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==}
engines: {node: '>=18'}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
@@ -3558,10 +3466,6 @@ packages:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
wrap-ansi@9.0.0:
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
engines: {node: '>=18'}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@@ -3595,10 +3499,6 @@ packages:
resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==}
engines: {node: ^14.17.0 || >=16.0.0}
yaml@2.3.4:
resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
engines: {node: '>= 14'}
yaml@2.4.2:
resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==}
engines: {node: '>= 14'}
@@ -3703,7 +3603,7 @@ snapshots:
'@babel/traverse': 7.24.1
'@babel/types': 7.24.0
convert-source-map: 2.0.0
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@@ -3804,7 +3704,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@@ -4013,7 +3913,7 @@ snapshots:
'@eslint/eslintrc@2.1.4':
dependencies:
ajv: 6.12.6
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
@@ -4029,7 +3929,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.14':
dependencies:
'@humanwhocodes/object-schema': 2.0.3
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@@ -4348,7 +4248,7 @@ snapshots:
'@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
@@ -4366,7 +4266,7 @@ snapshots:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
optionalDependencies:
typescript: 5.4.5
@@ -4387,7 +4287,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.4.5)
optionalDependencies:
@@ -4403,7 +4303,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
@@ -4418,7 +4318,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.4
@@ -4550,8 +4450,6 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ansi-escapes@6.2.1: {}
ansi-regex@5.0.1: {}
ansi-regex@6.0.1: {}
@@ -4762,15 +4660,6 @@ snapshots:
dependencies:
escape-string-regexp: 1.0.5
cli-cursor@4.0.0:
dependencies:
restore-cursor: 4.0.0
cli-truncate@4.0.0:
dependencies:
slice-ansi: 5.0.0
string-width: 7.1.0
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -4803,8 +4692,6 @@ snapshots:
colord@2.9.3: {}
colorette@2.0.20: {}
colorspace@1.1.4:
dependencies:
color: 3.2.1
@@ -4814,8 +4701,6 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
commander@11.1.0: {}
commander@7.2.0: {}
comment-parser@1.4.1: {}
@@ -4952,10 +4837,6 @@ snapshots:
dependencies:
ms: 2.1.3
debug@4.3.4:
dependencies:
ms: 2.1.2
debug@4.3.4(supports-color@5.5.0):
dependencies:
ms: 2.1.2
@@ -5040,8 +4921,6 @@ snapshots:
minimalistic-assert: 1.0.1
minimalistic-crypto-utils: 1.0.1
emoji-regex@10.3.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
@@ -5185,7 +5064,7 @@ snapshots:
eslint-plugin-import-x@0.5.0(eslint@8.57.0)(typescript@5.4.5):
dependencies:
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
doctrine: 3.0.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
@@ -5202,7 +5081,7 @@ snapshots:
'@es-joy/jsdoccomment': 0.42.0
are-docs-informative: 0.0.2
comment-parser: 1.4.1
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint: 8.57.0
esquery: 1.5.0
@@ -5258,7 +5137,7 @@ snapshots:
eslint-plugin-toml@0.11.0(eslint@8.57.0):
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
eslint-compat-utils: 0.5.0(eslint@8.57.0)
lodash: 4.17.21
@@ -5322,7 +5201,7 @@ snapshots:
eslint-plugin-yml@1.14.0(eslint@8.57.0):
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
eslint-compat-utils: 0.5.0(eslint@8.57.0)
lodash: 4.17.21
@@ -5358,7 +5237,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@@ -5420,8 +5299,6 @@ snapshots:
eventemitter3@4.0.7: {}
eventemitter3@5.0.1: {}
execa@8.0.1:
dependencies:
cross-spawn: 7.0.3
@@ -5587,8 +5464,6 @@ snapshots:
get-caller-file@2.0.5: {}
get-east-asian-width@1.2.0: {}
get-func-name@2.0.2: {}
get-intrinsic@1.2.4:
@@ -5760,7 +5635,7 @@ snapshots:
dependencies:
'@ioredis/commands': 1.2.0
cluster-key-slot: 1.1.2
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
@@ -5801,12 +5676,6 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@4.0.0: {}
is-fullwidth-code-point@5.0.0:
dependencies:
get-east-asian-width: 1.2.0
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -5891,36 +5760,10 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
lilconfig@3.0.0: {}
lilconfig@3.1.1: {}
lines-and-columns@1.2.4: {}
lint-staged@15.2.2:
dependencies:
chalk: 5.3.0
commander: 11.1.0
debug: 4.3.4
execa: 8.0.1
lilconfig: 3.0.0
listr2: 8.0.1
micromatch: 4.0.5
pidtree: 0.6.0
string-argv: 0.3.2
yaml: 2.3.4
transitivePeerDependencies:
- supports-color
listr2@8.0.1:
dependencies:
cli-truncate: 4.0.0
colorette: 2.0.20
eventemitter3: 5.0.1
log-update: 6.0.0
rfdc: 1.3.1
wrap-ansi: 9.0.0
local-pkg@0.5.0:
dependencies:
mlly: 1.6.1
@@ -5952,14 +5795,6 @@ snapshots:
lodash@4.17.21: {}
log-update@6.0.0:
dependencies:
ansi-escapes: 6.2.1
cli-cursor: 4.0.0
slice-ansi: 7.1.0
strip-ansi: 7.1.0
wrap-ansi: 9.0.0
logform@2.6.0:
dependencies:
'@colors/colors': 1.6.0
@@ -6023,7 +5858,7 @@ snapshots:
micromark@2.11.4:
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
parse-entities: 2.0.0
transitivePeerDependencies:
- supports-color
@@ -6041,8 +5876,6 @@ snapshots:
mime@1.6.0: {}
mimic-fn@2.1.0: {}
mimic-fn@4.0.0: {}
min-indent@1.0.1: {}
@@ -6210,10 +6043,6 @@ snapshots:
dependencies:
fn.name: 1.1.0
onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
@@ -6329,8 +6158,6 @@ snapshots:
picomatch@4.0.2: {}
pidtree@0.6.0: {}
pkg-types@1.1.0:
dependencies:
confbox: 0.1.7
@@ -6601,15 +6428,8 @@ snapshots:
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
restore-cursor@4.0.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
reusify@1.0.4: {}
rfdc@1.3.1: {}
rimraf@3.0.2:
dependencies:
glob: 7.2.3
@@ -6742,8 +6562,6 @@ snapshots:
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
signal-exit@4.1.0: {}
simple-git-hooks@2.11.1: {}
@@ -6764,16 +6582,6 @@ snapshots:
slash@5.1.0: {}
slice-ansi@5.0.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 4.0.0
slice-ansi@7.1.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 5.0.0
source-map-js@1.2.0: {}
sparse-bitfield@3.0.3:
@@ -6825,12 +6633,6 @@ snapshots:
emoji-regex: 9.2.2
strip-ansi: 7.1.0
string-width@7.1.0:
dependencies:
emoji-regex: 10.3.0
get-east-asian-width: 1.2.0
strip-ansi: 7.1.0
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
@@ -7087,7 +6889,7 @@ snapshots:
vite-node@1.5.2(@types/node@20.12.7):
dependencies:
cac: 6.7.14
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
pathe: 1.1.2
picocolors: 1.0.0
vite: 5.2.10(@types/node@20.12.7)
@@ -7119,7 +6921,7 @@ snapshots:
'@vitest/utils': 1.5.2
acorn-walk: 8.3.2
chai: 4.4.1
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
execa: 8.0.1
local-pkg: 0.5.0
magic-string: 0.30.10
@@ -7149,7 +6951,7 @@ snapshots:
vue-eslint-parser@9.4.2(eslint@8.57.0):
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
@@ -7219,12 +7021,6 @@ snapshots:
string-width: 5.1.2
strip-ansi: 7.1.0
wrap-ansi@9.0.0:
dependencies:
ansi-styles: 6.2.1
string-width: 7.1.0
strip-ansi: 7.1.0
wrappy@1.0.2: {}
ws@7.5.9: {}
@@ -7243,8 +7039,6 @@ snapshots:
lodash: 4.17.21
yaml: 2.4.2
yaml@2.3.4: {}
yaml@2.4.2: {}
yargs-parser@21.1.1: {}
@@ -14,6 +14,7 @@ export async function BlockParser(db: Database, reader: EosioShipReaderResolved)
setTimeout(() => process.exit(1), 10000)
})
blocks$.subscribe(async (block: IBlock) => {
// console.log('new block: ', block)
// process.stdout.write('\r') // Возврат каретки в начало строки
@@ -11,7 +11,6 @@ export class Database {
private sync: Collection | undefined
constructor() {
console.log('mongo2: ', mongoUri)
this.client = new MongoClient(mongoUri)
}
-1
View File
@@ -11,7 +11,6 @@ function getEnvVar(key: string): string {
return envVar
}
export const node_env = getEnvVar('NODE_ENV')
console.log('ENV: ', node_env)
export const eosioApi = getEnvVar('API')
export const shipApi = getEnvVar('SHIP')
export const mongoUri = `${getEnvVar('MONGO_EXPLORER_URI')}${node_env === 'test' ? '-test' : ''}`
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.34](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.33...coopback@1.7.34) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.33](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.32...coopback@1.7.33) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.32](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.31...coopback@1.7.32) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.31](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.31-alpha.1...coopback@1.7.31) (2024-08-25)
**Note:** Version bump only for package coopback
## [1.7.30](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.29...coopback@1.7.30) (2024-08-13)
**Note:** Version bump only for package coopback
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "create-nodejs-express-app",
"version": "1.7.31-alpha.1",
"version": "1.7.37-alpha.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-nodejs-express-app",
"version": "1.7.31-alpha.1",
"version": "1.7.37-alpha.1",
"license": "MIT",
"dependencies": {
"@a2seven/yoo-checkout": "^1.1.4",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "coopback",
"version": "1.7.31-alpha.1",
"version": "1.7.37-alpha.1",
"description": "",
"private": true,
"bin": "bin/createNodejsApp.js",
+2
View File
@@ -8,6 +8,7 @@ const envVarsSchema = Joi.object()
.keys({
NODE_ENV: Joi.string().valid('production', 'development', 'test').required(),
BASE_URL: Joi.string().required(),
SERVER_SECRET: Joi.string().required(),
SERVICE_USERNAME: Joi.string().required(),
SERVICE_WIF: Joi.string().required(),
PORT: Joi.number().default(3000),
@@ -44,6 +45,7 @@ export default {
env: envVars.NODE_ENV,
base_url: envVars.BASE_URL,
port: envVars.PORT,
server_secret: envVars.SERVER_SECRET,
service_wif: envVars.SERVICE_WIF,
service_username: envVars.SERVICE_USERNAME,
mongoose: {
+1 -1
View File
@@ -1,7 +1,7 @@
const allRoles = {
user: [''],
service: ['addUser', 'sendNotification', 'install'],
chairman: ['addUser', 'getUsers', 'manageUsers', 'loadAgenda', 'loadStaff', 'getDocuments', 'loadInfo'],
chairman: ['addUser', 'getUsers', 'manageUsers', 'loadAgenda', 'loadStaff', 'getDocuments', 'loadInfo', 'set-vars'],
member: ['getUsers', 'manageUsers', 'loadAgenda', 'loadStaff', 'getDocuments', 'loadInfo'],
};
@@ -18,7 +18,7 @@ export const loadAgenda = catchAsync(async (req: Request, res: Response) => {
const { coopname } = req.query;
const agenda = await coopService.loadAgenda(coopname as string);
const complexAgenda: Cooperative.Documents.IComplexAgenda[] = [];
const complexAgenda: Cooperative.Document.IComplexAgenda[] = [];
for (const { action, table } of agenda) {
const documents = await documentService.buildComplexDocument(action);
+2 -1
View File
@@ -4,4 +4,5 @@ export * as documentController from './document.controller';
export * as paymentController from './payment.controller';
export * as coopController from './coop.controller';
export * as notifyController from './notify.controller';
export * as monoController from './mono.controller';
export * as systemController from './system.controller';
export * as participantController from './participant.controller';
@@ -0,0 +1,10 @@
import httpStatus from 'http-status';
import { participantService } from '../services';
import type { RJoinCooperative } from '../types';
import catchAsync from '../utils/catchAsync';
export const joinCooperative = catchAsync(async (req: RJoinCooperative, res) => {
await participantService.joinCooperative(req.body);
res.status(httpStatus.OK).send();
});
@@ -1,14 +1,15 @@
import httpStatus from 'http-status';
import { getMonoStatus } from '../services/mono.service';
import { getMonoStatus } from '../services/system.service';
import { getBlockchainInfo } from '../services/blockchain.service';
import { IHealthResponse, IInstall, RInstall } from '../types';
import { Request, Response } from 'express';
import catchAsync from '../utils/catchAsync';
import { monoService } from '../services';
import { systemService } from '../services';
import type { ISetVars, RSetVars } from '../types/auto-generated/system.validation';
export const install = catchAsync(async (req: RInstall, res: Response) => {
const { body } = req;
await monoService.install(body as IInstall);
await systemService.install(body as IInstall);
res.status(httpStatus.OK).send();
});
@@ -23,3 +24,13 @@ export const getHealth = catchAsync(async (req: Request, res: Response) => {
res.status(httpStatus.OK).send(result);
});
export const setVars = catchAsync(async (req: RSetVars, res: Response) => {
await systemService.setVars(req.body as ISetVars);
res.status(httpStatus.OK).send();
});
export const getVarsSchema = catchAsync(async (req: RSetVars, res: Response) => {
const schema = await systemService.getVarsSchema();
res.status(httpStatus.OK).send(schema);
});
@@ -2,11 +2,11 @@ import http from 'http-status';
import ApiError from '../utils/ApiError';
import catchAsync from '../utils/catchAsync';
import { userService, tokenService, emailService, blockchainService } from '../services';
import { IAddUser, ICreateUser, RCreateUser, RJoinCooperative } from '../types';
import { IAddUser, ICreateUser, RCreateUser } from '../types';
import httpStatus from 'http-status';
import pick from '../utils/pick';
import { IGetResponse } from '../types/common';
import { IUser } from '../models/user.model';
import { IUser, userStatus } from '../models/user.model';
import { Request, Response } from 'express';
import { generateUsername } from '../../tests/utils/generateUsername';
import config from '../config/config';
@@ -45,7 +45,7 @@ export const addUser = catchAsync(async (req: Request, res: Response) => {
};
const user = await userService.createUser(newUser);
user.status = 'registered';
user.status = userStatus['4_Registered'];
user.is_registered = true;
await user.save();
@@ -58,11 +58,10 @@ export const addUser = catchAsync(async (req: Request, res: Response) => {
coopname: config.coopname,
meta: '',
});
console.log('user: ', user);
const token = await tokenService.generateInviteToken(user.email);
await emailService.sendInviteEmail(req.body.email, token);
} catch (e: any) {
console.log('on e: ', e);
logger.warn('error on add user: ', e);
await userService.deleteUserByUsername(newUser.username);
throw new ApiError(httpStatus.BAD_GATEWAY, e.message);
@@ -71,12 +70,6 @@ export const addUser = catchAsync(async (req: Request, res: Response) => {
res.status(httpStatus.CREATED).send({ user });
});
export const joinCooperative = catchAsync(async (req: RJoinCooperative, res) => {
await userService.joinCooperative(req.body);
res.status(httpStatus.OK).send();
});
export const getUsers = catchAsync(async (req, res) => {
const filter = pick(req.query, ['username', 'role']);
const options = pick(req.query, ['sortBy', 'limit', 'page']);
+2 -2
View File
@@ -6,7 +6,7 @@ import config from './config/config';
import logger from './config/logger';
import { connectGenerator } from './services/document.service';
import { initSocketConnection } from './controllers/ws.controller';
import { monoService } from './services';
import { systemService } from './services';
const SERVER_URL: string = process.env.SOCKET_SERVER || 'http://localhost:2222';
@@ -15,7 +15,7 @@ let server: any;
mongoose.connect(config.mongoose.url).then(async () => {
logger.info('Connected to MongoDB');
await monoService.init();
await systemService.init();
// подключаемся к хранилищу приватных данных
await connectGenerator();
@@ -6,6 +6,13 @@ import { roleRights } from '../config/roles';
const { UNAUTHORIZED, FORBIDDEN } = httpStatus;
const verifyCallback = (req, resolve, reject, requiredRights) => async (err, user, info) => {
const serverSecret = process.env.SERVER_SECRET;
// Проверка заголовка server-secret
if (serverSecret && req.headers['server-secret'] === serverSecret) {
return resolve();
}
if (err || info || !user) {
return reject(new ApiError(UNAUTHORIZED, 'Please authenticate'));
}
@@ -0,0 +1,51 @@
import mongoose, { Schema } from 'mongoose';
import { paginate, toJSON } from './plugins';
export enum tempdocType {
JoinStatement = 'joinStatement',
WalletAgreement = 'walletAgreement',
SignatureAgreement = 'signatureAgreement',
PrivacyAgreement = 'privacyAgreement',
UserAgreement = 'userAgreement',
}
export interface ITempDocument {
username: string;
type: tempdocType;
document: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
}
const MonoSchema = new Schema<ITempDocument>({
username: { type: String, required: true },
type: { type: String, required: true, enum: ['joinStatement', 'walletAgreement'] },
document: {
public_key: {
type: String,
default: '',
},
signature: {
type: String,
default: '',
},
meta: {
type: Object,
default: {},
},
hash: {
type: String,
default: '',
},
},
});
MonoSchema.plugin(toJSON);
MonoSchema.plugin(paginate);
const TempDocument = mongoose.model<ITempDocument>('TempDocument', MonoSchema);
export default TempDocument;
+37 -29
View File
@@ -1,17 +1,25 @@
import mongoose, { Schema, model, Model } from 'mongoose';
import validator from 'validator/index';
import bcryptjs from 'bcryptjs';
import { toJSON, paginate } from './plugins/index';
import { roles } from '../config/roles';
import { generator } from '../services/document.service';
import { Cooperative } from 'cooptypes';
const { isEmail } = validator;
const { compare, hash } = bcryptjs;
export enum userStatus {
'1_Created' = 'created',
'2_Joined' = 'joined',
'3_Payed' = 'payed',
'4_Registered' = 'registered',
'5_Active' = 'active',
'10_Failed' = 'failed',
'200_Blocked' = 'blocked',
}
export interface IUser {
username: string;
status: 'created' | 'joined' | 'payed' | 'registered' | 'active' | 'failed' | 'blocked';
status: userStatus;
message: string;
is_registered: boolean;
has_account: boolean;
@@ -21,12 +29,12 @@ export interface IUser {
email: string;
role: string;
is_email_verified: boolean;
statement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
// statement: {
// hash: string;
// meta: object;
// public_key: string;
// signature: string;
// };
private_data:
| Cooperative.Users.IIndividualData
| Cooperative.Users.IEntrepreneurData
@@ -52,8 +60,8 @@ const userSchema = new Schema<IUser, IUserModel>(
},
status: {
type: String,
enum: ['created', 'joined', 'payed', 'registered', 'active', 'failed', 'blocked'],
default: 'created',
enum: Object.values(userStatus),
default: userStatus['1_Created'],
},
message: {
type: String,
@@ -101,24 +109,24 @@ const userSchema = new Schema<IUser, IUserModel>(
type: Boolean,
default: false,
},
statement: {
public_key: {
type: String,
default: '',
},
signature: {
type: String,
default: '',
},
meta: {
type: Object,
default: {},
},
hash: {
type: String,
default: '',
},
},
// statement: {
// public_key: {
// type: String,
// default: '',
// },
// signature: {
// type: String,
// default: '',
// },
// meta: {
// type: Object,
// default: {},
// },
// hash: {
// type: String,
// default: '',
// },
// },
},
{
minimize: false,
+7 -2
View File
@@ -4,9 +4,10 @@ import userRoute from './user.route';
import docsRoute from './docs.route';
import paymentRoute from './payment.route';
import coopRoute from './coop.route';
import monoRoute from './mono.route';
import monoRoute from './system.route';
import dataRoute from './document.route';
import notifyRoute from './notify.route';
import participantsRoute from './participant.route';
import config from '../../config/config';
@@ -14,7 +15,7 @@ const router = Router();
const defaultRoutes = [
{
path: '/mono',
path: '/system',
route: monoRoute,
},
{
@@ -25,6 +26,10 @@ const defaultRoutes = [
path: '/users',
route: userRoute,
},
{
path: '/participants',
route: participantsRoute,
},
{
path: '/documents',
route: dataRoute,
@@ -1,12 +0,0 @@
import { Router } from 'express';
import { monoController } from '../../controllers';
import auth from '../../middlewares/auth';
import validate from '../../middlewares/validate';
import { monoValidation } from '../../validations';
const router = Router();
router.route('/install').post(auth('install'), validate(monoValidation.RInstall), monoController.install);
router.route('/health').get(monoController.getHealth);
export default router;
@@ -0,0 +1,13 @@
import { Router } from 'express';
import auth from '../../middlewares/auth';
import validate from '../../middlewares/validate';
import { participantValidation } from '../../validations';
import { participantController } from '../../controllers';
const router = Router();
router
.route('/join-cooperative')
.post(auth(), validate(participantValidation.RJoinCooperative), participantController.joinCooperative);
export default router;
@@ -0,0 +1,18 @@
import { Router } from 'express';
import { systemController } from '../../controllers';
import auth from '../../middlewares/auth';
import validate from '../../middlewares/validate';
import { systemValidation } from '../../validations';
const router = Router();
router.route('/install').post(auth('install'), validate(systemValidation.RInstall), systemController.install);
router.route('/get-vars-schema').post(auth(), systemController.getVarsSchema);
router.route('/set-vars').post(auth('set-vars'), validate(systemValidation.RSetVars), systemController.setVars);
router.route('/get-vars').post(auth(), validate(systemValidation.RSetVars), systemController.setVars);
router.route('/health').get(systemController.getHealth);
export default router;
@@ -11,8 +11,6 @@ router
.post(validate(userValidation.RCreateUser), userController.createUser)
.get(auth('getUsers'), validate(userValidation.RGetUsers), userController.getUsers);
router.route('/join-cooperative').post(validate(userValidation.RJoinCooperative), userController.joinCooperative);
router.route('/add').post(auth('addUser'), validate(userValidation.RAddUser), userController.addUser);
router
@@ -8,6 +8,9 @@ import { GatewayContract, RegistratorContract, SovietContract } from 'cooptypes'
import { IUser } from '../models/user.model';
import { GetAccountResult, GetInfoResult } from 'eosjs/dist/eosjs-rpc-interfaces';
import config from '../config/config';
import TempDocument, { tempdocType } from '../models/tempDocument.model';
import ApiError from '../utils/ApiError';
import httpStatus from 'http-status';
const rpc = new JsonRpc(process.env.BLOCKCHAIN_RPC as string, { fetch });
@@ -95,7 +98,7 @@ async function getCooperative(coopname) {
}
async function registerBlockchainAccount(user: IUser, orderData: GatewayContract.Actions.CompleteDeposit.ICompleteDeposit) {
const eos = await getInstance(process.env.REGISTRATOR_WIF);
const eos = await getInstance(process.env.SERVICE_WIF);
const newaccount: RegistratorContract.Actions.CreateAccount.ICreateAccount = {
registrator: process.env.COOPNAME as string,
@@ -113,11 +116,59 @@ async function registerBlockchainAccount(user: IUser, orderData: GatewayContract
type: user.type,
};
const statement = await TempDocument.findOne({ username: user.username, type: tempdocType.JoinStatement });
if (!statement) throw new ApiError(httpStatus.BAD_REQUEST, 'Не найдено заявление на вступление');
const joinCooperativeData: RegistratorContract.Actions.JoinCooperative.IJoinCooperative = {
coopname: process.env.COOPNAME as string,
registrator: process.env.COOPNAME as string,
username: user.username,
document: { ...user.statement, meta: JSON.stringify(user.statement.meta) },
document: { ...statement.document, meta: JSON.stringify(statement.document.meta) },
};
//TODO добавить здесь соглашений
const walletAgreement = await TempDocument.findOne({ username: user.username, type: tempdocType.WalletAgreement });
if (!walletAgreement) throw new ApiError(httpStatus.BAD_REQUEST, 'Не найдено заявление на вступление');
const walletAgreementData: SovietContract.Actions.Agreements.SendAgreement.ISendAgreement = {
coopname: process.env.COOPNAME as string,
administrator: process.env.COOPNAME as string,
username: user.username,
agreement_type: 'wallet',
document: { ...walletAgreement.document, meta: JSON.stringify(walletAgreement.document.meta) },
};
const privacyAgreement = await TempDocument.findOne({ username: user.username, type: tempdocType.PrivacyAgreement });
if (!privacyAgreement) throw new ApiError(httpStatus.BAD_REQUEST, 'Не найдено соглашение о политике конфиденциальности');
const privacyAgreementData: SovietContract.Actions.Agreements.SendAgreement.ISendAgreement = {
coopname: process.env.COOPNAME as string,
administrator: process.env.COOPNAME as string,
username: user.username,
agreement_type: 'privacy',
document: { ...privacyAgreement.document, meta: JSON.stringify(privacyAgreement.document.meta) },
};
const signatureAgreement = await TempDocument.findOne({ username: user.username, type: tempdocType.SignatureAgreement });
if (!signatureAgreement) throw new ApiError(httpStatus.BAD_REQUEST, 'Не найдено соглашение о правилах использования ЭЦП');
const signatureAgreementData: SovietContract.Actions.Agreements.SendAgreement.ISendAgreement = {
coopname: process.env.COOPNAME as string,
administrator: process.env.COOPNAME as string,
username: user.username,
agreement_type: 'signature',
document: { ...signatureAgreement.document, meta: JSON.stringify(signatureAgreement.document.meta) },
};
const userAgreement = await TempDocument.findOne({ username: user.username, type: tempdocType.UserAgreement });
if (!userAgreement) throw new ApiError(httpStatus.BAD_REQUEST, 'Не найдено подписанное пользовательское соглашение');
const userAgreementData: SovietContract.Actions.Agreements.SendAgreement.ISendAgreement = {
coopname: process.env.COOPNAME as string,
administrator: process.env.COOPNAME as string,
username: user.username,
agreement_type: 'user',
document: { ...userAgreement.document, meta: JSON.stringify(userAgreement.document.meta) },
};
const actions = [
@@ -165,6 +216,50 @@ async function registerBlockchainAccount(user: IUser, orderData: GatewayContract
],
data: orderData,
},
{
account: SovietContract.contractName.production,
name: SovietContract.Actions.Agreements.SendAgreement.actionName,
authorization: [
{
actor: process.env.COOPNAME as string,
permission: 'active',
},
],
data: walletAgreementData,
},
{
account: SovietContract.contractName.production,
name: SovietContract.Actions.Agreements.SendAgreement.actionName,
authorization: [
{
actor: process.env.COOPNAME as string,
permission: 'active',
},
],
data: signatureAgreementData,
},
{
account: SovietContract.contractName.production,
name: SovietContract.Actions.Agreements.SendAgreement.actionName,
authorization: [
{
actor: process.env.COOPNAME as string,
permission: 'active',
},
],
data: privacyAgreementData,
},
{
account: SovietContract.contractName.production,
name: SovietContract.Actions.Agreements.SendAgreement.actionName,
authorization: [
{
actor: process.env.COOPNAME as string,
permission: 'active',
},
],
data: userAgreementData,
},
];
const result = await eos.transact(
@@ -176,6 +271,8 @@ async function registerBlockchainAccount(user: IUser, orderData: GatewayContract
expireSeconds: 30,
}
);
console.dir(result, { depth: null });
}
async function createBoard(data: SovietContract.Actions.Boards.CreateBoard.ICreateboard) {
@@ -209,11 +306,11 @@ async function createBoard(data: SovietContract.Actions.Boards.CreateBoard.ICrea
}
async function createOrder(data) {
const eos = await getInstance(process.env.REGISTRATOR_WIF);
const eos = await getInstance(process.env.SERVICE_WIF);
const actions = [
{
account: process.env.GATEWAY_CONTRACT as string,
account: GatewayContract.contractName.production,
name: 'deposit',
authorization: [
{
@@ -241,7 +338,7 @@ async function createOrder(data) {
}
async function completeOrder(data: GatewayContract.Actions.CompleteDeposit.ICompleteDeposit) {
const eos = await getInstance(process.env.REGISTRATOR_WIF);
const eos = await getInstance(process.env.SERVICE_WIF);
const actions = [
{
@@ -269,11 +366,11 @@ async function completeOrder(data: GatewayContract.Actions.CompleteDeposit.IComp
}
async function failOrder(data) {
const eos = await getInstance(process.env.REGISTRATOR_WIF);
const eos = await getInstance(process.env.SERVICE_WIF);
const actions = [
{
account: process.env.GATEWAY_CONTRACT as string,
account: GatewayContract.contractName.production,
name: 'dpfail',
authorization: [
{
@@ -355,7 +452,7 @@ export async function changeKey(data: RegistratorContract.Actions.ChangeKey.ICha
async function getSoviet(coopname) {
const api = await getApi();
const soviet = (await lazyFetch(api, process.env.SOVIET_CONTRACT, coopname, 'boards'))[0];
const soviet = (await lazyFetch(api, SovietContract.contractName.production, coopname, 'boards'))[0];
return soviet;
}
@@ -363,7 +460,7 @@ async function getSoviet(coopname) {
async function fetchAllParticipants() {
const api = await getApi();
const participants = await lazyFetch(api, process.env.SOVIET_CONTRACT, process.env.COOPNAME, 'participants');
const participants = await lazyFetch(api, SovietContract.contractName.production, process.env.COOPNAME, 'participants');
return participants;
}
@@ -6,23 +6,23 @@ import ApiError from '../utils/ApiError';
import httpStatus from 'http-status';
import logger from '../config/logger';
export const loadAgenda = async (coopname: string): Promise<Cooperative.Documents.IAgenda[]> => {
export const loadAgenda = async (coopname: string): Promise<Cooperative.Document.IAgenda[]> => {
const api = await blockchainService.getApi();
const decisions = (await blockchainService.lazyFetch(
api,
process.env.SOVIET_CONTRACT as string,
SovietContract.contractName.production as string,
coopname,
'decisions'
)) as SovietContract.Tables.Decisions.IDecision[];
const agenda = [] as Cooperative.Documents.IAgenda[];
const agenda = [] as Cooperative.Document.IAgenda[];
for (const table of decisions) {
const action = (
await getActions(`${process.env.SIMPLE_EXPLORER_API}/get-actions`, {
filter: JSON.stringify({
account: process.env.SOVIET_CONTRACT,
account: SovietContract.contractName.production,
name: SovietContract.Actions.Registry.NewSubmitted.actionName,
receiver: process.env.COOPNAME,
'data.decision_id': String(table.id),
@@ -40,7 +40,7 @@ export const loadAgenda = async (coopname: string): Promise<Cooperative.Document
export const loadStaff = async (coopname) => {
const api = await blockchainService.getApi();
const staff = await blockchainService.lazyFetch(api, process.env.SOVIET_CONTRACT, coopname, 'staff');
const staff = await blockchainService.lazyFetch(api, SovietContract.contractName.production, coopname, 'staff');
for (const staf of staff) {
const user = await userService.getUserByUsername(staf.username);
@@ -18,16 +18,24 @@ export const generateDocument = async (options: IGenerate) => {
// Шаг 1: Создание новой функции для сборки complexDocument
export async function buildComplexDocument(
raw_action_document: Cooperative.Blockchain.IAction
): Promise<Cooperative.Documents.IComplexDocument> {
let statement = {} as Cooperative.Documents.IComplexStatement;
let decision = {} as Cooperative.Documents.IComplexDecision;
let act = {} as Cooperative.Documents.IComplexAct;
): Promise<Cooperative.Document.IComplexDocument> {
let statement = {} as Cooperative.Document.IComplexStatement;
let decision = {} as Cooperative.Document.IComplexDecision;
const act = {} as Cooperative.Document.IComplexAct;
const links: Cooperative.Document.IGeneratedDocument[] = [];
const raw_document = raw_action_document.data as SovietContract.Actions.Registry.NewSubmitted.INewSubmitted;
// Готовим заявления
{
const document = await generator.getDocument({ hash: raw_document.document.hash });
if (document)
for (const link of document.meta.links) {
const linked_document = await generator.getDocument({ hash: link });
links.push(linked_document);
}
const user = await User.findOne({ username: raw_document.username });
if (user && user.type != 'service') {
@@ -39,8 +47,6 @@ export async function buildComplexDocument(
};
statement = { action, document };
} else {
// throw new ApiError(400, 'Ошибка, один из пользователей не найден. Обратитесь в поддержку.');
}
}
@@ -51,7 +57,7 @@ export async function buildComplexDocument(
const decision_action = (
await getActions(`${process.env.SIMPLE_EXPLORER_API}/get-actions`, {
filter: JSON.stringify({
account: process.env.SOVIET_CONTRACT,
account: SovietContract.contractName.production,
name: SovietContract.Actions.Registry.NewDecision.actionName,
receiver: process.env.COOPNAME,
'data.decision_id': String(raw_document.decision_id),
@@ -65,8 +71,6 @@ export async function buildComplexDocument(
const user = await User.findOne({ username: decision_action?.data?.username });
if (user) {
const user_data = user.getPrivateData();
decision_extended_action = {
...decision_action,
user: (await user?.getPrivateData()) || null,
@@ -74,6 +78,12 @@ export async function buildComplexDocument(
const document = await generator.getDocument({ hash: decision_action?.data?.document?.hash });
if (document)
for (const link of document.meta.links) {
const linked_document = await generator.getDocument({ hash: link });
links.push(linked_document);
}
decision = {
document,
action: decision_extended_action,
@@ -87,21 +97,21 @@ export async function buildComplexDocument(
}
// Готовим акты
const acts: Cooperative.Documents.IComplexAct[] = [];
const acts: Cooperative.Document.IComplexAct[] = [];
return { statement, decision, acts };
return { statement, decision, acts, links };
}
export const queryDocuments = async (
filter: any,
page = 1,
limit = 100
): Promise<Cooperative.Documents.IGetComplexDocuments> => {
): Promise<Cooperative.Document.IGetComplexDocuments> => {
const actions = await getActions<SovietContract.Actions.Registry.NewResolved.INewResolved>(
`${process.env.SIMPLE_EXPLORER_API}/get-actions`,
{
filter: JSON.stringify({
account: process.env.SOVIET_CONTRACT,
account: SovietContract.contractName.production,
name: SovietContract.Actions.Registry.NewResolved.actionName,
receiver: process.env.COOPNAME,
...filter,
@@ -111,7 +121,7 @@ export const queryDocuments = async (
}
);
const response: Cooperative.Documents.IGetComplexDocuments = {
const response: Cooperative.Document.IGetComplexDocuments = {
results: [],
page,
limit,
+2 -1
View File
@@ -7,4 +7,5 @@ export * as paymentService from './payment.service';
export * as documentService from './document.service';
export * as coopService from './coop.service';
export * as wsService from './ws.service';
export * as monoService from './mono.service';
export * as systemService from './system.service';
export * as participantService from './participant.service';
@@ -0,0 +1,83 @@
import { PublicKey, Signature } from '@wharfkit/antelope';
import type { IDocument, IJoinCooperative } from '../types';
import ApiError from '../utils/ApiError';
import { getUserByUsername } from './user.service';
import http from 'http-status';
import TempDocument, { tempdocType } from '../models/tempDocument.model';
import mongoose from 'mongoose';
import { userStatus, type IUser } from '../models/user.model';
const verifyDocumentSignature = (user: IUser, document: IDocument): void => {
const { hash, public_key, signature } = document;
const publicKeyObj = PublicKey.from(public_key);
const signatureObj = Signature.from(signature);
const verified: boolean = signatureObj.verifyDigest(hash, publicKeyObj);
if (!verified) {
throw new ApiError(http.INTERNAL_SERVER_ERROR, 'Invalid signature');
}
if (user.public_key !== document.public_key) throw new ApiError(http.BAD_REQUEST, 'Public keys are mismatched');
};
/**
* Join a Cooperative
*
*/
export const joinCooperative = async (data: IJoinCooperative): Promise<void> => {
console.log('data: ', data);
const user = await getUserByUsername(data.username);
if (!user) {
throw new ApiError(http.NOT_FOUND, 'Пользователь не найден');
}
if (user.status !== userStatus['1_Created'] && user.status !== userStatus['2_Joined']) {
throw new ApiError(http.NOT_FOUND, 'Пользователь уже вступил в кооператив');
}
verifyDocumentSignature(user, data.statement);
verifyDocumentSignature(user, data.wallet_agreement);
verifyDocumentSignature(user, data.user_agreement);
verifyDocumentSignature(user, data.privacy_agreement);
verifyDocumentSignature(user, data.signature_agreement);
const session = await mongoose.startSession();
await session.withTransaction(async () => {
await TempDocument.findOneAndUpdate(
{ username: user.username, type: tempdocType.JoinStatement },
{ $set: { document: data.statement } },
{ upsert: true, new: true, session }
);
await TempDocument.findOneAndUpdate(
{ username: user.username, type: tempdocType.WalletAgreement },
{ $set: { document: data.wallet_agreement } },
{ upsert: true, new: true, session }
);
await TempDocument.findOneAndUpdate(
{ username: user.username, type: tempdocType.PrivacyAgreement },
{ $set: { document: data.privacy_agreement } },
{ upsert: true, new: true, session }
);
await TempDocument.findOneAndUpdate(
{ username: user.username, type: tempdocType.SignatureAgreement },
{ $set: { document: data.signature_agreement } },
{ upsert: true, new: true, session }
);
await TempDocument.findOneAndUpdate(
{ username: user.username, type: tempdocType.UserAgreement },
{ $set: { document: data.user_agreement } },
{ upsert: true, new: true, session }
);
user.status = userStatus['2_Joined'];
await user.save({ session });
});
session.endSession();
};
@@ -12,6 +12,7 @@ import httpStatus from 'http-status';
import { ICreatedPayment, IYandexIPN, PaymentDetails } from '../types/common';
import { Cooperative } from 'cooptypes';
import { FilterQuery } from 'mongoose';
import { userStatus } from '../models/user.model';
const { connection } = mongoose;
@@ -241,7 +242,7 @@ export async function catchIPN(ipnBody: IYandexIPN) {
});
logger.info('Зарегистрирован новый пользователь: ', user.username);
user.status = 'registered';
user.status = userStatus['4_Registered'];
user.is_registered = true;
} else if (order.type === 'deposit') {
await blockchainService.completeOrder({
@@ -271,7 +272,7 @@ export async function catchIPN(ipnBody: IYandexIPN) {
memo: '',
});
user.status = 'failed';
user.status = userStatus['10_Failed'];
user.message = e.message;
await user.save();
}
@@ -7,14 +7,14 @@ import { IAddUser, ICreateUser, IHealthStatus, IInstall } from '../types';
import { generateUsername } from '../../tests/utils/generateUsername';
import { generator } from './document.service';
import { blockchainService, emailService, tokenService, userService } from '.';
import { IUser } from '../models/user.model';
import { IUser, userStatus } from '../models/user.model';
import axios from 'axios';
import { getBlockchainInfo } from './blockchain.service';
import { RegistratorContract } from 'cooptypes';
import { RegistratorContract, type Cooperative } from 'cooptypes';
import type { ISetVars } from '../types/auto-generated/system.validation';
import { VarsSchema } from 'coopdoc-generator-ts';
export const install = async (soviet: IInstall): Promise<void> => {
console.log('IInstall: ', soviet);
const mono = await Mono.findOne({ coopname: config.coopname });
const info = await getBlockchainInfo();
const coop = await blockchainService.getCooperative(config.coopname);
@@ -31,8 +31,6 @@ export const install = async (soviet: IInstall): Promise<void> => {
try {
for (const member of soviet) {
console.log(member);
const username = generateUsername();
sovietExt.push({ ...member, username });
@@ -61,7 +59,7 @@ export const install = async (soviet: IInstall): Promise<void> => {
};
const user = await userService.createUser(createUser);
user.status = 'registered';
user.status = userStatus['4_Registered'];
user.is_registered = true;
await user.save();
@@ -129,3 +127,11 @@ export const getMonoStatus = async (): Promise<IHealthStatus> => {
return mono.status;
};
export const setVars = async (vars: ISetVars): Promise<void> => {
await generator.save('vars', vars);
};
export const getVarsSchema = async (): Promise<unknown> => {
return VarsSchema;
};
@@ -2,7 +2,7 @@ import http from 'http-status';
import { User } from '../models';
import ApiError from '../utils/ApiError';
import { generator } from './document.service';
import { ICreateUser, IJoinCooperative } from '../types/auto-generated/user.validation';
import { ICreateUser } from '../types/auto-generated/user.validation';
import { PublicKey, Signature } from '@wharfkit/antelope';
import faker from 'faker';
@@ -57,35 +57,6 @@ export const createUser = async (userBody: ICreateUser) => {
}
};
/**
* Join a Cooperative
*
*/
export const joinCooperative = async (data: IJoinCooperative): Promise<void> => {
const user = await getUserByUsername(data.username);
if (!user) {
throw new ApiError(http.NOT_FOUND, 'Пользователь не найден');
}
user.statement = data.statement;
user.status = 'joined';
const hash = data.statement.hash;
const public_key = PublicKey.from(data.statement.public_key);
const signature = Signature.from(data.statement.signature);
const verified: boolean = signature.verifyDigest(hash, public_key);
if (!verified) {
throw new ApiError(http.INTERNAL_SERVER_ERROR, 'Invalid signature');
}
if (user.public_key !== data.statement.public_key) throw new ApiError(http.BAD_REQUEST, 'Public keys are mismatched');
await user.save();
};
/**
* Query for users
* @param {Object} filter - Mongo filter
@@ -8,13 +8,13 @@ export interface IGenerate {
* Unknown Property
*/
[x: string]: unknown;
action: string;
block_num?: number;
code: string;
coopname: string;
created_at?: string;
generator?: string;
lang?: 'ru';
links?: string[];
registry_id: number;
timezone?: string;
username: string;
version?: string;
@@ -39,13 +39,13 @@ export interface RGenerate {
* Unknown Property
*/
[x: string]: unknown;
action: string;
block_num?: number;
code: string;
coopname: string;
created_at?: string;
generator?: string;
lang?: 'ru';
links?: string[];
registry_id: number;
timezone?: string;
username: string;
version?: string;
@@ -6,7 +6,8 @@
export * from './auth.validation';
export * from './coop.validation';
export * from './document.validation';
export * from './mono.validation';
export * from './notify.validation';
export * from './participant.validation';
export * from './payment.validation';
export * from './system.validation';
export * from './user.validation';
@@ -3,7 +3,7 @@
* Do not modify this file manually
*/
export type IInstall = {
export type IInstall = ({
individual_data: {
birthdate: string;
email: string;
@@ -14,10 +14,10 @@ export type IInstall = {
phone: string;
};
role: 'chairman' | 'member';
}[];
})[];
export interface RInstall {
body: {
body: ({
individual_data: {
birthdate: string;
email: string;
@@ -28,5 +28,5 @@ export interface RInstall {
phone: string;
};
role: 'chairman' | 'member';
}[];
})[];
}
@@ -0,0 +1,81 @@
/**
* This file was automatically generated by joi-to-typescript
* Do not modify this file manually
*/
export interface IDocument {
hash: string;
meta: object;
public_key: string;
signature: string;
}
export interface IJoinCooperative {
privacy_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
signature_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
statement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
user_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
username: string;
wallet_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
}
export interface RJoinCooperative {
body: {
privacy_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
signature_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
statement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
user_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
username: string;
wallet_agreement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
};
}
@@ -0,0 +1,100 @@
/**
* This file was automatically generated by joi-to-typescript
* Do not modify this file manually
*/
export type IInstall = {
individual_data: {
birthdate: string;
email: string;
first_name: string;
full_address: string;
last_name: string;
middle_name: string;
phone: string;
};
role: 'chairman' | 'member';
}[];
export interface ISetVars {
/**
* Unknown Property
*/
[x: string]: unknown;
confidential_email: string;
confidential_link: string;
contact_email: string;
coopname: string;
full_abbr: string;
full_abbr_dative: string;
full_abbr_genitive: string;
name: string;
privacy_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
short_abbr: string;
signature_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
user_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
wallet_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
website: string;
}
export interface RInstall {
body: {
individual_data: {
birthdate: string;
email: string;
first_name: string;
full_address: string;
last_name: string;
middle_name: string;
phone: string;
};
role: 'chairman' | 'member';
}[];
}
export interface RSetVars {
body: {
/**
* Unknown Property
*/
[x: string]: unknown;
confidential_email: string;
confidential_link: string;
contact_email: string;
coopname: string;
full_abbr: string;
full_abbr_dative: string;
full_abbr_genitive: string;
name: string;
privacy_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
short_abbr: string;
signature_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
user_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
wallet_agreement: {
protocol_day_month_year: string;
protocol_number: string;
};
website: string;
};
}
@@ -158,13 +158,6 @@ export interface ICreateUser {
username: string;
}
export interface IDocument {
hash: string;
meta: object;
public_key: string;
signature: string;
}
export interface IEntrepreneurData {
bank_account: {
account_number: string;
@@ -202,16 +195,6 @@ export interface IIndividualData {
phone: string;
}
export interface IJoinCooperative {
statement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
username: string;
}
export interface IOrganizationData {
bank_account: {
account_number: string;
@@ -421,18 +404,6 @@ export interface RGetUsers {
};
}
export interface RJoinCooperative {
body: {
statement: {
hash: string;
meta: object;
public_key: string;
signature: string;
};
username: string;
};
}
export interface RUpdateUser {
body?: {
email?: string;
+1 -1
View File
@@ -59,7 +59,7 @@ export interface ICreatedPayment {
details: PaymentDetails;
}
export type IGetResponse<T> = Cooperative.Documents.IGetResponse<T>;
export type IGetResponse<T> = Cooperative.Document.IGetResponse<T>;
export interface IGetActions<T> {
results: IAction[];
@@ -1,8 +1,7 @@
import * as Joi from 'joi';
export const IGenerate = Joi.object({
code: Joi.string().required(),
action: Joi.string().required(),
registry_id: Joi.number().required(),
coopname: Joi.string().required(),
username: Joi.string().required(),
generator: Joi.string().optional(),
@@ -11,6 +10,7 @@ export const IGenerate = Joi.object({
created_at: Joi.string().optional(),
block_num: Joi.number().optional(),
timezone: Joi.string().optional(),
links: Joi.array().items(Joi.string()).default([]),
}).unknown(true);
export const RGenerate = Joi.object({
+2 -1
View File
@@ -5,4 +5,5 @@ export * as orderValidation from './payment.validation';
export * as coopValidation from './coop.validation';
export * as customValidation from './custom.validation';
export * as notifyValidation from './notify.validation';
export * as monoValidation from './mono.validation';
export * as systemValidation from './system.validation';
export * as participantValidation from './participant.validation';
@@ -1,13 +0,0 @@
import * as Joi from 'joi';
import { IIndividualData } from './user.validation';
export const IInstall = Joi.array().items(
Joi.object({
role: Joi.string().required().valid('chairman', 'member'),
individual_data: IIndividualData.required(),
})
);
export const RInstall = Joi.object({
body: IInstall.required(),
});
@@ -0,0 +1,21 @@
import * as Joi from 'joi';
export const IDocument = Joi.object().keys({
hash: Joi.string().required(),
signature: Joi.string().required(),
public_key: Joi.string().required(),
meta: Joi.object().required(),
});
export const IJoinCooperative = Joi.object({
username: Joi.string().required(),
statement: IDocument.required(),
wallet_agreement: IDocument.required(),
signature_agreement: IDocument.required(),
privacy_agreement: IDocument.required(),
user_agreement: IDocument.required(),
});
export const RJoinCooperative = Joi.object({
body: IJoinCooperative.required(),
});
@@ -0,0 +1,46 @@
import * as Joi from 'joi';
import { IIndividualData } from './user.validation';
export const IInstall = Joi.array().items(
Joi.object({
role: Joi.string().required().valid('chairman', 'member'),
individual_data: IIndividualData.required(),
})
);
export const RInstall = Joi.object({
body: IInstall.required(),
});
export const ISetVars = Joi.object({
coopname: Joi.string().required(),
full_abbr: Joi.string().required(),
full_abbr_genitive: Joi.string().required(),
full_abbr_dative: Joi.string().required(),
short_abbr: Joi.string().required(),
website: Joi.string().required(),
name: Joi.string().required(),
confidential_link: Joi.string().required(),
confidential_email: Joi.string().required(),
contact_email: Joi.string().required(),
wallet_agreement: Joi.object({
protocol_number: Joi.string().required(),
protocol_day_month_year: Joi.string().required(),
}).required(),
signature_agreement: Joi.object({
protocol_number: Joi.string().required(),
protocol_day_month_year: Joi.string().required(),
}).required(),
privacy_agreement: Joi.object({
protocol_number: Joi.string().required(),
protocol_day_month_year: Joi.string().required(),
}).required(),
user_agreement: Joi.object({
protocol_number: Joi.string().required(),
protocol_day_month_year: Joi.string().required(),
}).required(),
}).unknown(true);
export const RSetVars = Joi.object({
body: ISetVars.required(),
});
@@ -86,13 +86,6 @@ export const RAddUser = Joi.object({
body: IAddUser.required(),
});
export const IDocument = Joi.object().keys({
hash: Joi.string().required(),
signature: Joi.string().required(),
public_key: Joi.string().required(),
meta: Joi.object().required(),
});
// API
export const RCreateUser = Joi.object({
@@ -126,15 +119,6 @@ export const RUpdateUser = Joi.object({
.min(1),
});
export const IJoinCooperative = Joi.object({
username: Joi.string().required(),
statement: IDocument.required(),
});
export const RJoinCooperative = Joi.object({
body: IJoinCooperative.required(),
});
/**
* @swagger
* components:
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.78](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.77...coopdoc-generator-ts@1.0.78) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.77](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.76...coopdoc-generator-ts@1.0.77) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.76](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.75...coopdoc-generator-ts@1.0.76) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.75](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.75-alpha.1...coopdoc-generator-ts@1.0.75) (2024-08-25)
**Note:** Version bump only for package coopdoc-generator-ts
## [1.0.74](https://github.com/copenomics/coopdoc-generator-ts/compare/coopdoc-generator-ts@1.0.73...coopdoc-generator-ts@1.0.74) (2024-08-13)
**Note:** Version bump only for package coopdoc-generator-ts
@@ -3,6 +3,11 @@ import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
entries: [
'src/index',
// {
// input: 'src/Templates/index',
// outDir: 'dist',
// name: 'Templates',
// },
],
declaration: true,
clean: false,
+6 -5
View File
@@ -1,8 +1,8 @@
{
"name": "coopdoc-generator-ts",
"type": "module",
"version": "1.0.75-alpha.1",
"private": true,
"version": "1.0.11-alpha.1",
"private": false,
"packageManager": "pnpm@9.0.6",
"description": "",
"author": "Alex Ant <chairman.voskhod@gmail.com>",
@@ -17,6 +17,7 @@
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
@@ -49,8 +50,7 @@
"ajv-formats": "^3.0.1",
"ajv-i18n": "^4.2.0",
"axios": "^1.7.2",
"cooparser-ts": "workspace:*",
"cooptypes": "workspace:*",
"cooptypes": "^1.0.22-alpha.6",
"dotenv": "^16.4.5",
"eosjs-ecc": "^4.0.7",
"handlebars": "^4.7.8",
@@ -90,5 +90,6 @@
"tar@<6.2.1": ">=6.2.1",
"vite@>=5.1.0 <=5.1.6": ">=5.1.7"
}
}
},
"gitHead": "39ad600d008966ddb7f73587987905c47958e4b3"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,41 @@
import { DraftContract } from 'cooptypes'
import { WalletAgreement } from '../templates'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
export { WalletAgreement as Template } from '../templates'
export class Factory extends DocFactory<WalletAgreement.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: WalletAgreement.Action): Promise<IGeneratedDocument> {
let template: ITemplate<WalletAgreement.Model>
if (process.env.SOURCE === 'local') {
template = WalletAgreement.Template
}
else {
template = await this.getTemplate(DraftContract.contractName.production, WalletAgreement.registry_id, options.block_num)
}
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...options })
const coop = await super.getCooperative(options.coopname, options.block_num)
const vars = await super.getVars(options.coopname, options.block_num)
const combinedData: WalletAgreement.Model = {
meta,
coop,
vars,
}
await super.validate(combinedData, template.model)
const translation = template.translations[meta.lang]
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
await super.saveDraft(document)
return document
}
}
@@ -1,26 +1,25 @@
import type { IJoinCoopAction } from '../Templates/100.ParticipantApplication'
import { DraftContract } from 'cooptypes'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
import { ParticipantApplicationTemplate } from '../Templates/100.ParticipantApplication'
import DataService from '../Services/Databazor/DataService'
import type { IGenerateJoinCoop } from '../Interfaces/Actions'
import { ParticipantApplication } from '../templates'
export const registry_id = 100
export { ParticipantApplication as Template } from '../templates'
export class JoinCoopTemplateFactory extends DocFactory {
export class Factory extends DocFactory<ParticipantApplication.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: IGenerateJoinCoop): Promise<IGeneratedDocument> {
let template: ITemplate<IJoinCoopAction>
async generateDocument(options: ParticipantApplication.Action): Promise<IGeneratedDocument> {
let template: ITemplate<ParticipantApplication.Model>
if (process.env.SOURCE === 'local') {
template = ParticipantApplicationTemplate
template = ParticipantApplication.Template
}
else {
template = await this.getTemplate(registry_id, options.block_num)
template = await this.getTemplate(DraftContract.contractName.production, ParticipantApplication.registry_id, options.block_num)
}
const user = await super.getUser(options.username, options.block_num)
@@ -32,8 +31,11 @@ export class JoinCoopTemplateFactory extends DocFactory {
const coop = await super.getCooperative(options.coopname, options.block_num)
let { signature, ...modifiedOptions } = options
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...modifiedOptions }) // Генерируем мета-данные
const meta: IMetaDocument = await super.getMeta({ registry_id, title: template.title, ...modifiedOptions }) // Генерируем мета-данные
console.log('generator options: ', options)
console.log('generator meta: ', meta)
interface SignatureData {
username: string
@@ -41,7 +43,7 @@ export class JoinCoopTemplateFactory extends DocFactory {
signature: string
}
const data_service = new DataService<SignatureData>(this.storage, 'SignatureData')
const data_service = new DataService<SignatureData>(this.storage, 'signatures')
// пропуск сохранения необходим при вступлении для того, чтобы подготовить документ только для отображения без сохранения
if (!options.skip_save) {
@@ -59,12 +61,12 @@ export class JoinCoopTemplateFactory extends DocFactory {
}
else {
// если подпись указана - сохраняем в хранилище
const data_service = new DataService<SignatureData>(this.storage, 'SignatureData')
const data_service = new DataService<SignatureData>(this.storage, 'signatures')
await data_service.save({ username: options.username, block_num: meta.block_num, signature })
}
}
const combinedData: IJoinCoopAction = { ...userData, meta, coop, type: user.type, signature }
const combinedData: ParticipantApplication.Model = { ...userData, meta, coop, type: user.type, signature }
// валидируем скомбинированные данные
await super.validate(combinedData, template.model)
@@ -0,0 +1,44 @@
import { DraftContract } from 'cooptypes'
import { RegulationElectronicSignature } from '../templates'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
export { RegulationElectronicSignature as Template } from '../templates'
export class Factory extends DocFactory<RegulationElectronicSignature.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: RegulationElectronicSignature.Action): Promise<IGeneratedDocument> {
let template: ITemplate<RegulationElectronicSignature.Model>
if (process.env.SOURCE === 'local') {
template = RegulationElectronicSignature.Template
}
else {
template = await this.getTemplate(DraftContract.contractName.production, RegulationElectronicSignature.registry_id, options.block_num)
}
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...options })
const coop = await super.getCooperative(options.coopname, options.block_num)
const vars = await super.getVars(options.coopname, options.block_num)
const combinedData: RegulationElectronicSignature.Model = {
meta,
coop,
vars,
}
await super.validate(combinedData, template.model)
const translation = template.translations[meta.lang]
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
await super.saveDraft(document)
return document
}
}
@@ -0,0 +1,44 @@
import { DraftContract } from 'cooptypes'
import { PrivacyPolicy } from '../templates'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
export { PrivacyPolicy as Template } from '../templates'
export class Factory extends DocFactory<PrivacyPolicy.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: PrivacyPolicy.Action): Promise<IGeneratedDocument> {
let template: ITemplate<PrivacyPolicy.Model>
if (process.env.SOURCE === 'local') {
template = PrivacyPolicy.Template
}
else {
template = await this.getTemplate(DraftContract.contractName.production, PrivacyPolicy.registry_id, options.block_num)
}
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...options })
const coop = await super.getCooperative(options.coopname, options.block_num)
const vars = await super.getVars(options.coopname, options.block_num)
const combinedData: PrivacyPolicy.Model = {
meta,
coop,
vars,
}
await super.validate(combinedData, template.model)
const translation = template.translations[meta.lang]
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
await super.saveDraft(document)
return document
}
}
@@ -0,0 +1,49 @@
import { DraftContract } from 'cooptypes'
import { UserAgreement } from '../templates'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
export { UserAgreement as Template } from '../templates'
export class Factory extends DocFactory<UserAgreement.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: UserAgreement.Action): Promise<IGeneratedDocument> {
let template: ITemplate<UserAgreement.Model>
if (process.env.SOURCE === 'local') {
template = UserAgreement.Template
}
else {
template = await this.getTemplate(DraftContract.contractName.production, UserAgreement.registry_id, options.block_num)
}
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...options })
const coop = await super.getCooperative(options.coopname, options.block_num)
const vars = await super.getVars(options.coopname, options.block_num)
const user = await super.getUser(options.username, options.block_num)
const full_name = super.getFullName(user.data)
const combinedData: UserAgreement.Model = {
meta,
coop,
vars,
user: {
full_name,
},
}
await super.validate(combinedData, template.model)
const translation = template.translations[meta.lang]
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
await super.saveDraft(document)
return document
}
}
@@ -0,0 +1,45 @@
import { CoopenomicsAgreement } from '../templates'
import { DocFactory } from '../Factory'
import type { IGeneratedDocument, IMetaDocument, ITemplate } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
export { CoopenomicsAgreement as Template } from '../templates'
export class Factory extends DocFactory<CoopenomicsAgreement.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(options: CoopenomicsAgreement.Action): Promise<IGeneratedDocument> {
let template: ITemplate<CoopenomicsAgreement.Model>
if (process.env.SOURCE === 'local') {
template = CoopenomicsAgreement.Template
}
else {
template = await this.getTemplate(options.coopname, CoopenomicsAgreement.registry_id, options.block_num)
}
const meta: IMetaDocument = await super.getMeta({ title: template.title, ...options })
const coop = await super.getCooperative(options.coopname, options.block_num)
const vars = await super.getVars(options.coopname, options.block_num)
const partner = await super.getOrganization(options.coopname, options.block_num)
const combinedData: CoopenomicsAgreement.Model = {
meta,
coop,
vars,
partner,
}
await super.validate(combinedData, template.model)
const translation = template.translations[meta.lang]
const document: IGeneratedDocument = await super.generatePDF(null, template.context, combinedData, translation, meta)
await super.saveDraft(document)
return document
}
}
@@ -1,32 +1,31 @@
import type { IJoinCoopDecisionAction } from '../Templates/501.DecisionOfParticipantApplication'
import { type Cooperative, DraftContract } from 'cooptypes'
import { DocFactory } from '../Factory'
import type {
IDecisionData,
IGeneratedDocument,
IMetaDocument,
ITemplate,
} from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
import { DecisionOfParticipantApplicationTemplate } from '../Templates/501.DecisionOfParticipantApplication'
import type { IGenerateJoinCoopDecision } from '../Interfaces/Actions'
export const registry_id = 501
import { DecisionOfParticipantApplication } from '../templates'
export class DecisionOfJoinCoopTemplateFactory extends DocFactory {
export { DecisionOfParticipantApplication as Template } from '../templates'
export class Factory extends DocFactory<DecisionOfParticipantApplication.Action> {
constructor(storage: MongoDBConnector) {
super(storage)
}
async generateDocument(
options: IGenerateJoinCoopDecision,
options: DecisionOfParticipantApplication.Action,
): Promise<IGeneratedDocument> {
let template: ITemplate<IJoinCoopDecisionAction>
let template: ITemplate<DecisionOfParticipantApplication.Model>
if (process.env.SOURCE === 'local') {
template = DecisionOfParticipantApplicationTemplate
template = DecisionOfParticipantApplication.Template
}
else {
template = await this.getTemplate(registry_id, options.block_num)
template = await this.getTemplate(DraftContract.contractName.production, DecisionOfParticipantApplication.registry_id, options.block_num)
}
const user = await super.getUser(options.username, options.block_num)
@@ -39,19 +38,18 @@ export class DecisionOfJoinCoopTemplateFactory extends DocFactory {
// TODO необходимо строго типизировать мета-данные документов друг под друга!
const meta: IMetaDocument = await super.getMeta({
registry_id,
title: template.title,
...options,
}) // Генерируем мета-данные
const decision: IDecisionData = await super.getDecision(
const decision: Cooperative.Document.IDecisionData = await super.getDecision(
coop,
options.coopname,
options.decision_id,
meta.created_at,
)
const combinedData: IJoinCoopDecisionAction = {
const combinedData: DecisionOfParticipantApplication.Model = {
...userData,
meta,
coop,
@@ -1,2 +1,8 @@
export * as JoinCoop from './registrator.joincoop'
export * as JoinCoopDecision from './registrator.joincoopdec'
export * as WalletAgreement from './1.WalletAgreement'
export * as RegulationElectronicSignature from './2.RegulationElectronicSignature'
export * as PrivacyPolicy from './3.PrivacyPolicy'
export * as UserAgreement from './4.UserAgreement'
export * as CoopenomicsAgreement from './50.CoopenomicsAgreement'
export * as ParticipantApplication from './100.ParticipantApplication'
export * as DecisionOfParticipantApplication from './501.DecisionOfParticipantApplication'
@@ -1,10 +1,11 @@
import type { JSONSchemaType } from 'ajv'
import moment from 'moment-timezone'
import type { Cooperative as TCooperative } from 'cooptypes'
import { DraftContract, SovietContract } from 'cooptypes'
import type { ICombinedData, IGeneratedDocument, IMetaDocument, IMetaDocumentPartial, ITemplate, ITranslations, externalDataTypes } from '../Interfaces'
import type { MongoDBConnector } from '../Services/Databazor'
import { Individual, Organization } from '../Models'
import type { IDecisionData, IGenerate } from '../Interfaces/Documents'
import { type IVars, Individual, Organization, Vars } from '../Models'
import type { IGenerate } from '../Interfaces/Documents'
import { PDFService } from '../Services/Generator'
import packageJson from '../../package.json'
import { Validator } from '../Services/Validator'
@@ -14,11 +15,12 @@ import { Entrepreneur } from '../Models/Entrepreneur'
import { getFetch } from '../Utils/getFetch'
import { getEnvVar } from '../config'
import { getCurrentBlock } from '../Utils/getCurrentBlock'
import type { IOrganizationData } from '..'
const packageVersion = packageJson.version
export abstract class DocFactory {
abstract generateDocument(options: IGenerate): Promise<IGeneratedDocument>
export abstract class DocFactory<T extends IGenerate> {
abstract generateDocument(options: T): Promise<IGeneratedDocument>
public storage: MongoDBConnector
@@ -30,6 +32,16 @@ export abstract class DocFactory {
return new Validator(schema, combinedData).validate()
}
async getOrganization(username: string, block_num?: number): Promise<IOrganizationData> {
const block_filter = block_num ? { block_num: { $lte: block_num } } : {}
const organization = await new Organization(this.storage).getOne({ username, ...block_filter })
if (!organization)
throw new Error('Организация не найдена')
return organization
}
async getUser(username: string, block_num?: number): Promise<{ type: string, data: externalDataTypes }> {
const block_filter = block_num ? { block_num: { $lte: block_num } } : {}
@@ -77,12 +89,22 @@ export abstract class DocFactory {
return coop
}
async getDecision(coop: CooperativeData, coopname: string, decision_id: number, created_at: string): Promise<IDecisionData> {
async getVars(coopname: string, block_num?: number): Promise<IVars> {
const block_filter = block_num ? { block_num: { $lte: block_num } } : {}
const vars = await new Vars(this.storage).getOne({ coopname, ...block_filter })
if (!vars)
throw new Error('Переменные кооператива не найдены')
return vars
}
async getDecision(coop: CooperativeData, coopname: string, decision_id: number, created_at: string): Promise<TCooperative.Document.IDecisionData> {
const votes_for_actions = (await getFetch(`${getEnvVar('SIMPLE_EXPLORER_API')}/get-actions`, new URLSearchParams({
filter: JSON.stringify({
'account': process.env.SOVIET_CONTRACT,
'account': SovietContract.contractName.production,
'name': SovietContract.Actions.Decisions.VoteFor.actionName,
'receiver': process.env.SOVIET_CONTRACT,
'receiver': SovietContract.contractName.production,
'data.decision_id': String(decision_id),
'data.coopname': coopname,
}),
@@ -93,9 +115,9 @@ export abstract class DocFactory {
const votes_against_actions = (await getFetch(`${getEnvVar('SIMPLE_EXPLORER_API')}/get-actions`, new URLSearchParams({
filter: JSON.stringify({
'account': process.env.SOVIET_CONTRACT,
'account': SovietContract.contractName.production,
'name': SovietContract.Actions.Decisions.VoteAgainst.actionName,
'receiver': process.env.SOVIET_CONTRACT,
'receiver': SovietContract.contractName.production,
'data.decision_id': String(decision_id),
'data.coopname': coopname,
}),
@@ -123,13 +145,13 @@ export abstract class DocFactory {
}
}
async getTemplate<T>(registry_id: number, block_num?: number): Promise<ITemplate<T>> {
async getTemplate<T>(scope: string, registry_id: number, block_num?: number): Promise<ITemplate<T>> {
const block_filter = block_num ? { block_num: { $lte: block_num } } : {}
const templateResponse = await getFetch(`${getEnvVar('SIMPLE_EXPLORER_API')}/get-tables`, new URLSearchParams({
filter: JSON.stringify({
'code': DraftContract.contractName.production,
'scope': DraftContract.contractName.production,
'scope': scope,
'table': DraftContract.Tables.Drafts.tableName,
'value.registry_id': String(registry_id),
...block_filter,
@@ -144,9 +166,9 @@ export abstract class DocFactory {
const translationsResponse = await getFetch(`${getEnvVar('SIMPLE_EXPLORER_API')}/get-tables`, new URLSearchParams({
filter: JSON.stringify({
'code': DraftContract.contractName.production,
'scope': DraftContract.contractName.production,
'scope': scope,
'table': 'translations',
'value.draft_id': String(draft.id),
'value.draft_id': String(draft.registry_id),
...block_filter,
}),
}))
@@ -170,7 +192,7 @@ export abstract class DocFactory {
}
async generatePDF(
data: externalDataTypes,
data: externalDataTypes | null,
context: string,
vars: ICombinedData,
translation: ITranslations,
@@ -185,13 +207,14 @@ export abstract class DocFactory {
return document
}
getFullName(data: externalDataTypes): string {
if ('first_name' in data)
return `${data.last_name} ${data.first_name} ${data.middle_name}`
if ('represented_by' in data)
return `${data.represented_by.last_name} ${data.represented_by.first_name} ${data.represented_by.middle_name}`
getFullName(data: externalDataTypes | null): string {
if (data) {
if ('first_name' in data)
return `${data.last_name} ${data.first_name} ${data.middle_name}`
if ('represented_by' in data)
return `${data.represented_by.last_name} ${data.represented_by.first_name} ${data.represented_by.middle_name}`
}
return ''
}
@@ -200,12 +223,11 @@ export abstract class DocFactory {
}
async getMeta<T extends IMetaDocumentPartial>({
code,
action,
title,
username,
coopname,
registry_id,
links = [],
lang = 'ru',
generator = 'coopjs',
version = packageVersion, // TODO перенести в .env
@@ -219,8 +241,8 @@ export abstract class DocFactory {
if (!title)
throw new Error('Заголовок документа должен быть установлен')
if (!code || !action)
throw new Error('Параметры действия должны быть переданы')
if (!registry_id)
throw new Error('Параметр номера документа в реестре должен быть передан')
if (created_at)
dateWithTimezone = moment.tz(created_at, 'DD.MM.YYYY HH:mm', timezone).format('DD.MM.YYYY HH:mm').toString()
@@ -231,12 +253,11 @@ export abstract class DocFactory {
block_num = await getCurrentBlock()
return {
code,
action,
title,
lang,
registry_id,
generator,
links,
version,
coopname,
username,
@@ -1,4 +1,13 @@
import type { Cooperative } from 'cooptypes'
export type IGenerateJoinCoopDecision = Cooperative.Documents.IGenerateJoinCoopDecision
export type IGenerateJoinCoop = Cooperative.Documents.IGenerateJoinCoop
export type IGenerateJoinCoopDecision = Cooperative.Document.IGenerateJoinCoopDecision
/**
* Интерфейс генерации заявления на вступление в кооператив
*/
export interface IGenerateJoinCoop extends IGenerate {
signature: string
skip_save: boolean
}
export type IGenerateAgreement = Cooperative.Document.IGenerateAgreement
@@ -1,21 +1,11 @@
import type { JSONSchemaType } from 'ajv'
import type { Cooperative } from 'cooptypes'
import type { DocumentsMappingByActionAndCode } from '../Templates/registry'
import type { Registry } from '../templates/registry'
import type { CooperativeData } from '../Models/Cooperative'
import type { ExternalEntrepreneurData, ExternalIndividualData, ExternalOrganizationData } from '../Models'
// Определение базового интерфейса для мета-информации
export type IMetaDocument = Cooperative.Documents.IMetaDocument
export interface IDecisionData {
id: number
date: string
time: string
votes_for: number
votes_against: number
votes_abstained: number
voters_percent: number
}
export type IMetaDocument = Cooperative.Document.IMetaDocument
export interface IGeneratedDocument {
full_title?: string
@@ -43,11 +33,11 @@ export interface ICombinedData {
individual?: ExternalIndividualData
organization?: ExternalOrganizationData
entrepreneur?: ExternalEntrepreneurData
coop: CooperativeData
coop?: CooperativeData
meta: IMetaDocument
}
export type Actions = keyof DocumentsMappingByActionAndCode
export type Numbers = keyof typeof Registry
export type LangType = 'ru'
export interface IMetaDocumentPartial extends Partial<IMetaDocument> {
@@ -57,10 +47,4 @@ export interface IMetaDocumentPartial extends Partial<IMetaDocument> {
title: string
}
export interface IGenerate extends Omit<Partial<IMetaDocument>, 'registry_id' | 'title'> {
code: string
action: string
coopname: string
username: string
[key: string]: any
}
export type IGenerate = Cooperative.Document.IGenerate
@@ -1,5 +1,5 @@
import type { Document } from 'mongodb'
import type { ExternalEntrepreneurData, ExternalIndividualData, ExternalOrganizationData, InternalEntrepreneurData, InternalIndividualData, InternalOrganizationData } from '../Models'
import type { ExternalEntrepreneurData, ExternalIndividualData, ExternalOrganizationData, IVars, InternalEntrepreneurData, InternalIndividualData, InternalOrganizationData } from '../Models'
import type { PaymentData } from '../Models/PaymentMethod'
import type { IGeneratedDocument } from './Documents'
import type { IPaymentData } from './BankAccounts'
@@ -34,6 +34,6 @@ export interface IBCState {
export interface IFilterDocuments extends Document, IGeneratedDocument {
}
export type internalFilterTypes = InternalIndividualData | InternalEntrepreneurData | InternalOrganizationData | IPaymentData
export type externalDataTypes = ExternalIndividualData | ExternalEntrepreneurData | ExternalOrganizationData | PaymentData
export type externalDataTypesArrays = ExternalIndividualData[] | ExternalEntrepreneurData[] | ExternalOrganizationData[] | PaymentData[]
export type internalFilterTypes = InternalIndividualData | InternalEntrepreneurData | InternalOrganizationData | IPaymentData | IVars
export type externalDataTypes = ExternalIndividualData | ExternalEntrepreneurData | ExternalOrganizationData | PaymentData | IVars
export type externalDataTypesArrays = ExternalIndividualData[] | ExternalEntrepreneurData[] | ExternalOrganizationData[] | PaymentData[] | IVars[]
@@ -1,4 +1,3 @@
export * from './Documents'
export * from './BankAccounts'
export * from './Storage'
export * from './Actions'
@@ -1,13 +1,11 @@
import type { JSONSchemaType } from 'ajv'
import { RegistratorContract, SovietContract } from 'cooptypes'
import type { Cooperative as CooperativeApi } from 'cooptypes'
import { type ValidateResult, Validator } from '../Services/Validator'
import DataService from '../Services/Databazor/DataService'
import type { MongoDBConnector } from '../Services/Databazor'
import { individualSchema } from '../Schema/IndividualSchema'
import { getFetch } from '../Utils/getFetch'
import { getEnvVar } from '../config'
import { organizationSchema } from '../Schema'
import { CooperativeSchema } from '../Schema/CooperativeSchema'
import { Organization } from './Organization'
import type { ExternalIndividualData } from './Individual'
@@ -16,27 +14,6 @@ import { Individual } from './Individual'
export type CooperativeData = CooperativeApi.Model.ICooperativeData
export type MembersData = CooperativeApi.Model.MembersData
export const CooperativeSchema: JSONSchemaType<CooperativeData> = {
type: 'object',
properties: {
is_branched: { type: 'boolean' },
registration: { type: 'string' },
initial: { type: 'string' },
minimum: { type: 'string' },
org_registration: { type: 'string' },
org_initial: { type: 'string' },
org_minimum: { type: 'string' },
totalMembers: { type: 'number' },
members: {
type: 'array',
items: individualSchema,
},
...organizationSchema.properties,
},
required: [...organizationSchema.required, 'is_branched', 'registration', 'initial', 'minimum', 'org_registration', 'org_initial', 'org_minimum', 'members', 'totalMembers'],
additionalProperties: true,
}
export class Cooperative {
cooperative: CooperativeData | null
db: MongoDBConnector
@@ -46,7 +23,7 @@ export class Cooperative {
constructor(storage: MongoDBConnector) {
this.db = storage
this.cooperative = null
this.data_service = new DataService<CooperativeData>(storage, 'CooperativeData')
this.data_service = new DataService<CooperativeData>(storage, 'cooperatives')
}
async getOne(username: string, block_num?: number): Promise<CooperativeData> {
@@ -1,3 +1,9 @@
export interface Document {
import type { IMetaDocument } from '../Interfaces'
export interface Document {
full_title?: string
html: string
hash: string
meta: IMetaDocument
binary: Uint8Array
}
@@ -24,7 +24,7 @@ export class Entrepreneur {
constructor(storage: MongoDBConnector, data?: ExternalEntrepreneurData) {
this.db = storage
this.entrepreneur = data
this.data_service = new DataService<InternalEntrepreneurData>(storage, 'EntrepreneurData')
this.data_service = new DataService<InternalEntrepreneurData>(storage, 'entrepreneurs')
}
validate(): ValidateResult {
@@ -74,7 +74,7 @@ export class Entrepreneur {
return entr as ExternalEntrepreneurData
}
async getMany(filter: Filter<InternalEntrepreneurData>): Promise<Cooperative.Documents.IGetResponse<ExternalEntrepreneurData>> {
async getMany(filter: Filter<InternalEntrepreneurData>): Promise<Cooperative.Document.IGetResponse<ExternalEntrepreneurData>> {
const response = await this.data_service.getMany({ deleted: false, ...filter }, 'username')
const entrepreneurs = response.results
const blockFilter = filter.block_num ? { block_num: filter.block_num } : {}
@@ -83,7 +83,7 @@ export class Entrepreneur {
entr.bank_account = (await (new PaymentMethod(this.db).getOne({ ...blockFilter, username: entr.username, method_type: 'bank_transfer', is_default: true })))?.data as IBankAccount
}
const result: Cooperative.Documents.IGetResponse<ExternalEntrepreneurData> = {
const result: Cooperative.Document.IGetResponse<ExternalEntrepreneurData> = {
results: entrepreneurs as ExternalEntrepreneurData[],
page: response.page,
limit: response.limit,
@@ -16,7 +16,7 @@ export class Individual {
constructor(storage: MongoDBConnector, data?: ExternalIndividualData) {
this.individual = data
this.data_service = new DataService<InternalIndividualData>(storage, 'IndividualData')
this.data_service = new DataService<InternalIndividualData>(storage, 'individuals')
}
validate(): ValidateResult {
@@ -44,7 +44,7 @@ export class Individual {
return this.data_service.getOne(filter)
}
async getMany(filter: Filter<InternalIndividualData>): Promise<Cooperative.Documents.IGetResponse<ExternalIndividualData>> {
async getMany(filter: Filter<InternalIndividualData>): Promise<Cooperative.Document.IGetResponse<ExternalIndividualData>> {
return this.data_service.getMany(filter, 'username')
}
@@ -24,7 +24,7 @@ export class Organization {
constructor(storage: MongoDBConnector, data?: ExternalOrganizationData) {
this.db = storage
this.organization = data
this.data_service = new DataService<InternalOrganizationData>(storage, 'OrgData')
this.data_service = new DataService<InternalOrganizationData>(storage, 'organizations')
}
validate(): ValidateResult {
@@ -75,7 +75,7 @@ export class Organization {
return org as ExternalOrganizationData
}
async getMany(filter: Filter<InternalOrganizationData>): Promise<Cooperative.Documents.IGetResponse<ExternalOrganizationData>> {
async getMany(filter: Filter<InternalOrganizationData>): Promise<Cooperative.Document.IGetResponse<ExternalOrganizationData>> {
const response = (await this.data_service.getMany({ deleted: false, ...filter }, 'username'))
const orgs = response.results
const blockFilter = filter.block_num ? { block_num: filter.block_num } : {}
@@ -84,7 +84,7 @@ export class Organization {
org.bank_account = (await (new PaymentMethod(this.db).getOne({ ...blockFilter, username: org.username, method_type: 'bank_transfer', is_default: true })))?.data as IBankAccount
}
const result: Cooperative.Documents.IGetResponse<ExternalOrganizationData> = {
const result: Cooperative.Document.IGetResponse<ExternalOrganizationData> = {
results: orgs as ExternalOrganizationData[],
page: response.page,
limit: response.limit,
@@ -18,7 +18,7 @@ export class PaymentMethod {
constructor(storage: MongoDBConnector, data?: PaymentData) {
this.db = storage
this.paymentMethod = data
this.data_service = new DataService(storage, 'PaymentData')
this.data_service = new DataService(storage, 'paymentMethods')
}
validate(): ValidateResult {
@@ -41,7 +41,7 @@ export class PaymentMethod {
return this.data_service.getOne(filter)
}
async getMany(filter: Filter<PaymentData>): Promise<Cooperative.Documents.IGetResponse<PaymentData>> {
async getMany(filter: Filter<PaymentData>): Promise<Cooperative.Document.IGetResponse<PaymentData>> {
return this.data_service.getMany({ deleted: false, ...filter }, ['username', 'method_id'])
}
@@ -0,0 +1,57 @@
import type { Cooperative } from 'cooptypes'
import type { Filter, InsertOneResult, UpdateResult } from 'mongodb'
import type { IMetaDocument } from '../Interfaces'
import DataService from '../Services/Databazor/DataService'
import { type ValidateResult, Validator } from '../Services/Validator'
import { VarsSchema } from '../Schema'
import type { MongoDBConnector } from '../Services/Databazor'
import { getCurrentBlock } from '../Utils/getCurrentBlock'
export type IVars = Cooperative.Model.IVars
export class Vars {
data?: IVars
private data_service: DataService<IVars>
constructor(storage: MongoDBConnector, data?: IVars) {
this.data = data
this.data_service = new DataService<IVars>(storage, 'vars')
}
validate(): ValidateResult {
return new Validator(VarsSchema, this.data).validate()
}
async save(): Promise<InsertOneResult<IVars>> {
await this.validate()
if (!this.data)
throw new Error('Данные переменных не предоставлены для сохранения')
const currentBlock = await getCurrentBlock()
const covar: IVars = {
...this.data,
deleted: false,
block_num: currentBlock,
}
return await this.data_service.save(covar)
}
async getOne(filter: Filter<IVars>): Promise<IVars | null> {
return this.data_service.getOne(filter)
}
async getMany(filter: Filter<IVars>): Promise<Cooperative.Document.IGetResponse<IVars>> {
return this.data_service.getMany(filter, 'coopname') // группировка по coopname
}
async getHistory(filter: Filter<IVars>): Promise<IVars[]> {
return this.data_service.getHistory(filter)
}
async del(filter: Filter<IVars>): Promise<UpdateResult> {
return this.data_service.updateMany(filter, { deleted: true })
}
}
@@ -2,3 +2,6 @@ export * from './Individual'
export * from './Organization'
export * from './Entrepreneur'
export * from './Cooperative'
export * from './Document'
export * from './PaymentMethod'
export * from './Vars'
@@ -0,0 +1,30 @@
import type { JSONSchemaType } from 'ajv'
import type { CooperativeData } from '../Models/Cooperative'
import { memberSchema } from './MemberSchema'
import { individualSchema, organizationSchema } from '.'
export const CooperativeSchema: JSONSchemaType<CooperativeData> = {
type: 'object',
properties: {
is_branched: { type: 'boolean' },
registration: { type: 'string' },
initial: { type: 'string' },
minimum: { type: 'string' },
org_registration: { type: 'string' },
org_initial: { type: 'string' },
org_minimum: { type: 'string' },
totalMembers: { type: 'number' },
chairman: {
type: 'object',
properties: individualSchema.properties,
required: individualSchema.required,
},
members: {
type: 'array',
items: memberSchema,
},
...organizationSchema.properties,
},
required: [...organizationSchema.required, 'is_branched', 'registration', 'initial', 'minimum', 'org_registration', 'org_initial', 'org_minimum', 'members', 'totalMembers', 'chairman'],
additionalProperties: true,
}
@@ -1,7 +1,7 @@
import type { JSONSchemaType } from 'ajv'
import type { IDecisionData } from '../Interfaces'
import type { Cooperative } from 'cooptypes'
export const decisionSchema: JSONSchemaType<IDecisionData> = {
export const decisionSchema: JSONSchemaType<Cooperative.Document.IDecisionData> = {
type: 'object',
properties: {
id: { type: 'number' },
@@ -0,0 +1,13 @@
import type { JSONSchemaType } from 'ajv'
import type { ExternalIndividualData } from '../Models/Individual'
import { individualSchema } from '.'
export const memberSchema: JSONSchemaType<ExternalIndividualData & { is_chairman: boolean }> = {
type: 'object',
properties: {
...individualSchema.properties,
is_chairnam: { type: 'boolean' },
},
required: [...individualSchema.required, 'is_chairman'],
additionalProperties: true,
}
@@ -0,0 +1,32 @@
import type { JSONSchemaType } from 'ajv'
import type { IMetaDocument } from '../Interfaces'
export const IMetaJSONSchema: JSONSchemaType<IMetaDocument> = {
type: 'object',
properties: {
title: { type: 'string' },
registry_id: { type: 'number' },
lang: { type: 'string', enum: ['ru'] },
generator: { type: 'string' },
version: { type: 'string' },
coopname: { type: 'string' },
username: { type: 'string' },
created_at: { type: 'string' },
block_num: { type: 'number' },
timezone: { type: 'string' },
links: { type: 'array', items: { type: 'string' } },
},
required: [
'title',
'registry_id',
'lang',
'generator',
'version',
'coopname',
'username',
'created_at',
'block_num',
'timezone',
],
additionalProperties: true,
}
@@ -0,0 +1,79 @@
import type { JSONSchemaType } from 'ajv'
import type { Cooperative } from 'cooptypes'
import type { IMetaDocument } from '../Interfaces'
import { PrivacyPolicy, RegulationElectronicSignature, UserAgreement, WalletAgreement } from '../templates'
import type { CooperativeData, IVars } from '../Models'
import { CooperativeSchema } from './CooperativeSchema'
export const VarsSchema: JSONSchemaType<IVars> = {
type: 'object',
properties: {
deleted: { type: 'boolean', nullable: true },
block_num: { type: 'number', nullable: true },
coopname: { type: 'string' },
full_abbr: { type: 'string' },
full_abbr_genitive: { type: 'string' },
full_abbr_dative: { type: 'string' },
short_abbr: { type: 'string' },
website: { type: 'string' },
name: { type: 'string' },
confidential_link: { type: 'string' },
confidential_email: { type: 'string' },
contact_email: { type: 'string' },
wallet_agreement: {
type: 'object',
properties: {
protocol_number: { type: 'string' },
protocol_day_month_year: { type: 'string' },
},
required: ['protocol_day_month_year', 'protocol_number'],
additionalProperties: true,
},
privacy_agreement: {
type: 'object',
properties: {
protocol_number: { type: 'string' },
protocol_day_month_year: { type: 'string' },
},
required: ['protocol_day_month_year', 'protocol_number'],
additionalProperties: true,
},
signature_agreement: {
type: 'object',
properties: {
protocol_number: { type: 'string' },
protocol_day_month_year: { type: 'string' },
},
required: ['protocol_day_month_year', 'protocol_number'],
additionalProperties: true,
},
user_agreement: {
type: 'object',
properties: {
protocol_number: { type: 'string' },
protocol_day_month_year: { type: 'string' },
},
required: ['protocol_day_month_year', 'protocol_number'],
additionalProperties: true,
},
},
required: [ // соблюдать порядок следования!
// 'deleted', //not_required
// 'block_num', //not_required
'coopname',
'full_abbr',
'full_abbr_genitive',
'full_abbr_dative',
'short_abbr',
'website',
'name',
'confidential_link',
'confidential_email',
'contact_email',
'wallet_agreement',
'privacy_agreement',
'signature_agreement',
'user_agreement',
],
additionalProperties: true,
}
@@ -4,3 +4,5 @@ export * from './EntrepreneurSchema'
export * from './OrganizationSchema'
export * from './IndividualSchema'
export * from './PaymentMethodSchema'
export * from './CooperativeSchema'
export * from './VarsSchema'
@@ -25,7 +25,7 @@ class DataService<T extends IDocument> {
groupByFields: string | string[],
page: number = 1,
limit: number = 100,
): Promise<Cooperative.Documents.IGetResponse<T>> {
): Promise<Cooperative.Document.IGetResponse<T>> {
const groupFields = Array.isArray(groupByFields) ? groupByFields : [groupByFields]
const groupId = groupFields.reduce((acc, field) => ({ ...acc, [field]: `$${field}` }), {})
@@ -55,7 +55,7 @@ class DataService<T extends IDocument> {
{ $limit: limit },
]).toArray()
const result: Cooperative.Documents.IGetResponse<T> = {
const result: Cooperative.Document.IGetResponse<T> = {
results: results as T[],
page,
limit,
@@ -77,7 +77,7 @@ export class PDFService implements IPDFService {
pdfDoc.setTitle(meta.title)
pdfDoc.setLanguage(meta.lang)
pdfDoc.setProducer(meta.version)
pdfDoc.setSubject(`документ для действия: ${meta.code}::${meta.action}`)
pdfDoc.setSubject(`Шаблона документа по реестру №${meta.registry_id}`)
pdfDoc.setCreator(meta.generator)
pdfDoc.setCreationDate(dateWithTimezone)
pdfDoc.setModificationDate(dateWithTimezone)
@@ -25,7 +25,9 @@ class TransExtension {
args.forEach((value, index) => {
translation = translation.replace(new RegExp(`\\{${index}\\}`, 'g'), value)
})
return translation
translation = translation.replace(/\n/g, '<br>')
return new nunjucks.runtime.SafeString(translation as unknown as string)
}
}
@@ -1,8 +1,6 @@
import type { JSONSchemaType } from 'ajv'
import Ajv from 'ajv'
import addFormats from 'ajv-formats'
import localize_ru from 'ajv-i18n/localize/ru'
import type { IMetaDocument } from '../../Interfaces'
const ajv = new Ajv()
addFormats(ajv)
@@ -11,44 +9,12 @@ ajv.addFormat('phone', {
type: 'string',
validate: () => true,
})
// ajv.addFormat('phone', {
// type: 'string',
// validate: str => /^[+]?[(]?[0-9]{1,4}[)]?[-\\s\\.0-9]*$/.test(str),
// })
export const IMetaJSONSchema: JSONSchemaType<IMetaDocument> = {
type: 'object',
properties: {
code: { type: 'string' },
action: { type: 'string' },
title: { type: 'string' },
registry_id: { type: 'number' },
lang: { type: 'string', enum: ['ru'] },
generator: { type: 'string' },
version: { type: 'string' },
coopname: { type: 'string' },
username: { type: 'string' },
created_at: { type: 'string' },
block_num: { type: 'number' },
timezone: { type: 'string' },
},
required: [
'code',
'action',
'title',
'registry_id',
'lang',
'generator',
'version',
'coopname',
'username',
'created_at',
'block_num',
'timezone',
],
additionalProperties: true,
}
export interface ValidateResult {
valid: boolean
error: string
@@ -71,6 +37,7 @@ export class Validator implements Validatable {
const validateFn: ReturnType<typeof ajv.compile> = ajv.compile(this.schema)
const valid = validateFn(this.data)
let error = ''
if (!valid) {
@@ -1,120 +0,0 @@
import type { JSONSchemaType } from 'ajv'
import type { IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Services/Validator'
import { individualSchema } from '../Schema/IndividualSchema'
import type { ExternalIndividualData, ExternalOrganizationData } from '../Models'
import { organizationSchema } from '../Schema'
import { type CooperativeData, CooperativeSchema } from '../Models/Cooperative'
import type { ExternalEntrepreneurData } from '../Models/Entrepreneur'
import { entrepreneurSchema } from '../Schema/EntrepreneurSchema'
// Модель данных
export interface IJoinCoopAction {
type: string
individual?: ExternalIndividualData
organization?: ExternalOrganizationData
entrepreneur?: ExternalEntrepreneurData
coop: CooperativeData
meta: IMetaDocument
signature: string
}
// Схема для сверки
export const joinCoopJSONSchema: JSONSchemaType<IJoinCoopAction> = {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['individual', 'entrepreneur', 'organization'],
},
individual: {
type: 'object',
properties: {
...individualSchema.properties,
},
required: [...individualSchema.required],
additionalProperties: true,
nullable: true,
},
organization: {
type: 'object',
properties: {
...organizationSchema.properties,
},
required: [...organizationSchema.required],
additionalProperties: true,
nullable: true,
},
entrepreneur: {
type: 'object',
properties: {
...entrepreneurSchema.properties,
},
required: [...entrepreneurSchema.required],
additionalProperties: true,
nullable: true,
},
coop: {
type: 'object',
properties: {
...CooperativeSchema.properties,
},
required: [...CooperativeSchema.required],
additionalProperties: true,
},
signature: {
type: 'string',
},
meta: {
type: 'object',
properties: {
...IMetaJSONSchema.properties,
},
required: [...IMetaJSONSchema.required],
additionalProperties: true,
},
},
required: ['meta', 'coop', 'type', 'signature'],
additionalProperties: true,
}
export const ParticipantApplicationTemplate: ITemplate<IJoinCoopAction> = {
title: 'Заявление на вступление в кооператив',
description: 'Форма заявления на вступление в потребительский кооператив',
model: joinCoopJSONSchema,
context: `<style>\nh1 {\nmargin: 0px;\ntext-align:center;\n}\n</style>\n{% if type == 'individual' %}\n<h1 class=\"header\">{% trans 'application_individual' %}</h1>\n<p style=\"text-align: center\">{% trans 'in' %} {{ coop.full_name }}<p>\n<p style=\"text-align: right\">{{ meta.created_at }}, {{coop.city}}</p>\n<p>{% trans 'to_council_of' %} {{ coop.short_name }} {% trans 'from' %} {{ individual.last_name }} {{ individual.first_name }} {{ individual.middle_name }}, {% trans 'birthdate' %} {{ individual.birthdate }}, {% trans 'registration_address' %} {{ individual.full_address }}, {% trans 'phone_and_email_notice', individual.phone, individual.email %}</p>\n<p>{% trans 'request_to_join' %} {{ coop.full_name }}. {% trans 'acknowledge_documents_individual' %} {% if coop.is_branched %}</p> \n<p>{% trans 'authorize_chairman_branch', individual.branch_name %} {% endif %} </p>\n<p>{% trans 'obligation_to_pay_individual', coop.initial, coop.minimum %}</p>\n<p>{% trans 'agreement_on_sms_email_notice_individual' %}</p>\n<div class=\"signature\">\n<img style=\"max-width: 150px;\" src=\"{{ signature }}\"/>\n<p>{% trans 'signature' %} </p>\n<p style=\"text-align: right;\">{{ individual.last_name }} {{ individual.first_name }} {{ individual.middle_name }}</p>\n</div>\n\n{% elif type == 'entrepreneur' %}\n<h1 class=\"header\">{% trans 'application_entrepreneur' %}</h1>\n<p style=\"text-align: center\">{% trans 'in' %} {{ coop.full_name }}<p>\n<p style=\"text-align: right\">{{ meta.created_at }}, {{coop.city}}</p> <p>{% trans 'to_council_of' %} {{ coop.short_name }} {% trans 'from_entrepreneur' %} {{ entrepreneur.last_name }} {{ entrepreneur.first_name }} {{ entrepreneur.middle_name }}, {% trans 'birthdate' %} {{ entrepreneur.birthdate }}, {% trans 'registration_address' %} {{ entrepreneur.full_address }}, {% trans 'entrepreneur_details', entrepreneur.details.inn, entrepreneur.details.ogrn, entrepreneur.bank_account.account_number, entrepreneur.bank_account.details.kpp, entrepreneur.bank_account.details.corr, entrepreneur.bank_account.details.bik, entrepreneur.bank_account.bank_name %}, {% trans 'phone_and_email_notice', entrepreneur.phone, entrepreneur.email %}</p>\n<p>{% trans 'request_to_join' %} {{ coop.full_name }}. {% trans 'acknowledge_documents_entrepreneur' %}</p> \n<p>{% if coop.is_branched %}{% trans 'authorize_chairman_branch', entrepreneur.branch_name %} {% endif %} </p>\n<p>{% trans 'obligation_to_pay_entrepreneur', coop.initial, coop.minimum %} </p>\n<p>{% trans 'agreement_on_sms_email_notice_entrepreneur' %}</p>\n<div class=\"signature\">\n<img style=\"max-width: 150px;\" src=\"{{ signature }}\"/>\n<p>{% trans 'signature' %} </p>\n<p style=\"text-align: right;\">{{ entrepreneur.last_name }} {{ entrepreneur.first_name }} {{ entrepreneur.middle_name }}</p>\n</div>\n\n{% elif type == 'organization' %}\n<h1 class=\"header\">{% trans 'application_legal_entity' %}</h1>\n<p style=\"text-align: center\">{% trans 'in' %} {{ coop.full_name }}<p>\n<p style=\"text-align: right\">{{ meta.created_at }}, {{coop.city}}</p>\n<p>{% trans 'to_council_of' %} «{{ coop.full_name }}» {% trans 'from_legal_entity' %} {{ organization.full_name }}, {% trans 'legal_address' %} {{ organization.full_address }}, {% trans 'legal_entity_details', organization.details.inn, organization.details.ogrn, organization.bank_account.account_number, organization.bank_account.details.kpp, organization.bank_account.details.corr, organization.bank_account.details.bik, organization.bank_account.bank_name %}, {% trans 'phone_and_email_notice', organization.phone, organization.email %}</p>\n<p>{% trans 'request_to_join_legal_entity', organization.represented_by.position, organization.represented_by.last_name, organization.represented_by.first_name, organization.represented_by.middle_name, organization.represented_by.based_on %} {{ coop.full_name }}.</p>\n<p>{% trans 'acknowledge_documents_legal_entity' %}</p> \n<p>{% if coop.is_branched %}{% trans 'authorize_chairman_branch_organization', organization.branch_name %} {% endif %}</p>\n<p>{% trans 'obligation_to_pay_legal_entity', coop.initial, coop.minimum %}</p>\n<p>{% trans 'agreement_on_sms_email_notice_legal_entity' %}</p>\n<div class=\"signature\">\n<img style=\"max-width: 150px;\" src=\"{{ signature }}\"/>\n<p>{% trans 'signature' %} </p>\n<p style=\"text-align: right;\">{{ organization.represented_by.last_name }} {{ organization.represented_by.first_name }} {{ organization.represented_by.middle_name }}</p>\n</div>\n\n{% endif %}\n\n`,
translations: {
ru: {
from: 'от',
application_individual: 'Заявление физического лица о приеме в пайщики',
to_council_of: 'В Совет',
birthdate: 'дата рождения',
registration_address: 'адрес регистрации (как в паспорте): ',
phone_and_email_notice: 'номер телефона с активированной функцией получения sms: {0}, адрес электронной почты: {1}.',
acknowledge_documents_individual: 'Подтверждаю, что с Уставом и иными нормативными документами Общества ознакомлен(а).',
agreement_on_sms_email_notice_individual: 'Выражаю свое согласие с тем, что информация, отправляемая Обществом в sms-сообщениях на указанный мной номер телефона, в сообщениях на указанный мной адрес электронной почты, или в PUSH уведомлениях с сайта, приравнивается к уведомлению меня Обществом в письменной форме.',
application_entrepreneur: 'Заявление индивидуального предпринимателя о приеме в пайщики',
from_entrepreneur: 'от индивидуального предпринимателя',
acknowledge_documents_entrepreneur: 'Подтверждаю, что с Уставом и иными нормативными документами Общества ознакомлен(а).',
agreement_on_sms_email_notice_entrepreneur: 'Выражаю свое согласие с тем, что информация, отправляемая Обществом в sms-сообщениях на указанный мной номер телефона, в сообщениях на указанный мной адрес электронной почты, или в PUSH уведомлениях с сайта, приравнивается к уведомлению меня Обществом в письменной форме.',
application_legal_entity: 'Заявление юридического лица о приеме в пайщики',
from_legal_entity: 'от юридического лица',
legal_address: 'юридический адрес организации',
legal_entity_details: 'ИНН {0}, ОГРН {1}, Р/с {2}, КПП {3}, К/с {4}, БИК {5}, банк получателя {6}',
acknowledge_documents_legal_entity: 'Подтверждает, что с Уставом и иными нормативными документами Общества ознакомлен.',
agreement_on_sms_email_notice_legal_entity: 'Выражает свое согласие с тем, что информация, отправляемая Обществом в sms-сообщениях на указанный номер телефона, в сообщениях на указанный адрес электронной почты, или в PUSH уведомлениях с сайта, приравнивается к уведомлению Заявителя Обществом в письменной форме.',
obligation_to_pay_individual: 'Обязуюсь своевременно внести в Общество вступительный {0} и минимальный паевой {1} взносы в порядке, предусмотренном Уставом Общества.',
obligation_to_pay_entrepreneur: 'Обязуюсь своевременно внести в Общество вступительный {0} и минимальный паевой {1} взносы в порядке, предусмотренном Уставом Общества.',
obligation_to_pay_legal_entity: 'Обязуется своевременно внести в Общество вступительный {0} и минимальный паевой {1} взносы в порядке, предусмотренном Уставом Общества.',
entrepreneur_details: 'ИНН {0}, ОГРНИП {1}, Р/с {2}, КПП {3}, К/с {4}, БИК {5}, банк получателя {6}',
authorize_chairman_branch: 'Уполномочиваю Председателя кооперативного участка {0} принимать участие с правом голоса в Общих собраниях уполномоченных Общества, на период моего членства в Обществе при указанном кооперативном участке.',
request_to_join_legal_entity: 'Заявитель, в лице представителя юридического лица - {0} {1} {2} {3}, действующий на основании {4}, просит принять в пайщики ',
authorize_chairman_branch_organization: 'Уполномочивает Председателя кооперативного участка {0} принимать участие с правом голоса в Общих собраниях уполномоченных Общества, на период моего членства в Обществе при указанном кооперативном участке.',
signature: 'подпись',
in: 'в',
request_to_join: 'Прошу принять меня в пайщики',
},
// ... другие переводы
},
}
@@ -1,123 +0,0 @@
import type { JSONSchemaType } from 'ajv'
import type { IDecisionData, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Services/Validator'
import { individualSchema } from '../Schema/IndividualSchema'
import { organizationSchema } from '../Schema'
import { type CooperativeData, CooperativeSchema } from '../Models/Cooperative'
import { entrepreneurSchema } from '../Schema/EntrepreneurSchema'
import { decisionSchema } from '../Schema/DecisionSchema'
import type { ExternalEntrepreneurData, ExternalIndividualData, ExternalOrganizationData } from '../Models'
// Модель данных
export interface IJoinCoopDecisionAction {
type: string
individual?: ExternalIndividualData
organization?: ExternalOrganizationData
entrepreneur?: ExternalEntrepreneurData
coop: CooperativeData
decision: IDecisionData
meta: IMetaDocument
}
// Схема для сверки
export const joinCoopJSONSchema: JSONSchemaType<IJoinCoopDecisionAction> = {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['individual', 'entrepreneur', 'organization'],
},
individual: {
type: 'object',
properties: {
...individualSchema.properties,
},
required: [...individualSchema.required],
additionalProperties: true,
nullable: true,
},
organization: {
type: 'object',
properties: {
...organizationSchema.properties,
},
required: [...organizationSchema.required],
additionalProperties: true,
nullable: true,
},
entrepreneur: {
type: 'object',
properties: {
...entrepreneurSchema.properties,
},
required: [...entrepreneurSchema.required],
additionalProperties: true,
nullable: true,
},
coop: {
type: 'object',
properties: {
...CooperativeSchema.properties,
},
required: [...CooperativeSchema.required],
additionalProperties: true,
},
decision: {
type: 'object',
properties: {
...decisionSchema.properties,
},
required: [...decisionSchema.required],
additionalProperties: true,
},
meta: {
type: 'object',
properties: {
...IMetaJSONSchema.properties,
},
required: [...IMetaJSONSchema.required],
additionalProperties: true,
},
},
required: ['meta', 'coop', 'type', 'decision'],
additionalProperties: true,
}
export const DecisionOfParticipantApplicationTemplate: ITemplate<IJoinCoopDecisionAction> = {
title: 'Решение совета о приёме пайщика в кооператив',
description: 'Форма решения совета о приёме пайщика в потребительский кооператив',
model: joinCoopJSONSchema,
context: `<style> \nh1 {\nmargin: 0px; \ntext-align:center;\n}\nh3{\nmargin: 0px;\npadding-top: 15px;\n}\n.about {\npadding: 20px;\n}\n.about p{\nmargin: 0px;\n}\n.signature {\npadding-top: 20px;\n}\n</style>\n\n<h1 class=\"header\">{% trans 'protocol_number', decision.id %}</h1>\n<p style=\"text-align:center\">{% trans 'council_meeting_name' %}\n{{ coop.full_name }}</p>\n<p style=\"text-align: right\"> {{ meta.created_at }}, {{ coop.city }}</p>\n\n<div class=\"about\">\n<p>{% trans 'meeting_format' %}</p>\n<p>{% trans 'meeting_place', coop.full_address %}</p>\n<p>{% trans 'meeting_date', decision.date %}</p>\n<p>{% trans 'opening_time', decision.time %}</p>\n</div>\n\n<h3>{% trans 'council_members' %}</h3>\n<ol>{% for member in coop.members %}\n<li>{{ member.last_name }} {{ member.first_name }} {{ member.middle_name }}{% if member.is_chairman %} {% trans 'chairman_of_the_council' %}{% endif %}</li>\n{% endfor %}\n</ol>\n\n<h3>{% trans 'meeting_legality' %} </h3>\n<p>{% trans 'voting_results', decision.voters_percent %} {% trans 'quorum' %} {% trans 'chairman_of_the_meeting', coop.chairman.last_name, coop.chairman.first_name, coop.chairman.middle_name %}.</p>\n\n<h3>{% trans 'agenda' %}</h3>\n<ol><li> {% trans 'decision_joincoop1' %}{% if type == 'individual' %} {{individual.last_name}} {{individual.first_name}} {{individual.middle.name}} ({{individual.birthdate}} {% trans 'birthdate' %}) {% endif %}{% if type == 'entrepreneur' %} {% trans 'entrepreneur' %} {{entrepreneur.last_name}} {{entrepreneur.first_name}} {{entrepreneur.middle.name}} ({% trans 'ogrnip' %} {{entrepreneur.details.ogrn}}) {% endif %}{% if type == 'organization' %} {{organization.short_name}} ({% trans 'ogrn' %} {{organization.details.ogrn}}) {% endif %}{% trans 'in_participants' %} {{ coop.short_name }}.\n</li></ol>\n\n<h3>{% trans 'voting' %}</h3>\n<p>{% trans 'vote_results', decision.votes_for, decision.votes_against, decision.votes_abstained %} </p>\n\n<h3>{% trans 'decision_made' %}</h3>\n<p>{% trans 'decision_joincoop2' %}{% if type == 'individual' %} {{individual.last_name}} {{individual.first_name}} {{individual.middle.name}} {{individual.birthdate}} {% trans 'birthdate' %}{% endif %} {% if type == 'entrepreneur' %}{% trans 'entrepreneur' %} {{entrepreneur.last_name}} {{entrepreneur.first_name}} {{entrepreneur.middle.name}}, {% trans 'ogrnip' %} {{entrepreneur.details.ogrn}}{% endif %} {% if type == 'organization' %} {{organization.short_name}}, {% trans 'ogrn' %} {{organization.details.ogrn}} {% endif %}</p>\n<hr>\n<p>{% trans 'closing_time', decision.time %}</p>\n\n<div class=\"signature\"> \n<p>{% trans 'signature' %}<p>\n<p style=\"text-align: right;\">{% trans 'chairman' %} {{ coop.chairman.last_name }} {{ coop.chairman.first_name }} {{ coop.chairman.middle_name }}</p></div>`,
translations: {
ru: {
meeting_format: 'Форма проведения собрания совета: заочная',
meeting_date: 'Дата проведения собрания совета: {0}',
meeting_place: 'Место проведения собрания совета: {0}',
opening_time: 'Время открытия собрания совета: {0}',
council_members: 'Члены Совета',
voting_results: 'Количество голосов составляет {0}% от общего числа членов Совета.',
meeting_legality: 'Собрание правомочно',
chairman_of_the_meeting: 'Председатель собрания совета: {0} {1} {2}',
agenda: 'Повестка дня',
vote_results: 'По первому вопросу повестки дня проголосовали: «За» – {0}; «Против» - {1}; «Воздержался» - {2}.',
decision_made: 'Решили',
closing_time: 'Время закрытия собрания совета: {0}.',
protocol_number: 'Протокол № {0}',
council_meeting_name: 'Собрания Совета',
chairman_of_the_council: '(председатель совета)',
signature: 'Документ подписан электронной подписью.',
chairman: 'Председатель',
birthdate: 'г.р.',
ogrnip: 'ОГРНИП',
entrepreneur: 'ИП',
ogrn: 'ОГРН',
quorum: 'Кворум для решения поставленных на повестку дня вопросов имеется.',
voting: 'Голосование',
in_participants: 'о приёме в пайщики',
decision_joincoop1: 'Рассмотреть заявление',
decision_joincoop2: 'Принять нового пайщика',
},
// ... другие переводы
},
}
@@ -1,2 +0,0 @@
export * from './100.ParticipantApplication'
export * from './registry'
@@ -1,11 +0,0 @@
import * as ParticipantApplication from './100.ParticipantApplication'
import * as DecisionOfParticipantApplication from './501.DecisionOfParticipantApplication'
export const DocumentsRegistry = {
100: ParticipantApplication.ParticipantApplicationTemplate,
501: DecisionOfParticipantApplication.DecisionOfParticipantApplicationTemplate,
}
export interface DocumentsMappingByActionAndCode {
'registrator::joincoop': ParticipantApplication.IJoinCoopAction // Тип данных для документа 'registrator::joincoop'
'registrator::joincoopdec': DecisionOfParticipantApplication.IJoinCoopDecisionAction // Тип данных для документа 'registrator::joincoopdec'
}
@@ -1,4 +1,4 @@
import { DraftContract } from 'cooptypes/index'
import { DraftContract } from 'cooptypes'
import { getEnvVar } from '../config'
import { getFetch } from './getFetch'
@@ -1,4 +1,4 @@
import { DraftContract } from 'cooptypes/index'
import { DraftContract } from 'cooptypes'
import { getEnvVar } from '../config'
import { getFetch } from './getFetch'
+27 -16
View File
@@ -1,23 +1,26 @@
export * from './Interfaces'
export * from './Templates'
export * from './templates'
export * from './Schema'
import type { Filter, InsertOneResult, UpdateResult } from 'mongodb'
import type { Cooperative as CooperativeModel } from 'cooptypes'
import type { Actions, IFilterDocuments, IGeneratedDocument, externalDataTypes, externalDataTypesArrays, internalFilterTypes } from './Interfaces'
import type { IFilterDocuments, IGeneratedDocument, Numbers, externalDataTypes, externalDataTypesArrays, internalFilterTypes } from './Interfaces'
import type { IGenerate } from './Interfaces/Documents'
import { JoinCoop, JoinCoopDecision } from './Actions'
import * as Actions from './Actions'
import { MongoDBConnector } from './Services/Databazor'
import type { ExternalIndividualData } from './Models/Individual'
import { Individual } from './Models/Individual'
import type { ExternalEntrepreneurData, ExternalOrganizationData } from './Models'
import { Entrepreneur, Organization } from './Models'
import type { ExternalEntrepreneurData, ExternalOrganizationData, IVars } from './Models'
import { Entrepreneur, Organization, Vars } from './Models'
import { Cooperative, type CooperativeData } from './Models/Cooperative'
import type { DocFactory } from './Factory'
import type { PaymentData } from './Models/PaymentMethod'
import { PaymentMethod } from './Models/PaymentMethod'
import { Registry } from './templates'
export type dataTypes = 'individual' | 'entrepreneur' | 'organization' | 'paymentMethod'
export type dataTypes = 'individual' | 'entrepreneur' | 'organization' | 'paymentMethod' | 'vars'
export type { ExternalOrganizationData as IOrganizationData } from './Models'
export type { ExternalIndividualData as IIndividualData } from './Models'
@@ -31,11 +34,11 @@ export interface IGenerator {
getDocument: (filter: Filter<IFilterDocuments>) => Promise<IGeneratedDocument>
constructCooperative: (username: string, block_num?: number) => Promise<CooperativeData | null>
save: ((type: 'individual', data: ExternalIndividualData) => Promise<InsertOneResult>) & ((type: 'entrepreneur', data: ExternalEntrepreneurData) => Promise<InsertOneResult>) & ((type: 'organization', data: ExternalOrganizationData) => Promise<InsertOneResult>) & ((type: 'paymentMethod', data: PaymentData) => Promise<InsertOneResult>)
save: ((type: 'individual', data: ExternalIndividualData) => Promise<InsertOneResult>) & ((type: 'entrepreneur', data: ExternalEntrepreneurData) => Promise<InsertOneResult>) & ((type: 'organization', data: ExternalOrganizationData) => Promise<InsertOneResult>) & ((type: 'paymentMethod', data: PaymentData) => Promise<InsertOneResult>) & ((type: 'vars', data: IVars) => Promise<InsertOneResult>)
get: (type: dataTypes, filter: Filter<internalFilterTypes>) => Promise<externalDataTypes | null>
del: (type: dataTypes, filter: Filter<internalFilterTypes>) => Promise<UpdateResult>
list: (type: dataTypes, filter: Filter<internalFilterTypes>) => Promise<CooperativeModel.Documents.IGetResponse<internalFilterTypes>>
list: (type: dataTypes, filter: Filter<internalFilterTypes>) => Promise<CooperativeModel.Document.IGetResponse<internalFilterTypes>>
getHistory: (type: dataTypes, filter: Filter<internalFilterTypes>) => Promise<externalDataTypesArrays>
}
@@ -43,7 +46,7 @@ export interface IGenerator {
export class Generator implements IGenerator {
// Определение фабрик
factories!: {
[K in Actions]: DocFactory
[K in Numbers]: DocFactory<IGenerate>
}
// Определение хранилища
@@ -53,10 +56,15 @@ export class Generator implements IGenerator {
async connect(mongoUri: string): Promise<void> {
this.storage = new MongoDBConnector(mongoUri)
// Инициализация фабрик для разных типов документов
// Инициализация фабрик документов
this.factories = {
'registrator::joincoop': new JoinCoop.JoinCoopTemplateFactory(this.storage),
'registrator::joincoopdec': new JoinCoopDecision.DecisionOfJoinCoopTemplateFactory(this.storage),
[Actions.WalletAgreement.Template.registry_id]: new Actions.WalletAgreement.Factory(this.storage), // 1
[Actions.RegulationElectronicSignature.Template.registry_id]: new Actions.RegulationElectronicSignature.Factory(this.storage), // 2
[Actions.PrivacyPolicy.Template.registry_id]: new Actions.PrivacyPolicy.Factory(this.storage), // 3
[Actions.UserAgreement.Template.registry_id]: new Actions.UserAgreement.Factory(this.storage), // 4
[Actions.CoopenomicsAgreement.Template.registry_id]: new Actions.UserAgreement.Factory(this.storage), // 50
[Actions.ParticipantApplication.Template.registry_id]: new Actions.ParticipantApplication.Factory(this.storage), // 100
[Actions.DecisionOfParticipantApplication.Template.registry_id]: new Actions.DecisionOfParticipantApplication.Factory(this.storage), // 501
}
await this.storage.connect()
}
@@ -68,10 +76,10 @@ export class Generator implements IGenerator {
// Метод генерации документа
async generate(options: IGenerate): Promise<IGeneratedDocument> {
const factory = this.factories[`${options.code}::${options.action}` as Actions] // Get the factory
const factory = this.factories[options.registry_id as Numbers] // Get the factory
if (!factory)
throw new Error(`Фабрика для документа типа ${options.code}::${options.action} не найдена.`)
throw new Error(`Фабрика для документа #${options.registry_id} не найдена.`)
// синтезируем документ
return await factory.generateDocument(options)
@@ -85,6 +93,7 @@ export class Generator implements IGenerator {
async save(type: 'entrepreneur', data: ExternalEntrepreneurData): Promise<InsertOneResult>
async save(type: 'organization', data: ExternalOrganizationData): Promise<InsertOneResult>
async save(type: 'paymentMethod', data: PaymentData): Promise<InsertOneResult>
async save(type: 'vars', data: IVars): Promise<InsertOneResult>
async save(type: dataTypes, data: externalDataTypes): Promise<InsertOneResult> {
const model = this.getModel(type, data)
@@ -103,13 +112,13 @@ export class Generator implements IGenerator {
}
// Универсальные методы получения списка объектов
async list(type: dataTypes, filter: Filter<internalFilterTypes>): Promise<CooperativeModel.Documents.IGetResponse<externalDataTypes>> {
async list(type: dataTypes, filter: Filter<internalFilterTypes>): Promise<CooperativeModel.Document.IGetResponse<externalDataTypes>> {
const model = this.getModel(type)
return model.getMany(filter)
}
// // Универсальные методы получения истории
async getHistory(type: 'individual' | 'entrepreneur' | 'organization' | 'paymentMethod', filter: Filter<internalFilterTypes>): Promise<externalDataTypesArrays> {
async getHistory(type: 'individual' | 'entrepreneur' | 'organization' | 'paymentMethod' | 'vars', filter: Filter<internalFilterTypes>): Promise<externalDataTypesArrays> {
const model = this.getModel(type)
return model.getHistory(filter)
}
@@ -125,6 +134,8 @@ export class Generator implements IGenerator {
return new Organization(this.storage, data as ExternalOrganizationData)
case 'paymentMethod':
return new PaymentMethod(this.storage, data as PaymentData)
case 'vars':
return new Vars(this.storage, data as IVars)
default:
throw new Error(`Unknown type: ${type}`)
@@ -0,0 +1,33 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { CooperativeSchema, VarsSchema } from '../Schema'
export const registry_id = Cooperative.Registry.WalletAgreement.registry_id
// Модель действия для генерации
export type Action = Cooperative.Registry.WalletAgreement.Action
// Модель данных
export type Model = Cooperative.Registry.WalletAgreement.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
},
required: ['meta', 'coop', 'vars'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.WalletAgreement.title,
description: Cooperative.Registry.WalletAgreement.description,
model: Schema,
context: Cooperative.Registry.WalletAgreement.context,
translations: Cooperative.Registry.WalletAgreement.translations,
}
@@ -0,0 +1,88 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { individualSchema } from '../Schema/IndividualSchema'
import type { ExternalIndividualData, ExternalOrganizationData } from '../Models'
import { organizationSchema } from '../Schema'
import { CooperativeSchema } from '../Schema/CooperativeSchema'
import type { ExternalEntrepreneurData } from '../Models/Entrepreneur'
import { entrepreneurSchema } from '../Schema/EntrepreneurSchema'
export const registry_id = Cooperative.Registry.ParticipantApplication.registry_id
/**
* Интерфейс генерации заявления на вступление в кооператив
*/
export type Action = Cooperative.Registry.ParticipantApplication.Action
// Модель данных
export type Model = Cooperative.Registry.ParticipantApplication.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['individual', 'entrepreneur', 'organization'],
},
individual: {
type: 'object',
properties: {
...individualSchema.properties,
},
required: [...individualSchema.required],
additionalProperties: true,
nullable: true,
},
organization: {
type: 'object',
properties: {
...organizationSchema.properties,
},
required: [...organizationSchema.required],
additionalProperties: true,
nullable: true,
},
entrepreneur: {
type: 'object',
properties: {
...entrepreneurSchema.properties,
},
required: [...entrepreneurSchema.required],
additionalProperties: true,
nullable: true,
},
coop: {
type: 'object',
properties: {
...CooperativeSchema.properties,
},
required: [...CooperativeSchema.required],
additionalProperties: true,
},
signature: {
type: 'string',
},
meta: {
type: 'object',
properties: {
...IMetaJSONSchema.properties,
},
required: [...IMetaJSONSchema.required],
additionalProperties: true,
},
},
required: ['meta', 'coop', 'type', 'signature'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.ParticipantApplication.title,
description: Cooperative.Registry.ParticipantApplication.description,
model: Schema,
context: Cooperative.Registry.ParticipantApplication.context,
translations: Cooperative.Registry.ParticipantApplication.translations,
}
@@ -0,0 +1,33 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { CooperativeSchema, VarsSchema } from '../Schema'
export const registry_id = Cooperative.Registry.RegulationElectronicSignature.registry_id
// Модель действия для генерации
export type Action = Cooperative.Registry.RegulationElectronicSignature.Action
// Модель данных
export type Model = Cooperative.Registry.RegulationElectronicSignature.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
},
required: ['meta', 'coop', 'vars'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.RegulationElectronicSignature.title,
description: Cooperative.Registry.RegulationElectronicSignature.description,
model: Schema,
context: Cooperative.Registry.RegulationElectronicSignature.context,
translations: Cooperative.Registry.RegulationElectronicSignature.translations,
}
@@ -0,0 +1,33 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { CooperativeSchema, VarsSchema } from '../Schema'
export const registry_id = Cooperative.Registry.PrivacyPolicy.registry_id
// Модель действия для генерации
export type Action = Cooperative.Registry.PrivacyPolicy.Action
// Модель данных
export type Model = Cooperative.Registry.PrivacyPolicy.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
},
required: ['meta', 'coop', 'vars'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.PrivacyPolicy.title,
description: Cooperative.Registry.PrivacyPolicy.description,
model: Schema,
context: Cooperative.Registry.PrivacyPolicy.context,
translations: Cooperative.Registry.PrivacyPolicy.translations,
}
@@ -0,0 +1,40 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { CooperativeSchema, VarsSchema } from '../Schema'
export const registry_id = Cooperative.Registry.UserAgreement.registry_id
// Модель действия для генерации
export type Action = Cooperative.Registry.UserAgreement.Action
// Модель данных
export type Model = Cooperative.Registry.UserAgreement.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
user: {
type: 'object',
properties: {
full_name: { type: 'string' },
},
required: ['full_name'],
},
},
required: ['meta', 'coop', 'vars', 'user'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.UserAgreement.title,
description: Cooperative.Registry.UserAgreement.description,
model: Schema,
context: Cooperative.Registry.UserAgreement.context,
translations: Cooperative.Registry.UserAgreement.translations,
}
@@ -0,0 +1,34 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { CooperativeSchema, VarsSchema, organizationSchema } from '../Schema'
export const registry_id = Cooperative.Registry.CoopenomicsAgreement.registry_id
// Модель действия для генерации
export type Action = Cooperative.Registry.CoopenomicsAgreement.Action
// Модель данных
export type Model = Cooperative.Registry.CoopenomicsAgreement.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
meta: IMetaJSONSchema,
coop: CooperativeSchema,
vars: VarsSchema,
partner: organizationSchema,
},
required: ['meta', 'coop', 'vars', 'partner'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.CoopenomicsAgreement.title,
description: Cooperative.Registry.CoopenomicsAgreement.description,
model: Schema,
context: Cooperative.Registry.CoopenomicsAgreement.context,
translations: Cooperative.Registry.CoopenomicsAgreement.translations,
}
@@ -0,0 +1,93 @@
import type { JSONSchemaType } from 'ajv'
import { Cooperative } from 'cooptypes'
import type { IGenerate, IMetaDocument, ITemplate } from '../Interfaces'
import { IMetaJSONSchema } from '../Schema/MetaSchema'
import { individualSchema } from '../Schema/IndividualSchema'
import { organizationSchema } from '../Schema'
import { type CooperativeData } from '../Models/Cooperative'
import { CooperativeSchema } from '../Schema/CooperativeSchema'
import { entrepreneurSchema } from '../Schema/EntrepreneurSchema'
import { decisionSchema } from '../Schema/DecisionSchema'
import type { ExternalEntrepreneurData, ExternalIndividualData, ExternalOrganizationData } from '../Models'
export const registry_id = Cooperative.Registry.DecisionOfParticipantApplication.registry_id
/**
* Интерфейс генерации решения совета
*/
export type Action = Cooperative.Registry.DecisionOfParticipantApplication.Action
export type Model = Cooperative.Registry.DecisionOfParticipantApplication.Model
// Схема для сверки
export const Schema: JSONSchemaType<Model> = {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['individual', 'entrepreneur', 'organization'],
},
individual: {
type: 'object',
properties: {
...individualSchema.properties,
},
required: [...individualSchema.required],
additionalProperties: true,
nullable: true,
},
organization: {
type: 'object',
properties: {
...organizationSchema.properties,
},
required: [...organizationSchema.required],
additionalProperties: true,
nullable: true,
},
entrepreneur: {
type: 'object',
properties: {
...entrepreneurSchema.properties,
},
required: [...entrepreneurSchema.required],
additionalProperties: true,
nullable: true,
},
coop: {
type: 'object',
properties: {
...CooperativeSchema.properties,
},
required: [...CooperativeSchema.required],
additionalProperties: true,
},
decision: {
type: 'object',
properties: {
...decisionSchema.properties,
},
required: [...decisionSchema.required],
additionalProperties: true,
},
meta: {
type: 'object',
properties: {
...IMetaJSONSchema.properties,
},
required: [...IMetaJSONSchema.required],
additionalProperties: true,
},
},
required: ['meta', 'coop', 'type', 'decision'],
additionalProperties: true,
}
export const Template: ITemplate<Model> = {
title: Cooperative.Registry.DecisionOfParticipantApplication.title,
description: Cooperative.Registry.DecisionOfParticipantApplication.description,
model: Schema,
context: Cooperative.Registry.DecisionOfParticipantApplication.context,
translations: Cooperative.Registry.DecisionOfParticipantApplication.translations,
}
@@ -0,0 +1,9 @@
export * as WalletAgreement from './1.WalletAgreement'
export * as RegulationElectronicSignature from './2.RegulationElectronicSignature'
export * as PrivacyPolicy from './3.PrivacyPolicy'
export * as UserAgreement from './4.UserAgreement'
export * as CoopenomicsAgreement from './50.CoopenomicsAgreement'
export * as ParticipantApplication from './100.ParticipantApplication'
export * as DecisionOfParticipantApplication from './501.DecisionOfParticipantApplication'
export * from './registry'

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