Обработка авторов, добавлен поиск по статьям авторов.
This commit is contained in:
parent
76b7ef5892
commit
9aef927eeb
570
package-lock.json
generated
570
package-lock.json
generated
@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.734.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.734.0",
|
||||
"@prisma/client": "^6.3.1",
|
||||
"@prisma/client": "^6.4.1",
|
||||
"axios": "^1.7.9",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cors": "^2.8.5",
|
||||
@ -37,7 +37,7 @@
|
||||
"@types/multer-s3": "^3.0.3",
|
||||
"@types/node": "^22.10.7",
|
||||
"@types/winston": "^2.4.4",
|
||||
"prisma": "^6.3.1",
|
||||
"prisma": "^6.4.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
@ -990,6 +990,431 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
|
||||
"integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz",
|
||||
"integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz",
|
||||
"integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz",
|
||||
"integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz",
|
||||
"integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz",
|
||||
"integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz",
|
||||
"integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz",
|
||||
"integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz",
|
||||
"integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz",
|
||||
"integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz",
|
||||
"integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz",
|
||||
"integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.33.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
|
||||
@ -1380,9 +1805,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/client": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.3.1.tgz",
|
||||
"integrity": "sha512-ARAJaPs+eBkemdky/XU3cvGRl+mIPHCN2lCXsl5Vlb0E2gV+R6IN7aCI8CisRGszEZondwIsW9Iz8EJkTdykyA==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.4.1.tgz",
|
||||
"integrity": "sha512-A7Mwx44+GVZVexT5e2GF/WcKkEkNNKbgr059xpr5mn+oUm2ZW1svhe+0TRNBwCdzhfIZ+q23jEgsNPvKD9u+6g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@ -1402,53 +1827,53 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/debug": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.3.1.tgz",
|
||||
"integrity": "sha512-RrEBkd+HLZx+ydfmYT0jUj7wjLiS95wfTOSQ+8FQbvb6vHh5AeKfEPt/XUQ5+Buljj8hltEfOslEW57/wQIVeA==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.4.1.tgz",
|
||||
"integrity": "sha512-Q9xk6yjEGIThjSD8zZegxd5tBRNHYd13GOIG0nLsanbTXATiPXCLyvlYEfvbR2ft6dlRsziQXfQGxAgv7zcMUA==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.3.1.tgz",
|
||||
"integrity": "sha512-sXdqEVLyGAJ5/iUoG/Ea5AdHMN71m6PzMBWRQnLmhhOejzqAaEr8rUd623ql6OJpED4s/U4vIn4dg1qkF7vGag==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.4.1.tgz",
|
||||
"integrity": "sha512-KldENzMHtKYwsOSLThghOIdXOBEsfDuGSrxAZjMnimBiDKd3AE4JQ+Kv+gBD/x77WoV9xIPf25GXMWffXZ17BA==",
|
||||
"devOptional": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.3.1",
|
||||
"@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
|
||||
"@prisma/fetch-engine": "6.3.1",
|
||||
"@prisma/get-platform": "6.3.1"
|
||||
"@prisma/debug": "6.4.1",
|
||||
"@prisma/engines-version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d",
|
||||
"@prisma/fetch-engine": "6.4.1",
|
||||
"@prisma/get-platform": "6.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/engines-version": {
|
||||
"version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0.tgz",
|
||||
"integrity": "sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA==",
|
||||
"version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d.tgz",
|
||||
"integrity": "sha512-Xq54qw55vaCGrGgIJqyDwOq0TtjZPJEWsbQAHugk99hpDf2jcEeQhUcF+yzEsSqegBaDNLA4IC8Nn34sXmkiTQ==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/fetch-engine": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.3.1.tgz",
|
||||
"integrity": "sha512-HOf/0umOgt+/S2xtZze+FHKoxpVg4YpVxROr6g2YG09VsI3Ipyb+rGvD6QGbCqkq5NTWAAZoOGNL+oy7t+IhaQ==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.4.1.tgz",
|
||||
"integrity": "sha512-uZ5hVeTmDspx7KcaRCNoXmcReOD+84nwlO2oFvQPRQh9xiFYnnUKDz7l9bLxp8t4+25CsaNlgrgilXKSQwrIGQ==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.3.1",
|
||||
"@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
|
||||
"@prisma/get-platform": "6.3.1"
|
||||
"@prisma/debug": "6.4.1",
|
||||
"@prisma/engines-version": "6.4.0-29.a9055b89e58b4b5bfb59600785423b1db3d0e75d",
|
||||
"@prisma/get-platform": "6.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/get-platform": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.3.1.tgz",
|
||||
"integrity": "sha512-AYLq6Hk9xG73JdLWJ3Ip9Wg/vlP7xPvftGBalsPzKDOHr/ImhwJ09eS8xC2vNT12DlzGxhfk8BkL0ve2OriNhQ==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.4.1.tgz",
|
||||
"integrity": "sha512-gXqZaDI5scDkBF8oza7fOD3Q3QMD0e0rBynlzDDZdTWbWmzjuW58PRZtj+jkvKje2+ZigCWkH8SsWZAsH6q1Yw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.3.1"
|
||||
"@prisma/debug": "6.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/abort-controller": {
|
||||
@ -2940,6 +3365,85 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
|
||||
"integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==",
|
||||
"devOptional": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.25.0",
|
||||
"@esbuild/android-arm": "0.25.0",
|
||||
"@esbuild/android-arm64": "0.25.0",
|
||||
"@esbuild/android-x64": "0.25.0",
|
||||
"@esbuild/darwin-arm64": "0.25.0",
|
||||
"@esbuild/darwin-x64": "0.25.0",
|
||||
"@esbuild/freebsd-arm64": "0.25.0",
|
||||
"@esbuild/freebsd-x64": "0.25.0",
|
||||
"@esbuild/linux-arm": "0.25.0",
|
||||
"@esbuild/linux-arm64": "0.25.0",
|
||||
"@esbuild/linux-ia32": "0.25.0",
|
||||
"@esbuild/linux-loong64": "0.25.0",
|
||||
"@esbuild/linux-mips64el": "0.25.0",
|
||||
"@esbuild/linux-ppc64": "0.25.0",
|
||||
"@esbuild/linux-riscv64": "0.25.0",
|
||||
"@esbuild/linux-s390x": "0.25.0",
|
||||
"@esbuild/linux-x64": "0.25.0",
|
||||
"@esbuild/netbsd-arm64": "0.25.0",
|
||||
"@esbuild/netbsd-x64": "0.25.0",
|
||||
"@esbuild/openbsd-arm64": "0.25.0",
|
||||
"@esbuild/openbsd-x64": "0.25.0",
|
||||
"@esbuild/sunos-x64": "0.25.0",
|
||||
"@esbuild/win32-arm64": "0.25.0",
|
||||
"@esbuild/win32-ia32": "0.25.0",
|
||||
"@esbuild/win32-x64": "0.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-register": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
|
||||
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"esbuild": ">=0.12 <1"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-register/node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-register/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
@ -3719,14 +4223,16 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.3.1.tgz",
|
||||
"integrity": "sha512-JKCZWvBC3enxk51tY4TWzS4b5iRt4sSU1uHn2I183giZTvonXaQonzVtjLzpOHE7qu9MxY510kAtFGJwryKe3Q==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.4.1.tgz",
|
||||
"integrity": "sha512-q2uJkgXnua/jj66mk6P9bX/zgYJFI/jn4Yp0aS6SPRrjH/n6VyOV7RDe1vHD0DX8Aanx4MvgmUPPoYnR6MJnPg==",
|
||||
"devOptional": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/engines": "6.3.1"
|
||||
"@prisma/engines": "6.4.1",
|
||||
"esbuild": ">=0.12 <1",
|
||||
"esbuild-register": "3.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"prisma": "build/index.js"
|
||||
|
@ -14,7 +14,7 @@
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.734.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.734.0",
|
||||
"@prisma/client": "^6.3.1",
|
||||
"@prisma/client": "^6.4.1",
|
||||
"axios": "^1.7.9",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cors": "^2.8.5",
|
||||
@ -40,7 +40,7 @@
|
||||
"@types/multer-s3": "^3.0.3",
|
||||
"@types/node": "^22.10.7",
|
||||
"@types/winston": "^2.4.4",
|
||||
"prisma": "^6.3.1",
|
||||
"prisma": "^6.4.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Article" ADD COLUMN "importId" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "isActive" BOOLEAN NOT NULL DEFAULT false;
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "bio" TEXT;
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "order" INTEGER NOT NULL DEFAULT 0;
|
@ -13,11 +13,13 @@ model User {
|
||||
password String
|
||||
displayName String
|
||||
avatarUrl String
|
||||
bio String?
|
||||
isAdmin Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
permissions Json
|
||||
articles Article[]
|
||||
order Int @default(0)
|
||||
}
|
||||
|
||||
model Article {
|
||||
|
@ -55,6 +55,7 @@ export async function listArticles(req: Request, res: Response) {
|
||||
articles,
|
||||
totalPages: Math.ceil(total / perPage),
|
||||
currentPage: page,
|
||||
total: total
|
||||
});
|
||||
} catch (error) {
|
||||
// Логируем ошибку и отправляем ответ с кодом 500
|
||||
|
@ -4,22 +4,26 @@ import { Prisma } from '@prisma/client';
|
||||
|
||||
export async function searchArticles(req: Request, res: Response) {
|
||||
try {
|
||||
const { q, page = 1, limit = 9 } = req.query;
|
||||
const { q, author, page = 1, limit = 9 } = req.query;
|
||||
const skip = ((Number(page) || 1) - 1) * (Number(limit) || 9);
|
||||
|
||||
// Определение where с явной обработкой q
|
||||
const where : Prisma.ArticleWhereInput =
|
||||
typeof q === 'string' && q.trim()
|
||||
? {
|
||||
OR: [
|
||||
{ title: { contains: q, mode: 'insensitive' } },
|
||||
{ excerpt: { contains: q, mode: 'insensitive' } },
|
||||
{ content: { contains: q, mode: 'insensitive' } },
|
||||
],
|
||||
}
|
||||
: {};
|
||||
// Формируем where-условие
|
||||
const where: Prisma.ArticleWhereInput = {
|
||||
...(typeof q === 'string' && q.trim()
|
||||
? {
|
||||
OR: [
|
||||
{ title: { contains: q, mode: 'insensitive' } },
|
||||
{ excerpt: { contains: q, mode: 'insensitive' } },
|
||||
{ content: { contains: q, mode: 'insensitive' } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
...(typeof author === 'string' && author.trim()
|
||||
? { authorId: author }
|
||||
: {}),
|
||||
};
|
||||
|
||||
// Выполнение запросов
|
||||
// Выполнение запроса
|
||||
const [articles, total] = await Promise.all([
|
||||
prisma.article.findMany({
|
||||
where,
|
||||
@ -47,7 +51,7 @@ export async function searchArticles(req: Request, res: Response) {
|
||||
currentPage: Number(page) || 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error during article search:', error);
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
console.error('Ошибка поиска по статьям:', error);
|
||||
res.status(500).json({ error: 'Серверная ошибка' });
|
||||
}
|
||||
}
|
||||
|
14
src/routes/authors/controllers/authors.ts
Normal file
14
src/routes/authors/controllers/authors.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Response } from 'express';
|
||||
import { AuthRequest } from '../../../middleware/auth';
|
||||
import { userService } from '../../../services/userService';
|
||||
|
||||
|
||||
// Список авторов - без permissions и без чистых админов
|
||||
export async function getAuthors(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const authors = await userService.getAuthors();
|
||||
res.json(authors);
|
||||
} catch {
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
}
|
9
src/routes/authors/index.ts
Normal file
9
src/routes/authors/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import express from 'express';
|
||||
import { getAuthors } from './controllers/authors';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
router.get('/', getAuthors);
|
||||
|
||||
export default router;
|
@ -7,46 +7,46 @@ import { prisma } from '../../../lib/prisma';
|
||||
import { getDefaultPermissions } from '../../../utils/permissions';
|
||||
|
||||
|
||||
// Список пользователей
|
||||
export async function getUsers(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
// Проверка прав администратора
|
||||
if (!req.user?.permissions.isAdmin) {
|
||||
res.status(403).json({ error: 'Admin access required' });
|
||||
res.status(403).json({ error: 'Требуются права администратора' });
|
||||
return
|
||||
}
|
||||
|
||||
// Получение списка пользователей
|
||||
const users = await userService.getUsers();
|
||||
res.json(users);
|
||||
} catch {
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
res.status(500).json({ error: 'Серверная ошибка' });
|
||||
}
|
||||
}
|
||||
|
||||
export async function createUser(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
if (!req.user?.permissions.isAdmin) {
|
||||
logger.warn(`Non-admin user ${req.user?.id} attempted to create user`);
|
||||
res.status(403).json({ error: 'Admin access required' });
|
||||
logger.warn(`Не администратор ${req.user?.id} пытается создать пользователя`);
|
||||
res.status(403).json({ error: 'Требуются права администратора' });
|
||||
return
|
||||
}
|
||||
|
||||
const { email, password, displayName, avatarUrl } = req.body;
|
||||
|
||||
// Check if user exists
|
||||
// Проверка существования пользователя
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
where: { email }
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
res.status(400).json({ error: 'User already exists' });
|
||||
res.status(400).json({ error: 'Пользователь уже существует' });
|
||||
return
|
||||
}
|
||||
|
||||
// Hash password
|
||||
// Вычисление хеша пароля
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
// Create user with default permissions
|
||||
// Создание пользователя с правами по умолчанию
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
@ -64,48 +64,49 @@ export async function createUser(req: AuthRequest, res: Response): Promise<void>
|
||||
}
|
||||
});
|
||||
|
||||
logger.info(`User created successfully: ${user.id}`);
|
||||
logger.info(`Успашное создание пользователя: ${user.id}`);
|
||||
res.status(201).json(user);
|
||||
} catch (error) {
|
||||
logger.error('Error creating user:', error);
|
||||
res.status(500).json({ error: 'Failed to create user' });
|
||||
logger.error('Ошибка создания пользователя:', error);
|
||||
res.status(500).json({ error: 'Ошибка создания пользователя' });
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateUser(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
if (!req.user?.permissions.isAdmin) {
|
||||
logger.warn(`Non-admin user ${req.user?.id} attempted to update user`);
|
||||
res.status(403).json({ error: 'Admin access required' });
|
||||
logger.warn(`Не администратор ${req.user?.id} пытается обновить пользователя`);
|
||||
res.status(403).json({ error: 'Требуются права администратора' });
|
||||
return
|
||||
}
|
||||
|
||||
const { id } = req.params;
|
||||
const { email, password, displayName, avatarUrl } = req.body;
|
||||
const { email, password, displayName, bio, avatarUrl } = req.body;
|
||||
|
||||
// Check if user exists
|
||||
// Проверка существования пользователя
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
where: { id }
|
||||
});
|
||||
|
||||
if (!existingUser) {
|
||||
res.status(404).json({ error: 'User not found' });
|
||||
res.status(404).json({ error: 'Пользователь не найден' });
|
||||
return
|
||||
}
|
||||
|
||||
// Prepare update data
|
||||
// Подготовка данных для изменения
|
||||
const updateData: any = {
|
||||
email,
|
||||
displayName,
|
||||
bio,
|
||||
avatarUrl
|
||||
};
|
||||
|
||||
// Only update password if provided
|
||||
// Если требуется сменить пароль
|
||||
if (password) {
|
||||
updateData.password = await bcrypt.hash(password, 10);
|
||||
}
|
||||
|
||||
// Update user
|
||||
// Обновление данных пользователя
|
||||
const user = await prisma.user.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
@ -113,24 +114,26 @@ export async function updateUser(req: AuthRequest, res: Response): Promise<void>
|
||||
id: true,
|
||||
email: true,
|
||||
displayName: true,
|
||||
bio: true,
|
||||
avatarUrl: true,
|
||||
permissions: true
|
||||
}
|
||||
});
|
||||
|
||||
logger.info(`User updated successfully: ${user.id}`);
|
||||
logger.info(`Успешное обновление пользователя: ${user.id}`);
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
logger.error('Error updating user:', error);
|
||||
res.status(500).json({ error: 'Failed to update user' });
|
||||
logger.error('Ошибка обновления пользователя:', error);
|
||||
res.status(500).json({ error: 'Ошибка обновления пользователя' });
|
||||
}
|
||||
}
|
||||
|
||||
// Обновление прав пользователя
|
||||
export async function updateUserPermissions(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
// Проверка прав администратора
|
||||
if (!req.user?.permissions.isAdmin) {
|
||||
res.status(403).json({ error: 'Admin access required' });
|
||||
res.status(403).json({ error: 'Требуются права администратора' });
|
||||
return
|
||||
}
|
||||
|
||||
@ -142,15 +145,16 @@ export async function updateUserPermissions(req: AuthRequest, res: Response): Pr
|
||||
const user = await userService.updateUserPermissions(id, permissions);
|
||||
res.json(user);
|
||||
} catch {
|
||||
res.status(500).json({ error: 'Server error' });
|
||||
res.status(500).json({ error: 'Серверная ошибка' });
|
||||
}
|
||||
}
|
||||
|
||||
// Удаление пользователя
|
||||
export async function deleteUser(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
if (!req.user?.permissions.isAdmin) {
|
||||
logger.warn(`Non-admin user ${req.user?.id} attempted to delete user`);
|
||||
res.status(403).json({ error: 'Admin access required' });
|
||||
logger.warn(`Не администратор ${req.user?.id} пытается удалить пользователя`);
|
||||
res.status(403).json({ error: 'Требуются права администратора' });
|
||||
return
|
||||
}
|
||||
|
||||
@ -162,7 +166,7 @@ export async function deleteUser(req: AuthRequest, res: Response): Promise<void>
|
||||
});
|
||||
|
||||
if (!existingUser) {
|
||||
res.status(404).json({ error: 'User not found' });
|
||||
res.status(404).json({ error: 'Пользователь не найден' });
|
||||
return
|
||||
}
|
||||
|
||||
@ -171,10 +175,10 @@ export async function deleteUser(req: AuthRequest, res: Response): Promise<void>
|
||||
where: { id }
|
||||
});
|
||||
|
||||
logger.info(`User deleted successfully: ${id}`);
|
||||
res.json({ message: 'User deleted successfully' });
|
||||
logger.info(`Успешное удаление пользователя: ${id}`);
|
||||
res.json({ message: 'Успешное удаление пользователя' });
|
||||
} catch (error) {
|
||||
logger.error('Error deleting user:', error);
|
||||
res.status(500).json({ error: 'Failed to delete user' });
|
||||
logger.error('Ошибка удаления пользователя:', error);
|
||||
res.status(500).json({ error: 'Ошибка удаления пользователя' });
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import {
|
||||
createUser,
|
||||
updateUser,
|
||||
updateUserPermissions,
|
||||
deleteUser
|
||||
deleteUser,
|
||||
} from './controllers/users';
|
||||
|
||||
const router = express.Router();
|
||||
|
@ -10,6 +10,7 @@ import userRoutes from './routes/users/index';
|
||||
import articleRoutes from './routes/articles/index';
|
||||
import galleryRoutes from './routes/gallery/index';
|
||||
import imagesRoutes from './routes/images/index';
|
||||
import authorRoutes from './routes/authors/index';
|
||||
|
||||
|
||||
const app = express();
|
||||
@ -33,6 +34,7 @@ app.use(errorLogger);
|
||||
// Маршруты
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/users', userRoutes);
|
||||
app.use('/api/authors', authorRoutes);
|
||||
app.use('/api/articles', articleRoutes);
|
||||
app.use('/api/gallery', galleryRoutes);
|
||||
app.use('/api/images', imagesRoutes);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { User, UserPermissions } from '../types/auth';
|
||||
import { Author, User, UserPermissions } from '../types/auth';
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
@ -12,6 +12,7 @@ export const userService = {
|
||||
email: string;
|
||||
displayName: string;
|
||||
avatarUrl: string;
|
||||
bio: string | null;
|
||||
permissions: JsonValue;
|
||||
}> = await prisma.user.findMany({
|
||||
select: {
|
||||
@ -19,6 +20,7 @@ export const userService = {
|
||||
email: true,
|
||||
displayName: true,
|
||||
avatarUrl: true,
|
||||
bio: true,
|
||||
permissions: true,
|
||||
},
|
||||
});
|
||||
@ -40,6 +42,40 @@ export const userService = {
|
||||
throw new Error('Failed to fetch users');
|
||||
}
|
||||
},
|
||||
|
||||
getAuthors: async (): Promise<Author[]> => {
|
||||
try {
|
||||
const authors = await prisma.user.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
displayName: true,
|
||||
avatarUrl: true,
|
||||
bio: true,
|
||||
_count: {
|
||||
select: { articles: true }, // Подсчёт количества статей автора
|
||||
},
|
||||
},
|
||||
where: { order: { not: 0 } },
|
||||
orderBy: {
|
||||
order: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
return authors.map(author => ({
|
||||
id: author.id,
|
||||
email: author.email,
|
||||
displayName: author.displayName,
|
||||
avatarUrl: author.avatarUrl,
|
||||
bio: author.bio,
|
||||
articlesCount: author._count.articles, // Количество статей
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('Ошибка получения авторов:', error);
|
||||
throw new Error('Ошибка получения авторов');
|
||||
}
|
||||
},
|
||||
|
||||
updateUserPermissions: async (
|
||||
userId: string,
|
||||
permissions: User['permissions']
|
||||
|
@ -13,5 +13,15 @@ export interface User {
|
||||
email: string;
|
||||
displayName: string;
|
||||
avatarUrl: string;
|
||||
bio: string;
|
||||
permissions: UserPermissions;
|
||||
}
|
||||
|
||||
export interface Author {
|
||||
id: string;
|
||||
email: string;
|
||||
displayName: string;
|
||||
avatarUrl: string;
|
||||
articlesCount: number;
|
||||
bio: string | null;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user