@igstack/app-catalog-backend-core 0.1.1-alpha-20260304152616 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11318 -1052
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4930 -1466
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
- package/prisma/schema.prisma +2 -2
- package/prisma.config.ts +13 -0
- package/src/db/client.ts +20 -2
- package/src/db/prisma.ts +3 -0
- package/src/db/syncAppCatalog.ts +1 -1
- package/src/db/tableSyncMagazine.ts +1 -1
- package/src/db/tableSyncPrismaAdapter.ts +2 -3
- package/src/generated/prisma/browser.ts +59 -0
- package/src/generated/prisma/client.ts +83 -0
- package/src/generated/prisma/commonInputTypes.ts +658 -0
- package/src/generated/prisma/enums.ts +26 -0
- package/src/generated/prisma/internal/class.ts +274 -0
- package/src/generated/prisma/internal/prismaNamespace.ts +1506 -0
- package/src/generated/prisma/internal/prismaNamespaceBrowser.ts +250 -0
- package/src/generated/prisma/models/DbAppForCatalog.ts +1490 -0
- package/src/generated/prisma/models/DbAppTagDefinition.ts +1199 -0
- package/src/generated/prisma/models/DbApprovalMethod.ts +1181 -0
- package/src/generated/prisma/models/DbAsset.ts +1394 -0
- package/src/generated/prisma/models/account.ts +1632 -0
- package/src/generated/prisma/models/session.ts +1447 -0
- package/src/generated/prisma/models/user.ts +1562 -0
- package/src/generated/prisma/models/verification.ts +1180 -0
- package/src/generated/prisma/models.ts +19 -0
- package/src/generated/prisma/pjtg.ts +183 -0
- package/src/index.ts +0 -27
- package/src/middleware/database.ts +13 -2
- package/src/middleware/featureRegistry.ts +0 -38
- package/src/modules/assets/upsertAsset.ts +1 -1
- package/src/server/controller.ts +0 -16
- package/src/modules/appCatalogAdmin/appCatalogAdminRouter.ts +0 -187
- package/src/modules/appCatalogAdmin/catalogBackupController.ts +0 -213
- package/src/modules/approvalMethod/approvalMethodRouter.ts +0 -169
- package/src/modules/approvalMethod/slugUtils.ts +0 -17
- package/src/modules/approvalMethod/syncApprovalMethods.ts +0 -38
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
// biome-ignore-all lint: generated file
|
|
5
|
+
// @ts-nocheck
|
|
6
|
+
/*
|
|
7
|
+
* This is a barrel export file for all models and their related types.
|
|
8
|
+
*
|
|
9
|
+
* 🟢 You can import this file directly.
|
|
10
|
+
*/
|
|
11
|
+
export type * from './models/user'
|
|
12
|
+
export type * from './models/session'
|
|
13
|
+
export type * from './models/account'
|
|
14
|
+
export type * from './models/verification'
|
|
15
|
+
export type * from './models/DbApprovalMethod'
|
|
16
|
+
export type * from './models/DbAppForCatalog'
|
|
17
|
+
export type * from './models/DbAppTagDefinition'
|
|
18
|
+
export type * from './models/DbAsset'
|
|
19
|
+
export type * from './commonInputTypes'
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as Prisma from './internal/prismaNamespace';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace PrismaJson {
|
|
4
|
+
// This namespace will always be empty. Definitions should be done by
|
|
5
|
+
// you manually, and merged automatically by typescript. Make sure that
|
|
6
|
+
// your declaration merging file is included in your tsconfig.json
|
|
7
|
+
//
|
|
8
|
+
// Learn more: https://github.com/arthurfiorette/prisma-json-types-generator/issues/143
|
|
9
|
+
// Declaration Merging: https://www.typescriptlang.org/docs/handbook/declaration-merging.html
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** A filter to be used against nullable List types. */
|
|
14
|
+
export type NullableListFilter<T> = {
|
|
15
|
+
equals?: T | T[] | null;
|
|
16
|
+
has?: T | null;
|
|
17
|
+
hasEvery?: T[];
|
|
18
|
+
hasSome?: T[];
|
|
19
|
+
isEmpty?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** A type to determine how to update a json field */
|
|
23
|
+
export type UpdateInput<T> = T extends object ? { [P in keyof T]?: UpdateInput<T[P]> } : T;
|
|
24
|
+
|
|
25
|
+
/** A type to determine how to update a json[] field */
|
|
26
|
+
export type UpdateManyInput<T> = T | T[] | { set?: T[]; push?: T | T[] };
|
|
27
|
+
|
|
28
|
+
/** A type to determine how to create a json[] input */
|
|
29
|
+
export type CreateManyInput<T> = T | T[] | { set?: T[] };
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A typed version of NestedStringFilter, allowing narrowing of string types to
|
|
33
|
+
* discriminated unions.
|
|
34
|
+
*/
|
|
35
|
+
export type TypedNestedStringFilter<S extends string> =
|
|
36
|
+
//@ts-ignore - When Prisma.StringFilter is not present, this type is not used
|
|
37
|
+
Prisma.StringFilter & {
|
|
38
|
+
equals?: S;
|
|
39
|
+
in?: S[];
|
|
40
|
+
notIn?: S[];
|
|
41
|
+
not?: TypedNestedStringFilter<S> | S;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A typed version of StringFilter, allowing narrowing of string types to discriminated
|
|
46
|
+
* unions.
|
|
47
|
+
*/
|
|
48
|
+
export type TypedStringFilter<S extends string> =
|
|
49
|
+
//@ts-ignore - When Prisma.StringFilter is not present, this type is not used
|
|
50
|
+
Prisma.StringFilter & {
|
|
51
|
+
equals?: S;
|
|
52
|
+
in?: S[];
|
|
53
|
+
notIn?: S[];
|
|
54
|
+
not?: TypedNestedStringFilter<S> | S;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A typed version of NestedStringNullableFilter, allowing narrowing of string types to
|
|
59
|
+
* discriminated unions.
|
|
60
|
+
*/
|
|
61
|
+
export type TypedNestedStringNullableFilter<S extends string> =
|
|
62
|
+
//@ts-ignore - When Prisma.StringNullableFilter is not present, this type is not used
|
|
63
|
+
Prisma.StringNullableFilter & {
|
|
64
|
+
equals?: S | null;
|
|
65
|
+
in?: S[] | null;
|
|
66
|
+
notIn?: S[] | null;
|
|
67
|
+
not?: TypedNestedStringNullableFilter<S> | S | null;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A typed version of StringNullableFilter, allowing narrowing of string types to
|
|
72
|
+
* discriminated unions.
|
|
73
|
+
*/
|
|
74
|
+
export type TypedStringNullableFilter<S extends string> =
|
|
75
|
+
//@ts-ignore - When Prisma.StringNullableFilter is not present, this type is not used
|
|
76
|
+
Prisma.StringNullableFilter & {
|
|
77
|
+
equals?: S | null;
|
|
78
|
+
in?: S[] | null;
|
|
79
|
+
notIn?: S[] | null;
|
|
80
|
+
not?: TypedNestedStringNullableFilter<S> | S | null;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A typed version of NestedStringWithAggregatesFilter, allowing narrowing of string types
|
|
85
|
+
* to discriminated unions.
|
|
86
|
+
*/
|
|
87
|
+
export type TypedNestedStringWithAggregatesFilter<S extends string> =
|
|
88
|
+
//@ts-ignore - When Prisma.NestedStringWithAggregatesFilter is not present, this type is not used
|
|
89
|
+
Prisma.NestedStringWithAggregatesFilter & {
|
|
90
|
+
equals?: S;
|
|
91
|
+
in?: S[];
|
|
92
|
+
notIn?: S[];
|
|
93
|
+
not?: TypedNestedStringWithAggregatesFilter<S> | S;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* A typed version of StringWithAggregatesFilter, allowing narrowing of string types to
|
|
98
|
+
* discriminated unions.
|
|
99
|
+
*/
|
|
100
|
+
export type TypedStringWithAggregatesFilter<S extends string> =
|
|
101
|
+
//@ts-ignore - When Prisma.StringWithAggregatesFilter is not present, this type is not used
|
|
102
|
+
Prisma.StringWithAggregatesFilter & {
|
|
103
|
+
equals?: S;
|
|
104
|
+
in?: S[];
|
|
105
|
+
notIn?: S[];
|
|
106
|
+
not?: TypedNestedStringWithAggregatesFilter<S> | S;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A typed version of NestedStringNullableWithAggregatesFilter, allowing narrowing of
|
|
111
|
+
* string types to discriminated unions.
|
|
112
|
+
*/
|
|
113
|
+
export type TypedNestedStringNullableWithAggregatesFilter<S extends string> =
|
|
114
|
+
//@ts-ignore - When Prisma.NestedStringNullableWithAggregatesFilter is not present, this type is not used
|
|
115
|
+
Prisma.NestedStringNullableWithAggregatesFilter & {
|
|
116
|
+
equals?: S | null;
|
|
117
|
+
in?: S[] | null;
|
|
118
|
+
notIn?: S[] | null;
|
|
119
|
+
not?: TypedNestedStringNullableWithAggregatesFilter<S> | S | null;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* A typed version of StringNullableWithAggregatesFilter, allowing narrowing of string
|
|
124
|
+
* types to discriminated unions.
|
|
125
|
+
*/
|
|
126
|
+
export type TypedStringNullableWithAggregatesFilter<S extends string> =
|
|
127
|
+
//@ts-ignore - When Prisma.StringNullableWithAggregatesFilter is not present, this type is not used
|
|
128
|
+
Prisma.StringNullableWithAggregatesFilter & {
|
|
129
|
+
equals?: S | null;
|
|
130
|
+
in?: S[] | null;
|
|
131
|
+
notIn?: S[] | null;
|
|
132
|
+
not?: TypedNestedStringNullableWithAggregatesFilter<S> | S | null;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A typed version of StringFieldUpdateOperationsInput, allowing narrowing of string types
|
|
137
|
+
* to discriminated unions.
|
|
138
|
+
*/
|
|
139
|
+
export type TypedStringFieldUpdateOperationsInput<S extends string> =
|
|
140
|
+
//@ts-ignore - When Prisma.StringFieldUpdateOperationsInput is not present, this type is not used
|
|
141
|
+
Prisma.StringFieldUpdateOperationsInput & {
|
|
142
|
+
set?: S;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A typed version of NullableStringFieldUpdateOperationsInput, allowing narrowing of
|
|
147
|
+
* string types to discriminated unions.
|
|
148
|
+
*/
|
|
149
|
+
export type TypedNullableStringFieldUpdateOperationsInput<S extends string> =
|
|
150
|
+
//@ts-ignore - When Prisma.NullableStringFieldUpdateOperationsInput is not present, this type is not used
|
|
151
|
+
Prisma.NullableStringFieldUpdateOperationsInput & {
|
|
152
|
+
set?: S | null;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* A typed version of StringNullableListFilter, allowing narrowing of string types to
|
|
157
|
+
* discriminated unions.
|
|
158
|
+
*/
|
|
159
|
+
export type TypedStringNullableListFilter<S extends string> =
|
|
160
|
+
//@ts-ignore - When Prisma.StringNullableListFilter is not present, this type is not used
|
|
161
|
+
Prisma.StringNullableListFilter & {
|
|
162
|
+
equals?: S[] | null;
|
|
163
|
+
has?: S | null;
|
|
164
|
+
hasEvery?: S[];
|
|
165
|
+
hasSome?: S[];
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* A typed version of the input type to update a string[] field, allowing narrowing of
|
|
170
|
+
* string types to discriminated unions.
|
|
171
|
+
*/
|
|
172
|
+
export type UpdateStringArrayInput<S extends string> = {
|
|
173
|
+
set?: S[];
|
|
174
|
+
push?: S | S[];
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* A typed version of the input type to create a string[] field, allowing narrowing of
|
|
179
|
+
* string types to discriminated unions.
|
|
180
|
+
*/
|
|
181
|
+
export type CreateStringArrayInput<S extends string> = {
|
|
182
|
+
set?: S[];
|
|
183
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -39,20 +39,6 @@ export {
|
|
|
39
39
|
type UserWithGroups,
|
|
40
40
|
} from './modules/auth/authorizationUtils'
|
|
41
41
|
|
|
42
|
-
// Admin
|
|
43
|
-
export {
|
|
44
|
-
createAdminChatHandler,
|
|
45
|
-
tool,
|
|
46
|
-
type AdminChatHandlerOptions,
|
|
47
|
-
} from './modules/admin/chat/createAdminChatHandler'
|
|
48
|
-
|
|
49
|
-
export {
|
|
50
|
-
createDatabaseTools,
|
|
51
|
-
createPrismaDatabaseClient,
|
|
52
|
-
DEFAULT_ADMIN_SYSTEM_PROMPT,
|
|
53
|
-
type DatabaseClient,
|
|
54
|
-
} from './modules/admin/chat/createDatabaseTools'
|
|
55
|
-
|
|
56
42
|
// Icon management
|
|
57
43
|
export {
|
|
58
44
|
registerIconRestController,
|
|
@@ -77,26 +63,14 @@ export {
|
|
|
77
63
|
type ScreenshotRestControllerConfig,
|
|
78
64
|
} from './modules/assets/screenshotRestController'
|
|
79
65
|
|
|
80
|
-
export { createScreenshotRouter } from './modules/assets/screenshotRouter'
|
|
81
|
-
|
|
82
66
|
export { syncAssets, type SyncAssetsConfig } from './modules/assets/syncAssets'
|
|
83
67
|
|
|
84
|
-
// App Catalog Admin
|
|
85
|
-
export { createAppCatalogAdminRouter } from './modules/appCatalogAdmin/appCatalogAdminRouter'
|
|
86
|
-
|
|
87
68
|
// App Catalog utilities
|
|
88
69
|
export {
|
|
89
70
|
checkAllLinks,
|
|
90
71
|
printLinkCheckReport,
|
|
91
72
|
} from './modules/appCatalog/checkLinks'
|
|
92
73
|
|
|
93
|
-
// Approval Methods
|
|
94
|
-
export { createApprovalMethodRouter } from './modules/approvalMethod/approvalMethodRouter'
|
|
95
|
-
export {
|
|
96
|
-
syncApprovalMethods,
|
|
97
|
-
type ApprovalMethodSyncInput,
|
|
98
|
-
} from './modules/approvalMethod/syncApprovalMethods'
|
|
99
|
-
|
|
100
74
|
// Database utilities
|
|
101
75
|
export {
|
|
102
76
|
connectDb,
|
|
@@ -123,7 +97,6 @@ export {
|
|
|
123
97
|
injectCustomScripts,
|
|
124
98
|
type EhDatabaseConfig,
|
|
125
99
|
type EhAuthConfig,
|
|
126
|
-
type EhAdminChatConfig,
|
|
127
100
|
type EhFeatureToggles,
|
|
128
101
|
type EhBackendProvider,
|
|
129
102
|
type EhLifecycleHooks,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { PrismaClient } from '
|
|
1
|
+
import { PrismaClient } from '../db/prisma'
|
|
2
|
+
import { PrismaPg } from '@prisma/adapter-pg'
|
|
3
|
+
import pg from 'pg'
|
|
2
4
|
import type { EhDatabaseConfig } from './types'
|
|
3
5
|
import { setDbClient } from '../db/client'
|
|
4
6
|
|
|
@@ -20,6 +22,7 @@ function formatConnectionUrl(config: EhDatabaseConfig): string {
|
|
|
20
22
|
*/
|
|
21
23
|
export class EhDatabaseManager {
|
|
22
24
|
private client: PrismaClient | null = null
|
|
25
|
+
private pool: pg.Pool | null = null
|
|
23
26
|
private config: EhDatabaseConfig
|
|
24
27
|
|
|
25
28
|
constructor(config: EhDatabaseConfig) {
|
|
@@ -34,8 +37,12 @@ export class EhDatabaseManager {
|
|
|
34
37
|
if (!this.client) {
|
|
35
38
|
const datasourceUrl = formatConnectionUrl(this.config)
|
|
36
39
|
|
|
40
|
+
// Prisma 7 with adapter: Create pg pool and wrap with adapter
|
|
41
|
+
this.pool = new pg.Pool({ connectionString: datasourceUrl })
|
|
42
|
+
const adapter = new PrismaPg(this.pool)
|
|
43
|
+
|
|
37
44
|
this.client = new PrismaClient({
|
|
38
|
-
|
|
45
|
+
adapter,
|
|
39
46
|
log:
|
|
40
47
|
process.env.NODE_ENV === 'development'
|
|
41
48
|
? ['warn', 'error']
|
|
@@ -58,5 +65,9 @@ export class EhDatabaseManager {
|
|
|
58
65
|
await this.client.$disconnect()
|
|
59
66
|
this.client = null
|
|
60
67
|
}
|
|
68
|
+
if (this.pool) {
|
|
69
|
+
await this.pool.end()
|
|
70
|
+
this.pool = null
|
|
71
|
+
}
|
|
61
72
|
}
|
|
62
73
|
}
|
|
@@ -8,16 +8,7 @@ import type {
|
|
|
8
8
|
import { registerIconRestController } from '../modules/icons/iconRestController'
|
|
9
9
|
import { registerAssetRestController } from '../modules/assets/assetRestController'
|
|
10
10
|
import { registerScreenshotRestController } from '../modules/assets/screenshotRestController'
|
|
11
|
-
import { createAdminChatHandler } from '../modules/admin/chat/createAdminChatHandler'
|
|
12
11
|
import { getAssetByName } from '../modules/icons/iconService'
|
|
13
|
-
import {
|
|
14
|
-
exportAsset,
|
|
15
|
-
exportCatalog,
|
|
16
|
-
importAsset,
|
|
17
|
-
importCatalog,
|
|
18
|
-
listAssets,
|
|
19
|
-
} from '../modules/appCatalogAdmin/catalogBackupController'
|
|
20
|
-
import multer from 'multer'
|
|
21
12
|
import { createMockSessionResponse } from '../modules/auth/devMockUserUtils'
|
|
22
13
|
|
|
23
14
|
interface FeatureRegistration {
|
|
@@ -70,18 +61,6 @@ const FEATURES: Array<FeatureRegistration> = [
|
|
|
70
61
|
router.all(`${basePath}/auth/{*any}`, authHandler)
|
|
71
62
|
},
|
|
72
63
|
},
|
|
73
|
-
{
|
|
74
|
-
name: 'adminChat',
|
|
75
|
-
defaultEnabled: false, // Only enabled if adminChat config is provided
|
|
76
|
-
register: (router, options) => {
|
|
77
|
-
if (options.adminChat) {
|
|
78
|
-
router.post(
|
|
79
|
-
`${options.basePath}/admin/chat`,
|
|
80
|
-
createAdminChatHandler(options.adminChat),
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
64
|
{
|
|
86
65
|
name: 'legacyIconEndpoint',
|
|
87
66
|
defaultEnabled: false,
|
|
@@ -143,29 +122,12 @@ export function registerFeatures(
|
|
|
143
122
|
basePath: `${basePath}/screenshots`,
|
|
144
123
|
})
|
|
145
124
|
|
|
146
|
-
// Catalog backup/restore
|
|
147
|
-
const upload = multer({ storage: multer.memoryStorage() })
|
|
148
|
-
router.get(`${basePath}/catalog/backup/export`, exportCatalog)
|
|
149
|
-
router.post(`${basePath}/catalog/backup/import`, importCatalog)
|
|
150
|
-
router.get(`${basePath}/catalog/backup/assets`, listAssets)
|
|
151
|
-
router.get(`${basePath}/catalog/backup/assets/:name`, exportAsset)
|
|
152
|
-
router.post(
|
|
153
|
-
`${basePath}/catalog/backup/assets`,
|
|
154
|
-
upload.single('file'),
|
|
155
|
-
importAsset,
|
|
156
|
-
)
|
|
157
|
-
|
|
158
125
|
// Optional toggleable features
|
|
159
126
|
const toggles = options.features || {}
|
|
160
127
|
|
|
161
128
|
for (const feature of FEATURES) {
|
|
162
129
|
const isEnabled = toggles[feature.name] ?? feature.defaultEnabled
|
|
163
130
|
|
|
164
|
-
// Special case: adminChat is only enabled if config is provided
|
|
165
|
-
if (feature.name === 'adminChat' && !options.adminChat) {
|
|
166
|
-
continue
|
|
167
|
-
}
|
|
168
|
-
|
|
169
131
|
if (isEnabled) {
|
|
170
132
|
feature.register(router, options, context)
|
|
171
133
|
}
|
package/src/server/controller.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { getAppCatalogData } from '../modules/appCatalog/service'
|
|
2
2
|
import type { AppCatalogData } from '../types'
|
|
3
3
|
|
|
4
|
-
import { createAppCatalogAdminRouter } from '../modules/appCatalogAdmin/appCatalogAdminRouter.js'
|
|
5
|
-
import { createApprovalMethodRouter } from '../modules/approvalMethod/approvalMethodRouter.js'
|
|
6
|
-
import { createScreenshotRouter } from '../modules/assets/screenshotRouter.js'
|
|
7
4
|
import type { BetterAuth } from '../modules/auth/auth'
|
|
8
5
|
import { createAuthRouter } from '../modules/auth/authRouter.js'
|
|
9
|
-
import { createIconRouter } from '../modules/icons/iconRouter.js'
|
|
10
6
|
import { publicProcedure, router, t } from './trpcSetup'
|
|
11
7
|
|
|
12
8
|
/**
|
|
@@ -32,18 +28,6 @@ export function createTrpcRouter(auth?: BetterAuth) {
|
|
|
32
28
|
},
|
|
33
29
|
),
|
|
34
30
|
|
|
35
|
-
// Icon management routes
|
|
36
|
-
icon: createIconRouter(),
|
|
37
|
-
|
|
38
|
-
// Screenshot management routes
|
|
39
|
-
screenshot: createScreenshotRouter(),
|
|
40
|
-
|
|
41
|
-
// App catalog admin routes
|
|
42
|
-
appCatalogAdmin: createAppCatalogAdminRouter(),
|
|
43
|
-
|
|
44
|
-
// Approval method routes
|
|
45
|
-
approvalMethod: createApprovalMethodRouter(),
|
|
46
|
-
|
|
47
31
|
// Auth routes (requires auth instance)
|
|
48
32
|
auth: createAuthRouter(t, auth),
|
|
49
33
|
})
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import { getDbClient } from '../../db'
|
|
3
|
-
import { adminProcedure, router } from '../../server/trpcSetup'
|
|
4
|
-
import type { AppAccessRequest } from '../../types'
|
|
5
|
-
|
|
6
|
-
// Zod schema for access method (simplified for now - you can expand this)
|
|
7
|
-
const AccessMethodSchema = z
|
|
8
|
-
.object({
|
|
9
|
-
type: z.enum([
|
|
10
|
-
'bot',
|
|
11
|
-
'ticketing',
|
|
12
|
-
'email',
|
|
13
|
-
'self-service',
|
|
14
|
-
'documentation',
|
|
15
|
-
'manual',
|
|
16
|
-
]),
|
|
17
|
-
})
|
|
18
|
-
.loose()
|
|
19
|
-
|
|
20
|
-
const AppLinkSchema = z.object({
|
|
21
|
-
displayName: z.string().optional(),
|
|
22
|
-
url: z.url(),
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
// New AppAccessRequest schema
|
|
26
|
-
const AppRoleSchema = z.object({
|
|
27
|
-
name: z.string(),
|
|
28
|
-
description: z.string().optional(),
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const ApproverContactSchema = z.object({
|
|
32
|
-
displayName: z.string(),
|
|
33
|
-
contact: z.string().optional(),
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const ApprovalUrlSchema = z.object({
|
|
37
|
-
label: z.string().optional(),
|
|
38
|
-
url: z.url(),
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const AppAccessRequestSchema = z.object({
|
|
42
|
-
approvalMethodId: z.string(),
|
|
43
|
-
comments: z.string().optional(),
|
|
44
|
-
requestPrompt: z.string().optional(),
|
|
45
|
-
postApprovalInstructions: z.string().optional(),
|
|
46
|
-
roles: z.array(AppRoleSchema).optional(),
|
|
47
|
-
approvers: z.array(ApproverContactSchema).optional(),
|
|
48
|
-
urls: z.array(ApprovalUrlSchema).optional(),
|
|
49
|
-
whoToReachOut: z.string().optional(),
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
const CreateAppForCatalogSchema = z.object({
|
|
53
|
-
slug: z
|
|
54
|
-
.string()
|
|
55
|
-
.min(1)
|
|
56
|
-
.regex(/^[a-z0-9-]+$/, 'Slug must be lowercase alphanumeric with hyphens'),
|
|
57
|
-
displayName: z.string().min(1),
|
|
58
|
-
description: z.string(),
|
|
59
|
-
access: AccessMethodSchema.optional(),
|
|
60
|
-
teams: z.array(z.string()).optional(),
|
|
61
|
-
accessRequest: AppAccessRequestSchema.optional(),
|
|
62
|
-
notes: z.string().optional(),
|
|
63
|
-
tags: z.array(z.string()).optional(),
|
|
64
|
-
appUrl: z.url().optional(),
|
|
65
|
-
links: z.array(AppLinkSchema).optional(),
|
|
66
|
-
iconName: z.string().optional(),
|
|
67
|
-
screenshotIds: z.array(z.string()).optional(),
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
const UpdateAppForCatalogSchema = CreateAppForCatalogSchema.partial().extend({
|
|
71
|
-
id: z.string(),
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
export function createAppCatalogAdminRouter() {
|
|
75
|
-
const prisma = getDbClient()
|
|
76
|
-
return router({
|
|
77
|
-
list: adminProcedure.query(async () => {
|
|
78
|
-
return prisma.dbAppForCatalog.findMany({
|
|
79
|
-
orderBy: { displayName: 'asc' },
|
|
80
|
-
})
|
|
81
|
-
}),
|
|
82
|
-
|
|
83
|
-
getById: adminProcedure
|
|
84
|
-
.input(z.object({ id: z.string() }))
|
|
85
|
-
.query(async ({ input }) => {
|
|
86
|
-
return prisma.dbAppForCatalog.findUnique({
|
|
87
|
-
where: { id: input.id },
|
|
88
|
-
})
|
|
89
|
-
}),
|
|
90
|
-
|
|
91
|
-
getBySlug: adminProcedure
|
|
92
|
-
.input(z.object({ slug: z.string() }))
|
|
93
|
-
.query(async ({ input }) => {
|
|
94
|
-
return prisma.dbAppForCatalog.findUnique({
|
|
95
|
-
where: { slug: input.slug },
|
|
96
|
-
})
|
|
97
|
-
}),
|
|
98
|
-
|
|
99
|
-
create: adminProcedure
|
|
100
|
-
.input(CreateAppForCatalogSchema)
|
|
101
|
-
.mutation(async ({ input }) => {
|
|
102
|
-
// Type assertion needed because Zod's passthrough() creates index signatures
|
|
103
|
-
// that don't structurally match Prisma's typed JSON fields.
|
|
104
|
-
// This is safe because Zod validates the input shape.
|
|
105
|
-
return prisma.dbAppForCatalog.create({
|
|
106
|
-
data: {
|
|
107
|
-
slug: input.slug,
|
|
108
|
-
displayName: input.displayName,
|
|
109
|
-
description: input.description,
|
|
110
|
-
teams: input.teams ?? [],
|
|
111
|
-
accessRequest: input.accessRequest as AppAccessRequest | undefined,
|
|
112
|
-
notes: input.notes,
|
|
113
|
-
tags: input.tags ?? [],
|
|
114
|
-
appUrl: input.appUrl,
|
|
115
|
-
links: input.links as Array<{ displayName?: string; url: string }>,
|
|
116
|
-
iconName: input.iconName,
|
|
117
|
-
screenshotIds: input.screenshotIds ?? [],
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
}),
|
|
121
|
-
|
|
122
|
-
update: adminProcedure
|
|
123
|
-
.input(UpdateAppForCatalogSchema)
|
|
124
|
-
.mutation(async ({ input }) => {
|
|
125
|
-
const { id, ...updateData } = input
|
|
126
|
-
|
|
127
|
-
// Type assertion needed because Zod's passthrough() creates index signatures
|
|
128
|
-
return prisma.dbAppForCatalog.update({
|
|
129
|
-
where: { id },
|
|
130
|
-
data: {
|
|
131
|
-
...(updateData.slug !== undefined && { slug: updateData.slug }),
|
|
132
|
-
...(updateData.displayName !== undefined && {
|
|
133
|
-
displayName: updateData.displayName,
|
|
134
|
-
}),
|
|
135
|
-
...(updateData.description !== undefined && {
|
|
136
|
-
description: updateData.description,
|
|
137
|
-
}),
|
|
138
|
-
...(updateData.teams !== undefined && { teams: updateData.teams }),
|
|
139
|
-
...(updateData.accessRequest !== undefined && {
|
|
140
|
-
accessRequest: updateData.accessRequest as
|
|
141
|
-
| AppAccessRequest
|
|
142
|
-
| undefined,
|
|
143
|
-
}),
|
|
144
|
-
...(updateData.notes !== undefined && { notes: updateData.notes }),
|
|
145
|
-
...(updateData.tags !== undefined && { tags: updateData.tags }),
|
|
146
|
-
...(updateData.appUrl !== undefined && {
|
|
147
|
-
appUrl: updateData.appUrl,
|
|
148
|
-
}),
|
|
149
|
-
...(updateData.links !== undefined && {
|
|
150
|
-
links: updateData.links as Array<{
|
|
151
|
-
displayName?: string
|
|
152
|
-
url: string
|
|
153
|
-
}>,
|
|
154
|
-
}),
|
|
155
|
-
...(updateData.iconName !== undefined && {
|
|
156
|
-
iconName: updateData.iconName,
|
|
157
|
-
}),
|
|
158
|
-
...(updateData.screenshotIds !== undefined && {
|
|
159
|
-
screenshotIds: updateData.screenshotIds,
|
|
160
|
-
}),
|
|
161
|
-
},
|
|
162
|
-
})
|
|
163
|
-
}),
|
|
164
|
-
|
|
165
|
-
updateScreenshots: adminProcedure
|
|
166
|
-
.input(
|
|
167
|
-
z.object({
|
|
168
|
-
id: z.string(),
|
|
169
|
-
screenshotIds: z.array(z.string()),
|
|
170
|
-
}),
|
|
171
|
-
)
|
|
172
|
-
.mutation(async ({ input }) => {
|
|
173
|
-
return prisma.dbAppForCatalog.update({
|
|
174
|
-
where: { id: input.id },
|
|
175
|
-
data: { screenshotIds: input.screenshotIds },
|
|
176
|
-
})
|
|
177
|
-
}),
|
|
178
|
-
|
|
179
|
-
delete: adminProcedure
|
|
180
|
-
.input(z.object({ id: z.string() }))
|
|
181
|
-
.mutation(async ({ input }) => {
|
|
182
|
-
return prisma.dbAppForCatalog.delete({
|
|
183
|
-
where: { id: input.id },
|
|
184
|
-
})
|
|
185
|
-
}),
|
|
186
|
-
})
|
|
187
|
-
}
|