@allbluecn/admin-app 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +19 -17
- package/src/components/admin/admin-user-menu.tsx +4 -4
- package/src/components/admin/developer-log.tsx +16 -32
- package/src/components/ai-memory/memory-facts-panel.tsx +30 -70
- package/src/components/ai-prompts/preview-panel.tsx +1 -1
- package/src/components/ai-prompts/prompt-editor.tsx +8 -9
- package/src/components/ai-prompts/prompt-table.tsx +6 -6
- package/src/components/ai-prompts/section-editor.tsx +3 -3
- package/src/components/ai-prompts/variable-panel.tsx +2 -2
- package/src/components/ai-prompts/version-history.tsx +21 -41
- package/src/components/ai-provider/model-list-editor.tsx +2 -3
- package/src/components/ai-provider/provider-form.tsx +7 -7
- package/src/components/ai-provider/provider-table.tsx +17 -40
- package/src/components/auth/admin-login-form.tsx +7 -7
- package/src/components/auth/icon-input.tsx +2 -2
- package/src/components/auth/password-input.tsx +2 -2
- package/src/components/component/component-form-dialog.tsx +10 -18
- package/src/components/component/component-import-dialog.tsx +6 -6
- package/src/components/component/component-preview.tsx +311 -0
- package/src/components/component/component-table.tsx +3 -3
- package/src/components/dependency/changelog-dialog.tsx +2 -2
- package/src/components/dependency/columns.tsx +3 -3
- package/src/components/dependency/dependency-table.tsx +7 -7
- package/src/components/dependency/edit-dialog.tsx +8 -8
- package/src/components/invitations/invitations-page.tsx +26 -49
- package/src/components/knowledge-public/bookmark-form-dialog.tsx +6 -6
- package/src/components/knowledge-public/compliance-form-dialog.tsx +6 -6
- package/src/components/knowledge-public/legal-form-dialog.tsx +7 -7
- package/src/components/layout/sidebar-02/app-sidebar.tsx +1 -2
- package/src/components/layout/sidebar-02/index.tsx +1 -1
- package/src/components/layout/sidebar-02/nav-main.tsx +2 -3
- package/src/components/layout/sidebar-02/nav-notifications.tsx +3 -3
- package/src/components/market/columns.tsx +4 -4
- package/src/components/market/market-app-form.tsx +6 -7
- package/src/components/market/market-app-list.tsx +14 -29
- package/src/components/monitoring/error-list.tsx +2 -2
- package/src/components/monitoring/metrics-stats.tsx +1 -1
- package/src/components/monitoring/request-log-table.tsx +2 -2
- package/src/components/oauth-providers/provider-page.tsx +20 -38
- package/src/components/permissions/assign-dialog.tsx +135 -0
- package/src/components/permissions/create-role-dialog.tsx +135 -0
- package/src/components/permissions/types.ts +49 -0
- package/src/components/user/columns.tsx +6 -6
- package/src/components/user/settings-activity-log.tsx +7 -7
- package/src/components/user/settings-profile/avatar-uploader.tsx +118 -0
- package/src/components/user/settings-profile/social-links.tsx +63 -0
- package/src/components/user/settings-profile.tsx +26 -125
- package/src/components/user/user-create-dialog.tsx +6 -6
- package/src/components/user/user-detail/error-boundary.tsx +19 -0
- package/src/components/user/user-detail/user-detail-dialogs.tsx +203 -0
- package/src/components/user/user-filters.tsx +4 -4
- package/src/lib/auth/page-gate.ts +28 -0
- package/src/lib/auth.config.ts +25 -9
- package/src/lib/i18n/detect.ts +1 -1
- package/src/lib/loader-serial.ts +14 -0
- package/src/providers/index.tsx +1 -1
- package/src/routeTree.gen.ts +67 -78
- package/src/routes/__root.tsx +4 -4
- package/src/routes/_nav/audit/route.lazy.tsx +1 -2
- package/src/routes/_nav/compliance/route.lazy.tsx +5 -3
- package/src/routes/_nav/components/route.lazy.tsx +14 -34
- package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +18 -38
- package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +18 -38
- package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +6 -6
- package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +3 -3
- package/src/routes/_nav/licenses/new/route.lazy.tsx +5 -5
- package/src/routes/_nav/licenses/route.lazy.tsx +1 -1
- package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +2 -2
- package/src/routes/_nav/monitoring/errors/route.lazy.tsx +10 -10
- package/src/routes/_nav/monitoring/errors/route.tsx +7 -0
- package/src/routes/_nav/monitoring/health/route.lazy.tsx +13 -15
- package/src/routes/_nav/monitoring/health/route.tsx +14 -0
- package/src/routes/_nav/monitoring/logs/route.lazy.tsx +24 -9
- package/src/routes/_nav/monitoring/logs/route.tsx +13 -0
- package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +12 -14
- package/src/routes/_nav/monitoring/metrics/route.tsx +7 -0
- package/src/routes/_nav/monitoring/overview/route.lazy.tsx +14 -13
- package/src/routes/_nav/monitoring/overview/route.tsx +17 -0
- package/src/routes/_nav/monitoring/route.lazy.tsx +6 -6
- package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +2 -2
- package/src/routes/_nav/permissions/route.lazy.tsx +21 -311
- package/src/routes/_nav/permissions/route.tsx +1 -1
- package/src/routes/_nav/route.tsx +5 -13
- package/src/routes/_nav/sso/route.lazy.tsx +2 -3
- package/src/routes/_nav/users/$userId/route.lazy.tsx +91 -156
- package/src/routes/_nav/users/-components/users-table.tsx +1 -1
- package/src/routes/_nav/users/route.lazy.tsx +1 -1
- package/src/routes/login/route.lazy.tsx +1 -1
- package/src/routes/setup/route.lazy.tsx +2 -2
- package/src/server/__tests__/admin-billing.test.ts +191 -16
- package/src/server/__tests__/compliance.test.ts +44 -7
- package/src/server/__tests__/permissions.test.ts +10 -5
- package/src/server/__tests__/prompt-defaults.test.ts +3 -3
- package/src/server/admin-ai-alerts.ts +2 -1
- package/src/server/admin-ai-usage.ts +2 -1
- package/src/server/ai-memory/store.ts +6 -2
- package/src/server/{serverFns/ai-prompts → ai-prompts}/prompt-defaults.ts +5 -3
- package/src/server/{serverFns/dependency → dependency}/helpers.ts +4 -3
- package/src/server/knowledge-public/github-sync.ts +2 -1
- package/src/server/license-issue.ts +2 -1
- package/src/server/middlewares/auth-rate-limit.ts +117 -0
- package/src/server/observability/health-check.ts +4 -1
- package/src/server/observability/metrics.ts +17 -15
- package/src/server/observability/request-middleware.ts +2 -1
- package/src/server/observability/timing.ts +14 -16
- package/src/server/serverFns/admin-billing.ts +107 -12
- package/src/server/serverFns/ai-memory/list-users.ts +2 -1
- package/src/server/serverFns/ai-prompts/activate.ts +2 -1
- package/src/server/serverFns/ai-prompts/get.ts +3 -2
- package/src/server/serverFns/ai-prompts/list.ts +3 -2
- package/src/server/serverFns/ai-prompts/rollback.ts +3 -1
- package/src/server/serverFns/ai-prompts/save.ts +5 -3
- package/src/server/serverFns/ai-provider/create.ts +4 -1
- package/src/server/serverFns/ai-provider/delete.ts +4 -1
- package/src/server/serverFns/ai-provider/get.ts +4 -1
- package/src/server/serverFns/ai-provider/list.ts +28 -1
- package/src/server/serverFns/ai-provider/seed-from-seed.ts +2 -1
- package/src/server/serverFns/ai-provider/update.ts +4 -1
- package/src/server/serverFns/anyhub/market.ts +8 -1
- package/src/server/serverFns/audit.ts +14 -1
- package/src/server/serverFns/auth/setup.ts +3 -1
- package/src/server/serverFns/compliance.ts +32 -3
- package/src/server/serverFns/components/import.ts +69 -14
- package/src/server/serverFns/components/list.ts +4 -1
- package/src/server/serverFns/components/mutations.ts +9 -1
- package/src/server/serverFns/dependency/list.ts +28 -5
- package/src/server/serverFns/dependency/sync.ts +7 -2
- package/src/server/serverFns/dependency/update.ts +4 -1
- package/src/server/serverFns/developer-log-auto-generate.ts +63 -32
- package/src/server/serverFns/developer-logs.ts +5 -1
- package/src/server/serverFns/invitations.ts +7 -1
- package/src/server/serverFns/knowledge-public/bookmarks/create.ts +2 -1
- package/src/server/serverFns/knowledge-public/bookmarks/delete.ts +2 -1
- package/src/server/serverFns/knowledge-public/bookmarks/detail.ts +2 -1
- package/src/server/serverFns/knowledge-public/bookmarks/list.ts +2 -1
- package/src/server/serverFns/knowledge-public/bookmarks/sync-all-github.ts +2 -1
- package/src/server/serverFns/knowledge-public/bookmarks/update.ts +2 -1
- package/src/server/serverFns/knowledge-public/compliance/create.ts +2 -1
- package/src/server/serverFns/knowledge-public/compliance/delete.ts +2 -1
- package/src/server/serverFns/knowledge-public/compliance/detail.ts +2 -1
- package/src/server/serverFns/knowledge-public/compliance/list.ts +2 -1
- package/src/server/serverFns/knowledge-public/compliance/update.ts +2 -1
- package/src/server/serverFns/knowledge-public/legal/create.ts +2 -1
- package/src/server/serverFns/knowledge-public/legal/delete.ts +2 -1
- package/src/server/serverFns/knowledge-public/legal/detail.ts +2 -1
- package/src/server/serverFns/knowledge-public/legal/list.ts +2 -1
- package/src/server/serverFns/knowledge-public/legal/update.ts +2 -1
- package/src/server/serverFns/licenses.ts +8 -2
- package/src/server/serverFns/monitoring/get-errors.ts +2 -1
- package/src/server/serverFns/monitoring/get-health.ts +2 -1
- package/src/server/serverFns/monitoring/get-metrics.ts +2 -1
- package/src/server/serverFns/monitoring/get-request-logs.ts +2 -1
- package/src/server/serverFns/monitoring/report-error.ts +2 -1
- package/src/server/serverFns/monitoring/reset.ts +2 -1
- package/src/server/serverFns/oauth-providers.ts +4 -1
- package/src/server/serverFns/permissions.ts +18 -11
- package/src/server/serverFns/sentry/config.ts +11 -8
- package/src/server/serverFns/sso-config.ts +17 -2
- package/src/server/serverFns/user/create.ts +6 -1
- package/src/server/serverFns/user/delete.ts +6 -1
- package/src/server/serverFns/user/detail.ts +5 -2
- package/src/server/serverFns/user/list.ts +19 -4
- package/src/server/serverFns/user/reset-password.ts +10 -2
- package/src/server/serverFns/user/update-role.ts +10 -2
- package/src/server/serverFns/user/update-status.ts +10 -2
- package/src/styles/globals.css +4 -0
- package/src/components/data-table/data-table-pagination.tsx +0 -112
- package/src/components/data-table/data-table.tsx +0 -218
- package/src/components/data-table/table-detail-layout.tsx +0 -98
- package/src/components/ui/alert-dialog.tsx +0 -187
- package/src/components/ui/alert.tsx +0 -75
- package/src/components/ui/avatar.tsx +0 -106
- package/src/components/ui/badge.tsx +0 -51
- package/src/components/ui/button.tsx +0 -57
- package/src/components/ui/card.tsx +0 -102
- package/src/components/ui/checkbox.tsx +0 -28
- package/src/components/ui/collapsible.tsx +0 -19
- package/src/components/ui/dialog.tsx +0 -155
- package/src/components/ui/dropdown-menu.tsx +0 -267
- package/src/components/ui/field.tsx +0 -236
- package/src/components/ui/input-group.tsx +0 -158
- package/src/components/ui/input.tsx +0 -19
- package/src/components/ui/label.tsx +0 -17
- package/src/components/ui/pagination.tsx +0 -130
- package/src/components/ui/select.tsx +0 -234
- package/src/components/ui/separator.tsx +0 -22
- package/src/components/ui/sheet.tsx +0 -135
- package/src/components/ui/sidebar.tsx +0 -721
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/switch.tsx +0 -29
- package/src/components/ui/table.tsx +0 -115
- package/src/components/ui/textarea.tsx +0 -17
- package/src/components/ui/toast.tsx +0 -282
- package/src/components/ui/tooltip.tsx +0 -63
- package/src/hooks/use-mobile.ts +0 -19
- package/src/lib/avatar.ts +0 -41
- /package/src/routes/{api.auth.$.ts → api/auth/$.ts} +0 -0
- /package/src/routes/{api.sentry-test.ts → api/sentry-test.ts} +0 -0
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { complianceCanonicalId } from '@/server/knowledge-public/canonical-id'
|
|
23
23
|
|
|
@@ -37,6 +37,7 @@ const createSchema = z.object({
|
|
|
37
37
|
export const adminCreateComplianceFn = createServerFn({ method: 'POST' })
|
|
38
38
|
.validator(createSchema)
|
|
39
39
|
.handler(async ({ data }) => {
|
|
40
|
+
const prisma = await getPrisma()
|
|
40
41
|
const session = await requireAdmin()
|
|
41
42
|
return prisma.industryCompliance.create({
|
|
42
43
|
data: {
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
export const adminDeleteComplianceFn = createServerFn({ method: 'POST' })
|
|
24
24
|
.validator(z.object({ id: z.string() }))
|
|
25
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
26
27
|
await requireAdmin()
|
|
27
28
|
const existing = await prisma.industryCompliance.findUnique({ where: { id: data.id } })
|
|
28
29
|
if (!existing) throw new Error('未找到')
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
export const adminGetComplianceDetailFn = createServerFn({ method: 'GET' })
|
|
24
24
|
.validator(z.object({ id: z.string() }))
|
|
25
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
26
27
|
await requireAdmin()
|
|
27
28
|
const item = await prisma.industryCompliance.findFirst({
|
|
28
29
|
where: { id: data.id, visibility: 'public', isDeleted: false },
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
const listSchema = z.object({
|
|
@@ -31,6 +31,7 @@ const listSchema = z.object({
|
|
|
31
31
|
export const adminListComplianceFn = createServerFn({ method: 'GET' })
|
|
32
32
|
.validator(listSchema)
|
|
33
33
|
.handler(async ({ data }) => {
|
|
34
|
+
const prisma = await getPrisma()
|
|
34
35
|
await requireAdmin()
|
|
35
36
|
const where: any = { visibility: 'public', isDeleted: false }
|
|
36
37
|
if (data.search) {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { complianceCanonicalId } from '@/server/knowledge-public/canonical-id'
|
|
23
23
|
|
|
@@ -38,6 +38,7 @@ const updateSchema = z.object({
|
|
|
38
38
|
export const adminUpdateComplianceFn = createServerFn({ method: 'POST' })
|
|
39
39
|
.validator(updateSchema)
|
|
40
40
|
.handler(async ({ data }) => {
|
|
41
|
+
const prisma = await getPrisma()
|
|
41
42
|
await requireAdmin()
|
|
42
43
|
const { id, code, ...rest } = data
|
|
43
44
|
const existing = await prisma.industryCompliance.findUnique({ where: { id } })
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { legalCanonicalId } from '@/server/knowledge-public/canonical-id'
|
|
23
23
|
|
|
@@ -39,6 +39,7 @@ const createSchema = z.object({
|
|
|
39
39
|
export const adminCreateLegalFn = createServerFn({ method: 'POST' })
|
|
40
40
|
.validator(createSchema)
|
|
41
41
|
.handler(async ({ data }) => {
|
|
42
|
+
const prisma = await getPrisma()
|
|
42
43
|
const session = await requireAdmin()
|
|
43
44
|
return prisma.legalRegulation.create({
|
|
44
45
|
data: {
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
export const adminDeleteLegalFn = createServerFn({ method: 'POST' })
|
|
24
24
|
.validator(z.object({ id: z.string() }))
|
|
25
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
26
27
|
await requireAdmin()
|
|
27
28
|
const existing = await prisma.legalRegulation.findUnique({ where: { id: data.id } })
|
|
28
29
|
if (!existing) throw new Error('未找到')
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
export const adminGetLegalDetailFn = createServerFn({ method: 'GET' })
|
|
24
24
|
.validator(z.object({ id: z.string() }))
|
|
25
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
26
27
|
await requireAdmin()
|
|
27
28
|
const item = await prisma.legalRegulation.findFirst({
|
|
28
29
|
where: { id: data.id, visibility: 'public', isDeleted: false },
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
|
|
23
23
|
const listSchema = z.object({
|
|
@@ -31,6 +31,7 @@ const listSchema = z.object({
|
|
|
31
31
|
export const adminListLegalFn = createServerFn({ method: 'GET' })
|
|
32
32
|
.validator(listSchema)
|
|
33
33
|
.handler(async ({ data }) => {
|
|
34
|
+
const prisma = await getPrisma()
|
|
34
35
|
await requireAdmin()
|
|
35
36
|
const where: any = { visibility: 'public', isDeleted: false }
|
|
36
37
|
if (data.search) {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { legalCanonicalId } from '@/server/knowledge-public/canonical-id'
|
|
23
23
|
|
|
@@ -40,6 +40,7 @@ const updateSchema = z.object({
|
|
|
40
40
|
export const adminUpdateLegalFn = createServerFn({ method: 'POST' })
|
|
41
41
|
.validator(updateSchema)
|
|
42
42
|
.handler(async ({ data }) => {
|
|
43
|
+
const prisma = await getPrisma()
|
|
43
44
|
await requireAdmin()
|
|
44
45
|
const { id, code, ...rest } = data
|
|
45
46
|
const existing = await prisma.legalRegulation.findUnique({ where: { id } })
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { issueLicense } from '@/server/license-issue'
|
|
23
23
|
|
|
@@ -30,6 +30,7 @@ const listSchema = z.object({
|
|
|
30
30
|
export const listLicensesFn = createServerFn({ method: 'GET' })
|
|
31
31
|
.validator(listSchema)
|
|
32
32
|
.handler(async ({ data }) => {
|
|
33
|
+
const prisma = await getPrisma()
|
|
33
34
|
await requireAdmin()
|
|
34
35
|
const where: any = data.search
|
|
35
36
|
? {
|
|
@@ -57,6 +58,7 @@ export const listLicensesFn = createServerFn({ method: 'GET' })
|
|
|
57
58
|
export const getLicenseDetailFn = createServerFn({ method: 'GET' })
|
|
58
59
|
.validator(z.object({ licenseId: z.string() }))
|
|
59
60
|
.handler(async ({ data }) => {
|
|
61
|
+
const prisma = await getPrisma()
|
|
60
62
|
await requireAdmin()
|
|
61
63
|
const license = await prisma.licenseKey.findUnique({
|
|
62
64
|
where: { id: data.licenseId },
|
|
@@ -69,6 +71,7 @@ export const getLicenseDetailFn = createServerFn({ method: 'GET' })
|
|
|
69
71
|
export const revokeLicenseFn = createServerFn({ method: 'POST' })
|
|
70
72
|
.validator(z.object({ licenseId: z.string() }))
|
|
71
73
|
.handler(async ({ data }) => {
|
|
74
|
+
const prisma = await getPrisma()
|
|
72
75
|
await requireAdmin()
|
|
73
76
|
await prisma.licenseKey.update({
|
|
74
77
|
where: { id: data.licenseId },
|
|
@@ -89,4 +92,7 @@ export const issueLicenseFn = createServerFn({ method: 'POST' })
|
|
|
89
92
|
expiresAt: z.string().datetime().nullable(),
|
|
90
93
|
}),
|
|
91
94
|
)
|
|
92
|
-
.handler(async ({ data }) =>
|
|
95
|
+
.handler(async ({ data }) => {
|
|
96
|
+
await requireAdmin()
|
|
97
|
+
return issueLicense(data)
|
|
98
|
+
})
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
20
20
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
21
|
|
|
22
22
|
export const getErrors = createServerFn({ method: 'GET' })
|
|
23
23
|
.handler(async () => {
|
|
24
|
+
const prisma = await getPrisma()
|
|
24
25
|
await requireAdmin()
|
|
25
26
|
|
|
26
27
|
const errors = await prisma.monitoringErrorReport.findMany({
|
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
20
20
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
21
|
import { performHealthCheck } from '@/server/observability'
|
|
22
22
|
|
|
23
23
|
export const getHealthStatus = createServerFn({ method: 'GET' })
|
|
24
24
|
.handler(async () => {
|
|
25
|
+
const prisma = await getPrisma()
|
|
25
26
|
await requireAdmin()
|
|
26
27
|
|
|
27
28
|
const current = await performHealthCheck()
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
20
20
|
import { metrics } from '@/server/observability'
|
|
21
|
-
import {
|
|
21
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
|
|
23
23
|
export const getMetrics = createServerFn({ method: 'GET' })
|
|
24
24
|
.handler(async () => {
|
|
25
|
+
const prisma = await getPrisma()
|
|
25
26
|
await requireAdmin()
|
|
26
27
|
|
|
27
28
|
const memory = process.memoryUsage()
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
20
20
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
21
|
|
|
22
22
|
type GetRequestLogsInput = {
|
|
@@ -37,6 +37,7 @@ const MONITORING_PREFIXES = [
|
|
|
37
37
|
export const getRequestLogs = createServerFn({ method: 'GET' })
|
|
38
38
|
.validator((data: GetRequestLogsInput) => data)
|
|
39
39
|
.handler(async ({ data }) => {
|
|
40
|
+
const prisma = await getPrisma()
|
|
40
41
|
await requireAdmin()
|
|
41
42
|
|
|
42
43
|
const where: any = {}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
20
20
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
21
|
|
|
22
22
|
type ReportErrorInput = {
|
|
@@ -30,6 +30,7 @@ type ReportErrorInput = {
|
|
|
30
30
|
export const reportClientError = createServerFn({ method: 'POST' })
|
|
31
31
|
.validator((data: ReportErrorInput) => data)
|
|
32
32
|
.handler(async ({ data }) => {
|
|
33
|
+
const prisma = await getPrisma()
|
|
33
34
|
await requireAdmin()
|
|
34
35
|
|
|
35
36
|
const key = `${data.errorName}:${data.errorMessage}`
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
20
20
|
import { metrics, resetErrors } from '@/server/observability'
|
|
21
|
-
import {
|
|
21
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
22
22
|
|
|
23
23
|
type ResetInput = {
|
|
24
24
|
type: 'errors' | 'metrics' | 'request-logs' | 'health' | 'all'
|
|
@@ -28,6 +28,7 @@ type ResetInput = {
|
|
|
28
28
|
export const resetMonitoring = createServerFn({ method: 'POST' })
|
|
29
29
|
.validator((data: ResetInput) => data)
|
|
30
30
|
.handler(async ({ data }) => {
|
|
31
|
+
const prisma = await getPrisma()
|
|
31
32
|
await requireAdmin()
|
|
32
33
|
|
|
33
34
|
const cutoff = data.days ? new Date(Date.now() - data.days * 86400000) : null
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// oauth-config 60s 缓存最长延迟 60s 生效(TTL 自然过期,符合 plan2 spec),无跨进程失效通道。
|
|
6
6
|
import { createServerFn } from '@tanstack/react-start'
|
|
7
7
|
import { z } from 'zod'
|
|
8
|
-
import {
|
|
8
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
9
9
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
10
10
|
import { decryptSecret, encryptSecret } from '@allbluecn/kernel/crypto'
|
|
11
11
|
|
|
@@ -30,6 +30,7 @@ function hasGoogleEnvFallback(): boolean {
|
|
|
30
30
|
export const listOAuthProvidersFn = createServerFn({ method: 'GET' })
|
|
31
31
|
.validator(z.object({}))
|
|
32
32
|
.handler(async (): Promise<{ providers: OAuthProviderView[] }> => {
|
|
33
|
+
const prisma = await getPrisma()
|
|
33
34
|
await requireAdmin()
|
|
34
35
|
const row = await prisma.oAuthProviderConfig.findUnique({
|
|
35
36
|
where: { provider: PROVIDER_KEY },
|
|
@@ -69,6 +70,7 @@ export const saveOAuthProviderFn = createServerFn({ method: 'POST' })
|
|
|
69
70
|
}),
|
|
70
71
|
)
|
|
71
72
|
.handler(async ({ data }) => {
|
|
73
|
+
const prisma = await getPrisma()
|
|
72
74
|
await requireAdmin()
|
|
73
75
|
const hasSecret = Boolean(data.clientSecret && data.clientSecret.length > 0)
|
|
74
76
|
if (!hasSecret) {
|
|
@@ -148,6 +150,7 @@ export const testOAuthProviderFn = createServerFn({ method: 'POST' })
|
|
|
148
150
|
export const deleteOAuthProviderFn = createServerFn({ method: 'POST' })
|
|
149
151
|
.validator(z.object({ provider: z.literal('google') }))
|
|
150
152
|
.handler(async ({ data }) => {
|
|
153
|
+
const prisma = await getPrisma()
|
|
151
154
|
await requireAdmin()
|
|
152
155
|
try {
|
|
153
156
|
await prisma.oAuthProviderConfig.delete({ where: { provider: data.provider } })
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createServerFn } from '@tanstack/react-start'
|
|
2
2
|
import { z } from 'zod'
|
|
3
|
-
import {
|
|
3
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
4
4
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
5
5
|
import { requireFeature } from '@/server/entitlements'
|
|
6
6
|
import { getProService } from '@/server/pro-services'
|
|
@@ -98,6 +98,7 @@ function buildSystemRolePresets(): SystemRolePreset[] {
|
|
|
98
98
|
export const listRolesFn = createServerFn({ method: 'GET' })
|
|
99
99
|
.validator(z.object({ workspaceId: z.string() }))
|
|
100
100
|
.handler(async ({ data }) => {
|
|
101
|
+
const prisma = await getPrisma()
|
|
101
102
|
await requireAdmin()
|
|
102
103
|
await requireFeature(undefined, 'advancedPermissions')
|
|
103
104
|
|
|
@@ -106,16 +107,16 @@ export const listRolesFn = createServerFn({ method: 'GET' })
|
|
|
106
107
|
})
|
|
107
108
|
if (systemCount === 0 && getProService('permissions')) {
|
|
108
109
|
const presets = buildSystemRolePresets()
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})
|
|
118
|
-
}
|
|
110
|
+
// DB-01/DB-06:系统角色种子从逐 preset create(N 次查询)改为 1 次 createMany
|
|
111
|
+
// (创建行不被消费,ownerRole 仍按 name 回查,行为等价)。查询次数 before: N + 2 → after: 3
|
|
112
|
+
await prisma.customRole.createMany({
|
|
113
|
+
data: presets.map((preset) => ({
|
|
114
|
+
workspaceId: data.workspaceId,
|
|
115
|
+
name: preset.name,
|
|
116
|
+
permissions: preset.permissions as never,
|
|
117
|
+
isSystem: true,
|
|
118
|
+
})),
|
|
119
|
+
})
|
|
119
120
|
const admins = await prisma.user.findMany({
|
|
120
121
|
where: { role: 'ADMIN' },
|
|
121
122
|
select: { id: true },
|
|
@@ -151,6 +152,7 @@ export const createRoleFn = createServerFn({ method: 'POST' })
|
|
|
151
152
|
}),
|
|
152
153
|
)
|
|
153
154
|
.handler(async ({ data }) => {
|
|
155
|
+
const prisma = await getPrisma()
|
|
154
156
|
await requireAdmin()
|
|
155
157
|
await requireFeature(undefined, 'advancedPermissions')
|
|
156
158
|
return prisma.customRole.create({
|
|
@@ -166,6 +168,7 @@ export const createRoleFn = createServerFn({ method: 'POST' })
|
|
|
166
168
|
export const deleteRoleFn = createServerFn({ method: 'POST' })
|
|
167
169
|
.validator(z.object({ roleId: z.string() }))
|
|
168
170
|
.handler(async ({ data }) => {
|
|
171
|
+
const prisma = await getPrisma()
|
|
169
172
|
await requireAdmin()
|
|
170
173
|
await requireFeature(undefined, 'advancedPermissions')
|
|
171
174
|
await prisma.customRole.delete({ where: { id: data.roleId } })
|
|
@@ -175,6 +178,7 @@ export const deleteRoleFn = createServerFn({ method: 'POST' })
|
|
|
175
178
|
export const assignRoleFn = createServerFn({ method: 'POST' })
|
|
176
179
|
.validator(z.object({ userId: z.string(), roleId: z.string() }))
|
|
177
180
|
.handler(async ({ data }) => {
|
|
181
|
+
const prisma = await getPrisma()
|
|
178
182
|
await requireAdmin()
|
|
179
183
|
await requireFeature(undefined, 'advancedPermissions')
|
|
180
184
|
await prisma.roleAssignment.create({ data: { userId: data.userId, roleId: data.roleId } })
|
|
@@ -184,6 +188,7 @@ export const assignRoleFn = createServerFn({ method: 'POST' })
|
|
|
184
188
|
export const unassignRoleFn = createServerFn({ method: 'POST' })
|
|
185
189
|
.validator(z.object({ assignmentId: z.string() }))
|
|
186
190
|
.handler(async ({ data }) => {
|
|
191
|
+
const prisma = await getPrisma()
|
|
187
192
|
await requireAdmin()
|
|
188
193
|
await requireFeature(undefined, 'advancedPermissions')
|
|
189
194
|
await prisma.roleAssignment.delete({ where: { id: data.assignmentId } })
|
|
@@ -193,6 +198,7 @@ export const unassignRoleFn = createServerFn({ method: 'POST' })
|
|
|
193
198
|
export const listRoleAssignmentsFn = createServerFn({ method: 'GET' })
|
|
194
199
|
.validator(z.object({ roleId: z.string() }))
|
|
195
200
|
.handler(async ({ data }) => {
|
|
201
|
+
const prisma = await getPrisma()
|
|
196
202
|
await requireAdmin()
|
|
197
203
|
await requireFeature(undefined, 'advancedPermissions')
|
|
198
204
|
return prisma.roleAssignment.findMany({
|
|
@@ -205,6 +211,7 @@ export const listRoleAssignmentsFn = createServerFn({ method: 'GET' })
|
|
|
205
211
|
export const listWorkspacesFn = createServerFn({ method: 'GET' })
|
|
206
212
|
.validator(z.object({}))
|
|
207
213
|
.handler(async () => {
|
|
214
|
+
const prisma = await getPrisma()
|
|
208
215
|
await requireAdmin()
|
|
209
216
|
await requireFeature(undefined, 'advancedPermissions')
|
|
210
217
|
return prisma.workspace.findMany({
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
20
20
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
21
|
|
|
22
22
|
export type SentryConfig = {
|
|
@@ -28,6 +28,7 @@ export type SentryConfig = {
|
|
|
28
28
|
|
|
29
29
|
export const getSentryConfig = createServerFn({ method: 'GET' })
|
|
30
30
|
.handler(async () => {
|
|
31
|
+
const prisma = await getPrisma()
|
|
31
32
|
await requireAdmin()
|
|
32
33
|
|
|
33
34
|
const settings = await prisma.systemSetting.findMany({
|
|
@@ -47,6 +48,7 @@ export const getSentryConfig = createServerFn({ method: 'GET' })
|
|
|
47
48
|
export const saveSentryConfig = createServerFn({ method: 'POST' })
|
|
48
49
|
.validator((data: SentryConfig) => data)
|
|
49
50
|
.handler(async ({ data }) => {
|
|
51
|
+
const prisma = await getPrisma()
|
|
50
52
|
await requireAdmin()
|
|
51
53
|
|
|
52
54
|
const entries: { key: string; value: string; category: string; desc: string }[] = [
|
|
@@ -56,13 +58,14 @@ export const saveSentryConfig = createServerFn({ method: 'POST' })
|
|
|
56
58
|
{ key: 'auth_token', value: data.authToken, category: 'sentry', desc: 'Sentry Auth Token(源码映射上传用)' },
|
|
57
59
|
]
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
|
|
61
|
+
// DB-01/DB-06:4 个配置项从逐条 upsert(4 次串行查询)改为事务内 deleteMany + createMany
|
|
62
|
+
// (2 次查询、原子提交)。key 全局唯一且仅 sentry 配置使用这 4 个裸键(其他配置均带命名空间前缀),
|
|
63
|
+
// 读取方均按 key→value 消费,重建行(新 id/createdAt)无行为影响。
|
|
64
|
+
// 查询次数 before: 4 → after: 2(事务内)
|
|
65
|
+
await prisma.$transaction([
|
|
66
|
+
prisma.systemSetting.deleteMany({ where: { key: { in: entries.map((entry) => entry.key) } } }),
|
|
67
|
+
prisma.systemSetting.createMany({ data: entries }),
|
|
68
|
+
])
|
|
66
69
|
|
|
67
70
|
return { ok: true }
|
|
68
71
|
})
|
|
@@ -17,21 +17,33 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
22
|
import { requireFeature } from '@/server/entitlements'
|
|
23
23
|
|
|
24
24
|
export const listSsoProvidersFn = createServerFn({ method: 'GET' })
|
|
25
25
|
.validator(z.object({ workspaceId: z.string().optional() }))
|
|
26
26
|
.handler(async ({ data }) => {
|
|
27
|
+
const prisma = await getPrisma()
|
|
27
28
|
await requireAdmin()
|
|
28
29
|
await requireFeature(undefined, 'sso')
|
|
29
30
|
const where: any = data.workspaceId ? { workspaceId: data.workspaceId } : {}
|
|
30
31
|
const [items, total] = await Promise.all([
|
|
31
32
|
prisma.ssoProvider.findMany({
|
|
32
33
|
where,
|
|
33
|
-
include: { _count: { select: { mappings: true } } },
|
|
34
34
|
orderBy: { createdAt: 'desc' },
|
|
35
|
+
// DB-05:config Json 含 IdP client secret 等凭据,列表页不消费,白名单排除
|
|
36
|
+
select: {
|
|
37
|
+
id: true,
|
|
38
|
+
workspaceId: true,
|
|
39
|
+
type: true,
|
|
40
|
+
name: true,
|
|
41
|
+
domain: true,
|
|
42
|
+
enabled: true,
|
|
43
|
+
createdAt: true,
|
|
44
|
+
updatedAt: true,
|
|
45
|
+
_count: { select: { mappings: true } },
|
|
46
|
+
},
|
|
35
47
|
}),
|
|
36
48
|
prisma.ssoProvider.count({ where }),
|
|
37
49
|
])
|
|
@@ -49,6 +61,7 @@ export const createSsoProviderFn = createServerFn({ method: 'POST' })
|
|
|
49
61
|
}),
|
|
50
62
|
)
|
|
51
63
|
.handler(async ({ data }) => {
|
|
64
|
+
const prisma = await getPrisma()
|
|
52
65
|
await requireAdmin()
|
|
53
66
|
await requireFeature(undefined, 'sso')
|
|
54
67
|
return prisma.ssoProvider.create({
|
|
@@ -65,6 +78,7 @@ export const createSsoProviderFn = createServerFn({ method: 'POST' })
|
|
|
65
78
|
export const deleteSsoProviderFn = createServerFn({ method: 'POST' })
|
|
66
79
|
.validator(z.object({ providerId: z.string() }))
|
|
67
80
|
.handler(async ({ data }) => {
|
|
81
|
+
const prisma = await getPrisma()
|
|
68
82
|
await requireAdmin()
|
|
69
83
|
await requireFeature(undefined, 'sso')
|
|
70
84
|
await prisma.ssoProvider.delete({ where: { id: data.providerId } })
|
|
@@ -74,6 +88,7 @@ export const deleteSsoProviderFn = createServerFn({ method: 'POST' })
|
|
|
74
88
|
export const toggleSsoProviderFn = createServerFn({ method: 'POST' })
|
|
75
89
|
.validator(z.object({ providerId: z.string(), enabled: z.boolean() }))
|
|
76
90
|
.handler(async ({ data }) => {
|
|
91
|
+
const prisma = await getPrisma()
|
|
77
92
|
await requireAdmin()
|
|
78
93
|
await requireFeature(undefined, 'sso')
|
|
79
94
|
return prisma.ssoProvider.update({
|
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
21
|
import bcrypt from 'bcryptjs'
|
|
22
|
+
import { requireAdmin } from '@/server/auth-helpers'
|
|
22
23
|
|
|
23
24
|
const createInput = z.object({
|
|
24
25
|
email: z.string().email(),
|
|
@@ -31,10 +32,14 @@ const createInput = z.object({
|
|
|
31
32
|
export const createUserFn = createServerFn({ method: 'POST' })
|
|
32
33
|
.validator(createInput)
|
|
33
34
|
.handler(async ({ data }) => {
|
|
35
|
+
const prisma = await getPrisma()
|
|
36
|
+
await requireAdmin()
|
|
34
37
|
const exists = await prisma.user.findUnique({ where: { email: data.email } })
|
|
35
38
|
if (exists) throw new Error('Email already exists')
|
|
36
39
|
const hashedPassword = await bcrypt.hash(data.password, 12)
|
|
37
40
|
return prisma.user.create({
|
|
38
41
|
data: { ...data, password: hashedPassword, username: data.name },
|
|
42
|
+
// 不回显 password 哈希
|
|
43
|
+
select: { id: true, email: true, username: true, role: true, status: true },
|
|
39
44
|
})
|
|
40
45
|
})
|
|
@@ -17,13 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
|
+
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
22
|
|
|
22
23
|
export const deleteUserFn = createServerFn({ method: 'POST' })
|
|
23
24
|
.validator(z.object({ userId: z.string() }))
|
|
24
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
27
|
+
await requireAdmin()
|
|
25
28
|
return prisma.user.update({
|
|
26
29
|
where: { id: data.userId },
|
|
27
30
|
data: { status: 'INACTIVE' },
|
|
31
|
+
// 不回显 password 哈希
|
|
32
|
+
select: { id: true, email: true, username: true, role: true, status: true },
|
|
28
33
|
})
|
|
29
34
|
})
|
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
19
|
import { z } from 'zod'
|
|
20
|
-
import {
|
|
20
|
+
import { getPrisma } from '@allbluecn/database/get-prisma'
|
|
21
|
+
import { requireAdmin } from '@/server/auth-helpers'
|
|
21
22
|
|
|
22
23
|
export const getUserDetailFn = createServerFn({ method: 'GET' })
|
|
23
24
|
.validator(z.object({ userId: z.string() }))
|
|
24
25
|
.handler(async ({ data }) => {
|
|
26
|
+
const prisma = await getPrisma()
|
|
27
|
+
await requireAdmin()
|
|
25
28
|
const user = await prisma.user.findUnique({
|
|
26
29
|
where: { id: data.userId },
|
|
27
30
|
select: {
|
|
@@ -36,7 +39,7 @@ export const getUserDetailFn = createServerFn({ method: 'GET' })
|
|
|
36
39
|
createdAt: true,
|
|
37
40
|
updatedAt: true,
|
|
38
41
|
lastLoginAt: true,
|
|
39
|
-
_count: { select: {
|
|
42
|
+
_count: { select: { designs: true, anyhubMarketApps: true, anyhubApps: true, reviews: true } },
|
|
40
43
|
loginLogs: { orderBy: { createdAt: 'desc' }, take: 20 },
|
|
41
44
|
},
|
|
42
45
|
})
|