Compare commits
1275 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f617cf1a1 | |||
| f8881cfcde | |||
| 0f5c7ad108 | |||
| b1ccb70b5b | |||
| dedfd68980 | |||
| e47ef47283 | |||
| a7e675f5ad | |||
| 67f1922ca2 | |||
| 702eb927bd | |||
| a6b15f0749 | |||
| bf80a839fa | |||
| 585afb16eb | |||
| 7ea382058b | |||
| a531bb1ab4 | |||
| cd08236dd6 | |||
| 1d72bd3960 | |||
| 3c08215671 | |||
| 4c45d1d701 | |||
| 8e10c57af2 | |||
| 0aeeb69581 | |||
| db86a8e001 | |||
| 61e33a2959 | |||
| a68068ded4 | |||
| 99dc260013 | |||
| e1f4fa066d | |||
| 0d60f4004d | |||
| 297055cb7c | |||
| be7c5fd864 | |||
| 818fa8b0a5 | |||
| 4ea43712d2 | |||
| d023beee30 | |||
| 2d1bef7087 | |||
| 3d3ba56282 | |||
| 729816ed26 | |||
| c1e6b1a433 | |||
| 1e8e5c4412 | |||
| 6c72942a30 | |||
| 7dff06d5b9 | |||
| 830b09ea2c | |||
| 8f2454d4fc | |||
| 9953f7e980 | |||
| fcb816b0e6 | |||
| b294c61b4e | |||
| 6435b50c72 | |||
| 7c804da6b2 | |||
| eaae515860 | |||
| 9bcfd3a654 | |||
| 109f4aaf98 | |||
| beb87b0c00 | |||
| 947077d011 | |||
| 3297616ad1 | |||
| 90c830fdb1 | |||
| 130c544191 | |||
| 63dcdde872 | |||
| e1a496759b | |||
| 99283dfdd7 | |||
| adee9ee032 | |||
| aaf3b5b98f | |||
| 3dbad0ff30 | |||
| 615eba3a84 | |||
| e7de054de2 | |||
| 6f911605d9 | |||
| 00a8461b5b | |||
| 7154c7f0e0 | |||
| 0f07666aeb | |||
| 489dc482e8 | |||
| 55c4759780 | |||
| 16b4fe0080 | |||
| 9cd995c5f2 | |||
| e60d6a5d67 | |||
| b274af05c3 | |||
| 40e725f2ed | |||
| 0f091eefc9 | |||
| 2b00c58e9b | |||
| 6d9681fb8a | |||
| acc4d27677 | |||
| ffe581a92b | |||
| 6e643515ce | |||
| 1cc7aca53f | |||
| e5111622a6 | |||
| 99b98cb5c9 | |||
| 20447cfb46 | |||
| 723a1813c9 | |||
| 04d52a0631 | |||
| 097d18cd56 | |||
| 5043995d14 | |||
| 804cfc8b72 | |||
| a0dc6f3333 | |||
| a53957271e | |||
| abae483dd3 | |||
| 4418e09211 | |||
| ca79457c19 | |||
| d2cd947b9c | |||
| ea28285639 | |||
| 6174ddea9a | |||
| ce56adc3c8 | |||
| 59334bb13a | |||
| 21cd1f5217 | |||
| 515df53c96 | |||
| cbf7f48c44 | |||
| ed37aeb615 | |||
| ea89558696 | |||
| c0bad75a37 | |||
| bdc227f110 | |||
| a9c3a1b6de | |||
| f0e7b0b63a | |||
| a709e2f1e3 | |||
| 3a34bd74db | |||
| b755cb715a | |||
| 42753fae0a | |||
| d8b8fa2d6e | |||
| a75277e0b8 | |||
| f95b83674b | |||
| bb13e780af | |||
| 6e80d5187c | |||
| db9b704d1d | |||
| 65a2b5361c | |||
| 7bca73cd7b | |||
| 59383014be | |||
| 60a5296f5f | |||
| eb4fe333a7 | |||
| 8d06d6d817 | |||
| b6afb536b6 | |||
| 790047fa8a | |||
| baf55b6b6d | |||
| 92d85244f1 | |||
| 0b26433b1a | |||
| 4f06bb40f8 | |||
| 46d571b65a | |||
| 7da1bfd315 | |||
| b30f47b5aa | |||
| ccc6c7206c | |||
| a549f4cae0 | |||
| 07c451ce22 | |||
| 62da624369 | |||
| a1a9b03180 | |||
| e4c1d37c35 | |||
| 42cacac256 | |||
| 2816970327 | |||
| 5744fcdcb2 | |||
| 3c412b394d | |||
| 4e64cea373 | |||
| db579db87f | |||
| f612a918d9 | |||
| 1a78e06a7a | |||
| 374a98ffc3 | |||
| d723e2e273 | |||
| 41030171b5 | |||
| aa31706bcc | |||
| 4e3810493d | |||
| eeb2db92ed | |||
| 5a2930029b | |||
| 2e9a73923b | |||
| 97e67f8a88 | |||
| 074849af74 | |||
| 6939783518 | |||
| 260e48fa48 | |||
| 52c4ef5df5 | |||
| 46b634e0fa | |||
| a556c29a17 | |||
| bbc4f508b5 | |||
| fe0243549a | |||
| d9196ba650 | |||
| a0ea1fa392 | |||
| 195bcb4495 | |||
| 929627a191 | |||
| 83a313b4b7 | |||
| f734bfb50f | |||
| 9efc22d195 | |||
| bd3bef5fb0 | |||
| ddbe49e847 | |||
| ed9bddec0b | |||
| 73a07eeb54 | |||
| 6e27aed804 | |||
| 5f955781a6 | |||
| c124f7310e | |||
| 73ffcae549 | |||
| 80e55ba0be | |||
| eecf955096 | |||
| 6426db9a5d | |||
| bf4753cd09 | |||
| a592eaf383 | |||
| 75d654cec3 | |||
| a18ed37600 | |||
| 6747a8dfbc | |||
| 583dfb8126 | |||
| bda31dd086 | |||
| 283af35f3b | |||
| 82564e2580 | |||
| fc6a9026e6 | |||
| e1538bb5ab | |||
| d47db969ea | |||
| f01de37a59 | |||
| cee429a0a0 | |||
| 321ee89676 | |||
| aa60484315 | |||
| b807df3ee8 | |||
| c11e922573 | |||
| 7135a3bbeb | |||
| 142b87dd67 | |||
| dff4579f28 | |||
| 2b3b662a9a | |||
| 98bc5195b1 | |||
| a02912ccbb | |||
| 2f1d29dfd2 | |||
| 11efacc4cb | |||
| 8133d0da3d | |||
| 093d63faae | |||
| 07f5e04488 | |||
| acfc97fc7c | |||
| 6e30554143 | |||
| fa1c788c41 | |||
| 3a688942c3 | |||
| 6797522618 | |||
| 4730a53313 | |||
| 5a538792f0 | |||
| 5f20289767 | |||
| 4c7ed97a76 | |||
| a9c2228e3c | |||
| ec44fcb7cb | |||
| 1f9c8d261b | |||
| 23ab3bd416 | |||
| 79482775d2 | |||
| 2dcb3678b0 | |||
| 8d7c206012 | |||
| c21c264426 | |||
| 77a39c18f1 | |||
| 65a00b0a8e | |||
| 0c2d5679f1 | |||
| 75d0e0de43 | |||
| 19ff864eaa | |||
| 6bbee7cb10 | |||
| e268923cf6 | |||
| 4fb3d7182c | |||
| 6e7a6ec032 | |||
| 0e92c92f87 | |||
| a6f1eb39ec | |||
| 21364f6239 | |||
| a0527094a9 | |||
| eda890c294 | |||
| 1ed8db87cc | |||
| 136892478f | |||
| aee90d31a0 | |||
| 6fe632fda3 | |||
| fa975a2f5b | |||
| bd5ab14d2f | |||
| 32890bfda9 | |||
| a3d4113b97 | |||
| 8acfa722f8 | |||
| 234beba06a | |||
| 90c27a0f73 | |||
| 2577a5d2c2 | |||
| 84bf10b65b | |||
| 5d70f5fd97 | |||
| f42cc59d53 | |||
| d12b222d52 | |||
| b663c7f9d4 | |||
| 30abfa7e23 | |||
| 0be32c34c5 | |||
| 8d4863b894 | |||
| ad1ae8fb54 | |||
| b31e41bfd9 | |||
| 999d5a937d | |||
| 45ea543a4b | |||
| 9d72a5e02d | |||
| 8973c45b4e | |||
| b3e5a5dc62 | |||
| d8bddadd42 | |||
| aa552d1c80 | |||
| 6daac5f442 | |||
| a8c453fbda | |||
| 3e15da5ad7 | |||
| 8e776e7d42 | |||
| de3d5654b4 | |||
| b0e19ffa30 | |||
| bacf451cf5 | |||
| 2a5600b6af | |||
| bfbc78d9b7 | |||
| d509281bdc | |||
| 866fdfb4f6 | |||
| 6c14d0f4c5 | |||
| b31a8e3bf8 | |||
| 7f3261e453 | |||
| 861c3617dd | |||
| 1f4b1f5421 | |||
| f851460a32 | |||
| 992ac6d9eb | |||
| 2e9ac57930 | |||
| ce8d090f27 | |||
| 4ec8b59fd6 | |||
| 6b086af8b4 | |||
| 52f95665ed | |||
| d1ce5ab105 | |||
| 0fd10649f4 | |||
| 3c65900768 | |||
| 0b962b4fee | |||
| a58633fc5f | |||
| 24c2ed3ae3 | |||
| 84a77d98cf | |||
| 20e50e02e9 | |||
| c8bb354972 | |||
| 3f9b73d211 | |||
| 40bbffed17 | |||
| b16ec4e809 | |||
| 9629c895d5 | |||
| f4420fcc03 | |||
| 17f8c3e134 | |||
| 02512a522c | |||
| 4974f99842 | |||
| a3d0c32be3 | |||
| 31523160fc | |||
| 183d5cdeec | |||
| 52fed810f2 | |||
| f58d63da8d | |||
| 6793e6fbdc | |||
| 4f88e9b97d | |||
| 5004cec9b3 | |||
| 76c81e4209 | |||
| 323043dc01 | |||
| 37902ce70a | |||
| c69e795d49 | |||
| c3b82af95a | |||
| 24510d4828 | |||
| 11a04a99f7 | |||
| 6e96eeaa05 | |||
| 2c16d4af5a | |||
| d1f9cf43de | |||
| 26fb11cb30 | |||
| a7a3eb8658 | |||
| fbedcd1f5f | |||
| 6033af0f23 | |||
| 4809786b16 | |||
| a37f40ff6e | |||
| 44f5cc9de0 | |||
| e059d0cbd9 | |||
| c51040b0de | |||
| eba2abc108 | |||
| ed7626009a | |||
| 442413ec6b | |||
| 90986df641 | |||
| 8b505dbce3 | |||
| 2b26e9643b | |||
| eb16f01839 | |||
| 872cf33d1c | |||
| afbce19028 | |||
| e27228e735 | |||
| 3125232114 | |||
| e552840cc4 | |||
| 569142845a | |||
| e62d837858 | |||
| 27badfb88a | |||
| e4d0781eb8 | |||
| 93c8373335 | |||
| 42bad6b4ea | |||
| 83d4bd88cf | |||
| 4141267104 | |||
| d5778f165b | |||
| 7128e26a27 | |||
| 78247e9969 | |||
| 66d36e034e | |||
| 4100ee842c | |||
| d4857c8e6e | |||
| 0f52781489 | |||
| 332f19cd22 | |||
| 53a1c103d6 | |||
| addf7a3e6b | |||
| c76078ea06 | |||
| 9299288e8a | |||
| dc34f24ee2 | |||
| fe83bf1483 | |||
| c184f9281d | |||
| 3127a69b67 | |||
| d7326c4f82 | |||
| f8478284b6 | |||
| 1c910de4b1 | |||
| 2c3cb955ef | |||
| 1d7746d839 | |||
| e16d2ba238 | |||
| 60f8b448ec | |||
| c0d61f29a8 | |||
| c47b99f9ee | |||
| 653429a6d6 | |||
| c2250e1817 | |||
| 92ca48d65f | |||
| 2f53d9a79d | |||
| d025bfe2da | |||
| fbc2460ac4 | |||
| 76c2800275 | |||
| 536bf984ee | |||
| 23f8af43ee | |||
| eba54bf2e7 | |||
| 50270e6541 | |||
| 5f7d9e80ee | |||
| a71ef35d5c | |||
| 2cf5291831 | |||
| 75e3e9dd7b | |||
| 7a75365d2f | |||
| 7a23d59aa1 | |||
| 2583423600 | |||
| 1d748a0424 | |||
| 86172790d1 | |||
| 92c9103059 | |||
| 16393dbc9d | |||
| e841b0ef03 | |||
| 27c7ae9d76 | |||
| dc3a40675d | |||
| 31e65ac2e3 | |||
| c2444d1b09 | |||
| 2faadae4cf | |||
| d24e51c355 | |||
| 8ed8af1b9c | |||
| 5f6b416f26 | |||
| 3671c05573 | |||
| db6eed9292 | |||
| 4c903ba0bb | |||
| 9eee216065 | |||
| 9e1dd02d70 | |||
| b986bf9bcc | |||
| a3e0e62efc | |||
| 8646c5acf6 | |||
| dab9465755 | |||
| 3a076cc4ea | |||
| 1b6d1ea0ef | |||
| c490284c65 | |||
| c3ca329138 | |||
| d0f73c32bb | |||
| 79e0da7cf2 | |||
| b261f505aa | |||
| 65c4c95cbe | |||
| 5b3c9c9055 | |||
| d32d4f845c | |||
| 637950d37f | |||
| 0e1ede58e5 | |||
| e914a11768 | |||
| 73d66dab35 | |||
| 634766a08e | |||
| 5fbc450e96 | |||
| 5acd7ae2c4 | |||
| 09578ddc5d | |||
| 8270801711 | |||
| de91c3cfc8 | |||
| 06888a2061 | |||
| cde2d33d03 | |||
| 9cf89f95d1 | |||
| 20486e15ea | |||
| 420c403da1 | |||
| cb8fdf3461 | |||
| 0937d08770 | |||
| 9b1fd8e1aa | |||
| d87861142c | |||
| ff5fc1d0f3 | |||
| d5a671cbb8 | |||
| d0508cbd96 | |||
| 12098cf8ac | |||
| 2557c35bea | |||
| 11f23bbd77 | |||
| 2b2ec729ac | |||
| 9292acec8c | |||
| 3095ed5375 | |||
| a333e303c1 | |||
| bd8512feab | |||
| c235fc4a7a | |||
| 9c283b9aee | |||
| 4e824d739b | |||
| fcbbc792b0 | |||
| ba7cf8e79e | |||
| 4ab49d8e43 | |||
| 7f864db80d | |||
| 772a163693 | |||
| c8e106f272 | |||
| ade4f0a1d4 | |||
| 4fcf933dd1 | |||
| 1fb60771ca | |||
| 2cd391e106 | |||
| 196f3bcba1 | |||
| bc73c5ca86 | |||
| f4badc15d1 | |||
| 76f731d0cd | |||
| 5e22858ab4 | |||
| bc1c54c43e | |||
| 95ac0d36f8 | |||
| 2bee3eb179 | |||
| 52165f2a0b | |||
| 9f2da226f4 | |||
| 46b999317d | |||
| 80bce3c9c2 | |||
| 90b25b4bd8 | |||
| f562f1eafd | |||
| ff520622ff | |||
| 1a6c6a4f31 | |||
| 4a9e0388f4 | |||
| e47b2a971e | |||
| 96777ec095 | |||
| 52019deef5 | |||
| c26a534ff6 | |||
| e5be5c0b05 | |||
| 5b07f52641 | |||
| e0109cb530 | |||
| 1496dd1598 | |||
| efcaeb2f00 | |||
| 1252946fe5 | |||
| 2913d5f636 | |||
| c50beb3d43 | |||
| 46b559001a | |||
| 55a2e2e060 | |||
| 12364a052f | |||
| 45ac971035 | |||
| 26b818c9a6 | |||
| 007836f52e | |||
| ed0982770b | |||
| dcc72e90b7 | |||
| b428660944 | |||
| 0008dcc0ee | |||
| e3fbf3981d | |||
| c5e9244a08 | |||
| e1fd823c13 | |||
| 346f0d636c | |||
| 315a259e5b | |||
| 3157a03c74 | |||
| 045807a748 | |||
| ea0e12ac80 | |||
| 692060af6c | |||
| d8b23a4b5c | |||
| 074bf55d6c | |||
| 84e505b817 | |||
| a12e6ff603 | |||
| b01d662a1c | |||
| e631dad499 | |||
| 7ab0bfdd6b | |||
| 35a4db43fb | |||
| 094028006b | |||
| c12f42fcac | |||
| 3e498b098b | |||
| bbf1a1a544 | |||
| 42d57f30bf | |||
| 19967a9ad0 | |||
| 9d1a8f12d8 | |||
| 57bebebe09 | |||
| d19303cd62 | |||
| 7c96e46a37 | |||
| f75e68f8ce | |||
| 9b922b00c1 | |||
| c8d9ee2457 | |||
| a29f23086a | |||
| 4a76365df4 | |||
| 972264844a | |||
| e23e6f3c1a | |||
| 03c10382d1 | |||
| 3abe24aa18 | |||
| 2a4eabcda5 | |||
| 280d98c9c4 | |||
| 227c5c80c8 | |||
| edd00a6ab5 | |||
| d57bb17fc7 | |||
| 098da5c868 | |||
| dfc17bcc26 | |||
| 7a5eab104e | |||
| e0bf815377 | |||
| 2cbc6f2890 | |||
| 5859b2c08b | |||
| 44eaa9dc8b | |||
| 49cd7a41dd | |||
| 53de5ece21 | |||
| 90dffa5fcc | |||
| ac6cd0ca15 | |||
| 0e970128ab | |||
| 9fc373384d | |||
| a76bd2ea55 | |||
| 3c610b74d2 | |||
| 0623005ff4 | |||
| 8b032eba9a | |||
| e3229b85fd | |||
| 1178431b8f | |||
| 9d92c4a2b1 | |||
| 0bda8707ce | |||
| 9cb7d3a0fd | |||
| f1204f948a | |||
| 455b8dafb0 | |||
| fe5a32d95b | |||
| b34f6f1690 | |||
| a89bc35c6f | |||
| e551b6c202 | |||
| c6ed1afc51 | |||
| 4bedebb74d | |||
| 741fc7eb05 | |||
| 000da1197c | |||
| dd8be29d54 | |||
| 099c2c7ff4 | |||
| 874232a152 | |||
| d21f046e1f | |||
| ef0e25878e | |||
| cd37619af1 | |||
| 209ee18943 | |||
| aff7733a5b | |||
| 4bb65921e4 | |||
| 26216a6a8c | |||
| 60c3f11d7e | |||
| fcab08bfab | |||
| e69ba466e1 | |||
| 675e85ee09 | |||
| 36ec13b2c4 | |||
| 0b9c36e3ce | |||
| 07cf895447 | |||
| 028f21f0cf | |||
| 77724e363d | |||
| 15863d8a5a | |||
| b836af58f0 | |||
| ef5d880f14 | |||
| 15fd03b4c0 | |||
| cac06f3e17 | |||
| 6d81c62cdf | |||
| 60e319589d | |||
| 7723a5785d | |||
| dd982fe6e2 | |||
| c02dfeaa97 | |||
| a3d513afb0 | |||
| 40fa99a1f9 | |||
| f26c996095 | |||
| 012c4dfb9f | |||
| 9337ca2616 | |||
| 5dcec4bcfd | |||
| ed2e5e4d09 | |||
| 2249f52c32 | |||
| f4ef5d2b53 | |||
| a92c5d6ce0 | |||
| b61ceaead6 | |||
| 0672cfc8f3 | |||
| b5859a43cc | |||
| de1cd7c737 | |||
| f588312ad3 | |||
| 643ef1fa45 | |||
| ec38a4ed33 | |||
| defbd80ce0 | |||
| f11b91e7fa | |||
| 58bb4d5a7f | |||
| d92af60d9b | |||
| bca1e043bd | |||
| 7719175e85 | |||
| 046146c4d8 | |||
| 0e2f66b35a | |||
| 56b9ff1dc9 | |||
| dab8e78cd5 | |||
| 67dd27b9a1 | |||
| 4605985a47 | |||
| 02ac27342a | |||
| cbc59a4a1c | |||
| 02758d96c7 | |||
| 12752134fd | |||
| 504e70441b | |||
| 85cd16e793 | |||
| aa2277f05e | |||
| 27eb96722a | |||
| 0215096c9e | |||
| 90d8c51402 | |||
| ba0bbfefe7 | |||
| dd65673c1e | |||
| 2f3f8de682 | |||
| 3ce6fcad3a | |||
| 4302e7426e | |||
| 4e246c35c8 | |||
| 0cbcae9624 | |||
| 313aed606f | |||
| aade735c79 | |||
| 1e5786a142 | |||
| 3e5e5eeafa | |||
| 8a48ee8e14 | |||
| 6a89981c77 | |||
| 03c014fdda | |||
| ae683cd3c9 | |||
| a0dcae0882 | |||
| 6e839b210c | |||
| c7f4f62e93 | |||
| 214aba8f01 | |||
| 153c9d944f | |||
| 99a9d15871 | |||
| f6fb905ef8 | |||
| a5456452f6 | |||
| 48cd9af739 | |||
| 01fac428d5 | |||
| 3acce100f6 | |||
| ba2dfe6598 | |||
| 46600c38a8 | |||
| b9ae66e557 | |||
| bed9010918 | |||
| d13ccbde71 | |||
| 2e2aac0413 | |||
| 5f18cff344 | |||
| 830300ea81 | |||
| 9da2fcfbca | |||
| ece68df495 | |||
| 6a43ddbee9 | |||
| ee58596ed0 | |||
| 5bce6e77ae | |||
| 5dec45c0c8 | |||
| b7ba6500e4 | |||
| 2a263d749b | |||
| 3a21af48d1 | |||
| cb3bfe99ce | |||
| 328d51622f | |||
| 38ead74697 | |||
| ffd4d72850 | |||
| d23d90a794 | |||
| c74036ad26 | |||
| a146a9f424 | |||
| ddc0c82cee | |||
| bab09ac0d7 | |||
| 8a6eb912c5 | |||
| b5fbd40ea3 | |||
| 46b1c085cd | |||
| e5642cd752 | |||
| be933e9085 | |||
| 26769675c7 | |||
| 672d6d67aa | |||
| b3c6967ed9 | |||
| 9a528b17e8 | |||
| 4532932749 | |||
| 639a8e2f35 | |||
| 56c2ab38c6 | |||
| 9769cc0ed4 | |||
| 96d66b2205 | |||
| fea73109ca | |||
| e39c15c16f | |||
| 2a13f60bbd | |||
| d8e9738d71 | |||
| f38b78f821 | |||
| 9c21630295 | |||
| ea502727ba | |||
| 72f4999162 | |||
| adf1dbe635 | |||
| af2cdb1ca1 | |||
| e499c0e990 | |||
| 206ab6793f | |||
| e207c90fd4 | |||
| c9864008a3 | |||
| 5c89b27a87 | |||
| 3c482ba017 | |||
| 2d684411d4 | |||
| 408ee36a8b | |||
| d9efbad80d | |||
| 92e5c9f71a | |||
| baef88be50 | |||
| 7eff6ac504 | |||
| a3ea4d4e18 | |||
| f12047e36f | |||
| c77f37cc43 | |||
| 8bc463b6d6 | |||
| 953429f0da | |||
| 8598050931 | |||
| 81566674a8 | |||
| aba9f88352 | |||
| 0093c6ddf7 | |||
| cd5a0c2fbc | |||
| b1c803d2f1 | |||
| 3883b68669 | |||
| 5111bb12cf | |||
| cc2518a346 | |||
| 6e98f4c953 | |||
| 8990b25970 | |||
| c0cdde8685 | |||
| 7a7e20e4c2 | |||
| 743ccd27b6 | |||
| 155d9110c5 | |||
| 651e0b3445 | |||
| 82f438cbe4 | |||
| c3c30b4e20 | |||
| 8b4889ce83 | |||
| 7ccaa0390d | |||
| 5f0ed73d0d | |||
| 54518b63d0 | |||
| 1c38f2e5fd | |||
| 7ba12707e1 | |||
| 01992b26f4 | |||
| 8670ba08d5 | |||
| 67698757cf | |||
| 833ef3f5d3 | |||
| b104f14899 | |||
| 60c86b1db8 | |||
| b6d2965962 | |||
| 1548552af3 | |||
| 002cf8025b | |||
| dfd7e4b62c | |||
| e54380cd81 | |||
| 09b3532793 | |||
| b36e288958 | |||
| bcd3c2739a | |||
| 695e653461 | |||
| b068ff810c | |||
| 1a57f7a047 | |||
| 90f955e48e | |||
| 14fbce5a6b | |||
| 5cff407379 | |||
| 79b7ff21f5 | |||
| 65996a40e9 | |||
| cf3566255a | |||
| 582c6fa36d | |||
| aefba8b4df | |||
| e43674fd29 | |||
| 3856826e4d | |||
| 00ed0b7691 | |||
| aa456f6cff | |||
| 3a9dfa643e | |||
| 28580114da | |||
| 8d47f118dd | |||
| d7b45157ff | |||
| db8a48284f | |||
| b00b8d6ca3 | |||
| 22b3d8f691 | |||
| 432c1cd476 | |||
| ed8e4a059a | |||
| 571c1e31ac | |||
| b294d0eea0 | |||
| 0b50fbc55d | |||
| f5d5534290 | |||
| 777eb7e398 | |||
| 9b1be55a9e | |||
| ef4a7d1fa1 | |||
| e6a7380aa5 | |||
| 2f41591339 | |||
| 8916ef0207 | |||
| c3288f765e | |||
| 11d631bee3 | |||
| e3be78edb0 | |||
| 59f01a8426 | |||
| 76b7c8ef3b | |||
| fbaae9ce76 | |||
| e70b58a3df | |||
| ec551c9de8 | |||
| 7a8cb5835a | |||
| 3b8ccf173b | |||
| 172ce29665 | |||
| e7d8a8d2c0 | |||
| cc7b43f4ba | |||
| 71425977f5 | |||
| 4549727d0b | |||
| e030d97059 | |||
| 13c1ca4f79 | |||
| 637d7c0db1 | |||
| 7513a4b6d6 | |||
| 76100ef07d | |||
| ab139209db | |||
| c6a31baaab | |||
| 7c9d4629b6 | |||
| 986858c20d | |||
| a0551095dc | |||
| d0804c886a | |||
| 1befca7e28 | |||
| 3d4482157a | |||
| 3cd71f1cd4 | |||
| eebf443c1d | |||
| 7aaf0b9375 | |||
| 5ff9675e60 | |||
| 646390edff | |||
| b1958c5442 | |||
| 01b9590e81 | |||
| 985a288bf3 | |||
| 01dcfb88e7 | |||
| 76415a8dec | |||
| 586b7c14f8 | |||
| 0ee4bf2b25 | |||
| 5673e8abe8 | |||
| c446e32a8a | |||
| eee9392fb4 | |||
| 82a3961608 | |||
| f8689fc409 | |||
| 7de93e1780 | |||
| 19e742b7d1 | |||
| e3f0250fd2 | |||
| e4b39b89f3 | |||
| d2888b49e8 | |||
| b97ed49a60 | |||
| 65936dc85b | |||
| b1d02ee302 | |||
| cca47abb9c | |||
| c810ba62b4 | |||
| dcce7ffacc | |||
| e9fb137146 | |||
| 7100c9c300 | |||
| e9b5496387 | |||
| 87ecde390d | |||
| 8b33c66e22 | |||
| b3bbb6624e | |||
| 2ddac45612 | |||
| ddd7d47516 | |||
| a770072809 | |||
| 5b38ce0b37 | |||
| 804708076a | |||
| a0ad71a524 | |||
| 9d03694ea7 | |||
| 7a619e0e9e | |||
| 6bd5eb7930 | |||
| 744d1859d5 | |||
| 8033e3fc8e | |||
| abb0b629f3 | |||
| 34a61f49f6 | |||
| 08c31171a0 | |||
| 40addbf595 | |||
| abd6da0a37 | |||
| 794d1c5019 | |||
| b8d048bf3c | |||
| bb7b650ebc | |||
| 5253de9279 | |||
| 094945e350 | |||
| eb6b58e6db | |||
| 7bcb6e30a7 | |||
| 7ed4024555 | |||
| 6fa45c5958 | |||
| a883f140d4 | |||
| 1bec52efcb | |||
| 674e58ec3f | |||
| 373d705387 | |||
| 46fb693020 | |||
| f1fe7d1545 | |||
| 44ab386835 | |||
| 51d736eba4 | |||
| dcc4f6bd03 | |||
| eef2482423 | |||
| f46a1fb9b5 | |||
| bae45af414 | |||
| aff3835f50 | |||
| 5f249f6032 | |||
| a185d7e9e8 | |||
| 3449caf0e2 | |||
| cc458cc916 | |||
| 2b6b56ace9 | |||
| 4d72c920c6 | |||
| b0186a1baa | |||
| bc3836b316 | |||
| 0a444efe55 | |||
| fba3988834 | |||
| b99e1abb03 | |||
| ab44237bb9 | |||
| 6d98dc073f | |||
| 9709ef4333 | |||
| cb60f6f735 | |||
| 5d0ab2e2db | |||
| 4e3b0b52c8 | |||
| 973590281c | |||
| 4f7defb85c | |||
| 59f4d8dc26 | |||
| be736e105a | |||
| 3be56ba462 | |||
| f7adf8457b | |||
| 80b8856f15 | |||
| 0860f47d88 | |||
| 382b75fccf | |||
| d3dacbd32d | |||
| 6c51e4b596 | |||
| d0bd4428be | |||
| 43ffcb7362 | |||
| ca5dfca290 | |||
| 8a495eff37 | |||
| bee6af12fb | |||
| 4a3dfc3eb7 | |||
| 4e87a4adc4 | |||
| d9bb9d5884 | |||
| 562be0cb89 | |||
| 2fdc86af97 | |||
| 220d1225b2 | |||
| e047a6e449 | |||
| 97b21a9d69 | |||
| 9be9570dea | |||
| cbfe37dbba | |||
| bf176a2c05 | |||
| 173c51eb26 | |||
| 71dbb090fb | |||
| 832133e6cc | |||
| 2730a92b01 | |||
| 40fb5c80eb | |||
| 6c65095961 | |||
| d02f7ae7bc | |||
| 9f0b4b24ba | |||
| 237357c1d5 | |||
| aefb1caf57 | |||
| a3328e7ef0 | |||
| db24588273 | |||
| 2cabeeb6bd | |||
| 88352202b0 | |||
| e02d8a949b | |||
| e7e5457cf2 | |||
| 29b98b0f7d | |||
| ae7378f474 | |||
| b05c17bee4 | |||
| a2d3dac226 | |||
| a8ec41e255 | |||
| 1d16062961 | |||
| 2a614e8656 | |||
| baaaaf01bf | |||
| 20f1fc51b1 | |||
| d749ebf981 | |||
| 04364c503c | |||
| ae2a040fe4 | |||
| 0debf23b5e | |||
| 55e7849b43 | |||
| 34d9a73677 | |||
| 0b9ccf5bc0 | |||
| 48e72bb9df | |||
| 35aed44bcb | |||
| e4cf693c0d | |||
| f0755f5f90 | |||
| bdfc6af688 | |||
| 31b4061a43 | |||
| a1b80f0323 | |||
| 1678686ce7 | |||
| c25d05196d | |||
| bdddc7ad03 | |||
| 1d1ad4f9fa | |||
| 099fcc7981 | |||
| 2ef44e45f6 | |||
| ebe62d0498 | |||
| 6472b20ea4 | |||
| 69cdb2d754 | |||
| f7d8000b48 | |||
| a44afbe1b9 | |||
| 662da1b8a9 | |||
| 2a3d743204 | |||
| 7241ee4c7a | |||
| 5c084d6e8b | |||
| 1060c7fdfc | |||
| b5d6c0e0b3 | |||
| d69644350e | |||
| 8634622a6a | |||
| cc73554350 | |||
| 8adf93d592 | |||
| 6bd60ddf96 | |||
| ea5bcbe4dd | |||
| 541b49069d | |||
| ba868866ec | |||
| 606ae48f13 | |||
| 09c5445f83 | |||
| 4a0a18a7b0 | |||
| ed9d1ab738 | |||
| a61e8084dd | |||
| e169380178 | |||
| b07d4ef6c3 | |||
| 4c713c7652 | |||
| 90e8c6b3c4 | |||
| 07bf05cb2c | |||
| 49d29902a8 | |||
| 32a90c2a9e | |||
| 16ed2c1517 | |||
| 8bb0f1c799 | |||
| f14fe2dd64 | |||
| 884f0ee0de | |||
| 744270f48c | |||
| c30849be3c | |||
| f295ac8b4d | |||
| 9469a8f43d | |||
| 786799ca40 | |||
| aa6238cf5a | |||
| 1ed31ee2e2 | |||
| 7d8c12977c | |||
| 81ee1d63a6 | |||
| cf1c1b3198 | |||
| bc7b1e8472 | |||
| 7319c41cc1 | |||
| 2f09fc32c0 | |||
| f85b3f54a1 | |||
| 1a68669d6d | |||
| 6345c2d414 | |||
| 87930cad75 | |||
| 3ab2232121 | |||
| 9719e25421 | |||
| 8e1f998c39 | |||
| deb1c224f8 | |||
| b2fa79898a | |||
| da2759a3c6 | |||
| f6bc696426 | |||
| da653e9b32 | |||
| 227e153bde | |||
| 12f906b9b0 | |||
| c8236d4d10 | |||
| e2006da50d | |||
| 433a7d3641 | |||
| 6b41c74b43 | |||
| cc3e7ff7c6 | |||
| a35a6bf642 | |||
| 9ecd523646 | |||
| e7f896c38e | |||
| 624ec743b1 | |||
| 553c5745ef | |||
| 3f2779ca3d | |||
| e51b962627 | |||
| f709e135b6 | |||
| 50b48aa247 | |||
| 508f2abc82 | |||
| 42ec56e578 | |||
| 92673dac6e | |||
| daf57aba35 | |||
| dee629c429 | |||
| 67f9092350 | |||
| 88691d47a5 | |||
| 0fdd9bc803 | |||
| 8452c607b4 | |||
| 4fc57c2d57 | |||
| 9f0b707a30 | |||
| 511bc351d5 | |||
| 56ee3e962c | |||
| 2781e8519d | |||
| 46575348fe | |||
| bae2ca646b | |||
| 0686c6ab00 | |||
| db04b66ce5 | |||
| c43c8a29af | |||
| aaea18abe1 | |||
| 0b6076cb61 | |||
| 3b6d02f02c | |||
| 625a0586a3 | |||
| 10d63ca586 | |||
| d2697bf9de | |||
| fa8c8843e2 | |||
| 7b59ea4b96 | |||
| 058215934e | |||
| 1d724d841f | |||
| 32db2100de | |||
| 095c77b65b | |||
| c1c07bff8f | |||
| 1206bd0e98 | |||
| 67bcd1b307 | |||
| 31ef70e433 | |||
| afb12961d2 | |||
| 3dbd40e334 | |||
| bc5d6e38c8 | |||
| 5a39143051 | |||
| 18e9571877 | |||
| a828f4c831 | |||
| 54ac12f250 | |||
| 9a6a72f605 | |||
| 03949489e8 | |||
| 8ebd735e7e | |||
| 39246da73f | |||
| bf33f60368 | |||
| 492a613769 | |||
| 2c02c3434e | |||
| a186ddd9d2 | |||
| 4b0c7a5e4e | |||
| 54cfbe3ab6 | |||
| 02015cf0b8 | |||
| 416e4d3598 | |||
| e0d9c4b0ea | |||
| 2659e3bc09 | |||
| d296167b6a | |||
| 89b0aa7fec | |||
| 787aadf444 | |||
| d67161a29b | |||
| 7f4777ead4 | |||
| 1e2147b143 | |||
| 9f0a2fbf63 | |||
| 7804851bc9 | |||
| adc50dd89e | |||
| 5378cf5ddc | |||
| a733bb605f | |||
| aaa1b5a264 | |||
| 5855cdee65 | |||
| c0d584e644 | |||
| 955f0f473e | |||
| 9ceb888124 | |||
| e902933693 | |||
| e07b47fb10 | |||
| 5bf08d9701 | |||
| 597fa1e6fa | |||
| dda3ec0ba0 | |||
| 991f08c749 | |||
| 923865cd7c | |||
| 606aee8ccd | |||
| 4a1cb27d0a | |||
| 26cd7f3a12 | |||
| f4045dbc56 | |||
| 33c2b24550 | |||
| cd86f3c8ea | |||
| 58026ebc2d | |||
| 9183275dad | |||
| 5e3a625d95 | |||
| 3297f9d2d2 | |||
| 29b8306a28 | |||
| d84746bac6 | |||
| 4eacf2ff0b | |||
| a68e0d6f61 | |||
| ddf44304c7 | |||
| 789d98f58e | |||
| 205574620d | |||
| d9bae12b31 | |||
| c951190794 | |||
| d4e1d69c3c | |||
| f93a32c07b | |||
| 8e7c152c0d | |||
| 6a64404f20 | |||
| 1a09589add | |||
| d0f9072ab5 | |||
| 011ed9f2d8 | |||
| 12332f83d9 | |||
| 8f75829948 | |||
| a7ffedb3b2 | |||
| 378d3b9747 | |||
| 5ba05409c4 | |||
| d86beef58f | |||
| 7315d67c9f | |||
| 59d79b8c7a | |||
| 3df97653a2 | |||
| 948d55e418 | |||
| 1d2c7281b1 | |||
| 35759b943c | |||
| 29da33e200 | |||
| 1d758f8126 | |||
| b663dac2ab | |||
| 485a3971e9 | |||
| 36b5d64ca6 | |||
| 8462a709bc | |||
| 20cabe8362 | |||
| 6967864361 | |||
| a6ee3840ae | |||
| 01de6139df | |||
| 6ba0924f6c | |||
| 00c75d1fd8 | |||
| 93f28fa9d5 | |||
| 0aed10eb8b | |||
| d84d687eee | |||
| d046f56832 | |||
| 0af1fbf313 | |||
| e9aaf4309e | |||
| 80fa1085d2 | |||
| 88195291fd | |||
| 39ad600d00 | |||
| c63a3aba6b | |||
| 782ecbe307 | |||
| f75bbfa048 | |||
| 3a772cc983 | |||
| 807113523e | |||
| 7df2af8611 | |||
| 10c1697b00 | |||
| 742e5d38ab | |||
| 1d3e7f8af0 | |||
| c99bacab64 | |||
| 95d7555ebc | |||
| 5854e0a23c | |||
| 81f7f32767 | |||
| c0374a7da1 | |||
| ed65e655b9 | |||
| d250e516b5 | |||
| e4f404b2c7 | |||
| 86571331f8 | |||
| 163d420af9 | |||
| 4925ea4af0 | |||
| 57b05ce348 | |||
| 427b53fcbd | |||
| 2ac7a31be6 | |||
| 4baed6409f | |||
| 2ea0ff0965 | |||
| 88b9a7edce | |||
| 538066b960 | |||
| b10dd1d75a | |||
| f743580b55 | |||
| 0688467302 | |||
| 29e972dbf2 | |||
| bd99697c5b | |||
| 1d5c431ff6 | |||
| 3736c510ff | |||
| 26c12c3a85 | |||
| 10bb08e5e6 | |||
| b50d5b6121 | |||
| 38b28752e1 | |||
| 87c51009de | |||
| a950a47b28 | |||
| 2609d10c0b | |||
| 7b4cb0f66c | |||
| 26db0e1e69 | |||
| 62e64cbd22 | |||
| 844a47830f | |||
| 2cc1e32f45 | |||
| 9890958b1e | |||
| 6dbd6d6edc | |||
| bf7a4dfd28 | |||
| f52626bda0 | |||
| 88cec4bf2b | |||
| b880def108 | |||
| bfd5dc039a |
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"agentCanUpdateSnapshot": true
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
ВАЖНО!!! Мы работаем в МОНО-репозитории pnpm, любая установка пакетов производится ЧЕРЕЗ ФИЛЬТР компонента в корне: pnpm add glob --filter notificator2.
|
||||
|
||||
ВАЖНО!!! НИКОГДА НЕ ЗАПУСКАЙ ПРИЛОЖЕНИЕ ИЛИ ЕГО СБОРКУ!!! Просто отчитайся что всё сделал.
|
||||
@@ -0,0 +1,151 @@
|
||||
---
|
||||
description:
|
||||
globs: components/controller/**
|
||||
alwaysApply: false
|
||||
---
|
||||
# NestJS Controller и Чистая архитектура
|
||||
|
||||
## Основные принципы
|
||||
1. Чистая архитектура - главный архитектурный подход. Пиши код с комментариями.
|
||||
2. Типы IName, IChecksum256, ITimePointSec - это просто строки.
|
||||
3. Домен должен быть полностью изолирован от инфраструктурных деталей.
|
||||
4. Направление зависимостей - внутрь (к ядру, домену).
|
||||
5. Домен, инфраструктура и приложение связаны через App.module, НЕ НУЖНО импортировать их друг в друга, а достаточно просто импортировать домен на уровне приложения чтобы использовать все экспорты домена.
|
||||
|
||||
## Структура проекта
|
||||
- `domain/` - доменный слой (бизнес-логика, независимая от инфраструктуры)
|
||||
- `infrastructure/` - инфраструктурный слой (адаптеры к внешним системам)
|
||||
- `modules/` - слой приложения (DTO, резолверы, сервисы)
|
||||
|
||||
## Слои и их взаимодействие
|
||||
1. **Домен**:
|
||||
- Содержит чистые доменные интерфейсы и реализованные на них сущности
|
||||
- НЕ должен зависеть от `cooptypes` (инфраструктурный контракт)
|
||||
- Использует собственные доменные типы (например, Date вместо строковых timestamp)
|
||||
- Интерфейсы портов описывают взаимодействие с внешними системами
|
||||
|
||||
2. **Инфраструктура**:
|
||||
- Содержит адаптеры к внешним системам (блокчейн, БД и т.д.)
|
||||
- Осуществляет преобразование между доменными и инфраструктурными типами
|
||||
- Общая логика преобразования выносится в утилитарные классы (например, `DomainToBlockchainUtils`)
|
||||
|
||||
3. **Модули (приложение)**:
|
||||
- DTO имплементируют доменные интерфейсы напрямую
|
||||
- Резолвер вызывает сервис, который принимает DTO
|
||||
- Сервис передает объекты DTO в интерактор домена
|
||||
|
||||
## Поток данных
|
||||
1. Резолвер принимает входные данные и передает их в сервис
|
||||
2. Сервис вызывает интерактор домена, передавая ему объекты DTO (имплементирующие доменный интерфейс)
|
||||
3. Интерактор выполняет бизнес-логику и взаимодействует с портами домена
|
||||
4. Адаптеры (инфраструктурный слой) преобразуют доменные объекты в формат внешних систем (JSON для хранения мета-данных, ISO для дат и т.д.)
|
||||
5. Адаптеры возвращают результаты в домен, домен возвращает данные в сервис, который возвращает их в резолвер
|
||||
|
||||
## Правила преобразования данных
|
||||
1. Преобразование DTO → доменный объект: не требуется, если DTO имплементирует доменный интерфейс
|
||||
2. Преобразование доменный объект → инфраструктурный тип: происходит в адаптерах
|
||||
3. Преобразование документов, дат и других сложных объектов: используются утилитарные классы уровня инфраструктуры
|
||||
|
||||
## Работа с типами данных
|
||||
1. **Даты**:
|
||||
- В доменных интерфейсах используется тип `Date`
|
||||
- В DTO используется тип `Date` с декораторами `@IsDate()` и `@Type(() => Date)`
|
||||
- В инфраструктурном слое происходит преобразование `Date` → `string` (ISO формат)
|
||||
```typescript
|
||||
// Доменный интерфейс
|
||||
interface MeetDomainInterface {
|
||||
open_at: Date;
|
||||
}
|
||||
|
||||
// DTO
|
||||
@Field(() => Date)
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
open_at!: Date;
|
||||
|
||||
// Адаптер
|
||||
const blockchainData = {
|
||||
open_at: domainToBlockchainUtils.convertDateToBlockchainFormat(data.open_at)
|
||||
};
|
||||
```
|
||||
|
||||
2. **Документы**:
|
||||
- В доменных интерфейсах используется собственный тип `SignedDocumentDomainInterface<T>`
|
||||
- В DTO используется соответствующий DTO-класс (например, `SignedDigitalDocumentInputDTO`)
|
||||
- В инфраструктурном слое происходит преобразование между форматами (meta-поля в JSON и т.д.)
|
||||
|
||||
## Типовые ошибки
|
||||
1. **Нарушение изоляции домена**: домен должен быть изолирован от инфраструктуры. Не используйте импорты из `cooptypes` в доменных интерфейсах.
|
||||
```typescript
|
||||
// Неправильно
|
||||
import { MeetContract } from 'cooptypes';
|
||||
export type VoteDomainInterface = MeetContract.Actions.Vote.IInput;
|
||||
|
||||
// Правильно
|
||||
export interface VoteDomainInterface {
|
||||
coopname: string;
|
||||
hash: string;
|
||||
// ... доменные поля
|
||||
}
|
||||
```
|
||||
|
||||
2. **Преобразование в неправильном слое**: преобразование доменных объектов в инфраструктурные типы должно происходить в адаптерах, а не в доменном слое или сервисе.
|
||||
```typescript
|
||||
// Неправильно (в доменном интеракторе)
|
||||
async vote(data: VoteDomainInterface) {
|
||||
const blockchainData = { ...data, meta: JSON.stringify(data.meta) };
|
||||
// ...
|
||||
}
|
||||
|
||||
// Правильно (в адаптере)
|
||||
async vote(data: VoteDomainInterface) {
|
||||
const blockchainData = this.convertToBlockchainFormat(data);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
3. **Дублирование логики преобразования**: общая логика преобразования должна быть вынесена в утилитарные классы.
|
||||
```typescript
|
||||
// Неправильно (дублирование в разных адаптерах)
|
||||
// В MeetAdapter
|
||||
private convertDoc(doc) { return { ...doc, meta: JSON.stringify(doc.meta) }; }
|
||||
// В BranchAdapter
|
||||
private convertDoc(doc) { return { ...doc, meta: JSON.stringify(doc.meta) }; }
|
||||
|
||||
// Правильно (общий утилитарный класс)
|
||||
// DomainToBlockchainUtils
|
||||
convertSignedDocumentToBlockchainFormat(doc) {
|
||||
return { ...doc, meta: JSON.stringify(doc.meta) };
|
||||
}
|
||||
```
|
||||
|
||||
## Примеры
|
||||
```typescript
|
||||
// Доменный интерфейс - чистый, без зависимостей от инфраструктуры
|
||||
export interface VoteOnAnnualGeneralMeetInputDomainInterface {
|
||||
coopname: string;
|
||||
hash: string;
|
||||
member: string;
|
||||
ballot: VoteItemInputDomainInterface[];
|
||||
}
|
||||
|
||||
// DTO имплементирует доменный интерфейс напрямую
|
||||
@InputType('VoteOnAnnualGeneralMeetInput')
|
||||
export class VoteOnAnnualGeneralMeetInputDTO implements VoteOnAnnualGeneralMeetInputDomainInterface {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
coopname!: string;
|
||||
// ... остальные поля
|
||||
}
|
||||
|
||||
// Адаптер преобразует доменный объект в инфраструктурный тип
|
||||
async vote(data: VoteOnAnnualGeneralMeetInputDomainInterface): Promise<TransactionResult> {
|
||||
// Преобразуем доменный объект в инфраструктурный тип
|
||||
const blockchainData: MeetContract.Actions.Vote.IInput = {
|
||||
coopname: data.coopname,
|
||||
hash: data.hash,
|
||||
// ... преобразование других полей
|
||||
};
|
||||
// ... отправка данных во внешнюю систему
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
description: SDK мутации и запросы для подключения на рабочем столе
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
Бэкенд реализован здесь components/controller, sdk здесь components/sdk.
|
||||
|
||||
Пример создания Query к API через SDK:
|
||||
|
||||
``` ts
|
||||
async function loadBranches(data: IGetBranchesInput): Promise<IBranch[]> {
|
||||
const { [Queries.Branches.GetBranches.name]: output } = await client.Query(
|
||||
Queries.Branches.GetBranches.query,
|
||||
{
|
||||
variables: {
|
||||
data
|
||||
}
|
||||
}
|
||||
);
|
||||
return output;
|
||||
}
|
||||
```
|
||||
|
||||
Такие запросы обычно хранятся в папке Entities и вызываются из его store.
|
||||
|
||||
Пример мутации:
|
||||
|
||||
``` ts
|
||||
async function selectBranch(data: ISelectBranchInput): Promise<boolean>{
|
||||
const {[Mutations.Branches.SelectBranch.name]: result} = await client.Mutation(Mutations.Branches.SelectBranch.mutation, {variables: {
|
||||
data
|
||||
}})
|
||||
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
Мутации обычно храним в папке features.
|
||||
|
||||
Как можешь обратить внимание, все мутации и запросы строятся по одному шаблону. Вся необходимая информация уже есть в SDK.
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
alwaysApply: true
|
||||
globs: **/desktop/**
|
||||
---
|
||||
# DESKTOP
|
||||
|
||||
- Пишем код фронтенда в архитектуре Feature Sliced Design (FSD).
|
||||
- Стиль шаблонов PUG на composite API.
|
||||
- Всегда создаём index.ts файлы для vue компонент.
|
||||
- Создавай индексные файлы для vue через export {default as NAME} from './where', а на уровне выше, если это необходимо, делай export * from './ui'
|
||||
- Всегда удаляем неиспользуемые импорты.
|
||||
- Не используем emit избыточно. Вместо них используем композабл функции моделей фич, если необходимо. Emit только в крайнем случае.
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
Файл [main.py](mdc:monocoop/monocoop/monocoop/components/docs/main.py) автоматически генерит ссылки на документацию SDK и GraphQL, которые формируются и публикуются автоматически. При создании документации к методам всегда применяй ссылки на SDK и GraphQL по форме:
|
||||
{{ get_sdk_doc("Mutations", "Accounts", "RegisterAccount") }} | {{ get_graphql_doc("Mutation.registerAccount") }}
|
||||
|
||||
### 🎯 Основные паттерны использования
|
||||
|
||||
**1. Стандартная структура для методов API:**
|
||||
```markdown
|
||||
## Название действия
|
||||
{{ get_sdk_doc("Namespace", "Module", "Method") }} | {{ get_graphql_doc("Type.methodName") }}
|
||||
|
||||
{{ get_typedoc_input("Namespace.Module.Method") }}
|
||||
|
||||
Результат:
|
||||
{{ get_typedoc_definition("Namespace.Module.Method", "IOutput") }}
|
||||
```
|
||||
|
||||
**2. Описание + пример (для сложных методов):**
|
||||
```markdown
|
||||
{{ get_typedoc_desc("Namespace.Module.Method") }}
|
||||
|
||||
{{ get_typedoc_input("Namespace.Module.Method") }}
|
||||
```
|
||||
|
||||
**3. Ссылки на типы данных:**
|
||||
```markdown
|
||||
У каждого аккаунта есть объект {{ get_graphql_definition("Account") }} в GraphQL-API
|
||||
```
|
||||
|
||||
### 🔧 Макросы и их применение
|
||||
|
||||
| Макрос | Назначение | Пример использования |
|
||||
|--------|------------|---------------------|
|
||||
| `get_sdk_doc` | Ссылка на SDK документацию | `{{ get_sdk_doc("Mutations", "Payments", "CreateDeposit") }}` |
|
||||
| `get_graphql_doc` | Ссылка на GraphQL операцию | `{{ get_graphql_doc("Query.getAccount") }}` |
|
||||
| `get_graphql_definition` | Ссылка на GraphQL тип | `{{ get_graphql_definition("Account") }}` |
|
||||
| `get_class_doc` | Ссылка на класс/метод SDK | `{{ get_class_doc("Document", "sign") }}` |
|
||||
| `get_typedoc_input` | **Полный пример** TypeScript вызова | `{{ get_typedoc_input("Mutations.Auth.Login") }}` |
|
||||
| `get_typedoc_definition` | **Структура интерфейса** | `{{ get_typedoc_definition("Mutations.Auth.Login", "IOutput") }}` |
|
||||
| `get_typedoc_desc` | Описание + примеры | `{{ get_typedoc_desc("Mutations.Auth.Login") }}` |
|
||||
| `get_typedoc_value` | Значение константы | `{{ get_typedoc_value("Constants.API_VERSION") }}` |
|
||||
|
||||
### 📝 Правила оформления
|
||||
|
||||
**ОБЯЗАТЕЛЬНО:**
|
||||
- Всегда используй `get_typedoc_input` для демонстрации **КАК вызывать** метод
|
||||
- Всегда используй `get_typedoc_definition` для показа **ЧТО возвращается**
|
||||
- Комбинируй SDK и GraphQL ссылки через ` | `: `{{ get_sdk_doc(...) }} | {{ get_graphql_doc(...) }}`
|
||||
|
||||
**ЖЕЛАТЕЛЬНО:**
|
||||
- Для сложных методов добавляй `get_typedoc_desc` в начало
|
||||
- Используй `get_graphql_definition` для ссылок на типы данных в тексте
|
||||
- Группируй связанные операции в одном разделе
|
||||
|
||||
**ФОРМАТ ССЫЛОК:**
|
||||
- SDK: `"Namespace", "Module", "Method"` (3 аргумента)
|
||||
- GraphQL: `"Type.methodName"` (точка между типом и методом)
|
||||
- Определения: просто имя типа `"TypeName"`
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Структура файлов шаблонов документов и алгоритм правки
|
||||
|
||||
## Основные директории и файлы
|
||||
|
||||
### 1. Определение типов и интерфейсов (cooptypes)
|
||||
**Путь:** `/cooptypes/src/cooperative/registry/[ID.DocumentName]/index.ts`
|
||||
|
||||
В этих файлах определяются:
|
||||
- Интерфейсы данных (`IAgendaMeet`, etc.)
|
||||
- Основная модель данных документа (`Model`)
|
||||
- HTML шаблон документа (`context`)
|
||||
- Переводы строк (`translations`)
|
||||
- Пример данных для тестирования (`exampleData`)
|
||||
|
||||
**Для изменения шаблона нужно править:**
|
||||
- Интерфейсы модели данных при изменении структуры
|
||||
- HTML в переменной `context` для изменения внешнего вида
|
||||
- Строки переводов в `translations.ru`
|
||||
|
||||
### 2. Схемы валидации (factory)
|
||||
**Путь:** `/factory/src/Schema/[SchemaName].ts`
|
||||
|
||||
Содержат:
|
||||
- JSON схемы для валидации данных
|
||||
- Определение обязательных полей
|
||||
|
||||
**При изменении структуры данных:**
|
||||
- Обновите соответствующую схему валидации
|
||||
- Обновите список обязательных полей в `required`
|
||||
|
||||
### 3. Фабрики документов (factory)
|
||||
**Путь:** `/factory/src/Actions/[ID.DocumentName].ts`
|
||||
|
||||
Обрабатывают:
|
||||
- Получение данных из разных источников
|
||||
- Сборку модели для шаблонизатора
|
||||
- Валидацию данных по схеме
|
||||
- Генерацию PDF
|
||||
|
||||
**При изменении логики сборки документа:**
|
||||
- Обновите метод `generateDocument()`
|
||||
- Добавьте новые источники данных
|
||||
|
||||
### 4. Шаблоны (factory)
|
||||
**Путь:** `/factory/src/Templates/[ID.DocumentName].ts`
|
||||
|
||||
Связывают:
|
||||
- Шаблон из cooptypes
|
||||
- Схему валидации
|
||||
- Метаданные документа
|
||||
|
||||
**После изменения в cooptypes:**
|
||||
- Убедитесь, что схема в Templates соответствует новой модели
|
||||
|
||||
### 5. Тесты (factory)
|
||||
**Путь:** `/factory/test/[category].test.ts`
|
||||
|
||||
Содержат:
|
||||
- Тестовые данные для генерации документов
|
||||
- Вызовы функции `testDocumentGeneration`
|
||||
|
||||
**После внесения изменений:**
|
||||
- Обновите тестовые данные в соответствии с новой структурой
|
||||
- Запустите тесты командой `pnpm test`
|
||||
|
||||
## Алгоритм внесения изменений
|
||||
|
||||
1. **Модификация типов**
|
||||
- Изменить файл в `/cooptypes/src/cooperative/registry/[ID.DocumentName]/index.ts`
|
||||
- Обновить интерфейсы, шаблон HTML и переводы
|
||||
|
||||
2. **Обновление схемы валидации**
|
||||
- Изменить соответствующую схему в `/factory/src/Schema/`
|
||||
- Убедиться, что обязательные поля совпадают с интерфейсом
|
||||
|
||||
3. **Компиляция библиотеки типов**
|
||||
- Выполнить `cd /cooptypes && pnpm build`
|
||||
|
||||
4. **Обновление тестовых данных**
|
||||
- Привести тестовые данные в соответствие с новой структурой
|
||||
|
||||
5. **Запуск тестов**
|
||||
- Выполнить `cd /factory && pnpm test [filename].test.ts`
|
||||
|
||||
## Особенности шаблонизации
|
||||
|
||||
- Используется Nunjucks для шаблонов
|
||||
- Поддерживаются конструкции: `{% if %}`, `{% for %}`, `{% trans %}`
|
||||
- Переменные вставляются через `{{ variable }}`
|
||||
- Переводы через `{% trans 'KEY' %}`
|
||||
@@ -0,0 +1,225 @@
|
||||
# Архитектура расширений в MonoCoop
|
||||
|
||||
## Основные принципы
|
||||
1. Расширения построены на модулях NestJS с использованием шаблона "Порты и адаптеры"
|
||||
2. Каждое расширение наследуется от `BaseExtModule` и реализует интерфейс `OnModuleInit`
|
||||
3. Расширения могут взаимодействовать с блокчейном через соответствующие порты
|
||||
4. Конфигурации расширений хранятся в БД и описываются с помощью Zod-схем
|
||||
5. Расширения регистрируются в глобальном реестре `AppRegistry`
|
||||
|
||||
## Структура расширения
|
||||
Минимальная структура расширения включает:
|
||||
- `XXX-extension.module.ts` - основной модуль расширения
|
||||
- `package.json` - информация о пакете
|
||||
- `README.md` - документация
|
||||
- `INSTALL.md` - инструкции по установке
|
||||
- `CHANGELOG.md` - история изменений
|
||||
|
||||
## Создание нового расширения
|
||||
1. Создайте директорию для расширения в `components/controller/src/extensions/`
|
||||
2. Создайте основной класс расширения, наследующийся от `BaseExtModule`
|
||||
3. Определите Zod-схему для конфигурации
|
||||
4. Реализуйте метод `initialize()`
|
||||
5. Зарегистрируйте расширение в `extensions.registry.ts`
|
||||
6. Добавьте расширение в список дефолтных приложений в `extension-domain.service.ts`
|
||||
|
||||
## Пример структуры модуля расширения
|
||||
```typescript
|
||||
// XXX-extension.module.ts
|
||||
export class XXXPlugin extends BaseExtModule {
|
||||
constructor(...) {
|
||||
super();
|
||||
}
|
||||
|
||||
name = 'xxx';
|
||||
plugin!: ExtensionDomainEntity<IConfig>;
|
||||
public configSchemas = Schema;
|
||||
|
||||
async initialize() {
|
||||
// Инициализация расширения
|
||||
// Настройка cron-задач
|
||||
}
|
||||
}
|
||||
|
||||
@Module({
|
||||
providers: [XXXPlugin],
|
||||
})
|
||||
export class XXXPluginModule {
|
||||
constructor(private readonly xxxPlugin: XXXPlugin) {}
|
||||
|
||||
async initialize() {
|
||||
await this.xxxPlugin.initialize();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Управление отображением конфигурации
|
||||
Zod-схемы используются для автоматического отображения формы настроек в интерфейсе пользователя.
|
||||
Через интерфейс `DeserializedDescriptionOfExtension` из `components/controller/src/types/shared/extension.types.ts`
|
||||
можно управлять отображением полей формы:
|
||||
|
||||
```typescript
|
||||
export const Schema = z.object({
|
||||
// Базовое поле с меткой
|
||||
simpleField: z.string().describe(
|
||||
describeField({
|
||||
label: 'Название поля',
|
||||
note: 'Подсказка под полем'
|
||||
})
|
||||
),
|
||||
|
||||
// Скрытое поле для служебного использования
|
||||
hiddenField: z.string().describe(
|
||||
describeField({
|
||||
label: 'Скрытое поле',
|
||||
visible: false
|
||||
})
|
||||
),
|
||||
|
||||
// Поле с проверкой значения
|
||||
validatedField: z.number().describe(
|
||||
describeField({
|
||||
label: 'Поле с валидацией',
|
||||
rules: ['val >= 5', 'val <= 100'],
|
||||
})
|
||||
),
|
||||
|
||||
// Форматированное поле с префиксом и суффиксом
|
||||
formattedField: z.number().describe(
|
||||
describeField({
|
||||
label: 'Форматированное поле',
|
||||
prepend: '$',
|
||||
append: 'USD',
|
||||
})
|
||||
),
|
||||
|
||||
// Многострочное текстовое поле
|
||||
multilineField: z.string().describe(
|
||||
describeField({
|
||||
label: 'Многострочное поле',
|
||||
maxRows: 5,
|
||||
minLength: 10,
|
||||
maxLength: 1000
|
||||
})
|
||||
),
|
||||
});
|
||||
```
|
||||
|
||||
Доступные поля для управления отображением:
|
||||
- `label` - название поля (обязательное)
|
||||
- `note` - пояснение или подсказка
|
||||
- `visible` - видимость поля (по умолчанию true)
|
||||
- `rules` - правила валидации в виде строковых выражений
|
||||
- `mask` - маска для ввода
|
||||
- `fillMask` - автозаполнение маски
|
||||
- `minLength` / `maxLength` - ограничения длины для текстовых полей
|
||||
- `maxRows` - количество строк для многострочного ввода
|
||||
- `append` / `prepend` - текст до/после значения поля
|
||||
|
||||
## Взаимодействие с блокчейном
|
||||
Для взаимодействия с блокчейном:
|
||||
1. Определите порт в доменном слое (например, `SovietBlockchainPort`)
|
||||
2. Инжектируйте порт в конструкторе расширения через DI
|
||||
3. Используйте методы порта для взаимодействия с блокчейном
|
||||
|
||||
```typescript
|
||||
@Inject(SOVIET_BLOCKCHAIN_PORT) private readonly sovietBlockchainPort: SovietBlockchainPort
|
||||
// ...
|
||||
const decisions = await this.sovietBlockchainPort.getDecisions(coopname);
|
||||
```
|
||||
|
||||
## Настройка планировщика задач
|
||||
Расширения могут использовать cron-задачи для периодического выполнения операций:
|
||||
|
||||
```typescript
|
||||
import cron from 'node-cron';
|
||||
|
||||
// Регистрация cron-задачи (каждые N минут)
|
||||
const cronExpression = `*/${this.plugin.config.checkInterval} * * * *`;
|
||||
cron.schedule(cronExpression, () => {
|
||||
this.logger.info('Запуск запланированной задачи');
|
||||
this.runTask();
|
||||
});
|
||||
```
|
||||
|
||||
## Работа с конфигурацией
|
||||
1. Определите Zod-схему для конфигурации
|
||||
2. Используйте `describeField` для добавления UI-метаданных к полям
|
||||
3. Получайте и обновляйте конфигурацию через репозиторий `extensionRepository`
|
||||
|
||||
```typescript
|
||||
export const Schema = z.object({
|
||||
checkInterval: z.number().describe(
|
||||
describeField({
|
||||
label: 'Интервал проверки (в минутах)',
|
||||
note: 'Минимум: 5 минут',
|
||||
rules: ['val >= 5'],
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
// Обновление конфигурации
|
||||
this.plugin.config.lastCheckDate = new Date().toISOString();
|
||||
await this.extensionRepository.update(this.plugin);
|
||||
```
|
||||
|
||||
## Логирование действий
|
||||
Расширения должны логировать свои действия:
|
||||
1. Используйте `WinstonLoggerService` для системного логирования
|
||||
2. Используйте `LogExtensionDomainRepository` для хранения логов в БД
|
||||
|
||||
```typescript
|
||||
// Системное логирование
|
||||
this.logger.info(`Выполнение операции для ${id}`);
|
||||
|
||||
// Сохранение лога в БД
|
||||
await this.logExtensionRepository.push(this.name, {
|
||||
type: 'operation',
|
||||
timestamp: new Date().toISOString(),
|
||||
data: { ... },
|
||||
});
|
||||
```
|
||||
|
||||
## Регистрация расширения
|
||||
После создания расширения, добавьте его в `extensions.registry.ts`:
|
||||
|
||||
```typescript
|
||||
export const AppRegistry: INamedExtension = {
|
||||
myExtension: {
|
||||
is_builtin: false,
|
||||
is_internal: true,
|
||||
is_available: true,
|
||||
is_desktop: false,
|
||||
title: 'Моё расширение',
|
||||
description: 'Описание функциональности.',
|
||||
image: 'https://example.com/image.png',
|
||||
class: MyExtensionPluginModule,
|
||||
schema: MyExtensionSchema,
|
||||
tags: ['тег1', 'тег2'],
|
||||
readme: getReadmeContent('./myExtension'),
|
||||
instructions: getInstructionsContent('./myExtension'),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Дефолтные настройки
|
||||
Добавьте расширение в список дефолтных приложений в `extension-domain.service.ts`:
|
||||
|
||||
```typescript
|
||||
getDefaultApps(): Partial<ExtensionDomainEntity>[] {
|
||||
return [
|
||||
// ...
|
||||
{
|
||||
name: 'myExtension',
|
||||
enabled: true,
|
||||
config: {
|
||||
// Дефолтные значения конфигурации
|
||||
parameter1: 'value1',
|
||||
parameter2: 42,
|
||||
},
|
||||
},
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
description:
|
||||
globs: **/controller/src/extensions/**
|
||||
alwaysApply: false
|
||||
---
|
||||
# Архитектура расширений в MonoCoop
|
||||
|
||||
## Основные принципы
|
||||
1. Расширения построены на модулях NestJS с использованием шаблона "Порты и адаптеры"
|
||||
2. Каждое расширение наследуется от `BaseExtModule` и реализует интерфейс `OnModuleInit`
|
||||
3. Расширения могут взаимодействовать с блокчейном через соответствующие порты
|
||||
4. Конфигурации расширений хранятся в БД и описываются с помощью Zod-схем
|
||||
5. Расширения регистрируются в глобальном реестре `AppRegistry`
|
||||
|
||||
## Структура расширения
|
||||
Минимальная структура расширения включает:
|
||||
- `XXX-extension.module.ts` - основной модуль расширения
|
||||
- `package.json` - информация о пакете
|
||||
- `README.md` - документация
|
||||
- `INSTALL.md` - инструкции по установке
|
||||
- `CHANGELOG.md` - история изменений
|
||||
|
||||
## Создание нового расширения
|
||||
1. Создайте директорию для расширения в `components/controller/src/extensions/`
|
||||
2. Создайте основной класс расширения, наследующийся от `BaseExtModule`
|
||||
3. Определите Zod-схему для конфигурации
|
||||
4. Реализуйте метод `initialize()`
|
||||
5. Зарегистрируйте расширение в `extensions.registry.ts`
|
||||
6. Добавьте расширение в список дефолтных приложений в `extension-domain.service.ts`
|
||||
|
||||
## Пример структуры модуля расширения
|
||||
```typescript
|
||||
// XXX-extension.module.ts
|
||||
export class XXXPlugin extends BaseExtModule {
|
||||
constructor(...) {
|
||||
super();
|
||||
}
|
||||
|
||||
name = 'xxx';
|
||||
plugin!: ExtensionDomainEntity<IConfig>;
|
||||
public configSchemas = Schema;
|
||||
|
||||
async initialize() {
|
||||
// Инициализация расширения
|
||||
// Настройка cron-задач
|
||||
}
|
||||
|
||||
// Дополнительные методы расширения
|
||||
}
|
||||
|
||||
@Module({
|
||||
providers: [XXXPlugin],
|
||||
})
|
||||
export class XXXPluginModule {
|
||||
constructor(private readonly xxxPlugin: XXXPlugin) {}
|
||||
|
||||
async initialize() {
|
||||
await this.xxxPlugin.initialize();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Взаимодействие с блокчейном
|
||||
Для взаимодействия с блокчейном:
|
||||
1. Определите порт в доменном слое (например, `SovietBlockchainPort`)
|
||||
2. Инжектируйте порт в конструкторе расширения через DI
|
||||
3. Используйте методы порта для взаимодействия с блокчейном
|
||||
|
||||
```typescript
|
||||
@Inject(SOVIET_BLOCKCHAIN_PORT) private readonly sovietBlockchainPort: SovietBlockchainPort
|
||||
// ...
|
||||
const decisions = await this.sovietBlockchainPort.getDecisions(coopname);
|
||||
```
|
||||
|
||||
## Настройка планировщика задач
|
||||
Расширения могут использовать cron-задачи для периодического выполнения операций:
|
||||
|
||||
```typescript
|
||||
import cron from 'node-cron';
|
||||
|
||||
// Регистрация cron-задачи (каждые N минут)
|
||||
const cronExpression = `*/${this.plugin.config.checkInterval} * * * *`;
|
||||
cron.schedule(cronExpression, () => {
|
||||
this.logger.info('Запуск запланированной задачи');
|
||||
this.runTask();
|
||||
});
|
||||
```
|
||||
|
||||
## Работа с конфигурацией
|
||||
1. Определите Zod-схему для конфигурации
|
||||
2. Используйте `describeField` для добавления UI-метаданных к полям
|
||||
3. Получайте и обновляйте конфигурацию через репозиторий `extensionRepository`
|
||||
|
||||
```typescript
|
||||
export const Schema = z.object({
|
||||
checkInterval: z.number().describe(
|
||||
describeField({
|
||||
label: 'Интервал проверки (в минутах)',
|
||||
note: 'Минимум: 5 минут',
|
||||
rules: ['val >= 5'],
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
// Обновление конфигурации
|
||||
this.plugin.config.lastCheckDate = new Date().toISOString();
|
||||
await this.extensionRepository.update(this.plugin);
|
||||
```
|
||||
|
||||
## Логирование действий
|
||||
Расширения должны логировать свои действия:
|
||||
1. Используйте `WinstonLoggerService` для системного логирования
|
||||
2. Используйте `LogExtensionDomainRepository` для хранения логов в БД
|
||||
|
||||
```typescript
|
||||
// Системное логирование
|
||||
this.logger.info(`Выполнение операции для ${id}`);
|
||||
|
||||
// Сохранение лога в БД
|
||||
await this.logExtensionRepository.push(this.name, {
|
||||
type: 'operation',
|
||||
timestamp: new Date().toISOString(),
|
||||
data: { ... },
|
||||
});
|
||||
```
|
||||
|
||||
## Регистрация расширения
|
||||
После создания расширения, добавьте его в `extensions.registry.ts`:
|
||||
|
||||
```typescript
|
||||
export const AppRegistry: INamedExtension = {
|
||||
myExtension: {
|
||||
is_builtin: false,
|
||||
is_internal: true,
|
||||
is_available: true,
|
||||
is_desktop: false,
|
||||
title: 'Моё расширение',
|
||||
description: 'Описание функциональности.',
|
||||
image: 'https://example.com/image.png',
|
||||
class: MyExtensionPluginModule,
|
||||
schema: MyExtensionSchema,
|
||||
tags: ['тег1', 'тег2'],
|
||||
readme: getReadmeContent('./myExtension'),
|
||||
instructions: getInstructionsContent('./myExtension'),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Дефолтные настройки
|
||||
Добавьте расширение в список дефолтных приложений в `extension-domain.service.ts`:
|
||||
|
||||
```typescript
|
||||
getDefaultApps(): Partial<ExtensionDomainEntity>[] {
|
||||
return [
|
||||
// ...
|
||||
{
|
||||
name: 'myExtension',
|
||||
enabled: true,
|
||||
config: {
|
||||
// Дефолтные значения конфигурации
|
||||
parameter1: 'value1',
|
||||
parameter2: 42,
|
||||
},
|
||||
},
|
||||
// ...
|
||||
];
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,261 @@
|
||||
---
|
||||
description:
|
||||
globs: src/**/*.ts
|
||||
alwaysApply: false
|
||||
---
|
||||
# Фабрика Документов Кооперативов
|
||||
|
||||
## Общая Архитектура
|
||||
|
||||
Фабрика документов — это система генерации PDF документов для кооперативов, построенная на TypeScript с использованием MongoDB для хранения данных. Система состоит из трех основных частей:
|
||||
|
||||
1. **registry/** — JSON-шаблоны документов (статические данные)
|
||||
2. **factory/** — основная фабрика с логикой генерации
|
||||
3. **cooptypes/** — типы данных и интерфейсы
|
||||
|
||||
## Структура Registry
|
||||
|
||||
В корневой папке `registry/` находятся JSON файлы с номерными названиями, представляющие шаблоны документов:
|
||||
|
||||
### Основные документы:
|
||||
- `1.walletProgramAgreement.json` — соглашение о кошельке
|
||||
- `2.regulationElectronicSignature.json` — регламент электронной подписи
|
||||
- `3.privacyPolicy.json` — политика конфиденциальности
|
||||
- `4.userAgreement.json` — пользовательское соглашение
|
||||
- `50.CoopenomicsAgreement.json` — соглашение с партнерами
|
||||
- `100.participantApplication.json` — заявление участника
|
||||
- `101.selectBranchStatement.json` — заявление о выборе филиала
|
||||
|
||||
### Документы общих собраний (300-304):
|
||||
- `300.annualGeneralMeetingAgenda.json` — предложение повестки дня
|
||||
- `301.annualGeneralMeetingSovietDecision.json` — протокол заседания совета
|
||||
- `302.annualGeneralMeetingNotification.json` — уведомление о собрании
|
||||
- `303.annualGeneralMeetingVotingBallot.json` — бюллетень для голосования
|
||||
- `304.annualGeneralMeetingDecision.json` — протокол общего собрания
|
||||
|
||||
### Инвестиционные документы (1000+):
|
||||
- `1000.investAgreement.json` — инвестиционное соглашение
|
||||
- `1001.investByResultStatement.json` — заявление о зачете по результатам
|
||||
- `1002.investByResultAct.json` — акт зачета по результатам
|
||||
- `1005.investByMoneyStatement.json` — заявление о зачете денежных средств
|
||||
|
||||
### Структура JSON-шаблона:
|
||||
```json
|
||||
{
|
||||
"context": "<div>...HTML шаблон с переменными...</div>",
|
||||
"model": {...данные для примера...},
|
||||
"translation": {...переводы ключей...},
|
||||
"object_model": {...схема объектной модели...}
|
||||
}
|
||||
```
|
||||
|
||||
## Фабрика (factory/)
|
||||
|
||||
### Основные компоненты:
|
||||
|
||||
#### src/index.ts — Главный класс Generator
|
||||
```typescript
|
||||
export class Generator implements IGenerator {
|
||||
// Хранилище фабрик для каждого типа документа
|
||||
factories: { [K in Numbers]: DocFactory<IGenerate> }
|
||||
|
||||
// MongoDB коннектор
|
||||
public storage: MongoDBConnector
|
||||
|
||||
// Основной метод генерации
|
||||
async generate(data: IGenerate, options?: IGenerationOptions): Promise<IGeneratedDocument>
|
||||
}
|
||||
```
|
||||
|
||||
#### Архитектура Factory Pattern:
|
||||
- Базовый класс `DocFactory<T>` в `src/Factory/index.ts`
|
||||
- Каждый документ имеет свою фабрику в `src/Actions/`
|
||||
- Фабрики наследуются от `DocFactory` и реализуют метод `generateDocument()`
|
||||
|
||||
### Сервисы:
|
||||
|
||||
#### Services/Generator/ — PDF генерация
|
||||
- `PDFService` — конвертирует HTML в PDF через WeasyPrint
|
||||
- Использует шрифт Arial (base64)
|
||||
- Добавляет метаданные в PDF
|
||||
- Вычисляет SHA-256 хеш документа
|
||||
|
||||
#### Services/Templator/ — Шаблонизация
|
||||
- Основан на Nunjucks
|
||||
- Поддерживает кастомное расширение `{% trans %}` для переводов
|
||||
- Рендерит HTML из шаблона с подстановкой переменных
|
||||
|
||||
#### Services/Validator/ — Валидация
|
||||
- Использует AJV для JSON Schema валидации
|
||||
- Поддерживает кастомные форматы (телефон)
|
||||
- Локализация ошибок на русском языке
|
||||
|
||||
#### Services/Databazor/ — База данных
|
||||
- `MongoDBConnector` — работа с MongoDB
|
||||
- `DataService` — абстракция над данными
|
||||
- Коллекции: `deltas`, `actions`, `documents`, и другие
|
||||
|
||||
### Модели данных (src/Models/):
|
||||
|
||||
#### Основные типы пользователей:
|
||||
- `Individual` — физические лица (ФИО, паспорт, адрес)
|
||||
- `Organization` — организации (ИНН, ОГРН, представитель)
|
||||
- `Entrepreneur` — ИП (ФИО + ИНН/ОГРН)
|
||||
|
||||
#### Кооперативные данные:
|
||||
- `Cooperative` — данные кооператива
|
||||
- `PaymentMethod` — платежные методы
|
||||
- `Vars` — переменные кооператива
|
||||
- `Project` — проекты
|
||||
|
||||
### Система Action-ов:
|
||||
|
||||
Каждый документ имеет Action класс в `src/Actions/` с методом `generateDocument()`:
|
||||
|
||||
1. **Получение шаблона** — из локального Registry или MongoDB
|
||||
2. **Сбор данных** — пользователь, кооператив, переменные, специфичные данные
|
||||
3. **Валидация** — проверка по JSON схеме
|
||||
4. **Рендеринг** — HTML из шаблона + данные
|
||||
5. **PDF генерация** — HTML → PDF с метаданными
|
||||
6. **Сохранение** — в MongoDB (если не skip_save)
|
||||
|
||||
## Система типов (cooptypes/)
|
||||
|
||||
### cooperative/registry/ — Типы документов
|
||||
Каждый документ имеет папку с интерфейсами:
|
||||
- `Action` — входные данные для генерации
|
||||
- `Model` — модель данных для шаблона
|
||||
- `Template` — структура шаблона
|
||||
|
||||
### contracts/ — Блокчейн контракты
|
||||
- `registrator/` — регистрация кооперативов
|
||||
- `soviet/` — управление советом
|
||||
- `meet/` — общие собрания
|
||||
- `wallet/`, `capital/`, `fund/` — финансовые операции
|
||||
|
||||
## База данных MongoDB
|
||||
|
||||
### Основные коллекции:
|
||||
|
||||
#### deltas — Состояние блокчейна
|
||||
```javascript
|
||||
{
|
||||
block_num: number,
|
||||
present: boolean,
|
||||
code: string, // название контракта
|
||||
scope: string, // область действия
|
||||
table: string, // имя таблицы
|
||||
primary_key: string,
|
||||
value: {...} // данные записи
|
||||
}
|
||||
```
|
||||
|
||||
#### actions — Действия блокчейна
|
||||
```javascript
|
||||
{
|
||||
block_num: number,
|
||||
account: string,
|
||||
name: string, // имя действия
|
||||
receiver: string,
|
||||
data: {...} // данные действия
|
||||
}
|
||||
```
|
||||
|
||||
#### documents — Сгенерированные документы
|
||||
```javascript
|
||||
{
|
||||
hash: string, // SHA-256 хеш
|
||||
binary: Uint8Array, // PDF данные
|
||||
html: string, // HTML исходник
|
||||
meta: { // метаданные
|
||||
title: string,
|
||||
created_at: string,
|
||||
lang: string
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Таблицы данных:
|
||||
- `coops` — кооперативы
|
||||
- `meets` — собрания
|
||||
- `questions` — вопросы собраний
|
||||
- `decisions` — решения совета
|
||||
- `individuals` — физические лица
|
||||
- `organizations` — организации
|
||||
- `entrepreneurs` — ИП
|
||||
- `paymentMethods` — платежные методы
|
||||
- `vars` — переменные кооперативов
|
||||
|
||||
## Генерация документов
|
||||
|
||||
### Процесс генерации:
|
||||
1. **Вызов** `generator.generate(action, options)`
|
||||
2. **Поиск фабрики** по `registry_id`
|
||||
3. **Загрузка шаблона** (локально или из БД)
|
||||
4. **Сбор данных** из MongoDB по `coopname`, `username`, `block_num`
|
||||
5. **Создание модели** — объединение всех данных
|
||||
6. **Валидация** модели по JSON схеме
|
||||
7. **Рендеринг HTML** через Nunjucks
|
||||
8. **Генерация PDF** через WeasyPrint
|
||||
9. **Добавление метаданных** в PDF
|
||||
10. **Вычисление хеша** SHA-256
|
||||
11. **Сохранение** в MongoDB
|
||||
|
||||
### Пример использования:
|
||||
```typescript
|
||||
const generator = new Generator()
|
||||
await generator.connect(mongoUri)
|
||||
|
||||
const document = await generator.generate({
|
||||
registry_id: '300',
|
||||
coopname: 'voskhod',
|
||||
username: 'ant',
|
||||
block_num: 0,
|
||||
meet: {...},
|
||||
questions: [...]
|
||||
})
|
||||
```
|
||||
|
||||
## Особенности реализации
|
||||
|
||||
### Шаблонизация:
|
||||
- HTML шаблоны с CSS стилями
|
||||
- Переменные в формате `{{variable.field}}`
|
||||
- Условная логика `{% if condition %}`
|
||||
- Циклы `{% for item in array %}`
|
||||
- Переводы `{% trans 'KEY', var1, var2 %}`
|
||||
|
||||
### Подписи:
|
||||
- Цифровые подписи вместо физических
|
||||
- Текст "Подписано электронной подписью"
|
||||
- Убраны подчеркивания для подписей
|
||||
|
||||
### Типы собраний:
|
||||
- `regular` — очередное
|
||||
- `extraordinary` — внеочередное
|
||||
- Условная логика в шаблонах
|
||||
|
||||
### Филиалы:
|
||||
- `coop.is_branched` — проверка на наличие филиалов
|
||||
- "пайщиков" vs "уполномоченных" в зависимости от типа
|
||||
|
||||
### Форматирование дат:
|
||||
- Формат: "г. Москва, 15 декабря 2024 г."
|
||||
- Без кавычек вокруг дат
|
||||
- Запятая после города
|
||||
|
||||
## Тестирование
|
||||
|
||||
### test/utils/index.ts — Тестовые утилиты:
|
||||
- `preLoading()` — инициализация тестовых данных
|
||||
- Создание кооператива, пользователей, платежных методов
|
||||
- Настройка данных собраний и решений
|
||||
- Очистка временных файлов
|
||||
|
||||
### Тестовые данные:
|
||||
- Кооператив "ВОСХОД"
|
||||
- Пользователи: ant, individual, entrepreneur
|
||||
- Организации: voskhod, branch, exampleorg
|
||||
- Собрания с вопросами и решениями
|
||||
|
||||
Фабрика поддерживает полный цикл создания документов кооператива от заявлений до протоколов собраний с возможностью кастомизации под разные типы кооперативов и требования.
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
description:
|
||||
globs: components/sdk/**
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Руководство по работе с GraphQL Zeus в SDK
|
||||
|
||||
## Основной процесс
|
||||
|
||||
1. **Анализ DTO бэкенда**:
|
||||
- Изучите структуру DTO классов (`@ObjectType`) в бэкенде
|
||||
- Обратите внимание на имена типов в декораторах `@ObjectType('ИмяТипа')`
|
||||
- Отметьте поля, связи и вложенные объекты
|
||||
|
||||
2. **Создание селекторов**:
|
||||
- Для каждого DTO создайте соответствующий селектор с именем `raw<ИмяТипа>Selector`
|
||||
- Селектор - это объект, где ключи соответствуют полям DTO, а значения - `true`
|
||||
- Для вложенных объектов используйте вложенные селекторы: `field: nestedSelector`
|
||||
- Для списков используйте один селектор без массива: `items: itemSelector`
|
||||
|
||||
3. **Валидация селекторов**:
|
||||
- Для каждого селектора создайте проверку типа:
|
||||
```typescript
|
||||
const _validate: MakeAllFieldsRequired<ValueTypes['ТочноеИмяГрафКьЭлТипа']> = rawSelector
|
||||
```
|
||||
- Имя типа должно точно совпадать с именем в декораторе `@ObjectType`
|
||||
|
||||
4. **Экспорт селекторов**:
|
||||
- Создайте финальный селектор с помощью функции `Selector`:
|
||||
```typescript
|
||||
export const typeSelector = Selector('ТочноеИмяГрафКьЭлТипа')(rawTypeSelector)
|
||||
```
|
||||
- Экспортируйте сырой селектор для переиспользования
|
||||
- Экспортируйте тип модели: `export type modelType = ModelTypes['ТочноеИмяГрафКьЭлТипа']`
|
||||
|
||||
5. **Создание запросов/мутаций**:
|
||||
- Используйте селекторы в запросах и мутациях:
|
||||
```typescript
|
||||
export const query = Selector('Query')({
|
||||
queryName: [{ data: $('data', 'ТочноеИмяВходногоТипа!') }, exportedSelector]
|
||||
})
|
||||
```
|
||||
- Для параметров используйте оператор `$` с точным именем входного типа
|
||||
- Создайте интерфейс входных данных:
|
||||
```typescript
|
||||
export interface IInput {
|
||||
data: ModelTypes['ТочноеИмяВходногоТипа']
|
||||
}
|
||||
```
|
||||
|
||||
## Особенности работы
|
||||
|
||||
- **Документы**: всегда сохраняйте структуру `{ hash, signatures, rawDocument }`
|
||||
- **Сложные DTO**: разбивайте на атомарные селекторы и комбинируйте их
|
||||
- **Типы в Zeus**: часто отличаются от имен классов в бэкенде, всегда проверяйте в `schema.gql`
|
||||
- **Массивы**: Zeus автоматически обрабатывает массивы, не используйте `[selector]`
|
||||
|
||||
Это руководство поможет правильно структурировать работу с SDK и избежать типичных ошибок при работе с Zeus.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
globs: notifications/src/workflows/**/*.ts
|
||||
---
|
||||
# Правила валидации воркфлоу
|
||||
|
||||
## 🚫 ID воркфлоу
|
||||
- **Длина ID не должна превышать 32 символа**
|
||||
- Используйте описательные, но короткие идентификаторы малыми латинскими буквами и тире.
|
||||
|
||||
## 🚫 Условия в шаблонах
|
||||
- **Запрещено использовать JavaScript выражения в шаблонах Novu**
|
||||
- Нельзя использовать:
|
||||
- Тернарные операторы: `{{condition ? "text1" : "text2"}}`
|
||||
- Логические операторы: `{{field && "text"}}`
|
||||
- Любые другие JS конструкции
|
||||
|
||||
## ✅ Рекомендации
|
||||
- Добавляйте текстовые поля в payload для условной логики
|
||||
- Вычисляйте значения на стороне сервера перед отправкой уведомления
|
||||
- Используйте только простые переменные: `{{payload.fieldName}}`
|
||||
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
dist
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
name: Build Docker Images
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Debug info
|
||||
run: |
|
||||
echo "Текущая ветка:"
|
||||
git branch --show-current
|
||||
echo "Последние коммиты:"
|
||||
git log -n 3 --oneline
|
||||
echo "Проверяем файлы в директории components/desktop/src-ssr:"
|
||||
ls -la components/desktop/src-ssr/ || echo "Директория не найдена!"
|
||||
echo "Проверяем файлы в middlewares:"
|
||||
ls -la components/desktop/src-ssr/middlewares/ || echo "Директория middlewares не найдена!"
|
||||
|
||||
- name: Set docker tags
|
||||
run: |
|
||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
TAG_NAME=${GITHUB_REF#refs/tags/}
|
||||
echo "DOCKER_TAG=$TAG_NAME" >> $GITHUB_ENV
|
||||
|
||||
# Проверяем, является ли тег продакшн-тегом (не содержит alpha, beta, rc и т.д.)
|
||||
if [[ ! $TAG_NAME =~ -(alpha|beta|rc|test) ]]; then
|
||||
echo "IS_PRODUCTION_TAG=true" >> $GITHUB_ENV
|
||||
echo "Это продакшн тег, будем добавлять latest"
|
||||
else
|
||||
echo "IS_PRODUCTION_TAG=false" >> $GITHUB_ENV
|
||||
echo "Это не продакшн тег, latest не добавляем"
|
||||
fi
|
||||
else
|
||||
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
|
||||
echo "IS_PRODUCTION_TAG=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
# Сначала собираем базовый образ с runtime
|
||||
- name: Build base image
|
||||
run: |
|
||||
docker build --target runtime -t dicoop/mono-base:${{ env.DOCKER_TAG }} .
|
||||
docker push dicoop/mono-base:${{ env.DOCKER_TAG }}
|
||||
|
||||
# Если это продакшн тег, добавляем latest
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/mono-base:${{ env.DOCKER_TAG }} dicoop/mono-base:latest
|
||||
docker push dicoop/mono-base:latest
|
||||
fi
|
||||
|
||||
# Создаем сервисные образы на основе базового
|
||||
- name: Build desktop image
|
||||
run: |
|
||||
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.desktop
|
||||
echo "CMD [\"pnpm\", \"-F\", \"@coopenomics/desktop\", \"run\", \"start\"]" >> Dockerfile.desktop
|
||||
docker build -t dicoop/desktop:${{ env.DOCKER_TAG }} -f Dockerfile.desktop .
|
||||
docker push dicoop/desktop:${{ env.DOCKER_TAG }}
|
||||
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/desktop:${{ env.DOCKER_TAG }} dicoop/desktop:latest
|
||||
docker push dicoop/desktop:latest
|
||||
fi
|
||||
|
||||
- name: Build controller image
|
||||
run: |
|
||||
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.coopback
|
||||
echo "CMD [\"pnpm\", \"-F\", \"@coopenomics/controller\", \"run\", \"start\"]" >> Dockerfile.coopback
|
||||
docker build -t dicoop/coopback:${{ env.DOCKER_TAG }} -f Dockerfile.coopback .
|
||||
docker push dicoop/coopback:${{ env.DOCKER_TAG }}
|
||||
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/coopback:${{ env.DOCKER_TAG }} dicoop/coopback:latest
|
||||
docker push dicoop/coopback:latest
|
||||
fi
|
||||
|
||||
- name: Build parser image
|
||||
run: |
|
||||
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.cooparser
|
||||
echo "CMD [\"pnpm\", \"-F\", \"@coopenomics/parser\", \"run\", \"start\"]" >> Dockerfile.cooparser
|
||||
docker build -t dicoop/cooparser:${{ env.DOCKER_TAG }} -f Dockerfile.cooparser .
|
||||
docker push dicoop/cooparser:${{ env.DOCKER_TAG }}
|
||||
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/cooparser:${{ env.DOCKER_TAG }} dicoop/cooparser:latest
|
||||
docker push dicoop/cooparser:latest
|
||||
fi
|
||||
|
||||
- name: Build notificator image
|
||||
run: |
|
||||
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.notificator
|
||||
echo "CMD [\"pnpm\", \"-F\", \"coop-notificator\", \"run\", \"start\"]" >> Dockerfile.notificator
|
||||
docker build -t dicoop/notificator:${{ env.DOCKER_TAG }} -f Dockerfile.notificator .
|
||||
docker push dicoop/notificator:${{ env.DOCKER_TAG }}
|
||||
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/notificator:${{ env.DOCKER_TAG }} dicoop/notificator:latest
|
||||
docker push dicoop/notificator:latest
|
||||
fi
|
||||
|
||||
- name: Build notifications image
|
||||
run: |
|
||||
echo "FROM dicoop/mono-base:${{ env.DOCKER_TAG }}" > Dockerfile.notifications
|
||||
echo "CMD [\"pnpm\", \"-F\", \"@coopenomics/notifications\", \"run\", \"sync\"]" >> Dockerfile.notifications
|
||||
docker build -t dicoop/notifications:${{ env.DOCKER_TAG }} -f Dockerfile.notifications .
|
||||
docker push dicoop/notifications:${{ env.DOCKER_TAG }}
|
||||
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
docker tag dicoop/notifications:${{ env.DOCKER_TAG }} dicoop/notifications:latest
|
||||
docker push dicoop/notifications:latest
|
||||
fi
|
||||
|
||||
# Отправка хука для деплоя
|
||||
- name: Trigger deployment webhook
|
||||
if: ${{ success() }}
|
||||
run: |
|
||||
if [[ $GITHUB_REF == refs/tags/*alpha* ]]; then
|
||||
# Хук для тестнета (alpha теги)
|
||||
curl -X POST ${{ vars.TESTNET_WEBHOOK_URL }} \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '${{ env.DOCKER_TAG }}'
|
||||
elif [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
# Хук для продакшена (остальные теги)
|
||||
curl -X POST ${{ vars.PRODUCTION_WEBHOOK_URL }} \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '${{ env.DOCKER_TAG }}'
|
||||
fi
|
||||
|
||||
# Уведомление в Telegram об успехе
|
||||
- name: Telegram notify success
|
||||
if: ${{ success() }}
|
||||
run: |
|
||||
if [[ "${{ env.IS_PRODUCTION_TAG }}" == "true" ]]; then
|
||||
ADDITIONAL_INFO=" (с тегом latest)"
|
||||
else
|
||||
ADDITIONAL_INFO=""
|
||||
fi
|
||||
|
||||
curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
|
||||
-d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
|
||||
-d text="✅ [GITHUB MONO] Успешная сборка контейнеров: $GITHUB_REPOSITORY ($GITHUB_REF) [${{ env.DOCKER_TAG }}]$ADDITIONAL_INFO"
|
||||
|
||||
# Уведомление в Telegram об ошибке
|
||||
- name: Telegram notify failure
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
curl -s -X POST https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage \
|
||||
-d chat_id=${{ secrets.TELEGRAM_CHAT_ID }} \
|
||||
-d text="❌ [GITHUB MONO] Ошибка при сборке контейнеров: $GITHUB_REPOSITORY ($GITHUB_REF) [${{ env.DOCKER_TAG }}]"
|
||||
@@ -0,0 +1,18 @@
|
||||
# .github/workflows/trigger-coopenomics.yml
|
||||
name: Trigger Contracts Docs Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev, testnet, main, capital] # или когда нужно триггерить
|
||||
|
||||
jobs:
|
||||
trigger-coopenomics:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger Coopenomics deployment
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
with:
|
||||
token: ${{ secrets.COOPENOMICS_PAT }}
|
||||
repository: coopenomics/coopenomics # укажи правильный owner/repo
|
||||
event-type: deploy_from_mono
|
||||
client-payload: '{"repository": "${{ github.repository }}", "sha": "${{ github.sha }}", "ref": "${{ github.ref }}", "actor": "${{ github.actor }}"}'
|
||||
@@ -0,0 +1,107 @@
|
||||
name: Publish Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- testnet
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
build-and-publish-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Install pnpm
|
||||
run: npm install -g pnpm
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install mkdocs-material mkdocs-macros-plugin mkdocs-section-index pymdown-extensions
|
||||
working-directory: ./components/docs
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./components/docs
|
||||
|
||||
- name: Patch spectaql-config.yml for CI
|
||||
run: |
|
||||
sed -i.bak "0,/url:.*/s|url:.*|url: 'https://testnet.coopenomics.world/backend/v1/graphql'|" spectaql-config.yml
|
||||
working-directory: ./components/controller
|
||||
|
||||
- name: Show patched spectaql-config.yml
|
||||
run: cat spectaql-config.yml
|
||||
working-directory: ./components/controller
|
||||
|
||||
- name: Build cooptypes
|
||||
run: pnpm run build
|
||||
working-directory: ./components/cooptypes
|
||||
|
||||
- name: Generate controller docs
|
||||
run: pnpm run docs
|
||||
working-directory: ./components/controller
|
||||
|
||||
- name: Copy controller docs
|
||||
run: |
|
||||
mkdir -p ./components/docs/docs/graphql
|
||||
cp -r ./components/controller/docs/* ./components/docs/docs/graphql/
|
||||
|
||||
- name: Generate sdk docs
|
||||
run: pnpm run docs
|
||||
working-directory: ./components/sdk
|
||||
|
||||
- name: Copy sdk docs
|
||||
run: |
|
||||
mkdir -p ./components/docs/docs/sdk
|
||||
cp -r ./components/sdk/docs/* ./components/docs/docs/sdk/
|
||||
|
||||
- name: Generate cooptypes docs
|
||||
run: pnpm run docs
|
||||
working-directory: ./components/cooptypes
|
||||
|
||||
- name: Copy cooptypes docs
|
||||
run: |
|
||||
mkdir -p ./components/docs/docs/cooptypes
|
||||
cp -r ./components/cooptypes/docs/* ./components/docs/docs/cooptypes/
|
||||
|
||||
- name: Build docs (mkdocs)
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
mkdocs build
|
||||
working-directory: ./components/docs
|
||||
|
||||
- name: Remove specific large file before publishing
|
||||
run: |
|
||||
# Удаляем конкретный большой файл sdk/typedoc.json
|
||||
rm -f ./components/docs/site/sdk/typedoc.json
|
||||
# Проверяем, что файл удален
|
||||
if [ -f "./components/docs/site/sdk/typedoc.json" ]; then
|
||||
echo "ERROR: typedoc.json still exists!"
|
||||
exit 1
|
||||
else
|
||||
echo "SUCCESS: typedoc.json removed successfully"
|
||||
fi
|
||||
|
||||
- name: Publish to GitHub Pages
|
||||
run: npx gh-pages --nojekyll -d site --repo https://x-access-token:${GITHUB_TOKEN}@github.com/coopenomics/mono.git
|
||||
working-directory: ./components/docs
|
||||
env:
|
||||
GIT_AUTHOR_NAME: github-actions
|
||||
GIT_AUTHOR_EMAIL: github-actions@github.com
|
||||
GIT_COMMITTER_NAME: github-actions
|
||||
GIT_COMMITTER_EMAIL: github-actions@github.com
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,31 @@
|
||||
name: Publish Packages
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/v') &&
|
||||
!contains(github.ref, '-alpha')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
- run: npm install -g pnpm
|
||||
- run: pnpm install
|
||||
- run: pnpm lerna run build
|
||||
- run: pnpm lerna publish from-package --yes
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -1,2 +1,11 @@
|
||||
node_modules/
|
||||
lerna-debug.log
|
||||
components/controller/graph.png
|
||||
blockchain-data/
|
||||
scripts/changelog-prompt.md
|
||||
scripts/changelog-release.md
|
||||
scripts/release-info.md
|
||||
components/docs/docs/sdk
|
||||
dist/
|
||||
.env
|
||||
.DS_Store
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120,
|
||||
"plugins": [
|
||||
"prettier-plugin-sort-imports"
|
||||
]
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"vue.volar",
|
||||
"vue.vscode-typescript-vue-plugin"
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"editor.bracketPairColorization.enabled": true,
|
||||
"editor.guides.bracketPairs": true,
|
||||
"editor.tabCompletion": "onlySnippets",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"eslint.run": "onType",
|
||||
"eslint.validate": ["javascript", "typescript", "vue"],
|
||||
"i18n-ally.localesPaths": ["src/i18n"],
|
||||
"typescript.format.enable": true,
|
||||
"typescript.format.indentSwitchCase": false,
|
||||
"typescript.validate.enable": true,
|
||||
"notebook.defaultFormatter": "Vue.volar",
|
||||
|
||||
// Оптимизация для монорепозитория
|
||||
"typescript.preferences.useAliasesForRenames": false,
|
||||
"typescript.preferences.includePackageJsonAutoImports": "on",
|
||||
"typescript.suggest.autoImports": true,
|
||||
"typescript.suggest.paths": true,
|
||||
"typescript.updateImportsOnFileMove.enabled": "always",
|
||||
"typescript.workspaceSymbols.scope": "currentProject",
|
||||
|
||||
// Настройки для снижения нагрузки
|
||||
"files.watcherExclude": {
|
||||
"**/node_modules/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
"**/node_modules/*/**": true,
|
||||
"**/.cache/**": true,
|
||||
"**/.quasar/**": true,
|
||||
"**/*.tsbuildinfo": true
|
||||
},
|
||||
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/dist": true,
|
||||
"**/.cache": true,
|
||||
"**/.quasar": true,
|
||||
"**/*.tsbuildinfo": true
|
||||
},
|
||||
|
||||
"files.exclude": {
|
||||
"**/.cache": true,
|
||||
"**/*.tsbuildinfo": true,
|
||||
"**/node_modules/.cache": true
|
||||
},
|
||||
|
||||
// TypeScript server настройки для монорепозитория
|
||||
"typescript.tsserver.maxTsServerMemory": 8192,
|
||||
"typescript.tsserver.watchOptions": {
|
||||
"excludeDirectories": [
|
||||
"**/node_modules",
|
||||
"**/dist",
|
||||
"**/.cache",
|
||||
"**/.quasar",
|
||||
"**/build"
|
||||
]
|
||||
},
|
||||
|
||||
// Использовать локальный TypeScript из монорепо
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
|
||||
// КРИТИЧЕСКИ ВАЖНО: включить project references для монорепозитория
|
||||
"typescript.tsserver.useSyntaxServer": "auto",
|
||||
"typescript.tsserver.experimental.enableProjectDiagnostics": true,
|
||||
|
||||
// Оптимизация для больших монорепозиториев
|
||||
"typescript.disableAutomaticTypeAcquisition": true,
|
||||
"typescript.surveys.enabled": false,
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Cursor Cloud specific instructions
|
||||
|
||||
### Обзор
|
||||
|
||||
Монорепозиторий «Цифровой Кооператив» (monocoop) — платформа управления кооперативами на блокчейне EOSIO. pnpm v9 + Lerna. Node.js v20.
|
||||
|
||||
### Сервисы
|
||||
|
||||
| Компонент | Контейнер | Порт | Описание |
|
||||
|-----------|-----------|------|----------|
|
||||
| controller | coopback | 2998 | NestJS GraphQL API |
|
||||
| desktop | desktop | 2999 | Vue 3 + Quasar SPA |
|
||||
| parser | cooparser | 4000 | Индексация блокчейна через SHiP |
|
||||
| blockchain | node | 8888, 8070 | EOSIO node + State History Plugin |
|
||||
| MongoDB | mongo | 27017 | Основная БД (replica set) |
|
||||
| Redis | monoredis | 6379 | Кэш и стримы |
|
||||
| PG | (см. compose) | 5532→5432 | Реляционная БД |
|
||||
|
||||
### Полный перезапуск (одна команда)
|
||||
|
||||
```
|
||||
pnpm run reboot
|
||||
```
|
||||
|
||||
Делает: останавливает контейнеры → чистит blockchain data и volumes → поднимает инфру → ждёт готовности → `pnpm run boot` → запускает parser и controller.
|
||||
|
||||
### Первоначальная настройка Cloud-окружения
|
||||
|
||||
1. **`/etc/hosts`** — обязательно для boot (запускается на хосте, обращается к MongoDB по docker hostname):
|
||||
```
|
||||
echo "127.0.0.1 mongo" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 monoredis" | sudo tee -a /etc/hosts
|
||||
```
|
||||
|
||||
2. **WeasyPrint** — системная зависимость для генерации PDF:
|
||||
```
|
||||
sudo apt-get install -y python3 python3-venv libpango-1.0-0 libcairo2 libffi-dev libjpeg-dev libopenjp2-7-dev libharfbuzz-dev
|
||||
sudo python3 -m venv /opt/weasyprint-venv && sudo /opt/weasyprint-venv/bin/pip install WeasyPrint==67
|
||||
sudo ln -sf /opt/weasyprint-venv/bin/weasyprint /usr/local/bin/weasyprint
|
||||
```
|
||||
|
||||
3. **Контракты** (test-режим — позволяет boot с 1 членом совета):
|
||||
```
|
||||
cd components/contracts && sudo rm -rf build && bash build-all.sh test
|
||||
```
|
||||
|
||||
4. **Shared-библиотеки** (порядок важен):
|
||||
```
|
||||
pnpm --filter cooptypes run build
|
||||
pnpm --filter @coopenomics/factory run build
|
||||
pnpm --filter @coopenomics/sdk run build
|
||||
pnpm --filter @coopenomics/notifications run build
|
||||
```
|
||||
|
||||
5. **`.env` файлы** — скопировать из `.env-example`, адаптировать hostnames:
|
||||
- Controller/Parser (в Docker): хосты по именам контейнеров из docker-compose (порт БД 5432)
|
||||
- Boot (на хосте): `127.0.0.1`, PG порт `5532`, mongo через `/etc/hosts`
|
||||
- Desktop: `127.0.0.1`
|
||||
- **CHAIN_ID**: берётся из `curl http://localhost:8888/v1/chain/get_info` после старта ноды
|
||||
- Controller требует `VAPID_PUBLIC_KEY` и `VAPID_PRIVATE_KEY`
|
||||
|
||||
6. **Запуск**: `pnpm run reboot`, затем `docker compose up -d --force-recreate coopback cooparser` (если .env менялись)
|
||||
|
||||
### Запуск тестов
|
||||
|
||||
- **Factory** (`components/factory`): нужен только MongoDB. Запуск:
|
||||
```
|
||||
NODE_ENV=test SOURCE=local MONGO_URI=$MONGO_URI SKIP_BLOCK_FETCH=TRUE pnpm --filter @coopenomics/factory test
|
||||
```
|
||||
`MONGO_URI` по умолчанию: `mongodb://<host>:27017/cooperative-x`.
|
||||
- **Boot** (`components/boot`): требует полный EOSIO blockchain + MongoDB + PG. Запуск после `pnpm run reboot`:
|
||||
```
|
||||
pnpm --filter @coopenomics/boot test
|
||||
```
|
||||
- **Duplicate transaction** — в boot-тестах EOSIO отклоняет транзакции с одинаковым хешем (TAPOS block + action data). При повторном вызове `refreshSegment` для того же участника — добавить `await sleep(500)` перед ним. Паттерн уже используется (см. комментарий на строке ~720 capital.test.ts).
|
||||
|
||||
### Маркетплейс (cooplace extension)
|
||||
|
||||
**Архитектура:**
|
||||
- `cooplace` = бэкенд маркетплейса (карточки, категории, настройки, match, cycles)
|
||||
- `marketplace` = фронтенд расширение (витрина, заказы — использует API cooplace)
|
||||
- `market-admin` = фронтенд админки (настройки, модерация)
|
||||
|
||||
**Ключевой принцип:** Каждая встречная заявка сразу в блокчейн → блокировка средств. Карточки в БД, заявки в blockchain.
|
||||
|
||||
**Циклы:** min_units/deadline — порог для supply, не для match. При истечении → cancel через blockchain.
|
||||
|
||||
**Настройки** (MarketplaceSettings): lead_request_policy (offers_only/orders_only/both), publish_access_policy (all_members/whitelist/council_only), moderation, cycles, delivery types.
|
||||
|
||||
### Критические gotchas
|
||||
|
||||
- **SHiP порт 8070** — `state-history-endpoint = 0.0.0.0:8070` в config.ini. Парсер: `SHIP=ws://node:8070`.
|
||||
- **Парсер START_BLOCK**: при `START_BLOCK=1` на чистой БД стартует с HEAD и делает частичную инициализацию. Для полного replay: временно `START_BLOCK=2`, после первого запуска вернуть `1`.
|
||||
- **SSR desktop в dev** — расширения не рендерятся из-за Pinia SSR-сериализации компонентов. Dev — SPA (`quasar dev`), production build SSR работает.
|
||||
- **Тестовые учётные данные**: email `ivanov@example.com`, ключ — дефолтный EOSIO dev key (см. `components/boot/.env-example`), пользователь `ant` (председатель).
|
||||
- **Docker hostnames**: без `network_mode: host` — контейнеры обращаются друг к другу по именам контейнеров из docker-compose.
|
||||
- **Установка пакетов**: только через фильтр — `pnpm add <pkg> --filter <component>`.
|
||||
+494
@@ -0,0 +1,494 @@
|
||||
# v2025.12.28-8
|
||||
|
||||
В этой версии представлен прототип трекера результатов интеллектуальной деятельности, реализован мост в 1С, обновлен интерфейс и существенно повышена стабильность системы.
|
||||
|
||||
---
|
||||
|
||||
### ✨ Новые функции
|
||||
- [#332](https://github.com/coopenomics/mono/issues/332): Прототип конструктора требований дополнительных документов при регистрации
|
||||
- [#330](https://github.com/coopenomics/mono/issues/330): Прототип моста в 1С:Бухгалтерию для передачи документов и проводок
|
||||
- [#329](https://github.com/coopenomics/mono/issues/329): Интеграция и тестирование LMS TUTOR для образовательных задач
|
||||
- [#328](https://github.com/coopenomics/mono/issues/328): Размещение прототипов мульти-лендингов на цифровой-кооператив.рф и coopenomics.world
|
||||
- [#326](https://github.com/coopenomics/mono/issues/326): Минимальный интерфейс трекера результатов интеллектуальной деятельности
|
||||
- [#324](https://github.com/coopenomics/mono/issues/324): Смарт-контракт генерации и капитализации результатов интеллектуальной деятельности ("Благорост")
|
||||
- [#322](https://github.com/coopenomics/mono/issues/322): Поставка обновлений ПО с нулевым даунтаймом по blue-green стратегии
|
||||
- [#321](https://github.com/coopenomics/mono/issues/321): Внедрение системы проводок по фондам для контрактов
|
||||
- [#319](https://github.com/coopenomics/mono/issues/319): Палитра команд и быстрый доступ к страницам рабочих столов (cmk+k)
|
||||
- [#316](https://github.com/coopenomics/mono/issues/316): Переход рабочего стола на GraphQL SDK
|
||||
- [#314](https://github.com/coopenomics/mono/issues/314): Развёртывание GlitchTip для мониторинга ошибок
|
||||
- [#306](https://github.com/coopenomics/mono/issues/306): Модуль запросов и мутаций для контракта капитализации
|
||||
|
||||
### 🐛 Исправления ошибок
|
||||
- [#312](https://github.com/coopenomics/mono/issues/312): Исправление подписки на изменение статуса коммитов
|
||||
- [#309](https://github.com/coopenomics/mono/issues/309): Исправление отображения чужих билетов времени в трекере
|
||||
|
||||
### 🔧 Улучшения
|
||||
- [#331](https://github.com/coopenomics/mono/issues/331): Настройка системы мониторинга сбоев и ошибок на базе GlitchTIP, Loki, Prometheus
|
||||
- [#327](https://github.com/coopenomics/mono/issues/327): Пользовательская документация по интерфейсам цифрового кооператива
|
||||
- [#325](https://github.com/coopenomics/mono/issues/325): Документирование смарт-контракта программы "Благорост"
|
||||
- [#308](https://github.com/coopenomics/mono/issues/308): Улучшение отображения рабочих столов в магазине приложений
|
||||
- [#307](https://github.com/coopenomics/mono/issues/307): Объединение настроек контракта с нативными настройками приложения
|
||||
- [#305](https://github.com/coopenomics/mono/issues/305): Объединение полей title и description в проекте
|
||||
- [#304](https://github.com/coopenomics/mono/issues/304): Доменная модель контракта капитализации на бэкенде
|
||||
- [#303](https://github.com/coopenomics/mono/issues/303): Пересмотр архитектуры парсера и формирования локальной истории
|
||||
- [#302](https://github.com/coopenomics/mono/issues/302): Рефакторинг архитектуры, внедрение двухконтурной шины данных и обработки микрофорков
|
||||
- [#301](https://github.com/coopenomics/mono/issues/301): Доработка и отладка контракта "Капитализация РИД" v0.2
|
||||
- [#222](https://github.com/coopenomics/mono/issues/222): Внедрение метода Водянова для распределения пула премий по программе "Благорост"
|
||||
- [#212](https://github.com/coopenomics/mono/issues/212): Снижение точности валютных значений до двух знаков после запятой в документах
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.12.28
|
||||
|
||||
В этой версии представлен прототип трекера результатов интеллектуальной деятельности, реализован мост в 1С, обновлен интерфейс и существенно повышена стабильность системы.
|
||||
|
||||
---
|
||||
|
||||
### ✨ Новые функции
|
||||
- [#332](https://github.com/coopenomics/mono/issues/332): Прототип конструктора требований дополнительных документов при регистрации
|
||||
- [#330](https://github.com/coopenomics/mono/issues/330): Прототип моста в 1С:Бухгалтерию для передачи документов и проводок
|
||||
- [#329](https://github.com/coopenomics/mono/issues/329): Интеграция и тестирование LMS TUTOR для образовательных задач
|
||||
- [#328](https://github.com/coopenomics/mono/issues/328): Размещение прототипов мульти-лендингов на цифровой-кооператив.рф и coopenomics.world
|
||||
- [#326](https://github.com/coopenomics/mono/issues/326): Минимальный интерфейс трекера результатов интеллектуальной деятельности
|
||||
- [#324](https://github.com/coopenomics/mono/issues/324): Смарт-контракт генерации и капитализации результатов интеллектуальной деятельности ("Благорост")
|
||||
- [#322](https://github.com/coopenomics/mono/issues/322): Поставка обновлений ПО с нулевым даунтаймом по blue-green стратегии
|
||||
- [#321](https://github.com/coopenomics/mono/issues/321): Внедрение системы проводок по фондам для контрактов
|
||||
- [#319](https://github.com/coopenomics/mono/issues/319): Палитра команд и быстрый доступ к страницам рабочих столов (cmk+k)
|
||||
- [#316](https://github.com/coopenomics/mono/issues/316): Переход рабочего стола на GraphQL SDK
|
||||
- [#314](https://github.com/coopenomics/mono/issues/314): Развёртывание GlitchTip для мониторинга ошибок
|
||||
- [#306](https://github.com/coopenomics/mono/issues/306): Модуль запросов и мутаций для контракта капитализации
|
||||
|
||||
### 🐛 Исправления ошибок
|
||||
- [#312](https://github.com/coopenomics/mono/issues/312): Исправление подписки на изменение статуса коммитов
|
||||
- [#309](https://github.com/coopenomics/mono/issues/309): Исправление отображения чужих билетов времени в трекере
|
||||
|
||||
### 🔧 Улучшения
|
||||
- [#331](https://github.com/coopenomics/mono/issues/331): Настройка системы мониторинга сбоев и ошибок на базе GlitchTIP, Loki, Prometheus
|
||||
- [#327](https://github.com/coopenomics/mono/issues/327): Пользовательская документация по интерфейсам цифрового кооператива
|
||||
- [#325](https://github.com/coopenomics/mono/issues/325): Документирование смарт-контракта программы "Благорост"
|
||||
- [#308](https://github.com/coopenomics/mono/issues/308): Улучшение отображения рабочих столов в магазине приложений
|
||||
- [#307](https://github.com/coopenomics/mono/issues/307): Объединение настроек контракта с нативными настройками приложения
|
||||
- [#305](https://github.com/coopenomics/mono/issues/305): Объединение полей title и description в проекте
|
||||
- [#304](https://github.com/coopenomics/mono/issues/304): Доменная модель контракта капитализации на бэкенде
|
||||
- [#303](https://github.com/coopenomics/mono/issues/303): Пересмотр архитектуры парсера и формирования локальной истории
|
||||
- [#302](https://github.com/coopenomics/mono/issues/302): Рефакторинг архитектуры, внедрение двухконтурной шины данных и обработки микрофорков
|
||||
- [#301](https://github.com/coopenomics/mono/issues/301): Доработка и отладка контракта "Капитализация РИД" v0.2
|
||||
- [#222](https://github.com/coopenomics/mono/issues/222): Внедрение метода Водянова для распределения пула премий по программе "Благорост"
|
||||
- [#212](https://github.com/coopenomics/mono/issues/212): Снижение точности валютных значений до двух знаков после запятой в документах
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.12.28
|
||||
|
||||
В этом релизе реализован смарт-контракт генерации и капитализации результатов интеллектуальной деятельности, завершена интеграция с учётными системами, улучшены интерфейсы и документация. Подробнее о контракте: https://coopenomics.world/contracts/group__public__capital.html
|
||||
|
||||
✨ Новые функции
|
||||
- [#324](https://github.com/coopenomics/mono/issues/324): Реализован смарт-контракт генерации и капитализации результатов интеллектуальной деятельности ("Благорост")
|
||||
- [#301](https://github.com/coopenomics/mono/issues/301): Контракт "Капитализация РИД" v0.2
|
||||
- [#330](https://github.com/coopenomics/mono/issues/330): Прототип моста в 1С:Бухгалтерию: выгрузка документов и проводки по счетам
|
||||
- [#322](https://github.com/coopenomics/mono/issues/322): Обновления ПО с нулевым даунтаймом по blue-green стратегии
|
||||
- [#319](https://github.com/coopenomics/mono/issues/319): Палитра команд и быстрый доступ к страницам рабочих столов (cmk+k)
|
||||
- [#308](https://github.com/coopenomics/mono/issues/308): Магазин приложений с поддержкой подключения нескольких рабочих столов одним приложением
|
||||
- [#326](https://github.com/coopenomics/mono/issues/326): Минимальный интерфейс трекера результатов интеллектуальной деятельности по программе "Благорост"
|
||||
- [#332](https://github.com/coopenomics/mono/issues/332): Прототип конструктора требований дополнительных документов при регистрации
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#312](https://github.com/coopenomics/mono/issues/312): Исправлена ошибка со статусом коммитов — подписка теперь работает корректно
|
||||
- [#309](https://github.com/coopenomics/mono/issues/309): Исправлен баг с отображением чужих билетов времени в трекере
|
||||
|
||||
🔧 Улучшения
|
||||
- [#325](https://github.com/coopenomics/mono/issues/325): Документирован смарт-контракт программы "Благорост"
|
||||
- [#327](https://github.com/coopenomics/mono/issues/327): Подготовлена пользовательская документация цифрового кооператива по интерфейсам
|
||||
- [#329](https://github.com/coopenomics/mono/issues/329): Интеграция и тестирование образовательной платформы LMS TUTOR на Wordpress
|
||||
- [#328](https://github.com/coopenomics/mono/issues/328): Размещены прототипы мульти-лендингов на цифровой-кооператив.рф и coopenomics.world
|
||||
- [#321](https://github.com/coopenomics/mono/issues/321): Встроена система проводок по фондам и интеграция с контрактами
|
||||
- [#318](https://github.com/coopenomics/mono/issues/318): Настроены Loki & Grafana для выгрузки логов из контейнеров
|
||||
- [#316](https://github.com/coopenomics/mono/issues/316): Завершён переход рабочего стола на GraphQL SDK
|
||||
- [#314](https://github.com/coopenomics/mono/issues/314): Развёрнут GlitchTip как альтернатива Sentry
|
||||
- [#307](https://github.com/coopenomics/mono/issues/307): Интеграция настроек контракта с нативными настройками приложения, поддержка импорта после конфигурации
|
||||
- [#306](https://github.com/coopenomics/mono/issues/306): Собран модуль запросов и мутаций контракта капитализации
|
||||
- [#305](https://github.com/coopenomics/mono/issues/305): Упрощена структура проекта — title & description объединены в одно поле
|
||||
- [#304](https://github.com/coopenomics/mono/issues/304): Реализована доменная модель контракта капитализации на бэкенде с поддержкой микрофорков
|
||||
- [#303](https://github.com/coopenomics/mono/issues/303): Пересмотрена архитектура парсера и формирования локальной истории
|
||||
- [#302](https://github.com/coopenomics/mono/issues/302): Рефакторинг архитектуры, реализована двухконтурная шина данных и обработка микрофорков
|
||||
- [#212](https://github.com/coopenomics/mono/issues/212): Уменьшена точность валютных значений в документах с четырёх до двух знаков
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.9.1
|
||||
|
||||
В системе Кооперативной Экономики развернут смарт-контракт CAPITAL v0.2 для генерации и капитализации результатов интеллектуальной деятельности. Контракт описывает и обеспечивает:
|
||||
- бизнес-процесс производства результатов интеллектуальной деятельности в кооперативах создателями, авторами, инвесторами, координаторами, мастерами и собственниками имущества в кооперации на проектах;
|
||||
- приём результатов интеллектуальной деятельности в качестве паевых взносов в кооператив;
|
||||
- распределение потока членских взносов среди вкладчиков;
|
||||
- капитализацию результатов интеллектуальной деятельности новыми результатами по модели золотого сечения;
|
||||
- оценку вкладов авторов и создателей по методу Водянова;
|
||||
|
||||
В основе математической модели контракта лежит принцип распределения справедливой выгоды между вкладчиками согласно концепции "Общественно-полезного времени", разработанной в рамках теорий Кузнецова и академика Глушкова при работе над проектом общегосударственной автоматизированной системы учета и обработки информации (ОГАС).
|
||||
|
||||
Подробнее в документации: https://coopenomics.world/contracts/group__public__capital.html
|
||||
|
||||
✨ Новые функции
|
||||
- [#301](https://github.com/coopenomics/mono/issues/301): Реализация контракта "Капитализация" v0.2: регистрация вкладчиков, создание и управление проектами, поддержка инвестиций, ссуд, членских взносов, проведение голосований, расчет капитализации, интеграция с внешними контрактами, поддержка импорта данных.
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.7.1-1
|
||||
|
||||
В этом релизе реализованы механизмы возврата паевого взноса пайщика и инструменты управления этим процессом для членов совета. Также внесены визуальные доработки интерфейсов для улучшения восприятия информации.
|
||||
|
||||
✨ Новые функции
|
||||
- [#276](https://github.com/coopenomics/mono/issues/276): Реализовать путь возврата паевого взноса из кошелька пайщика
|
||||
- [#281](https://github.com/coopenomics/mono/issues/281): Генерация заявления на возврат паевого взноса
|
||||
- [#282](https://github.com/coopenomics/mono/issues/282): Генерация решения совета на возврат паевого взноса
|
||||
- [#278](https://github.com/coopenomics/mono/issues/278): Введение методов управления возвратами паевых взносов в контроллере
|
||||
- [#279](https://github.com/coopenomics/mono/issues/279): Отобразить исходящие платежи с кнопками управления в реестре платежей для совета
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#286](https://github.com/coopenomics/mono/issues/286): Поправить ошибки склонений времени
|
||||
- [#262](https://github.com/coopenomics/mono/issues/262): Баг: рабочий стол совета включается, однако, страница всегда открывается со стола пайщика
|
||||
- [#261](https://github.com/coopenomics/mono/issues/261): Баг: первая загрузка переадресует на главную страницу всегда - прямой переход на собрание становится недоступен.
|
||||
|
||||
🔧 Улучшения
|
||||
- [#285](https://github.com/coopenomics/mono/issues/285): Корректировка дизайна кошелька, профиля, повестки совета, реестра документов, реестра платежей
|
||||
- [#284](https://github.com/coopenomics/mono/issues/284): Разместить кошелек на главную вместо профиля
|
||||
- [#283](https://github.com/coopenomics/mono/issues/283): Ввести лоадер на переходе между рабочими столами
|
||||
- [#280](https://github.com/coopenomics/mono/issues/280): Мигрировать имеющиеся данные о входящих платежах в новую модель
|
||||
- [#277](https://github.com/coopenomics/mono/issues/277): Рефакторинг модуля платежей: переход на унифицированную модель входящего и исходящего платежа
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.6.14
|
||||
|
||||
Разработан модуль для проведения очередных общих собраний пайщиков. Исправлены баги, внесены улучшения пользовательского интерфейса.
|
||||
|
||||
✨ Новые функции
|
||||
- [#264](https://github.com/coopenomics/mono/issues/264): Разработан смарт-контракт общего собрания пайщиков (meet)
|
||||
- [#263](https://github.com/coopenomics/mono/issues/263): Реализован модуль оповещений на электронные почты по жизненному циклу общего собрания пайщиков
|
||||
- [#273](https://github.com/coopenomics/mono/issues/273): Встроены реальные шаблоны документов общего собрания
|
||||
- [#268](https://github.com/coopenomics/mono/issues/268): Добавлена страница результатов общего собрания
|
||||
- [#267](https://github.com/coopenomics/mono/issues/267): Добавлена страница просмотра и скачивания бюллетеней и уведомлений по собранию
|
||||
- [#270](https://github.com/coopenomics/mono/issues/270): Ссылка в оповещении ведет на страницу собрания с документом-уведомлением для подписи
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#262](https://github.com/coopenomics/mono/issues/262): Исправлено некорректное открытие рабочего стола совета
|
||||
- [#261](https://github.com/coopenomics/mono/issues/261): Исправлена ошибка с редиректом при первой загрузке и прямом переходе на собрание
|
||||
- [#259](https://github.com/coopenomics/mono/issues/259): Исправлены отступы в мобильной карточке пайщика
|
||||
- [#258](https://github.com/coopenomics/mono/issues/258): Убран hover-эффект на документе и пайщике в таблице
|
||||
|
||||
🔧 Улучшения
|
||||
- [#274](https://github.com/coopenomics/mono/issues/274): Настроена рассылка оповещений на почту при получении решения о проведении собрания
|
||||
- [#272](https://github.com/coopenomics/mono/issues/272): Подписанные уведомления сохраняются и извлекаются из реестра по Graph-QL
|
||||
- [#271](https://github.com/coopenomics/mono/issues/271): Ведется подсчет количества пайщиков в каждом кооперативе при добавлении и удалении
|
||||
- [#260](https://github.com/coopenomics/mono/issues/260): Введен счетчик количества пайщиков в кооперативе на контракте регистратора
|
||||
- [#256](https://github.com/coopenomics/mono/issues/256): Отображается статус членства каждого пайщика
|
||||
- [#255](https://github.com/coopenomics/mono/issues/255): В разделе Платежи отображается ФИО/Наименование плательщика
|
||||
- [#269](https://github.com/coopenomics/mono/issues/269): Реализована рассылка уведомлений перед началом собрания
|
||||
- [#265](https://github.com/coopenomics/mono/issues/265): Проведена отладка и тестирование процесса общего собрания пайщиков
|
||||
- [#266](https://github.com/coopenomics/mono/issues/266): Протестированы все процессы общего собрания
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.5.14
|
||||
|
||||
В этом релизе реализован новый стандарт передачи и хранения документов по блокчейну с поддержкой неограниченного количества подписей и их валидацией. Также внесены улучшения в интерфейс и исправлены ошибки.
|
||||
|
||||
✨ Новые функции
|
||||
- [#252](https://github.com/coopenomics/mono/issues/252): Внедрение обновленного стандарта хранения и передачи документов по блокчейну
|
||||
- [#251](https://github.com/coopenomics/mono/issues/251): Реализация версионированного мигратора данных для контроллера кооператива
|
||||
- [#244](https://github.com/coopenomics/mono/issues/244): Обновление стандарта сборки документов и переход на хэш-идентификаторы
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#249](https://github.com/coopenomics/mono/issues/249): Исправлена спутанная маршрутизация между рабочими столами кооперативов
|
||||
- [#253](https://github.com/coopenomics/mono/issues/253): Исправлена избыточная точность суммы оплаты в заявлении на вступление
|
||||
|
||||
🔧 Улучшения
|
||||
- [#259](https://github.com/coopenomics/mono/issues/259): Исправлены отступы в мобильной карточке пайщика на странице пайщиков
|
||||
- [#258](https://github.com/coopenomics/mono/issues/258): Удалён hover-эффект для документов и пайщиков в таблице
|
||||
- [#257](https://github.com/coopenomics/mono/issues/257): Добавлено сохранение светлой/тёмной темы в localStorage и восстановление при загрузке страницы
|
||||
- [#256](https://github.com/coopenomics/mono/issues/256): Отображение статуса членства каждого пайщика в разделе "Пайщики"
|
||||
- [#255](https://github.com/coopenomics/mono/issues/255): Отображение ФИО/Наименования плательщика в разделе "Платежи"
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# v2025.5.2
|
||||
|
||||
В этом релизе рабочие столы переведены на серверный рендеринг, что улучшает стабильность развертывания и упрощает автоматизацию поставки ПО. Данный релиз является подготовительным к переходу на новый стандарт цифровых документов на платформе.
|
||||
|
||||
✨ Новые функции
|
||||
- [#245](https://github.com/coopenomics/mono/issues/245): Перевод десктопа на серверный рендеринг с поддержкой динамических переменных окружения
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#247](https://github.com/coopenomics/mono/issues/247): Исправлен баг с повторной поставкой ПО при обрывах соединения между серверами
|
||||
|
||||
🔧 Улучшения
|
||||
- [#246](https://github.com/coopenomics/mono/issues/246): Перевод CI/CD на сборку и поставку предсобранных докер-контейнеров
|
||||
|
||||
#releases
|
||||
|
||||
---
|
||||
|
||||
# MONO v2025.4.29
|
||||
|
||||
В этом релизе реализована новая архитектура рабочих столов с установкой через маркетплейс. Добавлены стол пайщика и стол совета, переработаны разделы документов и подписей, улучшено разделение кошелька и профиля для повышения удобства пользователей.
|
||||
|
||||
✨ Новые функции
|
||||
- [#234](https://github.com/coopenomics/mono/issues/234): Маркетплейс рабочих столов с поддержкой разных ролей и микросервисной архитектурой
|
||||
- [#238](https://github.com/coopenomics/mono/issues/238): Контроллер общего собрания пайщиков с поддержкой документооборота и подписей
|
||||
- [#233](https://github.com/coopenomics/mono/issues/233): Минимальный смарт-контракт общих собраний пайщиков
|
||||
- [#232](https://github.com/coopenomics/mono/issues/232): Бэкенд полного обозревателя блоков
|
||||
|
||||
🐛 Исправления ошибок
|
||||
- [#231](https://github.com/coopenomics/mono/issues/231): Исправления ошибок регистрации, выхода из системы, отображения платежей и редактирования организации
|
||||
|
||||
🔧 Улучшения
|
||||
- [#243](https://github.com/coopenomics/mono/issues/243): Контроль прав доступа на получении документов пайщика
|
||||
- [#242](https://github.com/coopenomics/mono/issues/242): Бесконечный скролл на документах пайщика и кооператива
|
||||
- [#241](https://github.com/coopenomics/mono/issues/241): Раздел "Документы" для пайщика
|
||||
- [#240](https://github.com/coopenomics/mono/issues/240): Множественные подписи на одном документе
|
||||
- [#239](https://github.com/coopenomics/mono/issues/239): Последовательные методы подписи протокола общего собрания
|
||||
- [#237](https://github.com/coopenomics/mono/issues/237): Мобильная вёрстка на страницах стола совета
|
||||
- [#236](https://github.com/coopenomics/mono/issues/236): Пересобран лендинг для MONO
|
||||
- [#235](https://github.com/coopenomics/mono/issues/235): Настроен флоу гитхаб-релизов с описаниями
|
||||
- [#226](https://github.com/coopenomics/mono/issues/226): Встроено редактирование пайщиков
|
||||
- [#224](https://github.com/coopenomics/mono/issues/224): Добавлено ТЗ по контракту капитализации
|
||||
|
||||
---
|
||||
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.2.10](https://github.com/coopenomics/mono/compare/v2.2.9...v2.2.10) (2025-03-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add Zeus type ([7bcb6e3](https://github.com/coopenomics/mono/commit/7bcb6e30a77b0ab89c5293188b58f08f19c8761e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.9](https://github.com/coopenomics/mono/compare/v2.2.8...v2.2.9) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.8](https://github.com/coopenomics/monocoop/compare/v2.2.7...v2.2.8) (2025-02-10)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.7](https://github.com/coopenomics/monocoop/compare/v2.2.6...v2.2.7) (2025-02-07)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.6](https://github.com/coopenomics/monocoop/compare/v2.2.6-alpha.0...v2.2.6) (2025-01-27)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.5](https://github.com/coopenomics/monocoop/compare/v2.2.4...v2.2.5) (2025-01-18)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.4](https://github.com/coopenomics/monocoop/compare/v2.2.0...v2.2.4) (2025-01-17)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.3](https://github.com/coopenomics/monocoop/compare/v2.2.0...v2.2.3) (2025-01-16)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.1](https://github.com/coopenomics/monocoop/compare/v2.2.0...v2.2.1) (2025-01-14)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.9](https://github.com/coopenomics/monocoop/compare/v2.1.8...v2.1.9) (2025-01-14)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.8](https://github.com/coopenomics/monocoop/compare/v2.1.6...v2.1.8) (2024-12-24)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.7](https://github.com/coopenomics/monocoop/compare/v2.1.6...v2.1.7) (2024-12-03)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.6](https://github.com/coopenomics/monocoop/compare/v2.1.5...v2.1.6) (2024-10-30)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.5](https://github.com/coopenomics/monocoop/compare/v2.1.4...v2.1.5) (2024-10-28)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.4](https://github.com/coopenomics/monocoop/compare/v2.1.4-alpha.2...v2.1.4) (2024-10-28)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.3](https://github.com/coopenomics/monocoop/compare/v2.1.2-alpha.10...v2.1.3) (2024-10-26)
|
||||
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/coopenomics/monocoop/compare/v2.1.1...v2.1.2) (2024-10-19)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/coopenomics/monocoop/compare/v2.1.1...v2.1.2) (2024-10-19)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [2.1.0](https://github.com/coopenomics/monocoop/compare/v2.0.10-alpha.3...v2.1.0) (2024-10-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* запрос соглашений ([9a6a72f](https://github.com/coopenomics/monocoop/commit/9a6a72f605ba52eef2ed6f18ccee6fbed287ea00))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.9](https://github.com/coopenomics/monocoop/compare/v2.0.8...v2.0.9) (2024-10-10)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.8](https://github.com/coopenomics/monocoop/compare/v2.0.7...v2.0.8) (2024-10-09)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.7](https://github.com/coopenomics/monocoop/compare/v2.0.6...v2.0.7) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.6](https://github.com/coopenomics/monocoop/compare/v2.0.5...v2.0.6) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.5](https://github.com/coopenomics/monocoop/compare/v2.0.5-alpha.0...v2.0.5) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.2](https://github.com/coopenomics/monocoop/compare/v2.0.2-alpha.1...v2.0.2) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package monocoop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 2.1.0 (2024-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **importers:** исправлена ошибка в импорте модуля @wharfkit/contract ([bf89032](https://github.com/coopenomics/monocoop/commit/bf89032d8f66444804a2521f4eb96ffc75b0f605))
|
||||
* **terminal:** исправлен шрифт в README ([889447a](https://github.com/coopenomics/monocoop/commit/889447a93ceadb577613ddb5b1cb2ef1cc3d54b6))
|
||||
* **terminal:** исправлено описание проекта ([989b318](https://github.com/coopenomics/monocoop/commit/989b3180ded99a871e018cf26e6c493449223c01))
|
||||
* **terminal:** fix typo in README.md ([fdf9996](https://github.com/coopenomics/monocoop/commit/fdf999619d2d69e960b062fe6815f5b057c95f48))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* добавлен docker-compose.yaml ([6a46697](https://github.com/coopenomics/monocoop/commit/6a46697c9d6cc3cde14dbce8f70997c00f9850de))
|
||||
* **package:** добавлен скрипт gpt-commit для удобного коммита ([e0b5107](https://github.com/coopenomics/monocoop/commit/e0b510799bb0ac68890d572deb652beefd0651c4))
|
||||
* **terminal:** добавлена поддержка новых команд ([73e4ca2](https://github.com/coopenomics/monocoop/commit/73e4ca226acebcbea3ae59a62def99d86efb1353))
|
||||
@@ -0,0 +1,39 @@
|
||||
k# Conventional Commits
|
||||
|
||||
### Основные типы коммитов:
|
||||
|
||||
- **`feat`**: Добавление новой функциональности (feature).
|
||||
- Пример: `feat: добавлена возможность загрузки файлов`
|
||||
|
||||
- **`fix`**: Исправление бага.
|
||||
- Пример: `fix: исправлена ошибка отображения кнопки на мобильных устройствах`
|
||||
|
||||
- **`chore`**: Изменения, не влияющие на исходный код (например, обновление зависимостей или инструментария).
|
||||
- Пример: `chore: обновление зависимостей`
|
||||
|
||||
- **`docs`**: Изменения в документации.
|
||||
- Пример: `docs: обновлено руководство пользователя`
|
||||
|
||||
- **`style`**: Изменения стиля кода, не влияющие на его функциональность (форматирование, пробелы, и т.д.).
|
||||
- Пример: `style: исправлены отступы в коде`
|
||||
|
||||
- **`refactor`**: Изменения в коде, которые не исправляют баги и не добавляют новую функциональность.
|
||||
- Пример: `refactor: улучшена структура класса`
|
||||
|
||||
- **`perf`**: Изменения, направленные на улучшение производительности.
|
||||
- Пример: `perf: оптимизирована работа с массивами`
|
||||
|
||||
- **`test`**: Добавление или изменение тестов.
|
||||
- Пример: `test: добавлен тест для проверки функции отправки сообщений`
|
||||
|
||||
### Дополнительные типы коммитов:
|
||||
|
||||
- **`build`**: Изменения, связанные с процессом сборки или зависимостями.
|
||||
- Пример: `build: обновление конфигурации Webpack`
|
||||
|
||||
- **`ci`**: Изменения, касающиеся настроек непрерывной интеграции (например, Travis, Jenkins).
|
||||
- Пример: `ci: настройка Travis для автоматических сборок`
|
||||
|
||||
- **`revert`**: Откат на предыдущие изменения.
|
||||
- Пример: `revert: откат коммита e0b5107`
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
FROM node:20-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Сразу копируем все файлы
|
||||
COPY . .
|
||||
|
||||
# Устанавливаем инструменты
|
||||
RUN npm install -g pnpm lerna
|
||||
|
||||
# Установка зависимостей
|
||||
# Используем версию pnpm, совместимую с существующим lock-файлом
|
||||
RUN pnpm install
|
||||
|
||||
# Установка системных зависимостей для WeasyPrint и диагностических утилит (Debian/Ubuntu версии)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
gcc \
|
||||
g++ \
|
||||
python3-dev \
|
||||
libpango-1.0-0 \
|
||||
libpangoft2-1.0-0 \
|
||||
libpangocairo-1.0-0 \
|
||||
libcairo2 \
|
||||
libcairo2-dev \
|
||||
libffi-dev \
|
||||
shared-mime-info \
|
||||
zlib1g-dev \
|
||||
libjpeg-dev \
|
||||
libopenjp2-7-dev \
|
||||
procps \
|
||||
wget \
|
||||
&& python3 -m venv /venv \
|
||||
&& /venv/bin/pip install WeasyPrint==67 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Сборка всех компонентов
|
||||
RUN lerna run build
|
||||
|
||||
# Финальный образ
|
||||
FROM builder AS runtime
|
||||
|
||||
# Настройка переменных окружения
|
||||
ENV PATH="/venv/bin:$PATH"
|
||||
|
||||
# Проверка WeasyPrint
|
||||
RUN weasyprint --version
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
# MARKET-LOGIC.md — Бизнес-процессы маркетплейса
|
||||
|
||||
## 2А. БИЗНЕС-ПРОЦЕССЫ СМАРТ-КОНТРАКТОВ
|
||||
|
||||
### Основные бизнес-сценарии
|
||||
|
||||
**Сценарий 1: Поставка-приобретение имущества**
|
||||
- **Описание:** Обмен имущества между пайщиками через кооператив с блокировкой средств и документооборотом
|
||||
- **Участники:** Заказчик, Поставщик, Совет кооператива, Председатель КУ
|
||||
- **Бизнес-ценность:** Основной процесс кооперативного маркетплейса
|
||||
|
||||
**Сценарий 1А.** Прямая поставка (OFFER→ORDER) — поставщик публикует, заказчик откликается
|
||||
**Сценарий 1Б.** Обратная поставка (ORDER→OFFER) — заказчик публикует, поставщики откликаются
|
||||
**Сценарий 1В.** Из запасов кооператива (COOPSTOCK) — имущество уже на балансе
|
||||
|
||||
**Сценарий 2: Гарантийный возврат**
|
||||
- **Описание:** Возврат бракованного имущества в течение гарантийного срока
|
||||
- **Участники:** Заказчик, Поставщик, Председатель КУ, Совет
|
||||
- **Бизнес-ценность:** Защита интересов пайщика и качества имущества
|
||||
|
||||
**Сценарий 3: Уничтожение/перепредложение**
|
||||
- **Описание:** Утилизация просроченного или перепродажа по новой цене
|
||||
- **Участники:** Председатель КУ, Совет
|
||||
- **Бизнес-ценность:** Управление складскими запасами и минимизация потерь
|
||||
|
||||
**Сценарий 4: Транспортировка**
|
||||
- **Описание:** Перевозка имущества между КУ группами
|
||||
- **Участники:** Председатель КУ отправителя, Водитель, Председатель КУ получателя
|
||||
- **Бизнес-ценность:** Логистика распределённой кооперативной сети
|
||||
|
||||
---
|
||||
|
||||
### Процесс 1А: Прямая поставка (OFFER→ORDER)
|
||||
|
||||
**Предусловия:**
|
||||
- Поставщик создал карточку товара в БД (статус: `published`)
|
||||
- Заказчик нашёл карточку на витрине и решил заказать
|
||||
- У заказчика достаточно средств на цифровом кошельке
|
||||
|
||||
**Последовательность шагов:**
|
||||
|
||||
#### Шаг 1: orderoffer — Заказчик создаёт заявку
|
||||
|
||||
- **Предусловие:** Карточка товара в БД (published). При создании заявки происходит **match** — заявка публикуется в блокчейн
|
||||
- **Исполнитель:** Заказчик (через контроллер, авторизация от кооператива)
|
||||
- **Подписываемые документы:** Заявление на конвертацию из кошелька (convert_in)
|
||||
- **Проводки по кошелькам:**
|
||||
- Списать у заказчика `total_cost` из ЦПП «Цифровой Кошелёк»
|
||||
- Начислить заказчику `total_cost` в ЦПП «Маркетплейс»
|
||||
- Заблокировать у заказчика `total_cost` в ЦПП «Маркетплейс»
|
||||
- **Статус заявки:** `active`
|
||||
- **Параметры:** `delivery_type` (internal/external), `contribution_type` (share/member)
|
||||
|
||||
#### Шаг 2: accept — Поставщик принимает заявку
|
||||
|
||||
- **Исполнитель:** Поставщик
|
||||
- **Подписываемые документы:**
|
||||
- Заявление на конвертацию в кошелёк (convert_out)
|
||||
- Заявление на имущественный паевой взнос (contribution_statement)
|
||||
- **Проводки:** Нет
|
||||
- **Эффект:** Создаётся **одно** заявление в совет — `authcontrib` (авторизация взноса)
|
||||
- **Статус заявки:** `accepted`
|
||||
|
||||
#### Шаг 3: authcontrib — Совет авторизует взнос
|
||||
|
||||
- **Исполнитель:** Совет кооператива (автоматически через soviet контракт)
|
||||
- **Подписываемые документы:** Решение совета об авторизации взноса
|
||||
- **Проводки:** Нет
|
||||
- **Статус заявки:** `authorized` — поставщик может начинать поставку
|
||||
|
||||
#### Шаг 4: supply — Поставщик поставляет имущество на КУ
|
||||
|
||||
- **Исполнитель:** Поставщик
|
||||
- **Подписываемые документы:** Акт поставки (supply_act)
|
||||
- **Проводки:** Нет
|
||||
- **Статус заявки:** `supplied1`
|
||||
|
||||
#### Шаг 5: supplcnf — Председатель КУ подтверждает поставку
|
||||
|
||||
- **Исполнитель:** Председатель КУ поставщика
|
||||
- **Подписываемые документы:** Акт подтверждения поставки (supply_act_conf)
|
||||
- **Проводки по кошелькам:**
|
||||
- Начислить поставщику `base_cost` в ЦПП «Маркетплейс»
|
||||
- Заблокировать у поставщика `base_cost` в ЦПП «Маркетплейс»
|
||||
- **Проводки по ledger:**
|
||||
- Увеличить паевой фонд (счёт 80) на `total_cost`
|
||||
- **Статус заявки:** `supplied2`, имущество на складе КУ
|
||||
|
||||
#### Шаг 6: [Транспортировка] — При необходимости (см. Сценарий 4)
|
||||
|
||||
#### Шаг 7: delivered — Готово к выдаче
|
||||
|
||||
- **Исполнитель:** Председатель КУ получателя
|
||||
- **Подписываемые документы:** Нет
|
||||
- **Проводки:** Нет
|
||||
- **Статус заявки:** `delivered`
|
||||
|
||||
#### Шаг 8: reqreturn — Заказчик запрашивает возврат
|
||||
|
||||
- **Исполнитель:** Заказчик
|
||||
- **Подписываемые документы:** Заявление на возврат паевого взноса имуществом (return_statement) — с актуальными данными о весе/составе
|
||||
- **Проводки:** Нет
|
||||
- **Эффект:** Создаётся заявление в совет — `authreturn`
|
||||
- **Статус заявки:** `reqreturn`
|
||||
|
||||
#### Шаг 9: authreturn — Совет авторизует возврат
|
||||
|
||||
- **Исполнитель:** Совет кооператива
|
||||
- **Подписываемые документы:** Решение совета об авторизации возврата
|
||||
- **Проводки:** Нет
|
||||
- **Статус заявки:** `retauthorized`
|
||||
|
||||
#### Шаг 10: receive — Председатель КУ передаёт имущество
|
||||
|
||||
- **Исполнитель:** Председатель КУ
|
||||
- **Подписываемые документы:** Акт приёма-передачи (receive_act)
|
||||
- **Проводки:** Нет
|
||||
- **Статус заявки:** `received1`
|
||||
|
||||
#### Шаг 11: receivecnf — Заказчик подтверждает получение
|
||||
|
||||
- **Исполнитель:** Заказчик
|
||||
- **Подписываемые документы:** Акт подтверждения получения (receive_act_conf)
|
||||
- **Проводки по кошелькам:**
|
||||
- Списать заблокированный баланс заказчика `total_cost` из ЦПП «Маркетплейс»
|
||||
- **Проводки по ledger:**
|
||||
- Уменьшить паевой фонд (счёт 80) на `base_cost`
|
||||
- **Статус заявки:** `received2`
|
||||
- **Эффект:** Устанавливается `warranty_delay_until` (текущее время + гарантийный срок)
|
||||
|
||||
#### Шаг 12: complete — Завершение после гарантии
|
||||
|
||||
- **Исполнитель:** Система (после истечения `warranty_delay_until`)
|
||||
- **Проводки по кошелькам:**
|
||||
- Списать заблокированный баланс поставщика `base_cost` из ЦПП «Маркетплейс»
|
||||
- Начислить поставщику `base_cost` в ЦПП «Цифровой Кошелёк»
|
||||
- **Статус:** Заявка удаляется из блокчейна
|
||||
|
||||
**Постусловия:**
|
||||
- Заказчик получил имущество
|
||||
- Поставщик получил средства на кошелёк
|
||||
- Членские взносы распределены по фондам кооператива
|
||||
|
||||
---
|
||||
|
||||
### Процесс 1Б: Обратная поставка (ORDER→OFFER)
|
||||
|
||||
**Предусловия:**
|
||||
- Заказчик создал карточку заказа в БД (статус: `published`, тип: `order`)
|
||||
- Поставщик нашёл заказ и готов поставить
|
||||
|
||||
**Последовательность шагов:**
|
||||
|
||||
#### Шаг 1: createorder — Заказчик публикует заказ
|
||||
|
||||
- **Предусловие:** Карточка заказа в БД. При публикации — **match** в блокчейн
|
||||
- **Проводки:** Списание + блокировка `total_cost` заказчика (аналогично orderoffer)
|
||||
- **Статус:** `active`
|
||||
|
||||
#### Шаг 2: respondoffer — Поставщик откликается
|
||||
|
||||
- **Исполнитель:** Поставщик
|
||||
- **Подписываемые документы:** Заявление на взнос + конвертация
|
||||
- **Эффект:** Создаётся заявление в совет `authcontrib`
|
||||
- **Статус предложения:** `accepted`
|
||||
|
||||
#### Шаги 3-12: Аналогичны Процессу 1А (authcontrib → complete)
|
||||
|
||||
---
|
||||
|
||||
### Процесс 1В: Из запасов кооператива (COOPSTOCK)
|
||||
|
||||
**Предусловия:**
|
||||
- Имущество уже на балансе кооператива (на складе КУ)
|
||||
- Председатель КУ создаёт предложение coopstock
|
||||
|
||||
**Последовательность шагов:**
|
||||
|
||||
#### Шаг 1: coopstock — Создание предложения
|
||||
|
||||
- **Исполнитель:** Председатель КУ
|
||||
- **Проводки:** Нет (имущество уже на балансе)
|
||||
- **Статус:** `delivered` (сразу готово к выдаче)
|
||||
|
||||
#### Шаг 2: acceptstock — Заказчик принимает
|
||||
|
||||
- **Исполнитель:** Заказчик
|
||||
- **Подписываемые документы:** Конвертация + заявление на возврат
|
||||
- **Проводки:** Блокировка `total_cost` заказчика
|
||||
- **Эффект:** Сразу создаётся заявление в совет `authreturn`
|
||||
- **Статус:** `reqreturn`
|
||||
|
||||
#### Шаги 3-6: authreturn → receive → receivecnf → complete (аналогично 1А шаги 9-12)
|
||||
|
||||
**Особенности:**
|
||||
- Пропущены шаги accept, authcontrib, supply, supplcnf — не нужны
|
||||
- Нет проводок по паевому фонду при поставке (имущество уже на балансе)
|
||||
|
||||
---
|
||||
|
||||
### Процесс 2: Гарантийный возврат
|
||||
|
||||
**Предусловия:**
|
||||
- Заявка в статусе `received2` (имущество получено)
|
||||
- Не истёк `warranty_delay_until`
|
||||
- Заказчик обнаружил дефект
|
||||
|
||||
**Последовательность шагов:**
|
||||
|
||||
#### Шаг 1: dispute — Заказчик подаёт претензию
|
||||
|
||||
- **Подписываемые документы:** Претензия (wdispute) + фото/видео
|
||||
- **Эффект:** Деньги поставщика дополнительно блокируются
|
||||
|
||||
#### Шаг 2: Рассмотрение на КУ (вне контракта)
|
||||
|
||||
- **Исполнитель:** Председатель КУ
|
||||
- **Действия:** Осмотр, подтверждение/отклонение претензии
|
||||
|
||||
#### Шаг 3: wauthorize — Совет авторизует возврат
|
||||
|
||||
- **Подписываемые документы:** Решение о возврате (wreturn_auth) + решение о выдаче поставщику (wsupply_auth)
|
||||
|
||||
#### Шаг 4: wreturn — Возврат имущества в кооператив
|
||||
|
||||
- **Проводки:** Разблокировка средств заказчика, начисление на кошелёк
|
||||
|
||||
#### Шаг 5: woffer — Предложение имущества поставщику
|
||||
|
||||
#### Шаг 6: waccept — Поставщик принимает/отказывается
|
||||
|
||||
**Альтернативные потоки:**
|
||||
- **Отклонение претензии:** Заказчик забирает имущество обратно
|
||||
- **Поставщик не забрал:** Имущество перепредлагается (→ reoffer) или уничтожается (→ destroy)
|
||||
|
||||
---
|
||||
|
||||
### Процесс 3: Уничтожение имущества
|
||||
|
||||
**Предусловия:**
|
||||
- Заявка в статусе `delivered` или `supplied2`
|
||||
- Истёк `deadline_for_receipt` (заказчик не пришёл)
|
||||
|
||||
**Шаг 1: destroy — Уничтожение**
|
||||
|
||||
- **Исполнитель:** Председатель КУ (chairman)
|
||||
- **Подписываемые документы:** Акт уничтожения (destruction_act)
|
||||
- **Проводки:**
|
||||
- Возврат заказчику: `total_cost - cancellation_fee` → разблокировать и вернуть в кошелёк
|
||||
- Штраф `cancellation_fee` → в фонд членских взносов (spreadamount)
|
||||
- Поставщику: `base_cost` → разблокировать и вернуть в кошелёк
|
||||
- **Эффект:** Заявка удаляется из блокчейна
|
||||
|
||||
---
|
||||
|
||||
### Процесс 3Б: Перепредложение (reoffer)
|
||||
|
||||
**Предусловия:**
|
||||
- Аналогичны destroy, но срок годности НЕ истёк
|
||||
|
||||
**Шаг 1: reoffer — Перепредложение по новой цене**
|
||||
|
||||
- **Исполнитель:** Председатель КУ
|
||||
- **Проводки:** Аналогичны destroy (возврат средств)
|
||||
- **Эффект:** Старая заявка удаляется, создаётся новая типа `coopstock` со статусом `delivered`
|
||||
|
||||
---
|
||||
|
||||
### Процесс 4: Транспортировка (Shipment)
|
||||
|
||||
**Предусловия:**
|
||||
- Имущество на складе КУ (статус `supplied2` или `shiprecvd`)
|
||||
- Нужно доставить на другой КУ
|
||||
|
||||
**Последовательность шагов:**
|
||||
|
||||
#### Шаг 1: createship — Создание перевозки
|
||||
- **Исполнитель:** Представитель КУ отправителя
|
||||
- **Документ:** Акт передачи (shsendact)
|
||||
- **Статус перевозки:** `loading`
|
||||
|
||||
#### Шаг 2: signbydriver — Подпись водителя
|
||||
- **Исполнитель:** Водитель-пайщик
|
||||
- **Документ:** Акт приёма (shloadact)
|
||||
- **Эффект:** Товары снимаются со склада
|
||||
- **Статус:** `transit`
|
||||
|
||||
#### Шаг 3: arrived — Прибытие
|
||||
- **Исполнитель:** Водитель
|
||||
- **Документ:** Акт доставки (sharriveact)
|
||||
- **Статус:** `arrived`
|
||||
|
||||
#### Шаг 4: receiveshipm — Приём на складе
|
||||
- **Исполнитель:** Представитель КУ получателя
|
||||
- **Документ:** Акт приёма на складе (shrecvact)
|
||||
- **Эффект:** Товары ставятся на склад КУ назначения, перевозка удаляется
|
||||
- **Статус заявок:** `shiprecvd`
|
||||
|
||||
**Альтернативный поток:** retransport — промежуточная перегрузка на другой маршрут
|
||||
|
||||
---
|
||||
|
||||
### Связи между процессами
|
||||
|
||||
- **Процесс 1 → Процесс 4:** После `supplcnf` (шаг 5) товар может пойти на транспортировку перед `delivered`
|
||||
- **Процесс 1 → Процесс 2:** После `receivecnf` (шаг 11) возможен гарантийный возврат до истечения `warranty_delay_until`
|
||||
- **Процесс 2 → Процесс 3:** Если поставщик не забирает возвращённое имущество → destroy/reoffer
|
||||
- **Процесс 1 → Процесс 3:** Если заказчик не приходит за товаром → destroy/reoffer
|
||||
- **Процесс 3Б → Процесс 1В:** reoffer создаёт coopstock → новый цикл 1В
|
||||
|
||||
---
|
||||
|
||||
## Ключевой принцип: Match = Блокчейн
|
||||
|
||||
**Каждая встречная заявка сразу публикуется в блокчейн.**
|
||||
|
||||
Карточки хранятся в БД (draft → moderation → published).
|
||||
Но как только появляется встречная заявка — она немедленно уходит в блокчейн.
|
||||
Блокировка средств — дело смарт-контракта, не контроллера.
|
||||
|
||||
### Циклы поставки (min_units + cycle_deadline)
|
||||
|
||||
Циклы НЕ влияют на match. Они определяют:
|
||||
- **Когда поставщик начинает поставку** (supply) — при наборе min_units
|
||||
- **Когда цикл истекает** — cancel всех заявок через блокчейн → возврат средств
|
||||
|
||||
Поток:
|
||||
1. Карточка published, `min_units: 100`, `cycle_deadline: 7 февраля`
|
||||
2. Заказчик 1 → order на 30 ед. → **сразу в блокчейн** → средства заблокированы
|
||||
3. Заказчик 2 → order на 50 ед. → **сразу в блокчейн** → средства заблокированы
|
||||
4. Заказчик 3 → order на 25 ед. → **сразу в блокчейн** → средства заблокированы
|
||||
5. Итого 105 ≥ 100 → поставщику разрешено начать supply
|
||||
6. Если бы до 7 февраля набрали только 70 → cancel всех заявок → возврат через блокчейн → новый цикл
|
||||
|
||||
---
|
||||
|
||||
### Бизнес-правила и ограничения
|
||||
|
||||
**Правило 1: Блокировка средств при заказе**
|
||||
- **Описание:** Средства заказчика блокируются в момент создания заявки в блокчейне (match)
|
||||
- **Применение:** orderoffer, createorder, acceptstock
|
||||
- **Последствия нарушения:** Заявка не может быть создана без достаточных средств
|
||||
|
||||
**Правило 2: Одно заявление в совет при принятии**
|
||||
- **Описание:** При accept создаётся только authcontrib (на взнос). authreturn — перед получением
|
||||
- **Применение:** accept, reqreturn
|
||||
- **Обоснование:** Заявление на возврат содержит точные данные (вес), доступные после доставки
|
||||
|
||||
**Правило 3: Тип доставки определяет маршрут**
|
||||
- **Описание:** `delivery_type: internal` — между КУ через Shipment, `external` — через внешний сервис (СДЭК)
|
||||
- **Применение:** Определяется в карточке при создании
|
||||
|
||||
**Правило 4: Тип взноса определяет проводки**
|
||||
- **Описание:** `contribution_type: share` — паевой взнос (возврат имуществом), `member` — членский взнос (кооператив покупает)
|
||||
- **Применение:** Влияет на проводки при complete
|
||||
|
||||
**Правило 5: Гарантийный период**
|
||||
- **Описание:** `warranty_delay_until = received_at + warranty_period_secs`. До истечения — complete невозможен, dispute возможен
|
||||
- **Применение:** complete, dispute
|
||||
|
||||
**Правило 6: Карточки в БД, заявки в блокчейне**
|
||||
- **Описание:** Карточки хранятся в PostgreSQL (draft → moderation → published). Каждая встречная заявка сразу публикуется в блокчейн — средства блокируются смарт-контрактом
|
||||
- **Применение:** MatchService при каждой встречной заявке
|
||||
|
||||
**Правило 7: Циклы — порог для supply, не для match**
|
||||
- **Описание:** min_units определяет когда поставщику разрешено начать supply. cycle_deadline — когда cancel при ненаборе. Каждый заказ сразу в блокчейн независимо от цикла
|
||||
- **Применение:** CycleService (cron каждые 5 мин)
|
||||
@@ -1,4 +1,120 @@
|
||||
# MONOCOOP
|
||||
# Цифровой Кооператив
|
||||
|
||||
Моно-репозиторий компонент Цифрового Кооператива.
|
||||
|
||||
<!-- badges -->
|
||||

|
||||

|
||||

|
||||
|
||||
Платформа «Цифровой Кооператив» — комплексное программное обеспечение для управления кооперативными организациями на основе блокчейна EOSIO. Система обеспечивает полный цикл управления кооперативом: от регистрации пайщиков и электронного документооборота до проведения собраний и финансового учёта. Построена на принципах прозрачности, децентрализации и простой электронной подписи.
|
||||
|
||||
Проект является частью экосистемы [Кооперативная Экономика](https://coopenomics.world).
|
||||
|
||||
## Архитектура
|
||||
|
||||
| Компонент | Пакет | Описание |
|
||||
|-----------|-------|----------|
|
||||
| [boot](components/boot) | `@coopenomics/boot` | CLI для инициализации и управления блокчейн-инфраструктурой |
|
||||
| [cleos](components/cleos) | `@coopenomics/cleos` | Утилита командной строки для работы с блокчейн-кошельком |
|
||||
| [contracts](components/contracts) | `@coopenomics/contracts` | Смарт-контракты EOSIO на C++ |
|
||||
| [controller](components/controller) | `@coopenomics/controller` | GraphQL API сервер (NestJS) |
|
||||
| [cooptypes](components/cooptypes) | `cooptypes` | Общие типы и интерфейсы блокчейн-контрактов |
|
||||
| [desktop](components/desktop) | `@coopenomics/desktop` | Рабочий стол кооператива (Vue 3 + Quasar) |
|
||||
| [factory](components/factory) | `@coopenomics/factory` | Генератор юридических документов |
|
||||
| [migrator](components/migrator) | `migrator` | Утилита миграции данных |
|
||||
| [notifications](components/notifications) | `@coopenomics/notifications` | Библиотека уведомлений на основе Novu |
|
||||
| [parser](components/parser) | `@coopenomics/parser` | Индексатор блокчейна через State History Plugin |
|
||||
| [sdk](components/sdk) | `@coopenomics/sdk` | TypeScript SDK для GraphQL API |
|
||||
| [setup](components/setup) | `@coopenomics/setup` | Мастер первоначальной настройки |
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### Предварительные требования
|
||||
|
||||
- Node.js >= 20
|
||||
- pnpm 9
|
||||
- Docker и Docker Compose
|
||||
- [WeasyPrint](https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#installation) (для генерации PDF)
|
||||
|
||||
### Установка
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Конфигурация
|
||||
|
||||
```bash
|
||||
pnpm run setup
|
||||
```
|
||||
|
||||
Интерактивный мастер создаст необходимые `.env` файлы для всех компонентов.
|
||||
|
||||
### Запуск инфраструктуры
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
pnpm run reboot
|
||||
```
|
||||
|
||||
## Разработка
|
||||
|
||||
### Бэкенд (controller + parser)
|
||||
|
||||
```bash
|
||||
pnpm run dev:backend
|
||||
```
|
||||
|
||||
### Фронтенд (desktop)
|
||||
|
||||
```bash
|
||||
pnpm run dev:desktop
|
||||
```
|
||||
|
||||
### Библиотеки (factory + cooptypes)
|
||||
|
||||
```bash
|
||||
pnpm run dev:lib
|
||||
```
|
||||
|
||||
### Все сервисы одновременно
|
||||
|
||||
```bash
|
||||
pnpm run dev:all
|
||||
```
|
||||
|
||||
> **Примечание:** установка пакетов производится только через фильтр: `pnpm add <пакет> --filter <компонент>`
|
||||
|
||||
## Тестирование
|
||||
|
||||
```bash
|
||||
# Все тесты
|
||||
pnpm run test
|
||||
|
||||
# Юнит-тесты (cooptypes, parser, notifications)
|
||||
pnpm run test:unit
|
||||
|
||||
# Компонентные тесты (factory)
|
||||
pnpm run test:component
|
||||
|
||||
# Интеграционные тесты (boot + blockchain)
|
||||
pnpm run test:integration
|
||||
```
|
||||
|
||||
## Сборка
|
||||
|
||||
```bash
|
||||
# Библиотеки (cooptypes, factory)
|
||||
pnpm run build:lib
|
||||
|
||||
# Смарт-контракты
|
||||
pnpm run build:contracts:all
|
||||
|
||||
# Desktop (SSR)
|
||||
pnpm --filter @coopenomics/desktop run build
|
||||
```
|
||||
|
||||
## Лицензия
|
||||
|
||||
Продукт Потребительского Кооператива «ВОСХОД» распространяется по лицензии [BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.ru).
|
||||
|
||||
Разрешено делиться, копировать и распространять материал, адаптировать и создавать производные произведения при условии указания авторства и сохранения той же лицензии. Коммерческое использование запрещено.
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
# 📋 Резюме создания компонентов Notifications
|
||||
|
||||
## ✅ Что создано
|
||||
|
||||
### 1. 📚 Библиотека `@monocoop/notifications`
|
||||
**Расположение:** `components/notifications/`
|
||||
|
||||
**Функции:**
|
||||
- ✅ Типизированные интерфейсы для workflow с Zod
|
||||
- ✅ Builder паттерн для создания workflow
|
||||
- ✅ Базовые шаблоны для email, in-app, push, SMS
|
||||
- ✅ Автоматическая конвертация Zod схем в JSON Schema для Novu
|
||||
- ✅ Экспорт всех workflow для использования в других пакетах
|
||||
|
||||
**Структура:**
|
||||
```
|
||||
src/
|
||||
├── types/ # Базовые типы и интерфейсы
|
||||
├── base/ # Утилиты и настройки по умолчанию
|
||||
├── workflows/ # Папки с workflow
|
||||
│ └── welcome/ # Пример приветственного workflow
|
||||
└── index.ts # Главный экспорт
|
||||
```
|
||||
|
||||
### 2. 🚀 NestJS приложение `@monocoop/notificator2`
|
||||
**Расположение:** `components/notificator2/`
|
||||
|
||||
**Функции:**
|
||||
- ✅ Автоматический upsert всех workflow в Novu при запуске
|
||||
- ✅ RESTful API для триггера уведомлений
|
||||
- ✅ Типизированная валидация payload
|
||||
- ✅ Health check endpoints
|
||||
- ✅ Использует библиотеку notifications для типов
|
||||
|
||||
**API Endpoints:**
|
||||
- `GET /api/notifications/health` - Health check
|
||||
- `GET /api/notifications/workflows` - Список workflow
|
||||
- `POST /api/notifications/trigger` - Универсальный триггер
|
||||
- `POST /api/notifications/trigger/welcome` - Триггер welcome workflow
|
||||
- `POST /api/notifications/workflows/upsert-all` - Принудительный upsert
|
||||
|
||||
## 🔧 Как использовать
|
||||
|
||||
### 1. Настройка библиотеки notifications
|
||||
```bash
|
||||
cd components/notifications
|
||||
pnpm install # или npm install
|
||||
pnpm build # для компиляции TypeScript
|
||||
```
|
||||
|
||||
### 2. Настройка notificator2
|
||||
```bash
|
||||
cd components/notificator2
|
||||
pnpm install # или npm install
|
||||
|
||||
# Настройка окружения
|
||||
cp .env.example .env
|
||||
# Добавить NOVU_API_KEY в .env
|
||||
|
||||
# Запуск
|
||||
pnpm start:dev
|
||||
```
|
||||
|
||||
### 3. Добавление нового workflow
|
||||
|
||||
**В библиотеке notifications:**
|
||||
```typescript
|
||||
// components/notifications/src/workflows/order/order-workflow.ts
|
||||
export const orderWorkflow = WorkflowBuilder
|
||||
.create<OrderPayload>()
|
||||
.name('Order Confirmation')
|
||||
.workflowId('order-confirmation')
|
||||
.payloadSchema(orderPayloadSchema)
|
||||
.addSteps([...])
|
||||
.build();
|
||||
```
|
||||
|
||||
**Регистрация в index.ts:**
|
||||
```typescript
|
||||
// components/notifications/src/workflows/index.ts
|
||||
import { orderWorkflow } from './order';
|
||||
|
||||
export const allWorkflows = [
|
||||
welcomeWorkflow,
|
||||
orderWorkflow, // ← добавить новый workflow
|
||||
];
|
||||
```
|
||||
|
||||
### 4. Использование API
|
||||
|
||||
**Триггер welcome workflow:**
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/notifications/trigger/welcome \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"subscriberId": "user-123",
|
||||
"email": "user@example.com",
|
||||
"payload": {
|
||||
"userName": "Иван Иванов",
|
||||
"userEmail": "user@example.com",
|
||||
"age": 25
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## 🎯 Преимущества архитектуры
|
||||
|
||||
1. **Типобезопасность** - Zod схемы обеспечивают валидацию на уровне TypeScript и runtime
|
||||
2. **Разделение ответственности** - Библиотека содержит только типы, сервер - логику
|
||||
3. **Расширяемость** - Легко добавлять новые workflow
|
||||
4. **Автоматизация** - Workflow автоматически синхронизируются с Novu
|
||||
5. **Переиспользование** - Типы можно использовать в других частях системы
|
||||
|
||||
## 🔄 Workflow при запуске
|
||||
|
||||
1. **Запуск notificator2** →
|
||||
2. **Чтение всех workflow из библиотеки** →
|
||||
3. **Проверка существования в Novu** →
|
||||
4. **Создание/обновление workflow** →
|
||||
5. **Готов к приёму запросов на триггеры**
|
||||
|
||||
## 📁 Структура как в testFramework2.ts
|
||||
|
||||
Вся логика из `testFramework2.ts` была перенесена в structured архитектуру:
|
||||
- ✅ `buildWorkflowData` → `WorkflowBuilder`
|
||||
- ✅ `baseSteps` → `createEmailStep`, `createInAppStep`, etc.
|
||||
- ✅ `upsertWorkflow` → `NovuService.upsertWorkflow`
|
||||
- ✅ `triggerWorkflow` → `NovuService.triggerWorkflow`
|
||||
- ✅ Типизация payload → Zod схемы + TypeScript типы
|
||||
@@ -0,0 +1,181 @@
|
||||
# TASKS.md — Прогресс выполнения задач
|
||||
|
||||
## Завершённые задачи
|
||||
- ✅ 1. Dev-окружение
|
||||
- ✅ 2. Security updates
|
||||
- ✅ 3. Unified test pipeline (162/163)
|
||||
- ✅ 4. README + описания компонентов
|
||||
- ✅ 5. AGENTS.md для всех компонентов
|
||||
- ✅ 6. Setup — профессиональный установщик
|
||||
- ✅ 7. Поисковая система документов (OpenSearch)
|
||||
- ✅ 8. Процессы (Capital extension) — бэкенд + фронтенд
|
||||
- ✅ 9. Отчёты ФНС — 8 генераторов, фабрика, GraphQL API
|
||||
|
||||
---
|
||||
|
||||
## Активные задачи
|
||||
|
||||
### 10. Генерация отчётов ФНС (доработка) ✅
|
||||
- [x] Фабрика генераторов (ReportRegistryService)
|
||||
- [x] 8 генераторов (Бухбаланс, 6-НДФЛ, РСВ, ПСВ, ДУСН, 4-ФСС, Увед. взносы, УУСН)
|
||||
- [x] GraphQL API (getAvailableReports, generateReport)
|
||||
- [x] Генераторы переписаны по XSD — структура соответствует схемам ФНС
|
||||
- [x] 48 unit-тестов для всех генераторов
|
||||
- [x] Desktop UI (страница отчётов) — расширение reports
|
||||
- [x] Интеграция с реальными данными ledger через LedgerInteractor
|
||||
- [x] OrganizationDataInput DTO для передачи данных организации
|
||||
|
||||
### 11. CASL + гранулированные права доступа + шаринг страниц
|
||||
|
||||
#### 11.1 CASL — система прав доступа ✅
|
||||
- [x] @casl/ability установлен
|
||||
- [x] Action enum: manage, read, create, update, delete, execute, share
|
||||
- [x] Subject enum: 30+ subjects для всех ресурсов
|
||||
- [x] CaslAbilityFactory: role-based + granular permissions
|
||||
- [x] CaslGuard + @CheckAbility decorator (обратная совместимость с RolesGuard)
|
||||
- [x] role в user сохранено (chairman, member, user)
|
||||
- [x] Тесты: 22/22 unit-тестов (chairman, member, user, granular permissions)
|
||||
|
||||
#### 11.2 Шаринг страниц ✅
|
||||
- [x] ShareTokenEntity с JWT, guest/member targets
|
||||
- [x] ShareService: create/verify/revoke
|
||||
- [x] GraphQL: createShareLink, revokeShareLink, getMyShareLinks, getSharedWithMe
|
||||
- [x] Два уровня: гости (linkName) и пайщики (targetUsername)
|
||||
- [x] Granular allowedActions per share link
|
||||
- [x] Кнопка "Поделиться" в Desktop Header (ShareHeaderAction)
|
||||
- [x] Диалог управления правами (ShareDialog)
|
||||
- [x] Страница "Доступные мне" на рабочем столе Пайщика (SharedWithMePage)
|
||||
|
||||
#### 11.3 Интеграция в desktop ✅
|
||||
- [x] useShareButtonProcess: авто-регистрация на всех страницах
|
||||
- [x] ShareButton + ShareDialog компоненты
|
||||
- [x] Интеграция в init-app process
|
||||
- [x] Валидация share tokens в route guard (frontend) — bypass ролей при наличии share_token
|
||||
|
||||
### 12. API ключи кооператива ✅
|
||||
- [x] ApiKeyEntity: хеш ключа (sha256), префикс, операции, срок
|
||||
- [x] ApiKeyService: create, validate, list, revoke
|
||||
- [x] ApiKeyGuard: аутентификация через x-api-key header
|
||||
- [x] GraphQL: createApiKey, getApiKeys, revokeApiKey (chairman only)
|
||||
- [x] Безопасность: ключ показывается ТОЛЬКО при создании, хранится хеш
|
||||
- [x] Desktop: ApiKeysPage в chairman extension
|
||||
- [x] UI: таблица ключей, создание, отзыв, копирование
|
||||
|
||||
### 15. Стол заказов (Marketplace) — полная реализация
|
||||
|
||||
#### 15.1 Смарт-контракт marketplace — реорганизация
|
||||
- [x] Исправить процесс: одно заявление в совет при accept (authcontrib), не два
|
||||
- [x] Новый action requestreturn — заявление на возврат подаётся перед получением
|
||||
- [x] authcontrib сразу ставит authorized
|
||||
- [x] authreturn работает для статуса reqreturn → retauthorized
|
||||
- [x] receive требует retauthorized (после авторизации возврата)
|
||||
- [x] orderoffer убран product_return_statement (подаётся позже)
|
||||
- [x] Путь coopstock — имущество уже в кооперативе
|
||||
- [x] acceptstock — заказчик принимает coopstock (сразу в requestreturn)
|
||||
- [x] Document::remove_document утилита
|
||||
- [x] Уничтожение просроченного (destroy) — возврат средств, штраф, выплата поставщику
|
||||
- [x] Перепредложение (reoffer) — закрытие старой заявки, создание coopstock с новой ценой
|
||||
- [x] Система перевозок — уже реализована (shipment/)
|
||||
- [x] Гарантийный возврат — уже реализован (dispute_on_offer/)
|
||||
- [x] Сборка marketplace.wasm + marketplace.abi (test mode) — OK
|
||||
- [x] ORDER→OFFER: createorder + respondoffer (заказчик публикует → поставщики откликаются)
|
||||
- [x] delivery_type: internal (между КУ) / external (СДЭК и т.д.) в request struct
|
||||
- [x] contribution_type: share (паевой) / member (членский) в request struct
|
||||
- [x] Убраны ВСЕ any из controller marketplace (service, interactor)
|
||||
- [x] Импортировано 87 файлов marketplace extension из ветки marketplace
|
||||
- [x] Domain: 11 entities, 7 repositories, 5 services (БД-first архитектура)
|
||||
- [x] Application: 30+ DTOs, 4 resolvers (категории, атрибуты, заявки)
|
||||
- [x] Infrastructure: TypeORM entities, mappers, adapters
|
||||
- [x] Архитектурный принцип: заявки в БД (draft→published), блокчейн при match
|
||||
- [x] Накопительный характер заявок — CycleService (canStartSupply, checkExpiredCycles, cron)
|
||||
|
||||
#### 15.2 Генерация типов
|
||||
- [x] Интерфейсы cooptypes: RequestReturn, Coopstock, AcceptStock, Destroy, Reoffer
|
||||
- [x] ABI marketplace сохранён (31 action) для генерации типов
|
||||
|
||||
#### 15.3 Controller (бэкенд)
|
||||
- [x] CooplaceBlockchainPort: 5 новых портов
|
||||
- [x] CooplaceBlockchainAdapter: 5 реализаций (reqReturn, coopstock, acceptStock, destroy, reoffer)
|
||||
- [x] DTOs: ReqReturnInput, CoopstockInput, AcceptStockInput, DestroyRequestInput, ReofferRequestInput
|
||||
- [x] GraphQL resolvers: 5 новых мутаций с авторизацией
|
||||
- [x] Service + Interactor: проброс до blockchain
|
||||
- [x] ShipmentResolver: createShipment, signByDriver, arrived, receiveShipment
|
||||
- [x] Интеграция с документами — через SignedDigitalDocumentInputDTO
|
||||
- [x] MarketplaceEventService: 13 event handlers для синхронизации с блокчейном
|
||||
|
||||
#### 15.4 Desktop (фронтенд)
|
||||
- [x] Маршруты: витрина, предложение, создание, мои заказы, модерация
|
||||
- [x] install.ts расширения market обновлён с agreementsBase и roles
|
||||
- [x] ReqReturnStep — шаг подачи заявления на возврат (step 7)
|
||||
- [x] RetAuthorizedStep — шаг авторизации возврата советом (step 8)
|
||||
- [x] Base.vue: новые статусы (reqreturn, retauthorized), badge coopstock
|
||||
- [x] Панель председателя КУ: WarehousePage (склад, выдача, destroy/reoffer)
|
||||
- [x] ShipmentsPage: таблица перевозок, timeline 4 этапов, создание
|
||||
- [x] DisputePage: подача претензии, список, timeline спора, решение совета
|
||||
|
||||
#### 15.X Разделение cooplace на бэкенд и фронтенд расширения
|
||||
- [x] CooplaceExtensionModule — бэкенд (карточки, категории, blockchain actions)
|
||||
- [x] ProductCardResolver: CRUD карточек (draft→published→archived)
|
||||
- [x] CategoryResolver: CRUD дерева категорий (chairman)
|
||||
- [x] Domain entities: ProductCard (тип, статус, delivery_type, contribution_type), Category, SupplyOrder
|
||||
- [x] Repositories: interfaces для карточек, категорий, заявок
|
||||
- [x] GraphQL: 3 queries + 6 mutations для карточек/категорий
|
||||
- [x] marketplace (desktop) — чистый фронтенд, использует API cooplace
|
||||
- [x] market-admin (desktop) — уже существует (extensions/market-admin)
|
||||
- [x] Controller стартует, 22+9 = 31 GraphQL endpoints
|
||||
|
||||
#### 15.Y Бэкенд карточек с циклами
|
||||
- [x] TypeORM entities: ProductCard (циклы), Category, SupplyOrder
|
||||
- [x] Repository adapters: CRUD + фильтры для всех entities
|
||||
- [x] ProductCardService: модерация (draft→moderation→published), циклы (min_units, deadline)
|
||||
- [x] addOrderToCard: инкремент cycle_collected_units, проверка min_units
|
||||
- [x] checkCycleDeadline: истечение → возврат → новый цикл (cycle_number++)
|
||||
- [x] ProductCardResolver: 9 queries/mutations с реальной БД логикой
|
||||
- [x] CooplaceExtensionModule: полная DI с TypeORM
|
||||
- [x] Исправлен белый экран desktop (vite-plugin-checker + share-button crash)
|
||||
|
||||
#### 15.Z Админка маркетплейса (настройки)
|
||||
- [x] MarketplaceSettingsEntity: lead_request_policy, publish_access_policy, whitelist, moderation, cycles, delivery, prices
|
||||
- [x] MarketplaceSettingsTypeormEntity + TypeORM repository (upsert)
|
||||
- [x] MarketplaceSettingsResolver: get/update settings, add/remove whitelist
|
||||
- [x] Перенесены ВСЕ DTOs/entities/repositories/services из extensions/marketplace → extensions/cooplace
|
||||
- [x] Desktop SettingsPage: radio groups, toggles, whitelist chips, price inputs
|
||||
- [x] market-admin: маршрут настроек как дефолтный + модерация + все заказы
|
||||
|
||||
#### 15.W Правильная логика match + cycles
|
||||
- [x] MatchService: каждая встречная заявка → сразу в блокчейн (блокировка средств смарт-контрактом)
|
||||
- [x] CycleService: min_units/deadline → порог для supply, НЕ для match
|
||||
- [x] CycleService: cron каждые 5 мин — проверка истёкших циклов → cancel через блокчейн
|
||||
- [x] MARKET-LOGIC.md обновлён с правильным принципом
|
||||
- [x] AGENTS.md обновлён с описанием маркетплейса
|
||||
|
||||
#### 15.5 Тесты
|
||||
- [x] Unit-тесты controller: 8 тестов marketplace actions + statuses (90/90 total)
|
||||
- [x] cooptypes собран с новыми actions
|
||||
- [x] Boot интеграционный тест: marketplace.test.ts (orderoffer + coopstock flows)
|
||||
- [x] Boot тест marketplace.test.ts: orderoffer + coopstock flows
|
||||
|
||||
### 16. Документация (docs)
|
||||
- [x] Раздел Cooplace: обзор архитектуры, жизненный цикл карточки, match, циклы
|
||||
- [x] Раздел Cooplace/dev: GraphQL API reference (настройки, карточки, поставки, перевозки, диспуты)
|
||||
- [x] Раздел Marketplace: пользовательская документация (витрина, заказ, администрирование)
|
||||
- [x] TypeDoc JSON сгенерирован из SDK (137MB)
|
||||
- [x] mkdocs.yml nav обновлён с «Стол заказов»
|
||||
- [x] .gitignore для typedoc.json (генерируется при сборке)
|
||||
|
||||
### 13. GraphQL Subscriptions ✅
|
||||
- [x] PubSubModule: глобальный PubSub provider
|
||||
- [x] WebSocket support в GraphQL module (graphql-ws)
|
||||
- [x] 5 Capital subscriptions: issueUpdated/Created, commitCreated/Updated, dataChanged
|
||||
- [x] systemStatusChanged — подписка на статус системы (install/init/update)
|
||||
- [x] sovietDataChanged — подписка на события собраний/решений
|
||||
- [x] Events publishing: GenerationService, ProjectManagementService, VotingService, SystemService, MeetEventService
|
||||
- [x] SDK: Subscriptions namespace (Capital)
|
||||
- [x] Auth через connectionParams.token
|
||||
- [x] `useGraphqlSubscription` composable на фронтенде
|
||||
- [x] **7 страниц Capital** переведены с polling на подписки
|
||||
- [x] **System store** — WebSocket мониторинг вместо setTimeout
|
||||
- [x] **init-wallet** — удалён рекурсивный setTimeout(run, 10_000)
|
||||
- [x] **MeetDetails, ListOfAgenda, WaitingRegistration** — подписки вместо setInterval
|
||||
- [x] **Provider, ConnectionAgreement** — удалён setInterval polling
|
||||
- [x] 0 использований setInterval в прикладном коде (только UI-анимация энергии)
|
||||
@@ -0,0 +1,64 @@
|
||||
# Test Plan — pnpm run test
|
||||
|
||||
## Архитектура
|
||||
```
|
||||
pnpm run test
|
||||
├── cooptypes — vitest run (smoke tests exports) ✅ 4/4
|
||||
├── parser — vitest run (config smoke tests) ✅ 3/3
|
||||
├── factory — vitest run (document generation tests) 🔧 17/85 → need mocks
|
||||
├── sdk — vitest run (API integration tests) 🔧 TODO
|
||||
├── notifications — vitest run (workflow tests) 🔧 TODO
|
||||
├── controller — jest / vitest (NestJS unit tests) 🔧 TODO
|
||||
└── boot — vitest run (blockchain integration) 🔧 53/60
|
||||
```
|
||||
|
||||
## Статус по компонентам
|
||||
|
||||
### cooptypes ✅ DONE
|
||||
- 4 smoke-теста экспортов
|
||||
- Не требует инфраструктуры
|
||||
|
||||
### parser ✅ DONE
|
||||
- 3 smoke-теста конфигурации
|
||||
- Не требует инфраструктуры
|
||||
|
||||
### factory 🔧 IN PROGRESS
|
||||
- **Проблема**: тесты обращаются к parser API (`SIMPLE_EXPLORER_API`) для get-tables/get-actions
|
||||
- **Решение**: Уже есть мок-система в `src/Utils/testMocks.ts` + `matchMock.ts`
|
||||
- **Нужно**: Добавить моки для ВСЕХ документов:
|
||||
- [ ] cooperative data mock (registrator.coops table)
|
||||
- [ ] soviet boards mock — уже есть через test setup в MongoDB
|
||||
- [ ] draft templates mock (draft.drafts + draft.translations tables)
|
||||
- [ ] decision data mocks (soviet.decisions table)
|
||||
- [ ] Мок для ReturnByMoney документов
|
||||
- [ ] Все документы 1000+ серии
|
||||
- **Текущие рабочие моки**: meet tables, votefor actions, returnByMoneyDecision actions
|
||||
- **После мокирования**: все 85 тестов должны проходить
|
||||
|
||||
### boot 🔧 NEEDS REBOOT
|
||||
- capital.test — 53/60 тестов проходят (после чистого reboot)
|
||||
- wallet.test — нужен полный boot с agreements
|
||||
- registrator.test — нужен полный boot
|
||||
- capital-import.test — отдельный тест импорта
|
||||
- **Требует**: pnpm run reboot перед запуском
|
||||
|
||||
### sdk 🔧 TODO
|
||||
- 1 тест файл с login + fetch extensions
|
||||
- Требует запущенный controller
|
||||
- Нужно: обновить chain_id, api_url, credentials
|
||||
|
||||
### controller 🔧 TODO
|
||||
- Все старые тесты удалены (устаревшие)
|
||||
- NestJS-приложение — нужны тесты через @nestjs/testing
|
||||
- Минимум: unit-тесты domain-логики, smoke-тест GraphQL API
|
||||
|
||||
### notifications 🔧 TODO
|
||||
- Нет тестов
|
||||
- Нужно: smoke-тесты workflow builder
|
||||
|
||||
### desktop — SKIP (нет тестов, UI-тестирование)
|
||||
|
||||
## Root script требования
|
||||
- `pnpm run test` — запускает ВСЕ тесты
|
||||
- fail-fast: если один пакет падает — весь pipeline падает
|
||||
- Последовательный запуск (не параллельный)
|
||||
File diff suppressed because one or more lines are too long
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
EOSIO_PUB_KEY=EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
|
||||
EOSIO_PRV_KEY=5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
|
||||
DATADIR=blockchain-data
|
||||
BPACCOUNT=eosio
|
||||
PASSWORD=PW5JGe4WsTPGrjnMzkGd4wfVdzoHCEySgbyq2WBWGAxSfevbXqAG4
|
||||
SERVER_SECRET=SECRET
|
||||
SERVER_URL=http://127.0.0.1:2998
|
||||
MONGO_URI=mongodb://127.0.0.1:27017/cooperative-x
|
||||
SIMPLE_EXPLORER_API=http://localhost:4000
|
||||
SKIP_BLOCK_FETCH=TRUE
|
||||
POSTGRES_HOST=127.0.0.1
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USERNAME=postgres
|
||||
POSTGRES_PASSWORD=postgres
|
||||
POSTGRES_DATABASE=voskhod
|
||||
@@ -0,0 +1,14 @@
|
||||
.cache
|
||||
.DS_Store
|
||||
.idea
|
||||
*.log
|
||||
*.tgz
|
||||
coverage
|
||||
dist
|
||||
lib-cov
|
||||
logs
|
||||
node_modules
|
||||
temp
|
||||
.env
|
||||
blockchain-data/*
|
||||
wallet-data/*
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/lib/**",
|
||||
"${workspaceFolder}/lib/eosiolib/contracts/**",
|
||||
"${workspaceFolder}/lib/eosiolib/core/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"int128_t=__int128_t",
|
||||
"uint128_t=__uint128_t"
|
||||
],
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
{
|
||||
// Enable the ESlint flat config support
|
||||
"prettier.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
// Auto fix
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
// "source.fixAll": "explicit",
|
||||
// "source.organizeImports": "never"
|
||||
},
|
||||
// Silent the stylistic rules in you IDE, but still auto fix them
|
||||
"eslint.rules.customizations": [
|
||||
{
|
||||
"rule": "style/*",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-indent",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-spacing",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-spaces",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-order",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-dangle",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*-newline",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*quotes",
|
||||
"severity": "off"
|
||||
},
|
||||
{
|
||||
"rule": "*semi",
|
||||
"severity": "off"
|
||||
}
|
||||
],
|
||||
// Enable eslint for all supported languages
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"vue",
|
||||
"html",
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc",
|
||||
"yaml"
|
||||
],
|
||||
// "[cpp]": {
|
||||
// "editor.defaultFormatter": "ms-vscode.cpptools",
|
||||
// },
|
||||
// "C_Cpp.vcFormat.indent.withinParentheses": "indent",
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
# @coopenomics/boot
|
||||
|
||||
## Назначение
|
||||
|
||||
CLI-утилита для инициализации блокчейна EOSIO и развёртывания кооператива. Выполняет полный цикл: запуск ноды → создание аккаунтов → активация фич → деплой контрактов → выпуск токенов → загрузка шаблонов → создание кооператива и совета.
|
||||
|
||||
## Структура
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.ts — CLI точка входа (commander): boot, boot:clean, boot:extra,
|
||||
│ start, stop, clear, cleos, deploy, create-coop, unlock
|
||||
├── init/
|
||||
│ ├── booter.ts — Главные сценарии: boot(), bootClean(), bootExtra()
|
||||
│ ├── infra.ts — startInfra() — базовая инфраструктура блокчейна
|
||||
│ │ installInitialData() — начальные данные (пользователи, совет)
|
||||
│ │ installExtraData() — расширенные данные
|
||||
│ └── cooperative.ts — CooperativeClass — создание программ ЦПП, регистрация
|
||||
│ └── participant.ts — Логика регистрации пайщика
|
||||
├── blockchain/
|
||||
│ └── index.ts — Класс Blockchain — обёртка над eosjs для работы с EOSIO
|
||||
│ (создание аккаунтов, деплой контрактов, транзакции, токены)
|
||||
├── configs/
|
||||
│ ├── index.ts — Главная конфигурация (аккаунты, ключи, токен, эмиссия)
|
||||
│ ├── networks.ts — Настройки сети (протокол, хост, порт)
|
||||
│ ├── contracts.ts — Список контрактов и путей к их WASM/ABI файлам
|
||||
│ └── protocol_features/ — JSON-файлы фич для активации на блокчейне
|
||||
├── docker/ — Управление Docker-контейнером ноды блокчейна
|
||||
│ ├── container.ts, run.ts, stop.ts, find.ts, exec.ts, deploy.ts
|
||||
│ ├── health.ts — Проверка готовности ноды
|
||||
│ └── purge.ts — Очистка данных блокчейна и БД
|
||||
├── *-init.ts — Инициализация реляционной БД (пользователи, vault, статус, extensions)
|
||||
├── tests/ — Интеграционные тесты
|
||||
│ ├── capital.test.ts — Основной тест (полный цикл ЦПП)
|
||||
│ ├── wallet.test.ts — Тесты кошелька
|
||||
│ ├── registrator.test.ts — Тесты регистрации
|
||||
│ └── capital/ — Вспомогательные функции для тестов капитала
|
||||
└── utils/ — Утилиты (sleep, randomHash, randomUsername, и т.д.)
|
||||
```
|
||||
|
||||
## Порядок загрузки (boot flow)
|
||||
|
||||
1. **startInfra()** — основа:
|
||||
- Инициализация `Blockchain` с ключами
|
||||
- Создание системных аккаунтов (eosio.token, registrator, soviet, и т.д.)
|
||||
- Активация фич протокола (PREACTIVATE_FEATURE → остальные)
|
||||
- Деплой смарт-контрактов (eosio.boot → eosio.system → все остальные)
|
||||
- Создание и выпуск токенов
|
||||
- Загрузка шаблонов документов из `@coopenomics/factory` Registry
|
||||
- Настройка ресурсов (powerup)
|
||||
|
||||
2. **installInitialData()** — данные кооператива:
|
||||
- Сохранение организации, платёжных методов, физлиц в MongoDB
|
||||
- Сохранение переменных кооператива (vars)
|
||||
- Регистрация пользователей в блокчейне
|
||||
- Инициализация реляционной БД (пользователи, vault)
|
||||
- Создание совета (board)
|
||||
- Создание программ ЦПП (Благорост, маркетплейс)
|
||||
|
||||
3. **bootClean()** — минимальная загрузка (только инфра + программы, без данных)
|
||||
|
||||
4. **bootExtra()** — расширенная загрузка (5 членов совета, дополнительные пайщики)
|
||||
|
||||
## Режимы контрактов
|
||||
|
||||
- **test** — контракты собранные с флагом `test` (позволяют boot с 1 членом совета)
|
||||
- **production** — стандартные контракты (требуют кворум)
|
||||
|
||||
Пути к WASM/ABI файлам указаны в `configs/contracts.ts`, относительно `../contracts/build/contracts/`.
|
||||
|
||||
## Тесты
|
||||
|
||||
- Фреймворк: **Vitest**
|
||||
- Основной тест: `src/tests/capital.test.ts` — полный цикл ЦПП (создание программ, проектов, инвестирование, голосование, конвертация)
|
||||
- Требует: полностью загруженный блокчейн (`pnpm run reboot`), MongoDB, реляционную БД
|
||||
|
||||
### Запуск
|
||||
|
||||
```
|
||||
pnpm --filter @coopenomics/boot test
|
||||
```
|
||||
|
||||
### Важно: Duplicate transaction
|
||||
|
||||
EOSIO отклоняет транзакции с одинаковым хешем (TAPOS block + action data). При повторных вызовах одинаковых действий нужен `await sleep(500)` между ними.
|
||||
|
||||
## Скрипты package.json
|
||||
|
||||
| Скрипт | Описание |
|
||||
|--------|----------|
|
||||
| `boot` | Полная загрузка: инфра + данные + кооператив |
|
||||
| `boot:clean` | Чистая загрузка: только инфра + программы |
|
||||
| `boot:extra` | Расширенная загрузка: инфра + 5 членов совета |
|
||||
| `create-coop` | Создание кооператива после boot:clean |
|
||||
| `test` | Vitest (capital.test.ts, timeout 240s) |
|
||||
| `test:all` | Все тесты |
|
||||
| `clear` | Очистка блокчейна и перезапуск ноды |
|
||||
|
||||
## Зависимости от других компонентов
|
||||
|
||||
- `cooptypes` (workspace) — типы контрактов
|
||||
- `@coopenomics/factory` (workspace) — реестр шаблонов, сохранение данных в MongoDB
|
||||
@@ -0,0 +1,80 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.2.10](https://github.com/coopenomics/mono/compare/v2.2.9...v2.2.10) (2025-03-27)
|
||||
|
||||
**Note:** Version bump only for package @coopenomics/boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.9](https://github.com/coopenomics/mono/compare/v2.2.8...v2.2.9) (2025-03-12)
|
||||
|
||||
**Note:** Version bump only for package @coopenomics/boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.8](https://github.com/coopenomics/contracts/compare/boot@0.1.7...boot@0.1.8) (2024-12-24)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.7](https://github.com/coopenomics/contracts/compare/boot@0.1.7-alpha.0...boot@0.1.7) (2024-10-16)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.6](https://github.com/coopenomics/contracts/compare/boot@0.1.5...boot@0.1.6) (2024-10-13)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.5](https://github.com/coopenomics/contracts/compare/boot@0.1.5-alpha.0...boot@0.1.5) (2024-09-26)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.4](https://github.com/coopenomics/contracts/compare/boot@0.1.4-alpha.0...boot@0.1.4) (2024-08-13)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.3](https://github.com/coopenomics/contracts/compare/boot@0.1.3-alpha.0...boot@0.1.3) (2024-08-13)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.2](https://github.com/coopenomics/contracts/compare/boot@0.1.2-alpha.0...boot@0.1.2) (2024-08-10)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.1.1](https://github.com/coopenomics/contracts/compare/boot@0.1.1-alpha.1...boot@0.1.1) (2024-08-09)
|
||||
|
||||
**Note:** Version bump only for package boot
|
||||
@@ -0,0 +1,100 @@
|
||||
# 🚀 @coopenomics/boot
|
||||
|
||||
CLI-утилита для инициализации блокчейн-инфраструктуры кооператива. Создаёт системные аккаунты, устанавливает смарт-контракты, настраивает токены и разворачивает кооперативную среду. Включает интеграционные тесты для основных подсистем платформы.
|
||||
|
||||
## Основные возможности
|
||||
|
||||
- Полный цикл развёртывания блокчейна EOSIO — от запуска ноды до создания кооператива
|
||||
- Установка системных и прикладных смарт-контрактов
|
||||
- Инициализация токенов и создание тестовых данных
|
||||
- Управление Docker-контейнерами блокчейн-ноды
|
||||
- Интеграционные тесты: паевые взносы (capital), кошелёк (wallet), регистрация участников (registrator)
|
||||
- Поддержка нескольких режимов загрузки: стандартный, чистый и расширенный
|
||||
|
||||
## Установка
|
||||
|
||||
Компонент является частью монорепозитория. Установка зависимостей из корня проекта:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Или только для этого компонента:
|
||||
|
||||
```bash
|
||||
pnpm install --filter @coopenomics/boot
|
||||
```
|
||||
|
||||
## Скрипты
|
||||
|
||||
| Скрипт | Команда | Описание |
|
||||
|--------|---------|----------|
|
||||
| `boot` | `pnpm run boot` | Запуск блокчейна и установка контрактов |
|
||||
| `boot:clean` | `pnpm run boot:clean` | Чистый запуск с полной переустановкой |
|
||||
| `boot:extra` | `pnpm run boot:extra` | Расширенная инициализация с дополнительными данными |
|
||||
| `deploy` | `pnpm run deploy` | Развёртывание контрактов на запущенной ноде |
|
||||
| `cli` | `pnpm run cli` | Интерактивный командный интерфейс (Commander.js) |
|
||||
| `clear` | `pnpm run clear` | Очистка данных блокчейна |
|
||||
| `start` | `pnpm run start` | Перезапуск ноды |
|
||||
| `stop` | `pnpm run stop` | Остановка ноды |
|
||||
| `test` | `pnpm run test` | Интеграционные тесты (capital) |
|
||||
| `test:all` | `pnpm run test:all` | Все интеграционные тесты |
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Скопируйте `.env-example` в `.env` и настройте переменные окружения:
|
||||
|
||||
- Endpoint блокчейн-ноды (API)
|
||||
- Строка подключения к MongoDB
|
||||
- Строка подключения к реляционной БД
|
||||
- Приватные ключи для развёртывания контрактов
|
||||
|
||||
Подробное описание переменных — в файле `.env-example`.
|
||||
|
||||
## Тестирование
|
||||
|
||||
Перед запуском тестов необходима работающая инфраструктура (см. `docker-compose.yaml` в корне проекта):
|
||||
|
||||
```bash
|
||||
pnpm --filter @coopenomics/boot run test
|
||||
pnpm --filter @coopenomics/boot run test:all
|
||||
```
|
||||
|
||||
Тесты используют **Vitest** с таймаутом 240 секунд — это связано с ожиданием подтверждения блокчейн-транзакций.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.ts # Точка входа CLI (Commander.js)
|
||||
├── init/ # Логика инициализации
|
||||
│ ├── booter.ts # Загрузчик блокчейна
|
||||
│ ├── cooperative.ts # Настройка кооператива
|
||||
│ ├── infra.ts # Инфраструктурная инициализация
|
||||
│ └── participant.ts # Создание участников
|
||||
├── blockchain/ # Взаимодействие с EOSIO (eosjs)
|
||||
├── docker/ # Управление Docker-контейнерами
|
||||
├── configs/ # Конфигурация ноды и протокол-фичи
|
||||
├── tests/ # Интеграционные тесты
|
||||
│ ├── capital.test.ts # Тесты паевых взносов
|
||||
│ ├── wallet.test.ts # Тесты кошелька
|
||||
│ └── registrator.test.ts # Тесты регистрации
|
||||
└── utils/ # Вспомогательные утилиты
|
||||
scripts/
|
||||
├── reboot.sh # Полный перезапуск
|
||||
├── clean_reboot.sh # Чистый перезапуск
|
||||
└── extra_reboot.sh # Расширенный перезапуск
|
||||
```
|
||||
|
||||
## Ключевые зависимости
|
||||
|
||||
- **eosjs** — взаимодействие с блокчейном EOSIO
|
||||
- **commander** — CLI-фреймворк
|
||||
- **dockerode** — управление Docker-контейнерами из Node.js
|
||||
- **mongoose** — работа с MongoDB
|
||||
- **pg** — работа с реляционной БД
|
||||
- **vitest** — тестирование
|
||||
|
||||
## Лицензия
|
||||
|
||||
[BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.ru)
|
||||
@@ -0,0 +1,19 @@
|
||||
// @ts-check
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu(
|
||||
{
|
||||
ignores: [
|
||||
// eslint ignore globs here
|
||||
],
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'unused-imports/no-unused-vars': 'off',
|
||||
'no-console': 'off',
|
||||
'unicorn/prefer-number-properties': 'off',
|
||||
// overrides
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "@coopenomics/boot",
|
||||
"type": "module",
|
||||
"version": "2026.2.22-2",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.0.6",
|
||||
"description": "CLI-утилита инициализации блокчейна и кооператива",
|
||||
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
|
||||
"license": "",
|
||||
"keywords": [],
|
||||
"scripts": {
|
||||
"enter": "./scripts/enter.sh",
|
||||
"cli": "esno src/index.ts",
|
||||
"deploy": "esno src/index.ts deploy",
|
||||
"cleos": "esno src/index.ts cleos",
|
||||
"unlock": "esno src/index.ts unlock",
|
||||
"boot": "esno src/index.ts boot",
|
||||
"boot:clean": "esno src/index.ts boot:clean",
|
||||
"boot:extra": "esno src/index.ts boot:extra",
|
||||
"reboot:clean": "cd components/boot/scripts && bash clean_reboot.sh",
|
||||
"reboot:extra": "cd components/boot/scripts && bash extra_reboot.sh",
|
||||
"create-coop": "esno src/index.ts create-coop",
|
||||
"clear": "./scripts/clear.sh",
|
||||
"start": "./scripts/restart.sh",
|
||||
"stop": "./scripts/stop.sh",
|
||||
"test": "vitest run src/tests/capital.test.ts --testTimeout=240000",
|
||||
"test:all": "vitest run --testTimeout=240000"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coopenomics/factory": "workspace:*",
|
||||
"@types/pg": "^8.16.0",
|
||||
"axios": "^1.13.5",
|
||||
"chai": "^5.1.2",
|
||||
"commander": "^12.1.0",
|
||||
"cooptypes": "workspace:*",
|
||||
"dockerode": "^4.0.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"eosjs": "^22.1.0",
|
||||
"eosjs-api": "^7.0.4",
|
||||
"eosjs-ecc": "^4.0.7",
|
||||
"execa": "^9.5.2",
|
||||
"mocha": "^10.7.3",
|
||||
"mongoose": "^9.2.2",
|
||||
"pg": "^8.16.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.18.0",
|
||||
"@antfu/ni": "^0.21.12",
|
||||
"@antfu/utils": "^0.7.8",
|
||||
"@types/dockerode": "^3.3.31",
|
||||
"@types/node": "^20.12.12",
|
||||
"bumpp": "^9.4.1",
|
||||
"eslint": "^9.2.0",
|
||||
"esno": "^4.7.0",
|
||||
"pnpm": "^9.1.1",
|
||||
"rimraf": "^5.0.7",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"vite": "^5.2.11",
|
||||
"vitest": "^1.6.0"
|
||||
}
|
||||
}
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# Определение ассоциативных массивов
|
||||
typeset -A contract_params_test contract_params_prod
|
||||
contract_params_test=(
|
||||
[ano]="ano"
|
||||
[gateway]="gateway"
|
||||
[draft]="draft"
|
||||
[marketplace]="marketplace"
|
||||
[soviet]="soviet"
|
||||
[registrator]="registrator"
|
||||
[system]="eosio"
|
||||
[fund]="fund"
|
||||
)
|
||||
contract_params_prod=(
|
||||
[ano]="ano"
|
||||
[gateway]="gateway"
|
||||
[draft]="draft"
|
||||
[marketplace]="marketplace"
|
||||
[soviet]="soviet"
|
||||
[registrator]="registrator"
|
||||
[system]="eosio"
|
||||
[fund]="fund"
|
||||
[template]="template"
|
||||
)
|
||||
|
||||
# Выбор массива параметров в зависимости от входящего аргумента
|
||||
if [ "$2" = "prod" ]; then
|
||||
contract_params=("${(@kv)contract_params_prod}")
|
||||
elif [ "$2" = "test" ]; then
|
||||
contract_params=("${(@kv)contract_params_test}")
|
||||
else
|
||||
contract_params=("${(@kv)contract_params_test}")
|
||||
fi
|
||||
|
||||
# Форматирование строки для переменной окружения
|
||||
contract_params_str=""
|
||||
for key value in "${(@kv)contract_params}"; do
|
||||
contract_params_str+="${key}=${value},"
|
||||
done
|
||||
|
||||
# Проверяем, задан ли аргумент для контрактов
|
||||
if [ -n "$1" ]; then
|
||||
contracts=$1
|
||||
else
|
||||
contracts="*"
|
||||
fi
|
||||
|
||||
# Запуск контейнера Docker
|
||||
docker run --rm --name cdt_v4.1.0 \
|
||||
--volume $(pwd):/project \
|
||||
-w /project \
|
||||
--env CONTRACT_PARAMS="$contract_params_str" \
|
||||
dicoop/cdt_v4.1.0 /bin/bash -c "
|
||||
|
||||
cd ../cpp
|
||||
|
||||
# Перебираем все папки в директории
|
||||
for folder in $contracts ; do
|
||||
# Убираем слэш из названия папки, чтобы получить имя контракта
|
||||
contract=\${folder%/}
|
||||
contract=\${contract##*/}
|
||||
|
||||
echo \"Сборка контракта \$contract в \$folder...\"
|
||||
|
||||
# Переходим в директорию контракта
|
||||
cd \$folder
|
||||
|
||||
# Извлекаем параметр для -contract из переменной окружения
|
||||
contract_param=\$(echo \$CONTRACT_PARAMS | grep -o \"\$contract=[^,]*\" | cut -d'=' -f2)
|
||||
|
||||
# Компилируем с использованием параметра -contract
|
||||
cdt-cpp -abigen -I include -R include -contract \$contract_param -o \$contract.wasm \$contract.cpp
|
||||
|
||||
# Возвращаемся назад
|
||||
cd ..
|
||||
|
||||
echo \"Сборка контракта \$contract завершена!\"
|
||||
done
|
||||
"
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
cd ../system/build && cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON -Dcdt_DIR="/cdt/build/lib/cmake/cdt" -Dleap_DIR="/blockchain/build/lib/cmake/leap" .. && make -j 2
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Останавливаем и удаляем контейнеры вместе с volumes
|
||||
echo "Останавливаем и удаляем контейнеры с volumes..."
|
||||
docker compose down -v mongo postgres cooparser || true
|
||||
|
||||
# Останавливаем blockchain контейнер перед удалением данных
|
||||
echo "Останавливаем blockchain контейнер..."
|
||||
docker compose stop node || true
|
||||
|
||||
# Удаляем blockchain data
|
||||
echo "Удаляем blockchain data..."
|
||||
# sudo chmod -R 755 ../blockchain-data/ 2>/dev/null || true
|
||||
sudo rm -rf ../blockchain-data/
|
||||
|
||||
# Пересоздаем и запускаем базы данных
|
||||
echo "Пересоздаем и запускаем базы данных..."
|
||||
docker compose up -d mongo postgres
|
||||
|
||||
# Ждем готовности MongoDB
|
||||
echo "Ждем готовности MongoDB..."
|
||||
until docker exec mongo mongosh --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; do
|
||||
echo "MongoDB еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "MongoDB готов!"
|
||||
|
||||
# Ждем готовности PostgreSQL
|
||||
echo "Ждем готовности PostgreSQL..."
|
||||
until docker exec postgres pg_isready -U postgres -d voskhod > /dev/null 2>&1; do
|
||||
echo "PostgreSQL еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL готов!"
|
||||
|
||||
# Запускаем boot процесс
|
||||
echo "Запускаем boot процесс..."
|
||||
pnpm run boot:clean
|
||||
|
||||
# Запускаем parser
|
||||
echo "Запускаем parser..."
|
||||
docker compose up -d cooparser
|
||||
|
||||
echo "Запускаем контроллер..."
|
||||
docker compose restart coopback || true
|
||||
|
||||
echo "Перезапуск завершен!"
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Останавливаем и удаляем контейнеры вместе с volumes
|
||||
echo "Останавливаем и удаляем контейнеры с volumes..."
|
||||
docker compose down -v mongo postgres cooparser || true
|
||||
|
||||
# Останавливаем blockchain контейнер перед удалением данных
|
||||
echo "Останавливаем blockchain контейнер..."
|
||||
docker compose stop node || true
|
||||
|
||||
# Удаляем blockchain data
|
||||
echo "Удаляем blockchain data..."
|
||||
# sudo chmod -R 755 ../blockchain-data/ 2>/dev/null || true
|
||||
sudo rm -rf ../blockchain-data/
|
||||
|
||||
# Пересоздаем и запускаем базы данных
|
||||
echo "Пересоздаем и запускаем базы данных..."
|
||||
docker compose up -d mongo postgres
|
||||
|
||||
# Ждем готовности MongoDB
|
||||
echo "Ждем готовности MongoDB..."
|
||||
until docker exec mongo mongosh --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; do
|
||||
echo "MongoDB еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "MongoDB готов!"
|
||||
|
||||
# Ждем готовности PostgreSQL
|
||||
echo "Ждем готовности PostgreSQL..."
|
||||
until docker exec postgres pg_isready -U postgres -d voskhod > /dev/null 2>&1; do
|
||||
echo "PostgreSQL еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL готов!"
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Передача аргументов cleos
|
||||
docker exec -it node /usr/local/bin/cleos "$@"
|
||||
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Импорт параметров сетей
|
||||
source ./networks.sh
|
||||
|
||||
# Устанавливаем значения по умолчанию
|
||||
network_param=$local
|
||||
account_name_param=""
|
||||
network=""
|
||||
|
||||
# Получаем первый аргумент, который должен быть именем контракта
|
||||
contract_name=$1
|
||||
|
||||
rm /Users/darksun/testnet/wallet/keosd.sock
|
||||
./kill.sh
|
||||
|
||||
# Проверяем наличие параметра -n и устанавливаем соответствующую сеть
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-n)
|
||||
network=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-t)
|
||||
account_name_param=$2
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Устанавливаем значение сети из networks.sh
|
||||
case $network in
|
||||
prod)
|
||||
network_param=$prod
|
||||
;;
|
||||
test)
|
||||
network_param=$test
|
||||
;;
|
||||
local)
|
||||
network_param=$local
|
||||
;;
|
||||
esac
|
||||
|
||||
# Разблокировка кошелька
|
||||
./unlock.sh
|
||||
|
||||
# Функция для установки контракта
|
||||
deploy_contract() {
|
||||
local contract=$1
|
||||
local dir=$2
|
||||
local account_name=$3
|
||||
echo "Устанавливаем контракт $contract на аккаунт $account_name..."
|
||||
if [ -z "$account_name_param" ]; then
|
||||
echo ./cleos.sh $network_param set contract $account_name $dir -p $account_name
|
||||
./cleos.sh $network_param set contract $account_name $dir -p $account_name
|
||||
else
|
||||
echo ./cleos.sh $network_param set contract $account_name_param $dir -p $account_name_param
|
||||
./cleos.sh $network_param set contract $account_name_param $dir -p $account_name_param
|
||||
fi
|
||||
}
|
||||
|
||||
# Если контракт указан, деплоим только его
|
||||
if [ ! -z "$contract_name" ]; then
|
||||
ls ./
|
||||
echo "Проверка наличия папки для контракта $contract_name..."
|
||||
if [ -d "./$contract_name" ]; then
|
||||
echo "Папка контракта найдена. Содержимое папки:"
|
||||
deploy_contract $contract_name "/contracts/cpp/$contract_name" $contract_name
|
||||
elif [[ "$contract_name" == "eosio.msig" || "$contract_name" == "eosio.token" || "$contract_name" == "eosio.wrap" ]]; then
|
||||
echo "Папка системного контракта найдена. Содержимое папки:"
|
||||
ls "/contracts/cpp/system/build/contracts/$contract_name"
|
||||
deploy_contract $contract_name "/contracts/cpp/system/build/contracts/$contract_name" $contract_name
|
||||
elif [ "$contract_name" == "eosio.system" ]; then
|
||||
echo "Папка системного контракта найдена. Содержимое папки:"
|
||||
ls "/contracts/cpp/system/build/contracts/$contract_name"
|
||||
deploy_contract $contract_name "/contracts/cpp/system/build/contracts/$contract_name" "eosio"
|
||||
elif [ "$contract_name" == "eosio.boot" ]; then
|
||||
echo "Папка системного контракта найдена. Содержимое папки:"
|
||||
ls "/contracts/cpp/system/build/contracts/$contract_name"
|
||||
deploy_contract $contract_name "/contracts/cpp/system/build/contracts/$contract_name" "eosio"
|
||||
else
|
||||
echo "Контракт $contract_name не найден"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Перебираем все папки с контрактами на верхнем уровне, исключая 'system'
|
||||
for dir in $(find /contracts/cpp/* -maxdepth 0 -type d ! -name 'system'); do
|
||||
contract=$(basename $dir)
|
||||
echo "Найдена папка $dir для контракта $contract. Содержимое папки:"
|
||||
ls $dir
|
||||
deploy_contract $contract $dir $contract
|
||||
done
|
||||
|
||||
# Исключение для контрактов в папке system
|
||||
special_system_contracts=("eosio.msig" "eosio.token" "eosio.wrap")
|
||||
for contract in "${special_system_contracts[@]}"; do
|
||||
echo "Найдена папка системного контракта для $contract. Содержимое папки:"
|
||||
ls "/contracts/cpp/system/build/contracts/$contract"
|
||||
deploy_contract $contract "/contracts/cpp/system/build/contracts/$contract" $contract
|
||||
done
|
||||
|
||||
deploy_contract "eosio.system" "/contracts/cpp/system/build/contracts/eosio.system" "eosio"
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
docker run --rm -it --name cdt \
|
||||
--volume $(pwd)/:/project \
|
||||
-w /project \
|
||||
dicoop/blockchain_v5.1.1:dev /bin/bash
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Останавливаем контроллер перед очисткой данных
|
||||
echo "Останавливаем контроллер..."
|
||||
docker compose down coopback || true
|
||||
|
||||
# Останавливаем и удаляем контейнеры вместе с volumes
|
||||
echo "Останавливаем и удаляем контейнеры с volumes..."
|
||||
docker compose down -v mongo postgres cooparser || true
|
||||
|
||||
# Останавливаем blockchain контейнер перед удалением данных
|
||||
echo "Останавливаем blockchain контейнер..."
|
||||
docker compose stop node || true
|
||||
|
||||
# Удаляем blockchain data
|
||||
echo "Удаляем blockchain data..."
|
||||
# sudo chmod -R 755 ../blockchain-data/ 2>/dev/null || true
|
||||
sudo rm -rf ../blockchain-data/
|
||||
|
||||
# Пересоздаем и запускаем базы данных
|
||||
echo "Пересоздаем и запускаем базы данных..."
|
||||
docker compose up -d mongo postgres
|
||||
|
||||
# Ждем готовности MongoDB
|
||||
echo "Ждем готовности MongoDB..."
|
||||
until docker exec mongo mongosh --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; do
|
||||
echo "MongoDB еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "MongoDB готов!"
|
||||
|
||||
# Ждем готовности PostgreSQL
|
||||
echo "Ждем готовности PostgreSQL..."
|
||||
until docker exec postgres pg_isready -U postgres -d voskhod > /dev/null 2>&1; do
|
||||
echo "PostgreSQL еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL готов!"
|
||||
|
||||
# Запускаем boot процесс
|
||||
echo "Запускаем boot процесс..."
|
||||
pnpm run boot:extra
|
||||
|
||||
# Запускаем parser
|
||||
echo "Запускаем parser..."
|
||||
docker compose up -d cooparser
|
||||
|
||||
echo "Запускаем контроллер..."
|
||||
docker compose up -d coopback
|
||||
|
||||
echo "Перезапуск завершен!"
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
cd ../
|
||||
doxygen
|
||||
cp -r ../docs/html/* ../../doctrine/site/contracts
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# убиваем keosd на всякий случай
|
||||
docker exec -it node pkill keosd
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Получаем текущую директорию
|
||||
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Проверяем, существуют ли директории
|
||||
if [ ! -d ~/testnet ]; then
|
||||
echo "Директория ~/testnet не найдена. Создание..."
|
||||
mkdir -p ~/testnet
|
||||
fi
|
||||
|
||||
if [ ! -d ~/testnet/config ]; then
|
||||
echo "Директория ~/testnet/config не найдена. Создание..."
|
||||
mkdir -p ~/testnet/config
|
||||
fi
|
||||
|
||||
# Проверяем, существует ли файл
|
||||
if [ ! -f ~/testnet/config/config.ini ]; then
|
||||
echo "Файл config.ini не найден. Копирование..."
|
||||
cp $dir/configs/master/config.ini ~/testnet/config/config.ini
|
||||
fi
|
||||
|
||||
# Запускаем контейнер Docker с нужными параметрами
|
||||
docker run --name node -d -p 8888:8888 -p 9876:9876 -p 8080:8080 \
|
||||
-v ~/testnet/data:/mnt/dev/data \
|
||||
-v ~/testnet/config:/mnt/dev/config \
|
||||
-v ~/testnet/wallet:/root/eosio-wallet \
|
||||
-v $dir/../../contracts:/contracts \
|
||||
dicoop/blockchain:v5.1.0-dev \
|
||||
/bin/bash -c '/usr/local/bin/nodeos -d /mnt/dev/data -p eosio --config-dir /mnt/dev/config --genesis-json /mnt/dev/config/genesis.json'
|
||||
|
||||
docker network connect hyperion node
|
||||
|
||||
echo "Контейнер node установлен - блокчейн запущен."
|
||||
sleep 10
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
local="-u http://localhost:8888"
|
||||
test="-u https://testnet.coopenomics.world/api"
|
||||
prod="-u https://voskhod.coopenomics.world/api"
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"net": {
|
||||
"assumed_stake_weight": 10000000,
|
||||
"current_weight_ratio": 500000000000000,
|
||||
"decay_secs": 86400,
|
||||
"exponent": 1,
|
||||
"max_price": "1000.0000 AXON",
|
||||
"min_price": "1000.0000 AXON",
|
||||
"target_weight_ratio": 500000000000000
|
||||
},
|
||||
"cpu": {
|
||||
"assumed_stake_weight": 10000000,
|
||||
"current_weight_ratio": 500000000000000,
|
||||
"decay_secs": 86400,
|
||||
"exponent": 1,
|
||||
"max_price": "1000.0000 AXON",
|
||||
"min_price": "1000.0000 AXON",
|
||||
"target_weight_ratio": 500000000000000
|
||||
},
|
||||
"min_powerup_fee": "0.0001 AXON",
|
||||
"powerup_days": 1
|
||||
}
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
cleos push action eosio cfgpowerup "[`cat ./powerup.json`]" -p eosio
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run unlock script before activating features
|
||||
./unlock.sh
|
||||
|
||||
# Activate PREACTIVATE_FEATURE before installing eosio.boot
|
||||
#./cleos.sh push action eosio activate '["0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd"]' -p eosio@active
|
||||
|
||||
curl --noproxy -X POST "http://localhost:8888/v1/producer/schedule_protocol_feature_activations" -d '{"protocol_features_to_activate": ["0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd"]}'
|
||||
|
||||
# Install eosio.boot which supports the native actions and activate
|
||||
# action that allows activating desired protocol features prior to
|
||||
# deploying a system contract with more features such as eosio.bios
|
||||
# or eosio.system
|
||||
./deploy.sh eosio.boot
|
||||
|
||||
# Activate remaining features
|
||||
./cleos.sh push action eosio activate '["c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b"]' -p eosio@active
|
||||
./cleos.sh push action eosio activate '["6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc"]' -p eosio@active
|
||||
|
||||
# Install the eosio.system contract
|
||||
./deploy.sh eosio.system
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Останавливаем и удаляем контейнер, если он существует
|
||||
docker stop node > /dev/null 2>&1 && docker rm node > /dev/null 2>&1
|
||||
|
||||
# Очищаем папку с данными блокчейна
|
||||
rm -rf ~/testnet/data/*
|
||||
|
||||
echo "Очистка завершена."
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Останавливаем и удаляем контейнеры вместе с volumes
|
||||
echo "Останавливаем и удаляем контейнеры с volumes..."
|
||||
docker compose down -v mongo postgres opensearch cooparser || true
|
||||
|
||||
# Останавливаем blockchain контейнер перед удалением данных
|
||||
echo "Останавливаем blockchain контейнер..."
|
||||
docker compose stop node || true
|
||||
|
||||
# Удаляем blockchain data
|
||||
echo "Удаляем blockchain data..."
|
||||
# sudo chmod -R 755 ../blockchain-data/ 2>/dev/null || true
|
||||
sudo rm -rf ../blockchain-data/
|
||||
|
||||
# Пересоздаем и запускаем базы данных
|
||||
echo "Пересоздаем и запускаем базы данных..."
|
||||
docker compose up -d mongo postgres opensearch
|
||||
|
||||
# Ждем готовности MongoDB
|
||||
echo "Ждем готовности MongoDB..."
|
||||
until docker exec mongo mongosh --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; do
|
||||
echo "MongoDB еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "MongoDB готов!"
|
||||
|
||||
# Ждем готовности PostgreSQL
|
||||
echo "Ждем готовности PostgreSQL..."
|
||||
until docker exec postgres pg_isready -U postgres -d voskhod > /dev/null 2>&1; do
|
||||
echo "PostgreSQL еще не готов, ждем..."
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL готов!"
|
||||
|
||||
# Запускаем boot процесс
|
||||
echo "Запускаем boot процесс..."
|
||||
pnpm run boot
|
||||
|
||||
# Запускаем parser
|
||||
echo "Запускаем parser..."
|
||||
docker compose up -d cooparser
|
||||
|
||||
echo "Запускаем контроллер..."
|
||||
docker compose restart coopback || true
|
||||
|
||||
echo "Перезапуск завершен!"
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
cd ../cpp/system/build/tests && ctest -j $(nproc) --rerun-failed --output-on-failure
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d $DATADIR ]; then
|
||||
mkdir -p $DATADIR;
|
||||
fi
|
||||
|
||||
ARCH=`uname -m`
|
||||
|
||||
NODEOS='/usr/local/bin/nodeos'
|
||||
|
||||
if [ "${ARCH}" = "x86_64" ]; then
|
||||
EOSVM=eos-vm-jit
|
||||
else
|
||||
EOSVM=eos-vm
|
||||
fi
|
||||
|
||||
$NODEOS \
|
||||
--signature-provider $EOSIO_PUB_KEY=KEY:$EOSIO_PRV_KEY \
|
||||
--plugin eosio::net_plugin \
|
||||
--plugin eosio::net_api_plugin \
|
||||
--plugin eosio::producer_plugin \
|
||||
--plugin eosio::producer_api_plugin \
|
||||
--plugin eosio::chain_plugin \
|
||||
--plugin eosio::chain_api_plugin \
|
||||
--plugin eosio::http_plugin \
|
||||
--data-dir $DATADIR"/data" \
|
||||
--blocks-dir $DATADIR"/blocks" \
|
||||
--config-dir $DATADIR"/config" \
|
||||
--producer-name $BPACCOUNT \
|
||||
--http-server-address 0.0.0.0:8888 \
|
||||
--p2p-listen-endpoint 0.0.0.0:9010 \
|
||||
--access-control-allow-origin=* \
|
||||
--contracts-console \
|
||||
--http-validate-host=false \
|
||||
--verbose-http-errors \
|
||||
--enable-stale-production \
|
||||
--trace-history \
|
||||
--chain-state-history \
|
||||
--max-transaction-time=2000 \
|
||||
--abi-serializer-max-time-ms=60000 \
|
||||
--http-max-response-time-ms=8000 \
|
||||
--chain-state-db-size-mb 8192 \
|
||||
--chain-state-db-guard-size-mb 1024 \
|
||||
--wasm-runtime=$EOSVM \
|
||||
>> $DATADIR"/coopos.log" 2>&1 & \
|
||||
echo $! > $DATADIR"/coopos.pid"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERBOSE=""
|
||||
|
||||
if [[ $1 == "--verbose" ]]; then
|
||||
VERBOSE="--verbose"
|
||||
fi
|
||||
|
||||
cd ../cpp/system/build/tests && ctest -j $(nproc) --output-on-failure $VERBOSE
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
source .env
|
||||
|
||||
if [ -f $DATADIR"/eosd.pid" ]; then
|
||||
pid=`cat $DATADIR"/eosd.pid"`
|
||||
echo $pid
|
||||
kill $pid
|
||||
rm -r $DATADIR"/eosd.pid"
|
||||
echo -ne "Stoping Node"
|
||||
while true; do
|
||||
[ ! -d "/proc/$pid/fd" ] && break
|
||||
echo -ne "."
|
||||
sleep 1
|
||||
done
|
||||
echo -ne "\rNode Stopped. \n"
|
||||
fi
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Переходим в директорию скрипта
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Проверяем наличие папки для хранения данных о кошельке
|
||||
if [ ! -d "$HOME/testnet/wallet" ]; then
|
||||
mkdir -p $HOME/testnet/wallet
|
||||
fi
|
||||
|
||||
# Проверяем наличие файла с паролем
|
||||
if [ ! -f "$HOME/testnet/wallet/password" ]; then
|
||||
echo "Создание нового кошелька..."
|
||||
# Создаем новый кошелек и сохраняем пароль в файл внутри контейнера
|
||||
docker exec -it node /usr/local/bin/cleos wallet create --file password.txt
|
||||
if [ $? -eq 0 ]; then
|
||||
# Копируем пароль из файла контейнера в локальный файл
|
||||
docker cp node:/workdir/password.txt $HOME/testnet/wallet/password
|
||||
# Удаляем временный файл из контейнера
|
||||
docker exec -it node rm /workdir/password.txt
|
||||
echo "Пароль от кошелька сохранён в файле $HOME/testnet/wallet/password"
|
||||
# Импортируем ключ в кошелек
|
||||
docker exec -it node /usr/local/bin/cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
|
||||
else
|
||||
echo "Не удалось создать кошелек"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Использование существующего кошелька..."
|
||||
# Разблокировка кошелька
|
||||
docker exec -it node /usr/local/bin/cleos wallet unlock --password $(cat $HOME/testnet/wallet/password) > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,532 @@
|
||||
plugin = eosio::chain_plugin
|
||||
plugin = eosio::producer_plugin
|
||||
plugin = eosio::chain_api_plugin
|
||||
plugin = eosio::http_plugin
|
||||
plugin = eosio::state_history_plugin
|
||||
plugin = eosio::producer_api_plugin
|
||||
plugin = eosio::resource_monitor_plugin
|
||||
|
||||
enable-stale-production = true
|
||||
read-only-read-window-time-us = 120000
|
||||
|
||||
net-threads = 2
|
||||
max-transaction-time=10000
|
||||
|
||||
http-server-address = 0.0.0.0:8888
|
||||
p2p-listen-endpoint = 0.0.0.0:9876
|
||||
access-control-allow-origin = *
|
||||
access-control-allow-credentials = false
|
||||
http-validate-host = false
|
||||
producer-name=eosio
|
||||
producer-name=core
|
||||
signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
|
||||
|
||||
http-max-response-time-ms = 30000
|
||||
max-body-size = 10485760
|
||||
abi-serializer-max-time-ms = 200000
|
||||
contracts-console = true
|
||||
|
||||
max-block-cpu-usage-threshold-us = 200000
|
||||
max-block-net-usage-threshold-bytes = 800000
|
||||
|
||||
verbose-http-errors = true
|
||||
chain-state-history = true
|
||||
trace-history = true
|
||||
state-history-endpoint = 0.0.0.0:8070
|
||||
resource-monitor-space-threshold = 99
|
||||
resource-monitor-not-shutdown-on-threshold-exceeded = true
|
||||
wasm-runtime = eos-vm
|
||||
|
||||
# Percentage of cpu block production time used to produce block. Whole number percentages, e.g. 80 for 80% (eosio::producer_plugin)
|
||||
# cpu-effort-percent = 80
|
||||
|
||||
# Percentage of cpu block production time used to produce last block. Whole number percentages, e.g. 80 for 80% (eosio::producer_plugin)
|
||||
# last-block-cpu-effort-percent = 80
|
||||
|
||||
|
||||
# the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin)
|
||||
# blocks-dir = "blocks"
|
||||
|
||||
# split the block log file when the head block number is the multiple of the stride
|
||||
# When the stride is reached, the current block log and index will be renamed '<blocks-retained-dir>/blocks-<start num>-<end num>.log/index'
|
||||
# and a new current block log and index will be created with the most recent block. All files following
|
||||
# this format will be used to construct an extended block log. (eosio::chain_plugin)
|
||||
# blocks-log-stride =
|
||||
|
||||
# the maximum number of blocks files to retain so that the blocks in those files can be queried.
|
||||
# When the number is reached, the oldest block file would be moved to archive dir or deleted if the archive dir is empty.
|
||||
# The retained block log files should not be manipulated by users. (eosio::chain_plugin)
|
||||
# max-retained-block-files =
|
||||
|
||||
# the location of the blocks retained directory (absolute path or relative to blocks dir).
|
||||
# If the value is empty, it is set to the value of blocks dir. (eosio::chain_plugin)
|
||||
# blocks-retained-dir =
|
||||
|
||||
# the location of the blocks archive directory (absolute path or relative to blocks dir).
|
||||
# If the value is empty, blocks files beyond the retained limit will be deleted.
|
||||
# All files in the archive directory are completely under user's control, i.e. they won't be accessed by nodeos anymore. (eosio::chain_plugin)
|
||||
# blocks-archive-dir =
|
||||
|
||||
# the location of the state directory (absolute path or relative to application data dir) (eosio::chain_plugin)
|
||||
# state-dir = "state"
|
||||
|
||||
# the location of the protocol_features directory (absolute path or relative to application config dir) (eosio::chain_plugin)
|
||||
# protocol-features-dir = "protocol_features"
|
||||
|
||||
# Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin)
|
||||
# checkpoint =
|
||||
|
||||
# Override default WASM runtime ( "eos-vm-jit", "eos-vm")
|
||||
# "eos-vm-jit" : A WebAssembly runtime that compiles WebAssembly code to native x86 code prior to execution.
|
||||
# "eos-vm" : A WebAssembly interpreter.
|
||||
# (eosio::chain_plugin)
|
||||
# wasm-runtime = eos-vm-jit
|
||||
|
||||
# The name of an account whose code will be profiled (eosio::chain_plugin)
|
||||
# profile-account =
|
||||
|
||||
# Override default maximum ABI serialization time allowed in ms (eosio::chain_plugin)
|
||||
# abi-serializer-max-time-ms = 15
|
||||
|
||||
# Maximum size (in MiB) of the chain state database (eosio::chain_plugin)
|
||||
# chain-state-db-size-mb = 1024
|
||||
|
||||
# Safely shut down node when free space remaining in the chain state database drops below this size (in MiB). (eosio::chain_plugin)
|
||||
# chain-state-db-guard-size-mb = 128
|
||||
|
||||
# Percentage of actual signature recovery cpu to bill. Whole number percentages, e.g. 50 for 50% (eosio::chain_plugin)
|
||||
# signature-cpu-billable-pct = 50
|
||||
|
||||
# Number of worker threads in controller thread pool (eosio::chain_plugin)
|
||||
# chain-threads = 2
|
||||
|
||||
# print contract's output to console (eosio::chain_plugin)
|
||||
# contracts-console = false
|
||||
|
||||
# print deeper information about chain operations (eosio::chain_plugin)
|
||||
deep-mind = false
|
||||
|
||||
# Account added to actor whitelist (may specify multiple times) (eosio::chain_plugin)
|
||||
# actor-whitelist =
|
||||
|
||||
# Account added to actor blacklist (may specify multiple times) (eosio::chain_plugin)
|
||||
# actor-blacklist =
|
||||
|
||||
# Contract account added to contract whitelist (may specify multiple times) (eosio::chain_plugin)
|
||||
# contract-whitelist =
|
||||
|
||||
# Contract account added to contract blacklist (may specify multiple times) (eosio::chain_plugin)
|
||||
# contract-blacklist =
|
||||
|
||||
# Action (in the form code::action) added to action blacklist (may specify multiple times) (eosio::chain_plugin)
|
||||
# action-blacklist =
|
||||
|
||||
# Public key added to blacklist of keys that should not be included in authorities (may specify multiple times) (eosio::chain_plugin)
|
||||
# key-blacklist =
|
||||
|
||||
# Deferred transactions sent by accounts in this list do not have any of the subjective whitelist/blacklist checks applied to them (may specify multiple times) (eosio::chain_plugin)
|
||||
# sender-bypass-whiteblacklist =
|
||||
|
||||
# Database read mode ("head", "irreversible", "speculative").
|
||||
# In "head" mode: database contains state changes up to the head block; transactions received by the node are relayed if valid.
|
||||
# In "irreversible" mode: database contains state changes up to the last irreversible block; transactions received via the P2P network are not relayed and transactions cannot be pushed via the chain API.
|
||||
# In "speculative" mode: database contains state changes by transactions in the blockchain up to the head block as well as some transactions not yet included in the blockchain; transactions received by the node are relayed if valid.
|
||||
# (eosio::chain_plugin)
|
||||
# read-mode = head
|
||||
|
||||
# Allow API transactions to be evaluated and relayed if valid. (eosio::chain_plugin)
|
||||
api-accept-transactions = true
|
||||
|
||||
# Chain validation mode ("full" or "light").
|
||||
# In "full" mode all incoming blocks will be fully validated.
|
||||
# In "light" mode all incoming blocks headers will be fully validated; transactions in those validated blocks will be trusted
|
||||
# (eosio::chain_plugin)
|
||||
# validation-mode = full
|
||||
|
||||
# Disable the check which subjectively fails a transaction if a contract bills more RAM to another account within the context of a notification handler (i.e. when the receiver is not the code of the action). (eosio::chain_plugin)
|
||||
# disable-ram-billing-notify-checks = false
|
||||
|
||||
# Subjectively limit the maximum length of variable components in a variable legnth signature to this size in bytes (eosio::chain_plugin)
|
||||
# maximum-variable-signature-length = 16384
|
||||
|
||||
# Indicate a producer whose blocks headers signed by it will be fully validated, but transactions in those validated blocks will be trusted. (eosio::chain_plugin)
|
||||
# trusted-producer =
|
||||
|
||||
# Database map mode ("mapped", "heap", or "locked").
|
||||
# In "mapped" mode database is memory mapped as a file.
|
||||
# In "heap" mode database is preloaded in to swappable memory and will use huge pages if available.
|
||||
# In "locked" mode database is preloaded, locked in to memory, and will use huge pages if available.
|
||||
# (eosio::chain_plugin)
|
||||
# database-map-mode = mapped
|
||||
|
||||
# Maximum size (in MiB) of the EOS VM OC code cache (eosio::chain_plugin)
|
||||
# eos-vm-oc-cache-size-mb = 1024
|
||||
|
||||
# Number of threads to use for EOS VM OC tier-up (eosio::chain_plugin)
|
||||
# eos-vm-oc-compile-threads = 1
|
||||
|
||||
# Enable EOS VM OC tier-up runtime (eosio::chain_plugin)
|
||||
# eos-vm-oc-enable = false
|
||||
|
||||
# enable queries to find accounts by various metadata. (eosio::chain_plugin)
|
||||
# enable-account-queries = false
|
||||
|
||||
# maximum allowed size (in bytes) of an inline action for a nonprivileged account (eosio::chain_plugin)
|
||||
# max-nonprivileged-inline-action-size = 4096
|
||||
|
||||
# Maximum size (in GiB) allowed to be allocated for the Transaction Retry feature. Setting above 0 enables this feature. (eosio::chain_plugin)
|
||||
# transaction-retry-max-storage-size-gb =
|
||||
|
||||
# How often, in seconds, to resend an incoming transaction to network if not seen in a block.
|
||||
# Needs to be at least twice as large as p2p-dedup-cache-expire-time-sec. (eosio::chain_plugin)
|
||||
# transaction-retry-interval-sec = 20
|
||||
|
||||
# Maximum allowed transaction expiration for retry transactions, will retry transactions up to this value.
|
||||
# Should be larger than transaction-retry-interval-sec. (eosio::chain_plugin)
|
||||
# transaction-retry-max-expiration-sec = 120
|
||||
|
||||
# Maximum size (in GiB) allowed to be allocated for the Transaction Finality Status feature. Setting above 0 enables this feature. (eosio::chain_plugin)
|
||||
# transaction-finality-status-max-storage-size-gb =
|
||||
|
||||
# Duration (in seconds) a successful transaction's Finality Status will remain available from being first identified. (eosio::chain_plugin)
|
||||
# transaction-finality-status-success-duration-sec = 180
|
||||
|
||||
# Duration (in seconds) a failed transaction's Finality Status will remain available from being first identified. (eosio::chain_plugin)
|
||||
# transaction-finality-status-failure-duration-sec = 180
|
||||
|
||||
# Log the state integrity hash on startup (eosio::chain_plugin)
|
||||
# integrity-hash-on-start = false
|
||||
|
||||
# Log the state integrity hash on shutdown (eosio::chain_plugin)
|
||||
# integrity-hash-on-stop = false
|
||||
|
||||
# If set to greater than 0, periodically prune the block log to store only configured number of most recent blocks.
|
||||
# If set to 0, no blocks are be written to the block log; block log file is removed after startup. (eosio::chain_plugin)
|
||||
# block-log-retain-blocks =
|
||||
|
||||
# The filename (relative to data-dir) to create a unix socket for HTTP RPC; set blank to disable. (eosio::http_plugin)
|
||||
# unix-socket-path =
|
||||
|
||||
# The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
|
||||
# http-server-address = 127.0.0.1:8888
|
||||
|
||||
# Specify the Access-Control-Allow-Origin to be returned on each request (eosio::http_plugin)
|
||||
# access-control-allow-origin =
|
||||
|
||||
# Specify the Access-Control-Allow-Headers to be returned on each request (eosio::http_plugin)
|
||||
# access-control-allow-headers =
|
||||
|
||||
# Specify the Access-Control-Max-Age to be returned on each request. (eosio::http_plugin)
|
||||
# access-control-max-age =
|
||||
|
||||
# Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin)
|
||||
# access-control-allow-credentials = false
|
||||
|
||||
# The maximum body size in bytes allowed for incoming RPC requests (eosio::http_plugin)
|
||||
# max-body-size = 2097152
|
||||
|
||||
# Maximum size in megabytes http_plugin should use for processing http requests. -1 for unlimited. 429 error response when exceeded. (eosio::http_plugin)
|
||||
# http-max-bytes-in-flight-mb = 500
|
||||
|
||||
# Maximum number of requests http_plugin should use for processing http requests. 429 error response when exceeded. (eosio::http_plugin)
|
||||
# http-max-in-flight-requests = -1
|
||||
|
||||
# Maximum time for processing a request, -1 for unlimited (eosio::http_plugin)
|
||||
# http-max-response-time-ms = 30
|
||||
|
||||
# Append the error log to HTTP responses (eosio::http_plugin)
|
||||
# verbose-http-errors = false
|
||||
|
||||
# If set to false, then any incoming "Host" header is considered valid (eosio::http_plugin)
|
||||
# http-validate-host = true
|
||||
|
||||
# Additionaly acceptable values for the "Host" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default. (eosio::http_plugin)
|
||||
# http-alias =
|
||||
|
||||
# Number of worker threads in http thread pool (eosio::http_plugin)
|
||||
# http-threads = 2
|
||||
|
||||
# If set to false, do not keep HTTP connections alive, even if client requests. (eosio::http_plugin)
|
||||
# http-keep-alive = true
|
||||
|
||||
# The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin)
|
||||
# p2p-listen-endpoint = 0.0.0.0:9876
|
||||
|
||||
# An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint. (eosio::net_plugin)
|
||||
# p2p-server-address =
|
||||
|
||||
# The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network.
|
||||
# Syntax: host:port[:<trx>|<blk>]
|
||||
# The optional 'trx' and 'blk' indicates to node that only transactions 'trx' or blocks 'blk' should be sent. Examples:
|
||||
# p2p.eos.io:9876
|
||||
# p2p.trx.eos.io:9876:trx
|
||||
# p2p.blk.eos.io:9876:blk
|
||||
# (eosio::net_plugin)
|
||||
# p2p-peer-address =
|
||||
|
||||
# Maximum number of client nodes from any single IP address (eosio::net_plugin)
|
||||
# p2p-max-nodes-per-host = 1
|
||||
|
||||
# Allow transactions received over p2p network to be evaluated and relayed if valid. (eosio::net_plugin)
|
||||
# p2p-accept-transactions = true
|
||||
|
||||
# The account and public p2p endpoint of a block producer node to automatically connect to when the it is in producer schedule proximity
|
||||
# . Syntax: account,host:port
|
||||
# Example,
|
||||
# eosproducer1,p2p.eos.io:9876
|
||||
# eosproducer2,p2p.trx.eos.io:9876:trx
|
||||
# eosproducer3,p2p.blk.eos.io:9876:blk
|
||||
# (eosio::net_plugin)
|
||||
# p2p-auto-bp-peer =
|
||||
|
||||
# The name supplied to identify this node amongst the peers. (eosio::net_plugin)
|
||||
# agent-name = EOS Test Agent
|
||||
|
||||
# Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin)
|
||||
# allowed-connection = any
|
||||
|
||||
# Optional public key of peer allowed to connect. May be used multiple times. (eosio::net_plugin)
|
||||
# peer-key =
|
||||
|
||||
# Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin)
|
||||
# peer-private-key =
|
||||
|
||||
# Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin)
|
||||
# max-clients = 25
|
||||
|
||||
# number of seconds to wait before cleaning up dead connections (eosio::net_plugin)
|
||||
# connection-cleanup-period = 30
|
||||
|
||||
# max connection cleanup time per cleanup call in milliseconds (eosio::net_plugin)
|
||||
# max-cleanup-time-msec = 10
|
||||
|
||||
# Maximum time to track transaction for duplicate optimization (eosio::net_plugin)
|
||||
# p2p-dedup-cache-expire-time-sec = 10
|
||||
|
||||
# Number of worker threads in net_plugin thread pool (eosio::net_plugin)
|
||||
# net-threads = 4
|
||||
|
||||
# number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin)
|
||||
# sync-fetch-span = 100
|
||||
|
||||
# Enable experimental socket read watermark optimization (eosio::net_plugin)
|
||||
# use-socket-read-watermark = false
|
||||
|
||||
# The string used to format peers when logging messages about them. Variables are escaped with ${<variable name>}.
|
||||
# Available Variables:
|
||||
# _name self-reported name
|
||||
#
|
||||
# _cid assigned connection id
|
||||
#
|
||||
# _id self-reported ID (64 hex characters)
|
||||
#
|
||||
# _sid first 8 characters of _peer.id
|
||||
#
|
||||
# _ip remote IP address of peer
|
||||
#
|
||||
# _port remote port number of peer
|
||||
#
|
||||
# _lip local IP address connected to peer
|
||||
#
|
||||
# _lport local port number connected to peer
|
||||
#
|
||||
# (eosio::net_plugin)
|
||||
# peer-log-format = ["${_name}" - ${_cid} ${_ip}:${_port}]
|
||||
|
||||
# peer heartbeat keepalive message interval in milliseconds (eosio::net_plugin)
|
||||
# p2p-keepalive-interval-ms = 10000
|
||||
|
||||
# Enable block production, even if the chain is stale. (eosio::producer_plugin)
|
||||
# enable-stale-production = false
|
||||
|
||||
# Start this node in a state where production is paused (eosio::producer_plugin)
|
||||
# pause-on-startup = false
|
||||
|
||||
# Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin)
|
||||
# max-transaction-time = 30
|
||||
|
||||
# Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited) (eosio::producer_plugin)
|
||||
# max-irreversible-block-age = -1
|
||||
|
||||
# ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin)
|
||||
# producer-name =
|
||||
|
||||
# Key=Value pairs in the form <public-key>=<provider-spec>
|
||||
# Where:
|
||||
# <public-key> is a string form of a vaild EOSIO public key
|
||||
#
|
||||
# <provider-spec> is a string in the form <provider-type>:<data>
|
||||
#
|
||||
# <provider-type> is KEY, KEOSD, or SE
|
||||
#
|
||||
# KEY:<data> is a string form of a valid EOSIO private key which maps to the provided public key
|
||||
#
|
||||
# KEOSD:<data> is the URL where keosd is available and the approptiate wallet(s) are unlocked
|
||||
#
|
||||
# (eosio::producer_plugin)
|
||||
# signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
|
||||
|
||||
# account that can not access to extended CPU/NET virtual resources (eosio::producer_plugin)
|
||||
# greylist-account =
|
||||
|
||||
# Limit (between 1 and 1000) on the multiple that CPU/NET virtual resources can extend during low usage (only enforced subjectively; use 1000 to not enforce any limit) (eosio::producer_plugin)
|
||||
# greylist-limit = 1000
|
||||
|
||||
# Offset of non last block producing time in microseconds. Valid range 0 .. -block_time_interval. (eosio::producer_plugin)
|
||||
# produce-time-offset-us = 0
|
||||
|
||||
# Offset of last block producing time in microseconds. Valid range 0 .. -block_time_interval. (eosio::producer_plugin)
|
||||
# last-block-time-offset-us = -200000
|
||||
|
||||
# Percentage of cpu block production time used to produce block. Whole number percentages, e.g. 80 for 80% (eosio::producer_plugin)
|
||||
# cpu-effort-percent = 10
|
||||
|
||||
# Percentage of cpu block production time used to produce last block. Whole number percentages, e.g. 80 for 80% (eosio::producer_plugin)
|
||||
# last-block-cpu-effort-percent = 10
|
||||
|
||||
# Threshold of CPU block production to consider block full; when within threshold of max-block-cpu-usage block can be produced immediately (eosio::producer_plugin)
|
||||
# max-block-cpu-usage-threshold-us = 5000
|
||||
|
||||
# Threshold of NET block production to consider block full; when within threshold of max-block-net-usage block can be produced immediately (eosio::producer_plugin)
|
||||
# max-block-net-usage-threshold-bytes = 1024
|
||||
|
||||
# Maximum wall-clock time, in milliseconds, spent retiring scheduled transactions (and incoming transactions according to incoming-defer-ratio) in any block before returning to normal transaction processing. (eosio::producer_plugin)
|
||||
# max-scheduled-transaction-time-per-block-ms = 100
|
||||
|
||||
# Time in microseconds allowed for a transaction that starts with insufficient CPU quota to complete and cover its CPU usage. (eosio::producer_plugin)
|
||||
# subjective-cpu-leeway-us = 31000
|
||||
|
||||
# Sets the maximum amount of failures that are allowed for a given account per window size. (eosio::producer_plugin)
|
||||
# subjective-account-max-failures = 3
|
||||
|
||||
# Sets the window size in number of blocks for subjective-account-max-failures. (eosio::producer_plugin)
|
||||
# subjective-account-max-failures-window-size = 1
|
||||
|
||||
# Sets the time to return full subjective cpu for accounts (eosio::producer_plugin)
|
||||
# subjective-account-decay-time-minutes = 1440
|
||||
|
||||
# ratio between incoming transactions and deferred transactions when both are queued for execution (eosio::producer_plugin)
|
||||
# incoming-defer-ratio = 1
|
||||
|
||||
# Maximum size (in MiB) of the incoming transaction queue. Exceeding this value will subjectively drop transaction with resource exhaustion. (eosio::producer_plugin)
|
||||
# incoming-transaction-queue-size-mb = 1024
|
||||
|
||||
# Disable subjective CPU billing for API/P2P transactions (eosio::producer_plugin)
|
||||
# disable-subjective-billing = true
|
||||
|
||||
# Account which is excluded from subjective CPU billing (eosio::producer_plugin)
|
||||
# disable-subjective-account-billing =
|
||||
|
||||
# Disable subjective CPU billing for P2P transactions (eosio::producer_plugin)
|
||||
# disable-subjective-p2p-billing = true
|
||||
|
||||
# Disable subjective CPU billing for API transactions (eosio::producer_plugin)
|
||||
# disable-subjective-api-billing = true
|
||||
|
||||
# Number of worker threads in producer thread pool (eosio::producer_plugin)
|
||||
# producer-threads = 1
|
||||
|
||||
# the location of the snapshots directory (absolute path or relative to application data dir) (eosio::producer_plugin)
|
||||
# snapshots-dir = "snapshots"
|
||||
|
||||
# Number of worker threads in read-only execution thread pool. Max 8. (eosio::producer_plugin)
|
||||
# read-only-threads =
|
||||
|
||||
# Time in microseconds the write window lasts. (eosio::producer_plugin)
|
||||
# read-only-write-window-time-us = 200000
|
||||
|
||||
# Time in microseconds the read window lasts. (eosio::producer_plugin)
|
||||
# read-only-read-window-time-us = 60000
|
||||
|
||||
# The local IP and port to listen for incoming prometheus metrics http request. (eosio::prometheus_plugin)
|
||||
# prometheus-exporter-address = 127.0.0.1:9101
|
||||
|
||||
# Time in seconds between two consecutive checks of resource usage. Should be between 1 and 300 (eosio::resource_monitor_plugin)
|
||||
# resource-monitor-interval-seconds = 2
|
||||
|
||||
# Threshold in terms of percentage of used space vs total space. If used space is above (threshold - 5%), a warning is generated. Unless resource-monitor-not-shutdown-on-threshold-exceeded is enabled, a graceful shutdown is initiated if used space is above the threshold. The value should be between 6 and 99 (eosio::resource_monitor_plugin)
|
||||
# resource-monitor-space-threshold = 90
|
||||
|
||||
# Absolute threshold in gibibytes of remaining space; applied to each monitored directory. If remaining space is less than value for any monitored directories then threshold is considered exceeded.Overrides resource-monitor-space-threshold value. (eosio::resource_monitor_plugin)
|
||||
# resource-monitor-space-absolute-gb =
|
||||
|
||||
# Used to indicate nodeos will not shutdown when threshold is exceeded. (eosio::resource_monitor_plugin)
|
||||
# resource-monitor-not-shutdown-on-threshold-exceeded =
|
||||
|
||||
# Number of resource monitor intervals between two consecutive warnings when the threshold is hit. Should be between 1 and 450 (eosio::resource_monitor_plugin)
|
||||
# resource-monitor-warning-interval = 30
|
||||
|
||||
# Limits the maximum time (in milliseconds) that is allowed for sending requests to a keosd provider for signing (eosio::signature_provider_plugin)
|
||||
# keosd-provider-timeout = 5
|
||||
|
||||
# the location of the state-history directory (absolute path or relative to application data dir) (eosio::state_history_plugin)
|
||||
# state-history-dir = "state-history"
|
||||
|
||||
# the location of the state history retained directory (absolute path or relative to state-history dir). (eosio::state_history_plugin)
|
||||
# state-history-retained-dir =
|
||||
|
||||
# the location of the state history archive directory (absolute path or relative to state-history dir).
|
||||
# If the value is empty string, blocks files beyond the retained limit will be deleted.
|
||||
# All files in the archive directory are completely under user's control, i.e. they won't be accessed by nodeos anymore. (eosio::state_history_plugin)
|
||||
# state-history-archive-dir =
|
||||
|
||||
# split the state history log files when the block number is the multiple of the stride
|
||||
# When the stride is reached, the current history log and index will be renamed '*-history-<start num>-<end num>.log/index'
|
||||
# and a new current history log and index will be created with the most recent blocks. All files following
|
||||
# this format will be used to construct an extended history log. (eosio::state_history_plugin)
|
||||
# state-history-stride =
|
||||
|
||||
# the maximum number of history file groups to retain so that the blocks in those files can be queried.
|
||||
# When the number is reached, the oldest history file would be moved to archive dir or deleted if the archive dir is empty.
|
||||
# The retained history log files should not be manipulated by users. (eosio::state_history_plugin)
|
||||
# max-retained-history-files =
|
||||
|
||||
# enable trace history (eosio::state_history_plugin)
|
||||
# trace-history = false
|
||||
|
||||
# enable chain state history (eosio::state_history_plugin)
|
||||
# chain-state-history = false
|
||||
|
||||
# the endpoint upon which to listen for incoming connections. Caution: only expose this port to your internal network. (eosio::state_history_plugin)
|
||||
# state-history-endpoint = 127.0.0.1:8080
|
||||
|
||||
# the path (relative to data-dir) to create a unix socket upon which to listen for incoming connections. (eosio::state_history_plugin)
|
||||
# state-history-unix-socket-path =
|
||||
|
||||
# enable debug mode for trace history (eosio::state_history_plugin)
|
||||
# trace-history-debug-mode = false
|
||||
|
||||
# if set, periodically prune the state history files to store only configured number of most recent blocks (eosio::state_history_plugin)
|
||||
# state-history-log-retain-blocks =
|
||||
|
||||
# the location of the trace directory (absolute path or relative to application data dir) (eosio::trace_api_plugin)
|
||||
# trace-dir = "traces"
|
||||
|
||||
# the number of blocks each "slice" of trace data will contain on the filesystem (eosio::trace_api_plugin)
|
||||
# trace-slice-stride = 10000
|
||||
|
||||
# Number of blocks to ensure are kept past LIB for retrieval before "slice" files can be automatically removed.
|
||||
# A value of -1 indicates that automatic removal of "slice" files will be turned off. (eosio::trace_api_plugin)
|
||||
# trace-minimum-irreversible-history-blocks = -1
|
||||
|
||||
# Number of blocks to ensure are uncompressed past LIB. Compressed "slice" files are still accessible but may carry a performance loss on retrieval
|
||||
# A value of -1 indicates that automatic compression of "slice" files will be turned off. (eosio::trace_api_plugin)
|
||||
# trace-minimum-uncompressed-irreversible-history-blocks = -1
|
||||
|
||||
# ABIs used when decoding trace RPC responses.
|
||||
# There must be at least one ABI specified OR the flag trace-no-abis must be used.
|
||||
# ABIs are specified as "Key=Value" pairs in the form <account-name>=<abi-def>
|
||||
# Where <abi-def> can be:
|
||||
# an absolute path to a file containing a valid JSON-encoded ABI
|
||||
# a relative path from `data-dir` to a file containing a valid JSON-encoded ABI
|
||||
# (eosio::trace_api_plugin)
|
||||
# trace-rpc-abi =
|
||||
|
||||
# Use to indicate that the RPC responses will not use ABIs.
|
||||
# Failure to specify this option when there are no trace-rpc-abi configuations will result in an Error.
|
||||
# This option is mutually exclusive with trace-rpc-api (eosio::trace_api_plugin)
|
||||
# trace-no-abis =
|
||||
|
||||
# Plugin(s) to enable, may be specified multiple times
|
||||
# plugin =
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/* eslint-disable node/prefer-global/process */
|
||||
import path from 'node:path'
|
||||
import { config } from 'dotenv'
|
||||
|
||||
config()
|
||||
|
||||
export default [
|
||||
{
|
||||
name: 'eosio.boot',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/system/contracts/eosio.boot'),
|
||||
target: 'eosio',
|
||||
},
|
||||
{
|
||||
name: 'eosio.system',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/system/contracts/eosio.system'),
|
||||
target: 'eosio',
|
||||
},
|
||||
{
|
||||
name: 'eosio.token',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/system/contracts/eosio.token'),
|
||||
target: 'eosio.token',
|
||||
},
|
||||
{
|
||||
name: 'eosio.msig',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/system/contracts/eosio.msig'),
|
||||
target: 'eosio.msig',
|
||||
},
|
||||
{
|
||||
name: 'eosio.wrap',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/system/contracts/eosio.wrap'),
|
||||
target: 'eosio.wrap',
|
||||
},
|
||||
{
|
||||
name: 'registrator',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/registrator'),
|
||||
target: 'registrator',
|
||||
},
|
||||
{
|
||||
name: 'soviet',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/soviet'),
|
||||
target: 'soviet',
|
||||
},
|
||||
{
|
||||
name: 'marketplace',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/marketplace'),
|
||||
target: 'marketplace',
|
||||
},
|
||||
{
|
||||
name: 'draft',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/draft'),
|
||||
target: 'draft',
|
||||
},
|
||||
{
|
||||
name: 'branch',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/branch'),
|
||||
target: 'branch',
|
||||
},
|
||||
{
|
||||
name: 'gateway',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/gateway'),
|
||||
target: 'gateway',
|
||||
},
|
||||
{
|
||||
name: 'fund',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/fund'),
|
||||
target: 'fund',
|
||||
},
|
||||
{
|
||||
name: 'ledger',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/ledger'),
|
||||
target: 'ledger',
|
||||
},
|
||||
{
|
||||
name: 'test',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/test'),
|
||||
target: 'test',
|
||||
},
|
||||
{
|
||||
name: 'contributor',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/contributor'),
|
||||
target: 'contributor',
|
||||
},
|
||||
{
|
||||
name: 'capital',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/capital'),
|
||||
target: 'capital',
|
||||
},
|
||||
{
|
||||
name: 'wallet',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/wallet'),
|
||||
target: 'wallet',
|
||||
},
|
||||
{
|
||||
name: 'loan',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/loan'),
|
||||
target: 'loan',
|
||||
},
|
||||
{
|
||||
name: 'meet',
|
||||
path: path.resolve(process.cwd(), '../contracts/build/contracts/meet'),
|
||||
target: 'meet',
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"initial_timestamp": "2024-06-19T06:00:00.000",
|
||||
"initial_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
|
||||
"initial_configuration": {
|
||||
"max_block_net_usage": 1048576,
|
||||
"target_block_net_usage_pct": 1000,
|
||||
"max_transaction_net_usage": 1048575,
|
||||
"base_per_transaction_net_usage": 12,
|
||||
"net_usage_leeway": 500,
|
||||
"context_free_discount_net_usage_num": 20,
|
||||
"context_free_discount_net_usage_den": 100,
|
||||
"max_block_cpu_usage": 1000000,
|
||||
"target_block_cpu_usage_pct": 1000,
|
||||
"max_transaction_cpu_usage": 290000,
|
||||
"min_transaction_cpu_usage": 100,
|
||||
"max_transaction_lifetime": 3600,
|
||||
"deferred_trx_expiration_window": 600,
|
||||
"max_transaction_delay": 3888000,
|
||||
"max_inline_action_size": 4096,
|
||||
"max_inline_action_depth": 10,
|
||||
"max_authority_depth": 6
|
||||
},
|
||||
"initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/* eslint-disable node/prefer-global/process */
|
||||
import path from 'node:path'
|
||||
import { config } from 'dotenv'
|
||||
import contracts from './contracts'
|
||||
|
||||
config()
|
||||
|
||||
const network = {
|
||||
name: 'local',
|
||||
protocol: 'http',
|
||||
host: 'localhost',
|
||||
port: ':8888',
|
||||
}
|
||||
|
||||
// const network = {
|
||||
// name: 'local',
|
||||
// protocol: 'https',
|
||||
// host: 'test.coopenomics.world:443/api',
|
||||
// port: '',
|
||||
// }
|
||||
|
||||
export const SYMBOL = 'AXON'
|
||||
export const GOVERN_SYMBOL = 'RUB'
|
||||
export const provider = 'voskhod'
|
||||
export const provider_chairman = 'ant'
|
||||
|
||||
export const public_key = process.env.EOSIO_PUB_KEY as string
|
||||
|
||||
export const private_key = process.env.EOSIO_PRV_KEY as string
|
||||
|
||||
export default {
|
||||
network,
|
||||
default_public_key: public_key,
|
||||
system: 'eosio',
|
||||
provider,
|
||||
provider_chairman,
|
||||
private_keys: [private_key],
|
||||
emission: {
|
||||
left_border: `1000.0000 ${SYMBOL}`,
|
||||
tact_duration: 86400,
|
||||
emission_factor: 0.618,
|
||||
},
|
||||
token: {
|
||||
symbol: SYMBOL,
|
||||
govern_symbol: GOVERN_SYMBOL,
|
||||
precision: 4,
|
||||
max_supply: `1000000000.0000 ${SYMBOL}`,
|
||||
},
|
||||
powerup: {
|
||||
days: 1,
|
||||
min_powerup: `0.0001 ${SYMBOL}`,
|
||||
},
|
||||
allocations: [
|
||||
{
|
||||
to: 'eosio',
|
||||
quantity: `100000.0000 ${SYMBOL}`,
|
||||
},
|
||||
],
|
||||
accounts: [
|
||||
{
|
||||
name: 'eosio.token',
|
||||
},
|
||||
{
|
||||
name: 'eosio.bpay',
|
||||
},
|
||||
{
|
||||
name: 'eosio.vpay',
|
||||
},
|
||||
{
|
||||
name: 'eosio.msig',
|
||||
},
|
||||
{
|
||||
name: 'eosio.wrap',
|
||||
},
|
||||
{
|
||||
name: 'eosio.power',
|
||||
},
|
||||
{
|
||||
name: 'eosio.saving',
|
||||
code_permissions_to: ['eosio.saving'],
|
||||
},
|
||||
{
|
||||
name: 'registrator',
|
||||
code_permissions_to: ['registrator'],
|
||||
},
|
||||
{
|
||||
name: 'capital',
|
||||
code_permissions_to: ['capital'],
|
||||
},
|
||||
{
|
||||
name: 'loan',
|
||||
code_permissions_to: ['loan'],
|
||||
},
|
||||
{
|
||||
name: 'ledger',
|
||||
code_permissions_to: ['ledger'],
|
||||
},
|
||||
{
|
||||
name: 'test',
|
||||
code_permissions_to: ['test'],
|
||||
},
|
||||
{
|
||||
name: 'meet',
|
||||
code_permissions_to: ['meet'],
|
||||
},
|
||||
{
|
||||
name: 'wallet',
|
||||
code_permissions_to: ['wallet'],
|
||||
},
|
||||
{
|
||||
name: 'soviet',
|
||||
code_permissions_to: ['soviet'],
|
||||
},
|
||||
{
|
||||
name: 'branch',
|
||||
code_permissions_to: ['branch'],
|
||||
},
|
||||
{
|
||||
name: 'marketplace',
|
||||
code_permissions_to: ['marketplace'],
|
||||
},
|
||||
{
|
||||
name: 'draft',
|
||||
code_permissions_to: ['draft'],
|
||||
},
|
||||
{
|
||||
name: 'gateway',
|
||||
code_permissions_to: ['gateway'],
|
||||
},
|
||||
{
|
||||
name: 'fund',
|
||||
code_permissions_to: ['fund'],
|
||||
},
|
||||
{
|
||||
name: 'contributor',
|
||||
code_permissions_to: ['contributor'],
|
||||
},
|
||||
// {
|
||||
// name: provider_chairman,
|
||||
// },
|
||||
{
|
||||
name: provider,
|
||||
code_permissions_to: ['registrator'],
|
||||
},
|
||||
],
|
||||
contracts,
|
||||
features: [
|
||||
{
|
||||
name: 'ACTION_RETURN_VALUE',
|
||||
hash: 'c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071',
|
||||
},
|
||||
{
|
||||
name: 'CONFIGURABLE_WASM_LIMITS2',
|
||||
hash: 'd528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40',
|
||||
},
|
||||
{
|
||||
name: 'BLOCKCHAIN_PARAMETERS',
|
||||
hash: '5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4',
|
||||
},
|
||||
{
|
||||
name: 'GET_SENDER',
|
||||
hash: 'f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d',
|
||||
},
|
||||
{
|
||||
name: 'FORWARD_SETCODE',
|
||||
hash: '2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25',
|
||||
},
|
||||
{
|
||||
name: 'ONLY_BILL_FIRST_AUTHORIZER',
|
||||
hash: '8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405',
|
||||
},
|
||||
{
|
||||
name: 'RESTRICT_ACTION_TO_SELF',
|
||||
hash: 'ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43',
|
||||
},
|
||||
{
|
||||
name: 'DISALLOW_EMPTY_PRODUCER_SCHEDULE',
|
||||
hash: '68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428',
|
||||
},
|
||||
{
|
||||
name: 'FIX_LINKAUTH_RESTRICTION',
|
||||
hash: 'e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526',
|
||||
},
|
||||
{
|
||||
name: 'REPLACE_DEFERRED',
|
||||
hash: 'ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99',
|
||||
},
|
||||
{
|
||||
name: 'NO_DUPLICATE_DEFERRED_ID',
|
||||
hash: '4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f',
|
||||
},
|
||||
{
|
||||
name: 'ONLY_LINK_TO_EXISTING_PERMISSION',
|
||||
hash: '1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241',
|
||||
},
|
||||
{
|
||||
name: 'RAM_RESTRICTIONS',
|
||||
hash: '4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67',
|
||||
},
|
||||
{
|
||||
name: 'WEBAUTHN_KEY',
|
||||
hash: '4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2',
|
||||
},
|
||||
{
|
||||
name: 'WTMSIG_BLOCK_SIGNATURES',
|
||||
hash: '299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707',
|
||||
},
|
||||
{
|
||||
name: 'GET_CODE_HASH',
|
||||
hash: 'bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99',
|
||||
},
|
||||
{
|
||||
name: 'GET_BLOCK_NUM',
|
||||
hash: '35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b',
|
||||
},
|
||||
{
|
||||
name: 'CRYPTO_PRIMITIVES',
|
||||
hash: '6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Network } from '../types'
|
||||
|
||||
export const networks: Network[] = [
|
||||
{
|
||||
name: 'local',
|
||||
protocol: 'http',
|
||||
host: '127.0.0.1',
|
||||
port: ':8888',
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "69b064c5178e2738e144ed6caa9349a3995370d78db29e494b3126ebd9111966",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "ACTION_RETURN_VALUE"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "70787548dcea1a2c52c913a37f74ce99e6caae79110d7ca7b859936a0075b314",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "BLOCKCHAIN_PARAMETERS"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "c0cce5bcd8ea19a28d9e12eafda65ebe6d0e0177e280d4f20c7ad66dcd9e011b",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "BLS_PRIMITIVES2"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "8139e99247b87f18ef7eae99f07f00ea3adf39ed53f4d2da3f44e6aa0bfd7c62",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "CONFIGURABLE_WASM_LIMITS2"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "68d6405cb8df3de95bd834ebb408196578500a9f818ff62ccc68f60b932f7d82",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "CRYPTO_PRIMITIVES"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "440c3efaaab212c387ce967c574dc813851cf8332d041beb418dfaf55facd5a9",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "DISABLE_DEFERRED_TRXS_STAGE_1"
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [
|
||||
"fce57d2331667353a0eac6b4209b67b843a7262a848af0a49a6e2fa9f6584eb4"
|
||||
],
|
||||
"description_digest": "a857eeb932774c511a40efb30346ec01bfb7796916b54c3c69fe7e5fb70d5cba",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "DISABLE_DEFERRED_TRXS_STAGE_2"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "2853617cec3eabd41881eb48882e6fc5e81a0db917d375057864b3befbe29acd",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "DISALLOW_EMPTY_PRODUCER_SCHEDULE"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "a98241c83511dc86c857221b9372b4aa7cea3aaebc567a48604e1d3db3557050",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "FIX_LINKAUTH_RESTRICTION"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "898082c59f921d0042e581f00a59d5ceb8be6f1d9c7a45b6f07c0e26eaee0222",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "FORWARD_SETCODE"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "e5d7992006e628a38c5e6c28dd55ff5e57ea682079bf41fef9b3cced0f46b491",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "GET_BLOCK_NUM"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "d2596697fed14a0840013647b99045022ae6a885089f35a7e78da7a43ad76ed4",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "GET_CODE_HASH"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "1eab748b95a2e6f4d7cb42065bdee5566af8efddf01a55a0a8d831b823f8828a",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "GET_SENDER"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [
|
||||
"ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"
|
||||
],
|
||||
"description_digest": "45967387ee92da70171efd9fefd1ca8061b5efe6f124d269cd2468b47f1575a0",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "NO_DUPLICATE_DEFERRED_ID"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "2f1f13e291c79da5a2bbad259ed7c1f2d34f697ea460b14b565ac33b063b73e2",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "ONLY_BILL_FIRST_AUTHORIZER"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "f3c3d91c4603cde2397268bfed4e662465293aab10cd9416db0d442b8cec2949",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "ONLY_LINK_TO_EXISTING_PERMISSION"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "64fe7df32e9b86be2b296b3f81dfd527f84e82b98e363bc97e40bc7a83733310",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": false,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "PREACTIVATE_FEATURE"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "1812fdb5096fd854a4958eb9d53b43219d114de0e858ce00255bd46569ad2c68",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "RAM_RESTRICTIONS"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "9908b3f8413c8474ab2a6be149d3f4f6d0421d37886033f27d4759c47a26d944",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "REPLACE_DEFERRED"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "e71b6712188391994c78d8c722c1d42c477cf091e5601b5cf1befd05721a57f3",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "RESTRICT_ACTION_TO_SELF"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "927fdf78c51e77a899f2db938249fb1f8bb38f4e43d9c1f75b190492080cbc34",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "WEBAUTHN_KEY"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"protocol_feature_type": "builtin",
|
||||
"dependencies": [],
|
||||
"description_digest": "ab76031cad7a457f4fd5f5fca97a3f03b8a635278e0416f77dcc91eb99a48e10",
|
||||
"subjective_restrictions": {
|
||||
"earliest_allowed_activation_time": "1970-01-01T00:00:00.000",
|
||||
"preactivation_required": true,
|
||||
"enabled": true
|
||||
},
|
||||
"builtin_feature_codename": "WTMSIG_BLOCK_SIGNATURES"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { runContainer } from './run'
|
||||
|
||||
export const container = await runContainer()
|
||||
@@ -0,0 +1,34 @@
|
||||
/* eslint-disable node/prefer-global/process */
|
||||
import Blockchain from '../blockchain'
|
||||
import contracts from '../configs/contracts'
|
||||
import type { INetwork } from '../configs/networks'
|
||||
import { networks } from '../configs/networks'
|
||||
import type { Contract } from '../types'
|
||||
import { execCommand } from './exec'
|
||||
|
||||
export async function deployCommand(name: string, pre_target: string, pre_network: string): Promise<void> {
|
||||
const network: INetwork | undefined = networks.find(el => el.name === pre_network)
|
||||
|
||||
if (!network)
|
||||
throw new Error('Сеть не найдена')
|
||||
|
||||
const contract = contracts.find(el => el.name === name)
|
||||
|
||||
if (!contract)
|
||||
throw new Error('Контракт не найден')
|
||||
|
||||
let target = contract.target
|
||||
|
||||
if (pre_target)
|
||||
target = pre_target
|
||||
|
||||
const contract_for_deploy: Contract = {
|
||||
path: contract.path,
|
||||
name,
|
||||
target,
|
||||
}
|
||||
|
||||
const blockchain = new Blockchain(network, [process.env.EOSIO_PRV_KEY as string])
|
||||
await blockchain.update_pass_instance()
|
||||
await blockchain.setContract(contract_for_deploy)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { exec } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
|
||||
const execAsync = promisify(exec)
|
||||
|
||||
export async function execCommand(command: string[]): Promise<void> {
|
||||
const fullCmd = ['docker', 'compose', 'exec', 'node', ...command].join(' ')
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line node/prefer-global/process
|
||||
const { stdout, stderr } = await execAsync(fullCmd, { env: process.env })
|
||||
if (stdout)
|
||||
console.log(stdout.trim())
|
||||
if (stderr)
|
||||
console.error(stderr.trim())
|
||||
}
|
||||
catch (err: any) {
|
||||
if (err.stdout)
|
||||
console.log(err.stdout.trim())
|
||||
if (err.stderr)
|
||||
console.error(err.stderr.trim())
|
||||
// опционально:
|
||||
// console.error(`Command failed with code ${err.code}`)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import Docker from 'dockerode'
|
||||
|
||||
const docker = new Docker()
|
||||
|
||||
export async function findContainerByName(name: string) {
|
||||
const containers = await docker.listContainers({ all: true })
|
||||
const containerInfo = containers.find(c => c.Names.includes(`/${name}`))
|
||||
|
||||
if (containerInfo) {
|
||||
return docker.getContainer(containerInfo.Id)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import axios from 'axios'
|
||||
|
||||
async function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export async function checkHealth() {
|
||||
const check = async (): Promise<void> => {
|
||||
try {
|
||||
const response = await axios.post('http://127.0.0.1:8888/v1/chain/get_info')
|
||||
const result = response.data
|
||||
await sleep(1000)
|
||||
|
||||
console.log('Node is healthy. Continue.', result)
|
||||
}
|
||||
|
||||
catch (error: any) {
|
||||
console.error(error)
|
||||
console.log('Блокчейн не доступен с ошибкой. Он поднят? docker compose up -d')
|
||||
|
||||
await sleep(1000)
|
||||
|
||||
return check() // Повторный вызов функции
|
||||
}
|
||||
}
|
||||
|
||||
return check()
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { promises as fs } from 'node:fs'
|
||||
import * as path from 'node:path'
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export async function clearDB(): Promise<void> {
|
||||
// Очистка MongoDB
|
||||
// eslint-disable-next-line node/prefer-global/process
|
||||
await mongoose.connect(process.env.MONGO_URI as string)
|
||||
|
||||
try {
|
||||
await mongoose.connection.collection('users').deleteMany({})
|
||||
console.log('Все документы удалены из коллекции users')
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Ошибка при удалении:', e)
|
||||
}
|
||||
|
||||
try {
|
||||
await mongoose.connection.collection('sync').deleteMany({})
|
||||
console.log('Все документы удалены из коллекции sync')
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Ошибка при удалении:', e)
|
||||
}
|
||||
|
||||
try {
|
||||
await mongoose.connection.collection('actions').deleteMany({})
|
||||
console.log('Все документы удалены из коллекции actions')
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Ошибка при удалении:', e)
|
||||
}
|
||||
|
||||
try {
|
||||
await mongoose.connection.collection('deltas').deleteMany({})
|
||||
console.log('Все документы удалены из коллекции deltas')
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Ошибка при удалении:', e)
|
||||
}
|
||||
|
||||
// PostgreSQL будет пересоздан полностью в скрипте extra_reboot.sh
|
||||
}
|
||||
|
||||
export async function clearDirectory(dirPath: string): Promise<void> {
|
||||
try {
|
||||
const files = await fs.readdir(dirPath)
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dirPath, file)
|
||||
const stats = await fs.stat(filePath)
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
await clearDirectory(filePath)
|
||||
await fs.rmdir(filePath)
|
||||
}
|
||||
else {
|
||||
await fs.unlink(filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`Error clearing directory ${dirPath}:`, err)
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteFile(filePath: string): Promise<void> {
|
||||
try {
|
||||
await fs.unlink(filePath)
|
||||
}
|
||||
catch (err) {
|
||||
// console.error(`Error deleting file ${filePath}:`, err)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user