返回 AiToEarn
app.module.ts
1 import type { TokenPayload } from '@yikart/aitoearn-auth'
2 import { createHash } from 'node:crypto'
3 import { Module, UnauthorizedException } from '@nestjs/common'
4 import { ScheduleModule } from '@nestjs/schedule'
5 import { AitoearnAiClientModule } from '@yikart/aitoearn-ai-client'
6 import { AitoearnAuthModule } from '@yikart/aitoearn-auth'
7 import { AitoearnQueueModule } from '@yikart/aitoearn-queue'
8 import { ChannelDbModule } from '@yikart/channel-db'
9 import { ConfigEditorModule } from '@yikart/config-editor'
10 import { ApiKeyRepository, MongodbModule, UserRepository, UserStatus } from '@yikart/mongodb'
11 import { RedlockModule } from '@yikart/redlock'
12 import { ServerRedisModule } from './common/redis'
13 import { AppConfig, config } from './config'
14 import { ApiKeyModule } from './core/api-key/api-key.module'
15 import { AssetsModule } from './core/assets/assets.module'
16 import { ChannelsModule } from './core/channels/channels.module'
17 import { ChannelsMcpModule } from './core/channels/mcp/channels.mcp.module'
18 import { RelayModule } from './core/channels/relay/relay.module'
19 import { ContentMcpModule } from './core/content/content-mcp.module'
20 import { ContentModule } from './core/content/content.module'
21 import { PublishModule } from './core/publish-record/publish-record.module'
22 import { ShortLinkModule } from './core/short-link/short-link.module'
23 import { UnifiedMcpModule } from './core/unified-mcp/unified-mcp.module'
24 import { UserModule } from './core/user/user.module'
25
26 @Module({
27 imports: [
28 ScheduleModule.forRoot(),
29 ConfigEditorModule.forRoot({
30 schema: AppConfig,
31 config,
32 routePrefix: 'config',
33 }),
34 MongodbModule.forRoot(config.mongodb),
35 ChannelDbModule.forRoot(config.channel.channelDb),
36 AitoearnQueueModule.forRoot({
37 redis: config.redis,
38 prefix: '{bull}',
39 }),
40 ServerRedisModule,
41 AitoearnAuthModule.forRootAsync({
42 inject: [UserRepository, ApiKeyRepository],
43 useFactory: (userRepository: UserRepository, apiKeyRepository: ApiKeyRepository) => {
44 const getOpenUser = async (userId: string) => {
45 const user = await userRepository.getById(userId)
46 if (!user || user.isDelete || user.status !== UserStatus.OPEN) {
47 throw new UnauthorizedException()
48 }
49 return user
50 }
51 return {
52 ...config.auth,
53 getTokenInfo: (payload: TokenPayload) => getOpenUser(payload.id),
54 getTokenInfoByApiKey: async (apiKey: string) => {
55 const keyHash = createHash('sha1').update(apiKey).digest('hex')
56 const record = await apiKeyRepository.getByKeyHash(keyHash)
57 if (!record) {
58 throw new UnauthorizedException()
59 }
60 await apiKeyRepository.updateLastUsedAt(record.id)
61 return getOpenUser(record.userId)
62 },
63 }
64 },
65 }),
66 RedlockModule.forRoot(config.redlock),
67 AitoearnAiClientModule.forRoot(config.aiClient),
68 AssetsModule,
69 UserModule,
70 ContentModule,
71 ChannelsModule,
72 PublishModule,
73 ShortLinkModule,
74 ApiKeyModule,
75 RelayModule,
76 // MCP modules (after business modules to ensure @Global services are available)
77 ChannelsMcpModule,
78 ContentMcpModule,
79 UnifiedMcpModule,
80 ],
81 controllers: [],
82 providers: [],
83 })
84 export class AppModule { }
85
85 lines TYPESCRIPT