hailin
7ff701369b
fix(tenant): use TenantContextModule.forRoot() for global tenant context
...
All services were providing TenantContextService directly without
making it global, causing DI resolution failures in child modules.
Now using TenantContextModule.forRoot() which exports TenantContextService
globally so all repositories can access it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 04:31:56 -08:00
hailin
6bb47dad85
fix(docker): copy shared module AFTER npm install to prevent wipe
...
npm install was clearing the @iconsulting/shared folder that was
copied before it. Moving the COPY command after npm install ensures
the shared package remains in node_modules.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 03:41:16 -08:00
hailin
1df5854825
feat(multi-tenant): apply tenant middleware and refactor repositories
...
- Apply TenantContextMiddleware to all 6 services
- Add SimpleTenantFinder for services without direct tenant DB access
- Add TenantFinderService for evolution-service with database access
- Refactor 8 repositories to extend BaseTenantRepository:
- user-postgres.repository.ts
- verification-code-postgres.repository.ts
- conversation-postgres.repository.ts
- message-postgres.repository.ts
- token-usage-postgres.repository.ts
- file-postgres.repository.ts
- order-postgres.repository.ts
- payment-postgres.repository.ts
- Add @iconsulting/shared dependency to evolution-service and knowledge-service
- Configure middleware to exclude health and super-admin paths
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 18:30:31 -08:00
hailin
422069be68
feat: add enterprise multi-tenancy infrastructure
...
- Add shared tenant module with AsyncLocalStorage-based context management
- Create TenantContextService, TenantContextMiddleware, TenantGuard
- Add @TenantId(), @Tenant(), @RequireFeatures() decorators
- Create BaseTenantRepository for automatic tenant filtering
- Add TenantORM entity for tenants table
- Add tenant_id column to all 16 ORM entities across 6 services
- Create database migration script for multi-tenancy support
- Add tenant-related error codes
This implements row-level isolation for 100% data separation between tenants.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 18:11:12 -08:00
hailin
65c0bdd17c
feat(payment): add transaction reliability and idempotency support
...
- Add TransactionService for atomic database operations with optimistic lock retry
- Implement pessimistic locking in payment callback handling to prevent race conditions
- Add idempotency check via transactionId unique index to prevent duplicate processing
- Add version columns to PaymentORM and OrderORM for optimistic locking
- Add composite indexes for performance (order_status, transaction_id)
- Optimize connection pool settings for both payment and conversation services
- Update init-db.sql with version columns and new indexes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 07:00:01 -08:00
hailin
7c22c173a5
fix(orm): add explicit column types for conversation and order entities
...
Fixed remaining TypeORM DataTypeNotSupportedError for "Object" type.
## conversation-service/ConversationORM
- title: varchar(255)
- endedAt: timestamptz
## payment-service/OrderORM
- serviceCategory: varchar(100)
- currency: varchar(10)
- paymentMethod: varchar(50)
- paidAt: timestamptz
- completedAt: timestamptz
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 01:57:20 -08:00
hailin
eb1cb9c496
fix(orm): add explicit PostgreSQL column types for nullable fields
...
Fixed TypeORM DataTypeNotSupportedError for "Object" type in PostgreSQL.
## Issues Fixed
1. **user-service/UserORM**
- fingerprint: varchar(255)
- phone: varchar(20)
- nickname: varchar(100)
- avatar: varchar(500)
2. **payment-service/PaymentORM**
- transactionId: varchar(255)
- currency: varchar(10)
- expiresAt: timestamptz
- paidAt: timestamptz
3. **conversation-service/MessageORM**
- inputTokens: int
- outputTokens: int
## Root Cause
@Column({ nullable: true }) without explicit `type` defaults to Object,
which PostgreSQL doesn't support.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 22:50:54 -08:00
hailin
afd707d15f
refactor(services): implement 4-layer Clean Architecture for all backend services
...
Refactored all 6 backend services to 4-layer Clean Architecture pattern
following knowledge-service as reference implementation.
## Architecture Pattern (4-Layer)
```
src/
├── domain/ # Pure business entities and interfaces
│ ├── entities/ # Domain entities (no ORM decorators)
│ ├── repositories/ # Repository interfaces + Symbol tokens
│ └── value-objects/ # Enums and value types
├── application/
│ ├── dtos/ # Data transfer objects
│ └── services/ # Application services (use case orchestration)
├── adapters/
│ ├── inbound/ # Controllers, gateways (API endpoints)
│ └── outbound/
│ ├── persistence/ # Repository implementations
│ ├── clients/ # External service clients
│ └── storage/ # File storage adapters
└── infrastructure/
└── database/postgres/
└── entities/ # ORM entities with decorators
```
## Services Refactored
### user-service
- adapters/inbound: AuthController, UserController
- adapters/outbound/persistence: UserPostgresRepository, VerificationCodePostgresRepository
- application/services: AuthService, UserService
- application/dtos: AuthDto, UserDto
### payment-service
- adapters/inbound: OrderController, PaymentController
- adapters/outbound/persistence: OrderPostgresRepository, PaymentPostgresRepository
- adapters/outbound/payment-methods: AlipayAdapter, WechatPayAdapter, StripeAdapter
- application/services: OrderService, PaymentService
- application/dtos: OrderDto, PaymentDto
### file-service
- adapters/inbound: FileController
- adapters/outbound/persistence: FilePostgresRepository
- adapters/outbound/storage: MinioStorageAdapter
- application/services: FileService
- application/dtos: UploadFileDto
### conversation-service
- adapters/inbound: ConversationController, InternalController, ConversationGateway
- adapters/outbound/persistence: ConversationPostgresRepository, MessagePostgresRepository, TokenUsagePostgresRepository
- application/services: ConversationService
- application/dtos: ConversationDto
### knowledge-service
- adapters/inbound: KnowledgeController, MemoryController, InternalMemoryController
- adapters/outbound/persistence: KnowledgePostgresRepository, MemoryPostgresRepository
- application/services: KnowledgeService, MemoryService
- application/dtos: KnowledgeDto, MemoryDto
### evolution-service
- domain/entities: AdminEntity
- domain/repositories: IAdminRepository (Symbol-based DI)
- domain/value-objects: AdminRole enum
- adapters/inbound: AdminController, EvolutionController
- adapters/outbound/persistence: AdminPostgresRepository
- adapters/outbound/clients: ConversationClient, KnowledgeClient
- application/services: AdminService, EvolutionService
- application/dtos: AdminDto, EvolutionDto
- infrastructure/database/postgres/entities: AdminORM
## Key Improvements
- Symbol-based dependency injection for repository interfaces
- ORM entities separated from domain entities
- Consistent 4-layer structure across all services
- DTOs for API contracts
- Clear separation: domain logic vs infrastructure concerns
## Configuration
- Updated turbo.json: renamed "pipeline" to "tasks" for Turbo 2.0+
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 22:18:22 -08:00
hailin
02954f56db
refactor(services): implement Clean Architecture across 4 services
...
## Overview
Refactor user-service, payment-service, file-service, and conversation-service
to follow Clean Architecture pattern based on knowledge-service reference.
## Architecture Pattern Applied
```
src/
├── domain/
│ ├── entities/ # Pure domain entities (no ORM decorators)
│ └── repositories/ # Repository interfaces + Symbol DI tokens
├── infrastructure/
│ └── database/postgres/
│ ├── entities/ # ORM entities with TypeORM decorators
│ └── *-postgres.repository.ts # Repository implementations
└── {feature}/
└── {feature}.module.ts # DI configuration with Symbol providers
```
## Changes by Service
### user-service (40% → 100% compliant)
- Created: IUserRepository, IVerificationCodeRepository interfaces
- Created: UserORM, VerificationCodeORM entities
- Created: UserPostgresRepository, VerificationCodePostgresRepository
- Modified: UserEntity, VerificationCodeEntity → pure domain with factory methods
- Updated: user.module.ts, auth.module.ts with Symbol-based DI
### payment-service (50% → 100% compliant)
- Created: IOrderRepository, IPaymentRepository interfaces
- Created: OrderORM, PaymentORM entities
- Created: OrderPostgresRepository, PaymentPostgresRepository
- Modified: OrderEntity, PaymentEntity → pure domain with factory methods
- Updated: order.module.ts, payment.module.ts with Symbol-based DI
### file-service (40% → 100% compliant)
- Created: IFileRepository interface
- Created: FileORM entity
- Created: FilePostgresRepository
- Modified: FileEntity → pure domain with factory methods
- Updated: file.module.ts with Symbol-based DI
### conversation-service (60% → 100% compliant)
- Created: IConversationRepository, IMessageRepository, ITokenUsageRepository
- Created: ConversationORM, MessageORM, TokenUsageORM entities
- Created: ConversationPostgresRepository, MessagePostgresRepository,
TokenUsagePostgresRepository
- Modified: ConversationEntity, MessageEntity, TokenUsageEntity → pure domain
- Updated: conversation.module.ts with Symbol-based DI
- Updated: app.module.ts, data-source.ts entity patterns
## Key Implementation Details
1. **Symbol-based DI Pattern**:
```typescript
export const USER_REPOSITORY = Symbol('IUserRepository');
@Module({
providers: [{ provide: USER_REPOSITORY, useClass: UserPostgresRepository }],
exports: [UserService, USER_REPOSITORY],
})
```
2. **Pure Domain Entities**: Factory methods `create()` and `fromPersistence()`
for controlled instantiation without ORM decorators
3. **Repository Implementations**: Include `toORM()` and `toEntity()` conversion
methods for anti-corruption layer between domain and infrastructure
4. **Entity Discovery**: Changed glob pattern from `*.entity` to `*.orm`
in app.module.ts and data-source.ts files
## Breaking Changes
- None for API consumers
- Internal architecture restructuring only
## Testing
- All 4 services compile successfully with `pnpm build`
- Database schema compatibility verified (column mappings preserved)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 21:18:25 -08:00
hailin
c98cae2e39
fix(payment): use PORT env variable instead of PAYMENT_SERVICE_PORT
...
Payment service was listening on wrong port (3004) because it used
PAYMENT_SERVICE_PORT which wasn't set in docker-compose.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 02:48:44 -08:00
hailin
224e1fb509
fix(health): exclude /health endpoint from API prefix
...
The health check endpoint should be at /health not /api/v1/health
for Docker health checks to work properly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 02:30:24 -08:00
hailin
223aa25af1
fix(docker): add health check endpoints and fix IPv6 issue
...
- Add /health endpoints to all NestJS services (user, payment, knowledge, conversation, evolution)
- Fix nginx healthcheck to use 127.0.0.1 instead of localhost (IPv6 issue)
- Add healthcheck configuration to docker-compose for all backend services
- Use start_period to allow services time to initialize before health checks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 02:13:42 -08:00
hailin
2f9fd3995b
fix: 使用jq正确处理package.json移除workspace依赖
...
sed直接删除行会导致JSON尾随逗号问题,改用jq
正确删除dependencies中的@iconsulting/shared键
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 08:49:41 -08:00
hailin
7417bc1d82
fix: 移除workspace协议依赖解决npm安装问题
...
npm不支持pnpm的workspace:*协议,在安装依赖前
使用sed移除@iconsulting相关依赖行,shared包
已通过COPY单独复制到node_modules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 08:45:38 -08:00
hailin
287aeb5c72
fix: 修复pnpm monorepo Docker构建问题
...
- 移除runner阶段的pnpm安装(不再需要)
- 使用npm install替代直接复制node_modules
- 单独复制@iconsulting/shared构建产物
- 解决pnpm符号链接在Docker中失效的问题
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 08:32:58 -08:00
hailin
a7add8ff90
Initial commit: iConsulting 香港移民咨询智能客服系统
...
项目架构:
- Monorepo (pnpm + Turborepo)
- 后端: NestJS 微服务 + Claude Agent SDK
- 前端: React + Vite + Ant Design
包含服务:
- conversation-service: 对话服务 (Claude AI)
- user-service: 用户认证服务
- payment-service: 支付服务 (支付宝/微信/Stripe)
- knowledge-service: 知识库服务 (RAG + Neo4j)
- evolution-service: 自我进化服务
- web-client: 用户前端
- admin-client: 管理后台
基础设施:
- PostgreSQL + Redis + Neo4j
- Kong API Gateway
- Nginx 反向代理
- Docker Compose 部署配置
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 00:01:12 -08:00