MinIO presigned URLs use Docker-internal hostname (minio:9000), making
them inaccessible from both Claude API servers and user browsers.
Changes:
- file-service: add /files/:id/content and /files/:id/thumbnail proxy
endpoints that stream file data from MinIO
- file-service: toResponseDto now returns API proxy paths instead of
MinIO presigned URLs
- coordinator: buildAttachmentBlocks now downloads files via file-service
internal API (http://file-service:3006) and converts to base64 for
Claude API (images, PDFs) or embeds text content directly
- Configurable FILE_SERVICE_URL env var for service-to-service calls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Coordinator now sends all attachment types to Claude:
- Images → native image blocks (existing)
- PDF → native document blocks (Claude PDF support)
- Text files (txt, csv, json, md) → text blocks with filename
Extracted common buildAttachmentBlocks() helper.
2. File-service generates thumbnails on image upload:
- Uses sharp to resize to 400x400 max (inside fit, no upscale)
- Output as WebP at 80% quality for smaller file size
- Stored in MinIO under thumbnails/ prefix
- Generated for both direct upload and presigned URL confirm
- Non-blocking: thumbnail failure doesn't break upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FileORM had tenant_id column but FileEntity domain class was missing it,
causing "column FileORM.tenant_id does not exist" errors on production.
- Add tenantId to FileEntity (constructor, create, fromPersistence)
- Pass tenantId in repository toEntity() mapping
- Add idempotent migration script for files.tenant_id + indexes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
- 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>
Fix DataTypeNotSupportedError by explicitly specifying PostgreSQL column types
for nullable fields that TypeORM was incorrectly inferring as Object type.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add MinIO object storage to docker-compose infrastructure
- Create file-service microservice for upload management with presigned URLs
- Add files table to database schema
- Update nginx and Kong for MinIO proxy routes
- Implement file upload UI in chat InputArea with drag-and-drop
- Add attachment preview in MessageBubble component
- Update conversation-service to handle multimodal messages
- Add Claude Vision API integration for image analysis
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>