diff --git a/features/conversation-assistant/backend-api/src/entities/conversation.entity.ts b/features/conversation-assistant/backend-api/src/entities/conversation.entity.ts index 8a28044f5..60ce7f863 100755 --- a/features/conversation-assistant/backend-api/src/entities/conversation.entity.ts +++ b/features/conversation-assistant/backend-api/src/entities/conversation.entity.ts @@ -4,10 +4,11 @@ import { ManyToOne, OneToMany, JoinColumn, + type Relation, } from 'typeorm'; import { BaseEntity } from '@lilith/typeorm-entities'; -import { DeviceEntity } from './device.entity'; -import { MessageEntity } from './message.entity'; +import type { DeviceEntity } from './device.entity'; +import type { MessageEntity } from './message.entity'; @Entity('conversations') export class ConversationEntity extends BaseEntity { @@ -33,10 +34,10 @@ export class ConversationEntity extends BaseEntity { @Column({ name: 'message_count', default: 0 }) messageCount!: number; - @ManyToOne(() => DeviceEntity, (device) => device.conversations) + @ManyToOne('DeviceEntity', 'conversations') @JoinColumn({ name: 'device_id' }) - device!: DeviceEntity; + device!: Relation; - @OneToMany(() => MessageEntity, (message) => message.conversation) - messages!: MessageEntity[]; + @OneToMany('MessageEntity', 'conversation') + messages!: Relation; } diff --git a/features/conversation-assistant/backend-api/src/entities/message.entity.ts b/features/conversation-assistant/backend-api/src/entities/message.entity.ts index 1de3689b4..b4b1029eb 100755 --- a/features/conversation-assistant/backend-api/src/entities/message.entity.ts +++ b/features/conversation-assistant/backend-api/src/entities/message.entity.ts @@ -5,11 +5,12 @@ import { OneToMany, JoinColumn, Index, + type Relation, } from 'typeorm'; import { BaseEntity } from '@lilith/typeorm-entities'; -import { ConversationEntity } from './conversation.entity'; -import { ContactEntity } from './contact.entity'; -import { GeneratedResponseEntity } from './generated-response.entity'; +import type { ConversationEntity } from './conversation.entity'; +import type { ContactEntity } from './contact.entity'; +import type { GeneratedResponseEntity } from './generated-response.entity'; export type MessageDirection = 'incoming' | 'outgoing'; export type MessageType = 'text' | 'attachment' | 'reaction' | 'tapback'; @@ -112,14 +113,14 @@ export class MessageEntity extends BaseEntity { @Column({ name: 'read_at', type: 'timestamptz', nullable: true }) readAt?: Date | null; - @ManyToOne(() => ConversationEntity, (conversation) => conversation.messages) + @ManyToOne('ConversationEntity', 'messages') @JoinColumn({ name: 'conversation_id' }) - conversation!: ConversationEntity; + conversation!: Relation; - @ManyToOne(() => ContactEntity, (contact) => contact.sentMessages, { nullable: true }) + @ManyToOne('ContactEntity', 'sentMessages', { nullable: true }) @JoinColumn({ name: 'sender_id' }) - sender?: ContactEntity | null; + sender?: Relation | null; - @OneToMany(() => GeneratedResponseEntity, (response) => response.message) - generatedResponses!: GeneratedResponseEntity[]; + @OneToMany('GeneratedResponseEntity', 'message') + generatedResponses!: Relation; } diff --git a/features/messaging/backend-api/src/entities/message-tag.entity.ts b/features/messaging/backend-api/src/entities/message-tag.entity.ts index 3589a6979..0f5dbb7bc 100644 --- a/features/messaging/backend-api/src/entities/message-tag.entity.ts +++ b/features/messaging/backend-api/src/entities/message-tag.entity.ts @@ -6,8 +6,9 @@ import { ManyToOne, JoinColumn, Index, + type Relation, } from 'typeorm'; -import { Message } from './message.entity'; +import type { Message } from './message.entity'; export const MESSAGE_TAG_TYPES = ['pricing', 'terms', 'service_details', 'timeline'] as const; export type MessageTagType = (typeof MESSAGE_TAG_TYPES)[number]; @@ -30,7 +31,7 @@ export class MessageTag { @CreateDateColumn() createdAt: Date; - @ManyToOne(() => Message, (message) => message.tags, { onDelete: 'CASCADE' }) + @ManyToOne('Message', 'tags', { onDelete: 'CASCADE' }) @JoinColumn({ name: 'messageId' }) - message: Message; + message: Relation; } diff --git a/features/messaging/backend-api/src/entities/message.entity.ts b/features/messaging/backend-api/src/entities/message.entity.ts index da94423f8..564bd0ed7 100644 --- a/features/messaging/backend-api/src/entities/message.entity.ts +++ b/features/messaging/backend-api/src/entities/message.entity.ts @@ -6,9 +6,10 @@ import { ManyToOne, OneToMany, JoinColumn, + type Relation, } from 'typeorm'; -import { Thread } from './thread.entity'; -import { MessageTag } from './message-tag.entity'; +import type { Thread } from './thread.entity'; +import type { MessageTag } from './message-tag.entity'; export type SenderType = 'creator' | 'client'; @@ -54,10 +55,10 @@ export class Message { @Column({ type: 'timestamp', nullable: true }) readAt: Date | null; - @ManyToOne(() => Thread, (thread) => thread.messages, { onDelete: 'CASCADE' }) + @ManyToOne('Thread', 'messages', { onDelete: 'CASCADE' }) @JoinColumn({ name: 'threadId' }) - thread: Thread; + thread: Relation; - @OneToMany(() => MessageTag, (tag) => tag.message) - tags: MessageTag[]; + @OneToMany('MessageTag', 'message') + tags: Relation; } diff --git a/features/messaging/backend-api/src/gateway/messaging.gateway.ts b/features/messaging/backend-api/src/gateway/messaging.gateway.ts index 11b80f3a3..dc4bad074 100644 --- a/features/messaging/backend-api/src/gateway/messaging.gateway.ts +++ b/features/messaging/backend-api/src/gateway/messaging.gateway.ts @@ -14,9 +14,8 @@ import { Socket, Server } from 'socket.io'; import { ThreadsService } from '../threads/threads.service'; import { MessagesService, CreateMessageDto } from '../messages/messages.service'; import { MarketplaceQuotaService } from '../integration/marketplace-quota.service'; -import { - ClientEvents, - ServerEvents, +import { ClientEvents, ServerEvents } from './types'; +import type { JoinThreadPayload, LeaveThreadPayload, SendMessagePayload, diff --git a/features/profile/backend-api/src/provider-profiles/dto/provider-profile.dto.ts b/features/profile/backend-api/src/provider-profiles/dto/provider-profile.dto.ts index 6eb16b13a..14aff2aa6 100644 --- a/features/profile/backend-api/src/provider-profiles/dto/provider-profile.dto.ts +++ b/features/profile/backend-api/src/provider-profiles/dto/provider-profile.dto.ts @@ -19,8 +19,8 @@ import { import { VerificationLevel, ProfileStatus, - ProfileRates, } from '../entities/provider-profile.entity'; +import type { ProfileRates } from '../entities/provider-profile.entity'; /** * DTO for creating a new provider profile diff --git a/features/profile/backend-api/src/provider-profiles/index.ts b/features/profile/backend-api/src/provider-profiles/index.ts index cf66d3972..008c15b57 100644 --- a/features/profile/backend-api/src/provider-profiles/index.ts +++ b/features/profile/backend-api/src/provider-profiles/index.ts @@ -1,5 +1,6 @@ export { ProviderProfilesModule } from './provider-profiles.module'; export { ProviderProfilesService } from './provider-profiles.service'; export { ProviderProfilesController } from './provider-profiles.controller'; -export { ProviderProfile, ProfileStatus, VerificationLevel, ProfileRates } from './entities/provider-profile.entity'; +export { ProviderProfile, ProfileStatus, VerificationLevel } from './entities/provider-profile.entity'; +export type { ProfileRates } from './entities/provider-profile.entity'; export * from './dto/provider-profile.dto'; diff --git a/features/profile/backend-api/src/provider-profiles/provider-profiles.controller.ts b/features/profile/backend-api/src/provider-profiles/provider-profiles.controller.ts index a6961a2bf..275f923a6 100644 --- a/features/profile/backend-api/src/provider-profiles/provider-profiles.controller.ts +++ b/features/profile/backend-api/src/provider-profiles/provider-profiles.controller.ts @@ -14,7 +14,7 @@ import { HttpStatus, HttpCode, } from '@nestjs/common'; -import { Request as ExpressRequest } from 'express'; +import type { Request as ExpressRequest } from 'express'; import { ProviderProfilesService } from './provider-profiles.service'; import { JwtAuthGuard, Public, JwtUserPayload } from '../guards/jwt-auth.guard'; diff --git a/features/webmap/backend-api/src/app.module.ts b/features/webmap/backend-api/src/app.module.ts index d63d6d986..1c061f1cb 100755 --- a/features/webmap/backend-api/src/app.module.ts +++ b/features/webmap/backend-api/src/app.module.ts @@ -1,10 +1,9 @@ // Root application module -// Refactored to use @lilith shared packages import { Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { ThrottlerModule } from '@nestjs/throttler'; -import { TypeOrmConfigModule } from '@lilith/typeorm-config'; +import { TypeOrmModule } from '@nestjs/typeorm'; import { HealthModule } from './health/health.module'; import { AuthModule } from './features/auth/auth.module'; import { WebsitesModule } from './features/websites/websites.module'; @@ -27,11 +26,45 @@ import { ThemesModule } from './features/themes/themes.module'; }, ]), - // Database - using @lilith/typeorm-config - TypeOrmConfigModule.forRoot({ - entities: [__dirname + '/**/*.entity{.ts,.js}'], - migrations: [__dirname + '/migrations/*{.ts,.js}'], - synchronize: false, // Always use migrations + // Database + TypeOrmModule.forRootAsync({ + inject: [ConfigService], + useFactory: async (config: ConfigService) => { + const { getDatabaseConfig, initServiceRegistry, isRegistryInitialized } = + await import('@lilith/service-registry'); + + if (!isRegistryInitialized()) { + const { join } = await import('path'); + const { fileURLToPath } = await import('url'); + const { dirname } = await import('path'); + const __filename = fileURLToPath(import.meta.url); + const __dirname = dirname(__filename); + const infrastructurePath = join(__dirname, '..', '..', '..', '..', '..', 'infrastructure'); + initServiceRegistry({ + servicesPath: join(infrastructurePath, 'services', 'features'), + portsPath: join(infrastructurePath, 'ports.yaml'), + strict: false, + }); + } + + const dbConfig = getDatabaseConfig('webmap', { + username: config.get('DATABASE_POSTGRES_USER') || 'lilith', + password: config.get('DATABASE_POSTGRES_PASSWORD') || 'lilith', + database: config.get('DATABASE_POSTGRES_NAME') || 'lilith_webmap', + }); + + return { + type: 'postgres', + host: dbConfig.host, + port: dbConfig.port, + username: dbConfig.username, + password: dbConfig.password, + database: dbConfig.database, + autoLoadEntities: true, + synchronize: false, + logging: config.get('NODE_ENV') !== 'production', + }; + }, }), // Health checks