Compare commits
10 Commits
1c6dfc4f8b
...
23c1d33adb
| Author | SHA1 | Date |
|---|---|---|
|
|
23c1d33adb | |
|
|
a8220921cb | |
|
|
ba85b076ad | |
|
|
f938c63cf6 | |
|
|
bf96452f1b | |
|
|
8b68d8a5cf | |
|
|
bb15bfef28 | |
|
|
405ffafe11 | |
|
|
684a010537 | |
|
|
f724a71ade |
|
|
@ -0,0 +1,79 @@
|
|||
# Dependencies
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Build outputs
|
||||
dist
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.docker
|
||||
|
||||
# IDE files
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory
|
||||
coverage
|
||||
*.lcov
|
||||
.nyc_output
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Docker
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
.dockerignore
|
||||
|
||||
# Data directories (will be mounted as volumes)
|
||||
data
|
||||
uploads
|
||||
results
|
||||
|
||||
# Temporary files
|
||||
temp
|
||||
tmp
|
||||
|
||||
# Test files
|
||||
tests
|
||||
test-*.sh
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
docs
|
||||
infrastructure.md
|
||||
|
||||
# Other
|
||||
.claude
|
||||
.mcp.json
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Application Configuration
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
LOG_LEVEL=debug
|
||||
|
||||
# CORS Configuration
|
||||
CORS_ORIGIN=*
|
||||
|
||||
# Database Configuration
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=banatie_db
|
||||
DB_USER=banatie_user
|
||||
DB_PASSWORD=development_password
|
||||
|
||||
# MinIO Storage Configuration
|
||||
STORAGE_TYPE=minio
|
||||
MINIO_ENDPOINT=minio:9000
|
||||
MINIO_ACCESS_KEY=minioadmin
|
||||
MINIO_SECRET_KEY=minioadmin
|
||||
MINIO_USE_SSL=false
|
||||
MINIO_BUCKET_PREFIX=banatie
|
||||
MINIO_PUBLIC_URL=http://localhost:9000
|
||||
|
||||
# AI Service Configuration (using the existing API key from .env)
|
||||
GEMINI_API_KEY=AIzaSyBaOt9JMPGKA3811FL-ssf1n5Hh9Jauly8
|
||||
|
||||
# File Upload Configuration
|
||||
MAX_FILE_SIZE=5242880
|
||||
MAX_FILES=3
|
||||
|
||||
# Multi-tenancy Configuration
|
||||
DEFAULT_ORG_ID=demo
|
||||
DEFAULT_USER_ID=guest
|
||||
|
||||
# Directory Configuration (for Docker containers)
|
||||
RESULTS_DIR=/app/results
|
||||
UPLOADS_DIR=/app/uploads/temp
|
||||
|
||||
# Logging Configuration
|
||||
LOG_LEVEL=info
|
||||
|
|
@ -77,4 +77,13 @@ uploads/
|
|||
|
||||
# Temporary files
|
||||
temp/
|
||||
tmp/
|
||||
tmp/
|
||||
|
||||
# Docker data directories
|
||||
data/
|
||||
.env.docker
|
||||
.env.production
|
||||
|
||||
# Docker volumes (persistent data)
|
||||
postgres-data/
|
||||
minio-data/
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"context7": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@upstash/context7-mcp",
|
||||
"--api-key",
|
||||
"ctx7sk-48cb1995-935a-4cc5-b9b0-535d600ea5e6"
|
||||
],
|
||||
"env": {}
|
||||
},
|
||||
"brave-search": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-brave-search"
|
||||
],
|
||||
"env": {
|
||||
"BRAVE_API_KEY": "BSAcRGGikEzY4B2j3NZ8Qy5NYh9l4HZ"
|
||||
}
|
||||
},
|
||||
"postgres": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=unrestricted"],
|
||||
"env": {
|
||||
"DATABASE_URI": "postgresql://postgres:postgres@localhost:5433/prime_db"
|
||||
}
|
||||
},
|
||||
"mastra": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["@mastra/mcp-docs-server@latest"],
|
||||
"env": {}
|
||||
},
|
||||
"browsermcp": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["-y", "@browsermcp/mcp@latest"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# Development stage - for docker-compose development with hot reload
|
||||
FROM node:20-alpine AS development
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm globally
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy package files for dependency installation
|
||||
COPY package*.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Use development command with hot reload
|
||||
CMD ["pnpm", "dev"]
|
||||
|
||||
# Builder stage - for production build
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm globally
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json pnpm-lock.yaml ./
|
||||
|
||||
# Install all dependencies (including dev dependencies for build)
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build TypeScript to JavaScript
|
||||
RUN pnpm build
|
||||
|
||||
# Production stage - optimized final image
|
||||
FROM node:20-alpine AS production
|
||||
WORKDIR /app
|
||||
|
||||
# Create non-root user for security
|
||||
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
|
||||
|
||||
# Install pnpm globally
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Copy package files
|
||||
COPY --from=builder /app/package*.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml ./
|
||||
|
||||
# Install only production dependencies
|
||||
RUN pnpm install --prod --frozen-lockfile
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# Create required directories and set ownership
|
||||
RUN mkdir -p logs && chown -R nodejs:nodejs /app
|
||||
|
||||
# Switch to non-root user
|
||||
USER nodejs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD node -e "require('http').request('http://localhost:3000/health', (res) => { \
|
||||
process.exit(res.statusCode === 200 ? 0 : 1) \
|
||||
}).on('error', () => process.exit(1)).end()"
|
||||
|
||||
# Start the application
|
||||
CMD ["node", "dist/server.js"]
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
target: development
|
||||
container_name: banatie-app-dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./src:/app/src # Hot reload for development
|
||||
- ./logs:/app/logs # Persistent logs
|
||||
networks:
|
||||
- banatie-dev
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
minio:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
env_file:
|
||||
- .env.docker
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: banatie-postgres-dev
|
||||
ports:
|
||||
- "5434:5432" # Avoid conflicts with other PostgreSQL instances
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql
|
||||
networks:
|
||||
- banatie-dev
|
||||
environment:
|
||||
POSTGRES_DB: banatie_db
|
||||
POSTGRES_USER: banatie_user
|
||||
POSTGRES_PASSWORD: development_password
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U banatie_user -d banatie_db"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: banatie-minio-dev
|
||||
ports:
|
||||
- "9000:9000" # S3 API
|
||||
- "9001:9001" # Web Console
|
||||
volumes:
|
||||
- ./data/minio:/data
|
||||
networks:
|
||||
- banatie-dev
|
||||
environment:
|
||||
MINIO_ROOT_USER: minioadmin
|
||||
MINIO_ROOT_PASSWORD: minioadmin
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
|
||||
minio-init:
|
||||
image: minio/mc:latest
|
||||
container_name: banatie-minio-init
|
||||
networks:
|
||||
- banatie-dev
|
||||
depends_on:
|
||||
minio:
|
||||
condition: service_healthy
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
echo 'Setting up MinIO alias...';
|
||||
mc alias set minio http://minio:9000 minioadmin minioadmin;
|
||||
|
||||
echo 'Creating demo bucket...';
|
||||
mc mb --ignore-existing minio/banatie-demo;
|
||||
|
||||
echo 'Setting up public read policy for generated images...';
|
||||
mc anonymous set download minio/banatie-demo/users/guest/generated;
|
||||
|
||||
echo 'Creating banatie service user...';
|
||||
mc admin user add minio banatie-user banatie-password;
|
||||
|
||||
echo 'Attaching readwrite policy to banatie user...';
|
||||
mc admin policy attach minio readwrite --user=banatie-user;
|
||||
|
||||
echo 'Creating lifecycle policy for temp files (7 days retention)...';
|
||||
cat > /tmp/lifecycle.json << EOF
|
||||
{
|
||||
\"Rules\": [
|
||||
{
|
||||
\"ID\": \"temp-files-cleanup\",
|
||||
\"Status\": \"Enabled\",
|
||||
\"Filter\": {
|
||||
\"Prefix\": \"users/\"
|
||||
},
|
||||
\"Expiration\": {
|
||||
\"Days\": 7
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
mc ilm import minio/banatie-demo < /tmp/lifecycle.json;
|
||||
|
||||
echo 'MinIO initialization completed successfully!';
|
||||
exit 0;
|
||||
"
|
||||
restart: "no"
|
||||
|
||||
networks:
|
||||
banatie-dev:
|
||||
driver: bridge
|
||||
name: banatie-dev-network
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
driver: local
|
||||
minio-data:
|
||||
driver: local
|
||||
|
|
@ -0,0 +1,937 @@
|
|||
# Banatie Service Infrastructure Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This document defines the complete containerization and deployment architecture for the Banatie AI image generation service with MinIO object storage and PostgreSQL database integration.
|
||||
|
||||
## Architecture Summary
|
||||
|
||||
### Core Principles
|
||||
- **Complete Service Isolation**: Banatie ecosystem is fully isolated from core VPS services
|
||||
- **Dedicated Database**: Separate PostgreSQL container exclusively for Banatie
|
||||
- **S3-Compatible Storage**: MinIO for scalable object storage with multi-tenant support
|
||||
- **Container-First Approach**: All components run as Docker containers
|
||||
- **Network Segregation**: Internal communication via dedicated Docker networks
|
||||
|
||||
### Service Components
|
||||
|
||||
```
|
||||
Banatie Ecosystem (Isolated)
|
||||
├── Banatie App Container (Node.js/TypeScript/Express)
|
||||
├── PostgreSQL Container (Dedicated instance)
|
||||
└── MinIO Container (S3-compatible object storage)
|
||||
```
|
||||
|
||||
## Network Architecture
|
||||
|
||||
### Production Networks
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
banatie-network:
|
||||
driver: bridge
|
||||
internal: true # No external internet access
|
||||
|
||||
proxy-network:
|
||||
external: true # Existing Caddy reverse proxy network
|
||||
```
|
||||
|
||||
### Network Access Matrix
|
||||
|
||||
| Service | banatie-network | proxy-network | External Access |
|
||||
|---------|----------------|---------------|-----------------|
|
||||
| Banatie App | ✅ Internal | ✅ HTTP only | ❌ Direct |
|
||||
| PostgreSQL | ✅ Internal | ❌ None | ❌ None |
|
||||
| MinIO | ✅ Internal | ✅ Console only | ❌ Direct |
|
||||
| Caddy Proxy | ❌ None | ✅ Routing | ✅ Internet |
|
||||
|
||||
### VPS Integration Points
|
||||
|
||||
**Isolation from Core Services:**
|
||||
- **NO** shared resources with existing PostgreSQL (`/opt/services/`)
|
||||
- **NO** access to NextCloud, Gitea, or other core services
|
||||
- **ONLY** connection point: Caddy reverse proxy for HTTP routing
|
||||
|
||||
**Shared Infrastructure:**
|
||||
- Caddy reverse proxy for SSL termination and routing
|
||||
- Host filesystem for persistent data storage
|
||||
- UFW firewall rules and security policies
|
||||
|
||||
## Directory Structure
|
||||
|
||||
### Development Environment
|
||||
```
|
||||
banatie-service/
|
||||
├── src/ # Application source code
|
||||
├── Dockerfile # Multi-stage container build
|
||||
├── docker-compose.yml # Local development setup
|
||||
├── .env.example # Environment template
|
||||
├── .dockerignore # Build exclusions
|
||||
└── data/ # Local development data
|
||||
├── postgres/ # PostgreSQL data
|
||||
└── minio/ # MinIO data
|
||||
```
|
||||
|
||||
### Production Environment (VPS)
|
||||
```
|
||||
/opt/banatie/ # Isolated deployment directory
|
||||
├── docker-compose.yml # Production configuration
|
||||
├── .env # Production environment (secure)
|
||||
├── Dockerfile # Production Dockerfile
|
||||
├── data/ # Persistent data storage
|
||||
│ ├── postgres/ # PostgreSQL data
|
||||
│ └── minio/ # MinIO data
|
||||
├── configs/ # Service configurations
|
||||
├── logs/ # Application logs
|
||||
└── scripts/ # Deployment scripts
|
||||
```
|
||||
|
||||
## Container Specifications
|
||||
|
||||
### 1. Banatie Application Container
|
||||
|
||||
**Base Image**: `node:20-alpine`
|
||||
**Build Strategy**: Multi-stage for optimization
|
||||
**Runtime**: Node.js with TypeScript compilation
|
||||
|
||||
```dockerfile
|
||||
# Multi-stage build for production
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json pnpm-lock.yaml ./
|
||||
RUN npm install -g pnpm && pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
RUN pnpm build
|
||||
|
||||
FROM node:20-alpine
|
||||
WORKDIR /app
|
||||
RUN npm install -g pnpm
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package*.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml ./
|
||||
RUN pnpm install --prod --frozen-lockfile
|
||||
EXPOSE 3000
|
||||
CMD ["node", "dist/server.js"]
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
- Hot-reload support in development
|
||||
- Production-optimized build with dependencies pruning
|
||||
- Health check endpoints for monitoring
|
||||
- Structured logging to stdout
|
||||
|
||||
### 2. PostgreSQL Container
|
||||
|
||||
**Image**: `postgres:15-alpine`
|
||||
**Purpose**: Metadata storage for user sessions, image metadata, organization data
|
||||
**Data**: User accounts, image metadata, upload sessions, organization settings
|
||||
|
||||
**Database Schema:**
|
||||
- `users` - User authentication and profiles
|
||||
- `organizations` - Multi-tenant organization data
|
||||
- `images` - Generated image metadata and references
|
||||
- `sessions` - User session management
|
||||
- `uploads` - Temporary upload tracking
|
||||
|
||||
### 3. MinIO Container
|
||||
|
||||
**Image**: `minio/minio:latest`
|
||||
**Purpose**: S3-compatible object storage for images and files
|
||||
**Ports**: 9000 (S3 API), 9001 (Web Console)
|
||||
|
||||
**Storage Strategy:**
|
||||
- Persistent volumes for data durability
|
||||
- Bucket-per-organization architecture
|
||||
- Lifecycle policies for temporary file cleanup
|
||||
- Presigned URLs for direct browser uploads
|
||||
|
||||
## Multi-Tenant Storage Architecture
|
||||
|
||||
### MinIO Bucket Organization
|
||||
|
||||
```
|
||||
banatie-{org-id}/ # Organization bucket (e.g., banatie-demo)
|
||||
├── users/
|
||||
│ └── {user-id}/ # User-specific namespace
|
||||
│ ├── generated/ # AI-generated images
|
||||
│ │ ├── 2024/01/ # Date-based organization
|
||||
│ │ └── thumbnails/ # Generated thumbnails
|
||||
│ ├── references/ # User-uploaded reference images
|
||||
│ └── temp/ # Temporary processing files (7-day TTL)
|
||||
├── shared/ # Organization-wide shared resources
|
||||
│ ├── templates/ # Shared image templates
|
||||
│ └── public/ # Public organization assets
|
||||
└── metadata/ # JSON metadata files
|
||||
├── users.json # User directory metadata
|
||||
└── policies.json # Access control policies
|
||||
```
|
||||
|
||||
### Demo Organization Setup
|
||||
|
||||
**Default Configuration:**
|
||||
- **Organization**: `demo` (org-id: demo)
|
||||
- **User**: `guest` (user-id: guest)
|
||||
- **Bucket**: `banatie-demo`
|
||||
- **Access**: Public read for demo images
|
||||
|
||||
**Demo Bucket Structure:**
|
||||
```
|
||||
banatie-demo/
|
||||
├── users/
|
||||
│ └── guest/
|
||||
│ ├── generated/ # Guest user's generated images
|
||||
│ └── references/ # Guest user's reference uploads
|
||||
└── shared/
|
||||
└── examples/ # Example images for UI
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
### Development Environment (.env)
|
||||
|
||||
```env
|
||||
# Application Configuration
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
LOG_LEVEL=debug
|
||||
|
||||
# Database Configuration
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=banatie_db
|
||||
DB_USER=banatie_user
|
||||
DB_PASSWORD=development_password
|
||||
|
||||
# MinIO Configuration
|
||||
STORAGE_TYPE=minio
|
||||
MINIO_ENDPOINT=minio:9000
|
||||
MINIO_ACCESS_KEY=minioadmin
|
||||
MINIO_SECRET_KEY=minioadmin
|
||||
MINIO_USE_SSL=false
|
||||
MINIO_BUCKET_PREFIX=banatie
|
||||
|
||||
# AI Service Configuration
|
||||
GEMINI_API_KEY=your_gemini_api_key_here
|
||||
|
||||
# Multi-tenancy Configuration
|
||||
DEFAULT_ORG_ID=demo
|
||||
DEFAULT_USER_ID=guest
|
||||
```
|
||||
|
||||
### Production Environment (.env.production)
|
||||
|
||||
```env
|
||||
# Application Configuration
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Database Configuration
|
||||
DB_HOST=banatie-postgres
|
||||
DB_PORT=5432
|
||||
DB_NAME=banatie_db
|
||||
DB_USER=banatie_user
|
||||
DB_PASSWORD=${SECURE_DB_PASSWORD}
|
||||
|
||||
# MinIO Configuration
|
||||
STORAGE_TYPE=minio
|
||||
MINIO_ENDPOINT=banatie-minio:9000
|
||||
MINIO_ACCESS_KEY=${SECURE_MINIO_ACCESS_KEY}
|
||||
MINIO_SECRET_KEY=${SECURE_MINIO_SECRET_KEY}
|
||||
MINIO_USE_SSL=false
|
||||
MINIO_BUCKET_PREFIX=banatie
|
||||
|
||||
# AI Service Configuration
|
||||
GEMINI_API_KEY=${SECURE_GEMINI_API_KEY}
|
||||
|
||||
# Multi-tenancy Configuration
|
||||
DEFAULT_ORG_ID=demo
|
||||
DEFAULT_USER_ID=guest
|
||||
|
||||
# Security
|
||||
JWT_SECRET=${SECURE_JWT_SECRET}
|
||||
SESSION_SECRET=${SECURE_SESSION_SECRET}
|
||||
```
|
||||
|
||||
## Docker Compose Configurations
|
||||
|
||||
### Development Configuration
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml (Local Development)
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
target: development
|
||||
container_name: banatie-app-dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./src:/app/src # Hot reload
|
||||
- ./logs:/app/logs
|
||||
networks:
|
||||
- banatie-dev
|
||||
depends_on:
|
||||
- postgres
|
||||
- minio
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: banatie-postgres-dev
|
||||
ports:
|
||||
- "5433:5432" # Avoid conflicts with system PostgreSQL
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql
|
||||
networks:
|
||||
- banatie-dev
|
||||
environment:
|
||||
POSTGRES_DB: banatie_db
|
||||
POSTGRES_USER: banatie_user
|
||||
POSTGRES_PASSWORD: development_password
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U banatie_user -d banatie_db"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: banatie-minio-dev
|
||||
ports:
|
||||
- "9000:9000" # S3 API
|
||||
- "9001:9001" # Web Console
|
||||
volumes:
|
||||
- ./data/minio:/data
|
||||
networks:
|
||||
- banatie-dev
|
||||
environment:
|
||||
MINIO_ROOT_USER: minioadmin
|
||||
MINIO_ROOT_PASSWORD: minioadmin
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
networks:
|
||||
banatie-dev:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### Production Configuration
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml (Production on VPS)
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
banatie-app:
|
||||
build:
|
||||
context: .
|
||||
target: production
|
||||
container_name: banatie-app
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- banatie-network
|
||||
- proxy-network
|
||||
depends_on:
|
||||
banatie-postgres:
|
||||
condition: service_healthy
|
||||
banatie-minio:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
banatie-postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: banatie-postgres
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- banatie-network
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql
|
||||
environment:
|
||||
POSTGRES_DB: banatie_db
|
||||
POSTGRES_USER: banatie_user
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U banatie_user -d banatie_db"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
banatie-minio:
|
||||
image: minio/minio:latest
|
||||
container_name: banatie-minio
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- banatie-network
|
||||
- proxy-network
|
||||
volumes:
|
||||
- ./data/minio:/data
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
networks:
|
||||
banatie-network:
|
||||
driver: bridge
|
||||
internal: true # No external internet access
|
||||
|
||||
proxy-network:
|
||||
external: true # Existing Caddy network
|
||||
```
|
||||
|
||||
## Caddy Integration
|
||||
|
||||
### Caddy Configuration Addition
|
||||
|
||||
Add to existing Caddyfile in `/opt/services/configs/caddy/Caddyfile`:
|
||||
|
||||
```caddy
|
||||
# Banatie App - Main API
|
||||
banatie.app {
|
||||
reverse_proxy banatie-app:3000
|
||||
|
||||
# Security headers
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "DENY"
|
||||
X-XSS-Protection "1; mode=block"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
}
|
||||
|
||||
# Rate limiting
|
||||
rate_limit {
|
||||
zone banatie_api {
|
||||
key {remote_host}
|
||||
events 100
|
||||
window 1m
|
||||
}
|
||||
}
|
||||
|
||||
# Logging
|
||||
log {
|
||||
output file /opt/services/logs/banatie_access.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# MinIO Console - Admin Interface
|
||||
minio.banatie.app {
|
||||
reverse_proxy banatie-minio:9001
|
||||
|
||||
# Security headers for console
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "SAMEORIGIN"
|
||||
}
|
||||
|
||||
# Logging
|
||||
log {
|
||||
output file /opt/services/logs/minio_console_access.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# MinIO S3 API - Direct file access
|
||||
s3.banatie.app {
|
||||
reverse_proxy banatie-minio:9000
|
||||
|
||||
# CORS for browser uploads
|
||||
header {
|
||||
Access-Control-Allow-Origin "*"
|
||||
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
||||
Access-Control-Allow-Headers "Content-Type, Authorization"
|
||||
}
|
||||
|
||||
# Rate limiting for uploads
|
||||
rate_limit {
|
||||
zone banatie_s3 {
|
||||
key {remote_host}
|
||||
events 50
|
||||
window 1m
|
||||
}
|
||||
}
|
||||
|
||||
# Logging
|
||||
log {
|
||||
output file /opt/services/logs/minio_s3_access.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Service Implementation Strategy
|
||||
|
||||
### 1. Storage Service Abstraction
|
||||
|
||||
Create `src/services/StorageService.ts`:
|
||||
|
||||
```typescript
|
||||
export interface StorageService {
|
||||
// Bucket management
|
||||
createBucket(orgId: string): Promise<void>;
|
||||
deleteBucket(orgId: string): Promise<void>;
|
||||
listBuckets(): Promise<string[]>;
|
||||
|
||||
// File operations
|
||||
uploadFile(orgId: string, userId: string, fileName: string, buffer: Buffer, contentType: string): Promise<string>;
|
||||
downloadFile(orgId: string, userId: string, fileName: string): Promise<Buffer>;
|
||||
deleteFile(orgId: string, userId: string, fileName: string): Promise<void>;
|
||||
|
||||
// URL generation
|
||||
getPresignedUploadUrl(orgId: string, userId: string, fileName: string, expirySeconds: number): Promise<string>;
|
||||
getPresignedDownloadUrl(orgId: string, userId: string, fileName: string, expirySeconds: number): Promise<string>;
|
||||
|
||||
// File management
|
||||
listUserFiles(orgId: string, userId: string): Promise<FileMetadata[]>;
|
||||
moveFile(fromPath: string, toPath: string): Promise<void>;
|
||||
copyFile(fromPath: string, toPath: string): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. MinIO Implementation
|
||||
|
||||
Create `src/services/MinioStorageService.ts`:
|
||||
|
||||
```typescript
|
||||
import { Client as MinioClient } from 'minio';
|
||||
import { StorageService } from './StorageService';
|
||||
|
||||
export class MinioStorageService implements StorageService {
|
||||
private client: MinioClient;
|
||||
private bucketPrefix: string;
|
||||
|
||||
constructor(
|
||||
endpoint: string,
|
||||
accessKey: string,
|
||||
secretKey: string,
|
||||
useSSL: boolean = false,
|
||||
bucketPrefix: string = 'banatie'
|
||||
) {
|
||||
this.client = new MinioClient({
|
||||
endPoint: endpoint.replace(/^https?:\/\//, ''),
|
||||
port: useSSL ? 443 : 9000,
|
||||
useSSL,
|
||||
accessKey,
|
||||
secretKey
|
||||
});
|
||||
this.bucketPrefix = bucketPrefix;
|
||||
}
|
||||
|
||||
private getBucketName(orgId: string): string {
|
||||
return `${this.bucketPrefix}-${orgId}`;
|
||||
}
|
||||
|
||||
private getFilePath(userId: string, category: 'generated' | 'references' | 'temp', fileName: string): string {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
|
||||
return `users/${userId}/${category}/${year}/${month}/${fileName}`;
|
||||
}
|
||||
|
||||
// Implementation methods...
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Database Schema
|
||||
|
||||
Create `scripts/init-db.sql`:
|
||||
|
||||
```sql
|
||||
-- Banatie Database Initialization
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- Organizations table
|
||||
CREATE TABLE organizations (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
settings JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Users table
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
username VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(255),
|
||||
role VARCHAR(50) DEFAULT 'user',
|
||||
settings JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(organization_id, username)
|
||||
);
|
||||
|
||||
-- Images table
|
||||
CREATE TABLE images (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
original_prompt TEXT,
|
||||
enhanced_prompt TEXT,
|
||||
model_used VARCHAR(100),
|
||||
file_size BIGINT,
|
||||
content_type VARCHAR(100),
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Upload sessions table (for tracking multi-part uploads)
|
||||
CREATE TABLE upload_sessions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
session_data JSONB NOT NULL,
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX idx_users_org_id ON users(organization_id);
|
||||
CREATE INDEX idx_images_user_id ON images(user_id);
|
||||
CREATE INDEX idx_images_created_at ON images(created_at);
|
||||
CREATE INDEX idx_upload_sessions_user_id ON upload_sessions(user_id);
|
||||
CREATE INDEX idx_upload_sessions_expires_at ON upload_sessions(expires_at);
|
||||
|
||||
-- Insert demo organization and user
|
||||
INSERT INTO organizations (id, name, slug) VALUES
|
||||
('00000000-0000-0000-0000-000000000001', 'Demo Organization', 'demo');
|
||||
|
||||
INSERT INTO users (id, organization_id, username, role) VALUES
|
||||
('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000001', 'guest', 'user');
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Local Development Setup
|
||||
|
||||
1. **Clone Repository**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd banatie-service
|
||||
```
|
||||
|
||||
2. **Environment Configuration**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with development settings
|
||||
```
|
||||
|
||||
3. **Start Development Environment**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. **Verify Services**
|
||||
```bash
|
||||
# Check service status
|
||||
docker-compose ps
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f app
|
||||
|
||||
# Access services
|
||||
# App: http://localhost:3000
|
||||
# MinIO Console: http://localhost:9001 (minioadmin/minioadmin)
|
||||
# PostgreSQL: localhost:5433
|
||||
```
|
||||
|
||||
5. **Development with Hot Reload**
|
||||
```bash
|
||||
# Edit source files in src/
|
||||
# Changes automatically reload in container
|
||||
```
|
||||
|
||||
### Testing Workflow
|
||||
|
||||
```bash
|
||||
# Run tests in development environment
|
||||
docker-compose exec app pnpm test
|
||||
|
||||
# Run with coverage
|
||||
docker-compose exec app pnpm test:coverage
|
||||
|
||||
# Run linting
|
||||
docker-compose exec app pnpm lint
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### VPS Deployment Process
|
||||
|
||||
1. **Prepare VPS Directory**
|
||||
```bash
|
||||
# SSH to VPS
|
||||
ssh usul-vps
|
||||
|
||||
# Create Banatie directory
|
||||
sudo mkdir -p /opt/banatie
|
||||
sudo chown usul:usul /opt/banatie
|
||||
cd /opt/banatie
|
||||
```
|
||||
|
||||
2. **Clone and Configure**
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repository-url> .
|
||||
|
||||
# Create production environment
|
||||
cp .env.example .env
|
||||
# Edit .env with production settings and secure passwords
|
||||
```
|
||||
|
||||
3. **Generate Secure Credentials**
|
||||
```bash
|
||||
# Generate secure passwords
|
||||
DB_PASSWORD=$(openssl rand -base64 32 | tr -d '\n\r ')
|
||||
MINIO_ACCESS_KEY=$(openssl rand -base64 20 | tr -d '\n\r ')
|
||||
MINIO_SECRET_KEY=$(openssl rand -base64 40 | tr -d '\n\r ')
|
||||
JWT_SECRET=$(openssl rand -base64 64 | tr -d '\n\r ')
|
||||
|
||||
# Add to .env file
|
||||
echo "DB_PASSWORD=$DB_PASSWORD" >> .env
|
||||
echo "MINIO_ACCESS_KEY=$MINIO_ACCESS_KEY" >> .env
|
||||
echo "MINIO_SECRET_KEY=$MINIO_SECRET_KEY" >> .env
|
||||
echo "JWT_SECRET=$JWT_SECRET" >> .env
|
||||
|
||||
# Secure the file
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
4. **Update Caddy Configuration**
|
||||
```bash
|
||||
# Add Banatie routes to Caddyfile
|
||||
sudo nano /opt/services/configs/caddy/Caddyfile
|
||||
# Add the Banatie configuration from above
|
||||
|
||||
# Reload Caddy
|
||||
cd /opt/services
|
||||
./manage-services.sh caddy reload
|
||||
```
|
||||
|
||||
5. **Deploy Services**
|
||||
```bash
|
||||
cd /opt/banatie
|
||||
|
||||
# Build and start services
|
||||
docker-compose up -d
|
||||
|
||||
# Verify deployment
|
||||
docker-compose ps
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
6. **Verify Deployment**
|
||||
```bash
|
||||
# Check health endpoints
|
||||
curl https://banatie.app/health
|
||||
curl https://minio.banatie.app/minio/health/live
|
||||
|
||||
# Check logs
|
||||
docker-compose logs banatie-app
|
||||
docker-compose logs banatie-postgres
|
||||
docker-compose logs banatie-minio
|
||||
```
|
||||
|
||||
### Manual Update Process
|
||||
|
||||
```bash
|
||||
# SSH to VPS
|
||||
ssh usul-vps
|
||||
cd /opt/banatie
|
||||
|
||||
# Pull latest changes
|
||||
git pull origin main
|
||||
|
||||
# Rebuild and restart
|
||||
docker-compose build banatie-app
|
||||
docker-compose up -d
|
||||
|
||||
# Verify update
|
||||
docker-compose logs -f banatie-app
|
||||
curl https://banatie.app/health
|
||||
```
|
||||
|
||||
## Monitoring and Maintenance
|
||||
|
||||
### Health Checks
|
||||
|
||||
**Application Health Check** (`/health`):
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2024-01-01T12:00:00.000Z",
|
||||
"services": {
|
||||
"database": "connected",
|
||||
"minio": "connected",
|
||||
"gemini_api": "accessible"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
**MinIO Health Check** (`/minio/health/live`):
|
||||
- Returns 200 OK when MinIO is operational
|
||||
- Used by Docker healthcheck and monitoring
|
||||
|
||||
### Log Management
|
||||
|
||||
**Application Logs**:
|
||||
- Location: `/opt/banatie/logs/`
|
||||
- Format: Structured JSON
|
||||
- Rotation: Daily with 30-day retention
|
||||
|
||||
**Access Logs**:
|
||||
- Caddy logs: `/opt/services/logs/banatie_*.log`
|
||||
- Format: JSON with request/response details
|
||||
|
||||
### Backup Strategy
|
||||
|
||||
**Database Backup**:
|
||||
```bash
|
||||
# Create backup
|
||||
docker exec banatie-postgres pg_dump -U banatie_user banatie_db > banatie_db_backup.sql
|
||||
|
||||
# Restore backup
|
||||
docker exec -i banatie-postgres psql -U banatie_user banatie_db < banatie_db_backup.sql
|
||||
```
|
||||
|
||||
**MinIO Data Backup**:
|
||||
```bash
|
||||
# Backup MinIO data
|
||||
sudo tar -czf banatie_minio_backup.tar.gz -C /opt/banatie/data minio/
|
||||
|
||||
# Restore MinIO data
|
||||
sudo tar -xzf banatie_minio_backup.tar.gz -C /opt/banatie/data
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Container Security
|
||||
- Non-root users in containers
|
||||
- Read-only root filesystems where possible
|
||||
- Resource limits (memory, CPU)
|
||||
- Health checks for automatic restart
|
||||
|
||||
### Network Security
|
||||
- Internal network isolation
|
||||
- No direct external access to database or MinIO
|
||||
- Rate limiting at proxy level
|
||||
- HTTPS-only external access
|
||||
|
||||
### Data Security
|
||||
- Encrypted environment variables
|
||||
- Secure secret generation
|
||||
- Regular credential rotation
|
||||
- Audit logging
|
||||
|
||||
### Access Control
|
||||
- MinIO bucket policies per organization
|
||||
- PostgreSQL row-level security
|
||||
- JWT-based API authentication
|
||||
- Role-based access control
|
||||
|
||||
## Future Scalability
|
||||
|
||||
### Horizontal Scaling Options
|
||||
- Multiple Banatie app containers behind load balancer
|
||||
- MinIO distributed mode for storage scaling
|
||||
- PostgreSQL read replicas for read scaling
|
||||
- Redis for session storage and caching
|
||||
|
||||
### Multi-Region Deployment
|
||||
- Regional MinIO clusters
|
||||
- Database replication
|
||||
- CDN integration for static assets
|
||||
- Geo-distributed deployment
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Container Won't Start**:
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs [service-name]
|
||||
|
||||
# Check resource usage
|
||||
docker stats
|
||||
|
||||
# Rebuild container
|
||||
docker-compose build [service-name]
|
||||
docker-compose up -d [service-name]
|
||||
```
|
||||
|
||||
**Database Connection Issues**:
|
||||
```bash
|
||||
# Test database connectivity
|
||||
docker exec banatie-postgres pg_isready -U banatie_user -d banatie_db
|
||||
|
||||
# Check environment variables
|
||||
docker exec banatie-app env | grep DB_
|
||||
|
||||
# Restart database
|
||||
docker-compose restart banatie-postgres
|
||||
```
|
||||
|
||||
**MinIO Access Issues**:
|
||||
```bash
|
||||
# Check MinIO status
|
||||
docker exec banatie-minio mc admin info local
|
||||
|
||||
# Test S3 API
|
||||
curl -f http://localhost:9000/minio/health/live
|
||||
|
||||
# Check access keys
|
||||
docker exec banatie-app env | grep MINIO_
|
||||
```
|
||||
|
||||
**Network Connectivity**:
|
||||
```bash
|
||||
# Check networks
|
||||
docker network ls
|
||||
docker network inspect banatie_banatie-network
|
||||
|
||||
# Test internal connectivity
|
||||
docker exec banatie-app ping banatie-postgres
|
||||
docker exec banatie-app ping banatie-minio
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Last Updated**: 2024-09-26
|
||||
**Maintained By**: Banatie Development Team
|
||||
|
|
@ -43,7 +43,8 @@
|
|||
"express-rate-limit": "^7.4.1",
|
||||
"express-validator": "^7.2.0",
|
||||
"helmet": "^8.0.0",
|
||||
"mime": "^4.1.0",
|
||||
"mime": "3.0.0",
|
||||
"minio": "^8.0.6",
|
||||
"multer": "^2.0.2",
|
||||
"winston": "^3.17.0"
|
||||
},
|
||||
|
|
|
|||
310
pnpm-lock.yaml
310
pnpm-lock.yaml
|
|
@ -30,8 +30,11 @@ importers:
|
|||
specifier: ^8.0.0
|
||||
version: 8.1.0
|
||||
mime:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
specifier: 3.0.0
|
||||
version: 3.0.0
|
||||
minio:
|
||||
specifier: ^8.0.6
|
||||
version: 8.0.6
|
||||
multer:
|
||||
specifier: ^2.0.2
|
||||
version: 2.0.2
|
||||
|
|
@ -767,6 +770,9 @@ packages:
|
|||
resolution: {integrity: sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@zxing/text-encoding@0.9.0':
|
||||
resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==}
|
||||
|
||||
accepts@2.0.0:
|
||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
|
@ -826,6 +832,10 @@ packages:
|
|||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
babel-jest@29.7.0:
|
||||
resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
|
|
@ -868,6 +878,9 @@ packages:
|
|||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
block-stream2@2.1.0:
|
||||
resolution: {integrity: sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==}
|
||||
|
||||
body-parser@2.2.0:
|
||||
resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==}
|
||||
engines: {node: '>=18'}
|
||||
|
|
@ -882,6 +895,9 @@ packages:
|
|||
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
browser-or-node@2.1.1:
|
||||
resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==}
|
||||
|
||||
browserslist@4.26.2:
|
||||
resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
|
|
@ -894,6 +910,10 @@ packages:
|
|||
bser@2.1.1:
|
||||
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
|
||||
|
||||
buffer-crc32@1.0.0:
|
||||
resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
|
||||
|
|
@ -912,6 +932,10 @@ packages:
|
|||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
call-bind@1.0.8:
|
||||
resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
call-bound@1.0.4:
|
||||
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -1041,6 +1065,10 @@ packages:
|
|||
supports-color:
|
||||
optional: true
|
||||
|
||||
decode-uri-component@0.2.2:
|
||||
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
dedent@1.7.0:
|
||||
resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -1056,6 +1084,10 @@ packages:
|
|||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
|
@ -1216,6 +1248,9 @@ packages:
|
|||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
|
||||
execa@5.1.1:
|
||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -1264,6 +1299,10 @@ packages:
|
|||
fast-safe-stringify@2.1.1:
|
||||
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
|
||||
|
||||
fast-xml-parser@4.5.3:
|
||||
resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==}
|
||||
hasBin: true
|
||||
|
||||
fastq@1.19.1:
|
||||
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
||||
|
||||
|
|
@ -1281,6 +1320,10 @@ packages:
|
|||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
filter-obj@1.1.0:
|
||||
resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
finalhandler@2.1.0:
|
||||
resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
|
@ -1303,6 +1346,10 @@ packages:
|
|||
fn.name@1.1.0:
|
||||
resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
|
||||
|
||||
for-each@0.3.5:
|
||||
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
form-data@4.0.4:
|
||||
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
|
@ -1416,6 +1463,9 @@ packages:
|
|||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -1490,6 +1540,14 @@ packages:
|
|||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
ipaddr.js@2.2.0:
|
||||
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
is-arguments@1.2.0:
|
||||
resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
|
||||
|
|
@ -1500,6 +1558,10 @@ packages:
|
|||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-callable@1.2.7:
|
||||
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-core-module@2.16.1:
|
||||
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -1516,6 +1578,10 @@ packages:
|
|||
resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
is-generator-function@1.1.0:
|
||||
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-glob@4.0.3:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -1527,10 +1593,18 @@ packages:
|
|||
is-promise@4.0.0:
|
||||
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
|
||||
|
||||
is-regex@1.2.1:
|
||||
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-stream@2.0.1:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-typed-array@1.1.15:
|
||||
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
|
|
@ -1836,9 +1910,9 @@ packages:
|
|||
engines: {node: '>=4.0.0'}
|
||||
hasBin: true
|
||||
|
||||
mime@4.1.0:
|
||||
resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==}
|
||||
engines: {node: '>=16'}
|
||||
mime@3.0.0:
|
||||
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
|
||||
mimic-fn@2.1.0:
|
||||
|
|
@ -1855,6 +1929,10 @@ packages:
|
|||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
minio@8.0.6:
|
||||
resolution: {integrity: sha512-sOeh2/b/XprRmEtYsnNRFtOqNRTPDvYtMWh+spWlfsuCV/+IdxNeKVUMKLqI7b5Dr07ZqCPuaRGU/rB9pZYVdQ==}
|
||||
engines: {node: ^16 || ^18 || >=20}
|
||||
|
||||
mkdirp@0.5.6:
|
||||
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
|
||||
hasBin: true
|
||||
|
|
@ -1995,6 +2073,10 @@ packages:
|
|||
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
prelude-ls@1.2.1:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
|
@ -2034,6 +2116,10 @@ packages:
|
|||
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
query-string@7.1.3:
|
||||
resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
|
|
@ -2098,6 +2184,10 @@ packages:
|
|||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
safe-regex-test@1.1.0:
|
||||
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
safe-stable-stringify@2.5.0:
|
||||
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -2105,6 +2195,9 @@ packages:
|
|||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
sax@1.4.1:
|
||||
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
||||
|
||||
semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
|
@ -2122,6 +2215,10 @@ packages:
|
|||
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
set-function-length@1.2.2:
|
||||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||
|
||||
|
|
@ -2173,6 +2270,10 @@ packages:
|
|||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
split-on-first@1.1.0:
|
||||
resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
sprintf-js@1.0.3:
|
||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||
|
||||
|
|
@ -2191,10 +2292,20 @@ packages:
|
|||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
stream-chain@2.2.5:
|
||||
resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==}
|
||||
|
||||
stream-json@1.9.1:
|
||||
resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==}
|
||||
|
||||
streamsearch@1.1.0:
|
||||
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
strict-uri-encode@2.0.0:
|
||||
resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
string-length@4.0.2:
|
||||
resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -2222,6 +2333,9 @@ packages:
|
|||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strnum@1.1.2:
|
||||
resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==}
|
||||
|
||||
superagent@10.2.3:
|
||||
resolution: {integrity: sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==}
|
||||
engines: {node: '>=14.18.0'}
|
||||
|
|
@ -2257,6 +2371,9 @@ packages:
|
|||
text-hex@1.0.0:
|
||||
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
|
||||
|
||||
through2@4.0.2:
|
||||
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
|
||||
|
||||
tmpl@1.0.5:
|
||||
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
|
||||
|
||||
|
|
@ -2376,6 +2493,9 @@ packages:
|
|||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
util@0.12.5:
|
||||
resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
|
||||
|
||||
uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
|
|
@ -2395,12 +2515,19 @@ packages:
|
|||
walker@1.0.8:
|
||||
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
|
||||
|
||||
web-encoding@1.1.5:
|
||||
resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==}
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
which-typed-array@1.1.19:
|
||||
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
|
@ -2444,6 +2571,14 @@ packages:
|
|||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
xml2js@0.6.2:
|
||||
resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
xmlbuilder@11.0.1:
|
||||
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
|
||||
engines: {node: '>=4.0'}
|
||||
|
||||
xtend@4.0.2:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
|
@ -3246,6 +3381,9 @@ snapshots:
|
|||
'@typescript-eslint/types': 8.44.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@zxing/text-encoding@0.9.0':
|
||||
optional: true
|
||||
|
||||
accepts@2.0.0:
|
||||
dependencies:
|
||||
mime-types: 3.0.1
|
||||
|
|
@ -3297,6 +3435,10 @@ snapshots:
|
|||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
dependencies:
|
||||
possible-typed-array-names: 1.1.0
|
||||
|
||||
babel-jest@29.7.0(@babel/core@7.28.4):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.4
|
||||
|
|
@ -3362,6 +3504,10 @@ snapshots:
|
|||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
block-stream2@2.1.0:
|
||||
dependencies:
|
||||
readable-stream: 3.6.2
|
||||
|
||||
body-parser@2.2.0:
|
||||
dependencies:
|
||||
bytes: 3.1.2
|
||||
|
|
@ -3389,6 +3535,8 @@ snapshots:
|
|||
dependencies:
|
||||
fill-range: 7.1.1
|
||||
|
||||
browser-or-node@2.1.1: {}
|
||||
|
||||
browserslist@4.26.2:
|
||||
dependencies:
|
||||
baseline-browser-mapping: 2.8.6
|
||||
|
|
@ -3405,6 +3553,8 @@ snapshots:
|
|||
dependencies:
|
||||
node-int64: 0.4.0
|
||||
|
||||
buffer-crc32@1.0.0: {}
|
||||
|
||||
buffer-equal-constant-time@1.0.1: {}
|
||||
|
||||
buffer-from@1.1.2: {}
|
||||
|
|
@ -3420,6 +3570,13 @@ snapshots:
|
|||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
call-bind@1.0.8:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
get-intrinsic: 1.3.0
|
||||
set-function-length: 1.2.2
|
||||
|
||||
call-bound@1.0.4:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
|
|
@ -3554,12 +3711,20 @@ snapshots:
|
|||
optionalDependencies:
|
||||
supports-color: 5.5.0
|
||||
|
||||
decode-uri-component@0.2.2: {}
|
||||
|
||||
dedent@1.7.0: {}
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
depd@2.0.0: {}
|
||||
|
|
@ -3737,6 +3902,8 @@ snapshots:
|
|||
|
||||
etag@1.8.1: {}
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
|
||||
execa@5.1.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
|
|
@ -3820,6 +3987,10 @@ snapshots:
|
|||
|
||||
fast-safe-stringify@2.1.1: {}
|
||||
|
||||
fast-xml-parser@4.5.3:
|
||||
dependencies:
|
||||
strnum: 1.1.2
|
||||
|
||||
fastq@1.19.1:
|
||||
dependencies:
|
||||
reusify: 1.1.0
|
||||
|
|
@ -3838,6 +4009,8 @@ snapshots:
|
|||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
filter-obj@1.1.0: {}
|
||||
|
||||
finalhandler@2.1.0:
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@5.5.0)
|
||||
|
|
@ -3868,6 +4041,10 @@ snapshots:
|
|||
|
||||
fn.name@1.1.0: {}
|
||||
|
||||
for-each@0.3.5:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
form-data@4.0.4:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
|
|
@ -4003,6 +4180,10 @@ snapshots:
|
|||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
|
|
@ -4069,6 +4250,13 @@ snapshots:
|
|||
|
||||
ipaddr.js@1.9.1: {}
|
||||
|
||||
ipaddr.js@2.2.0: {}
|
||||
|
||||
is-arguments@1.2.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-arrayish@0.2.1: {}
|
||||
|
||||
is-arrayish@0.3.4: {}
|
||||
|
|
@ -4077,6 +4265,8 @@ snapshots:
|
|||
dependencies:
|
||||
binary-extensions: 2.3.0
|
||||
|
||||
is-callable@1.2.7: {}
|
||||
|
||||
is-core-module@2.16.1:
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
|
|
@ -4087,6 +4277,13 @@ snapshots:
|
|||
|
||||
is-generator-fn@2.1.0: {}
|
||||
|
||||
is-generator-function@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
get-proto: 1.0.1
|
||||
has-tostringtag: 1.0.2
|
||||
safe-regex-test: 1.1.0
|
||||
|
||||
is-glob@4.0.3:
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
|
@ -4095,8 +4292,19 @@ snapshots:
|
|||
|
||||
is-promise@4.0.0: {}
|
||||
|
||||
is-regex@1.2.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
gopd: 1.2.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
is-stream@2.0.1: {}
|
||||
|
||||
is-typed-array@1.1.15:
|
||||
dependencies:
|
||||
which-typed-array: 1.1.19
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
istanbul-lib-coverage@3.2.2: {}
|
||||
|
|
@ -4573,7 +4781,7 @@ snapshots:
|
|||
|
||||
mime@2.6.0: {}
|
||||
|
||||
mime@4.1.0: {}
|
||||
mime@3.0.0: {}
|
||||
|
||||
mimic-fn@2.1.0: {}
|
||||
|
||||
|
|
@ -4587,6 +4795,23 @@ snapshots:
|
|||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minio@8.0.6:
|
||||
dependencies:
|
||||
async: 3.2.6
|
||||
block-stream2: 2.1.0
|
||||
browser-or-node: 2.1.1
|
||||
buffer-crc32: 1.0.0
|
||||
eventemitter3: 5.0.1
|
||||
fast-xml-parser: 4.5.3
|
||||
ipaddr.js: 2.2.0
|
||||
lodash: 4.17.21
|
||||
mime-types: 2.1.35
|
||||
query-string: 7.1.3
|
||||
stream-json: 1.9.1
|
||||
through2: 4.0.2
|
||||
web-encoding: 1.1.5
|
||||
xml2js: 0.6.2
|
||||
|
||||
mkdirp@0.5.6:
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
|
|
@ -4716,6 +4941,8 @@ snapshots:
|
|||
dependencies:
|
||||
find-up: 4.1.0
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
prettier-linter-helpers@1.0.0:
|
||||
|
|
@ -4750,6 +4977,13 @@ snapshots:
|
|||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
||||
query-string@7.1.3:
|
||||
dependencies:
|
||||
decode-uri-component: 0.2.2
|
||||
filter-obj: 1.1.0
|
||||
split-on-first: 1.1.0
|
||||
strict-uri-encode: 2.0.0
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
range-parser@1.2.1: {}
|
||||
|
|
@ -4811,10 +5045,18 @@ snapshots:
|
|||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
safe-regex-test@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-regex: 1.2.1
|
||||
|
||||
safe-stable-stringify@2.5.0: {}
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
sax@1.4.1: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.7.2: {}
|
||||
|
|
@ -4844,6 +5086,15 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
set-function-length@1.2.2:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
get-intrinsic: 1.3.0
|
||||
gopd: 1.2.0
|
||||
has-property-descriptors: 1.0.2
|
||||
|
||||
setprototypeof@1.2.0: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
|
|
@ -4901,6 +5152,8 @@ snapshots:
|
|||
|
||||
source-map@0.6.1: {}
|
||||
|
||||
split-on-first@1.1.0: {}
|
||||
|
||||
sprintf-js@1.0.3: {}
|
||||
|
||||
stack-trace@0.0.10: {}
|
||||
|
|
@ -4913,8 +5166,16 @@ snapshots:
|
|||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
stream-chain@2.2.5: {}
|
||||
|
||||
stream-json@1.9.1:
|
||||
dependencies:
|
||||
stream-chain: 2.2.5
|
||||
|
||||
streamsearch@1.1.0: {}
|
||||
|
||||
strict-uri-encode@2.0.0: {}
|
||||
|
||||
string-length@4.0.2:
|
||||
dependencies:
|
||||
char-regex: 1.0.2
|
||||
|
|
@ -4940,6 +5201,8 @@ snapshots:
|
|||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
strnum@1.1.2: {}
|
||||
|
||||
superagent@10.2.3:
|
||||
dependencies:
|
||||
component-emitter: 1.3.1
|
||||
|
|
@ -4987,6 +5250,10 @@ snapshots:
|
|||
|
||||
text-hex@1.0.0: {}
|
||||
|
||||
through2@4.0.2:
|
||||
dependencies:
|
||||
readable-stream: 3.6.2
|
||||
|
||||
tmpl@1.0.5: {}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
|
|
@ -5078,6 +5345,14 @@ snapshots:
|
|||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
util@0.12.5:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
is-arguments: 1.2.0
|
||||
is-generator-function: 1.1.0
|
||||
is-typed-array: 1.1.15
|
||||
which-typed-array: 1.1.19
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
v8-to-istanbul@9.3.0:
|
||||
|
|
@ -5094,6 +5369,12 @@ snapshots:
|
|||
dependencies:
|
||||
makeerror: 1.0.12
|
||||
|
||||
web-encoding@1.1.5:
|
||||
dependencies:
|
||||
util: 0.12.5
|
||||
optionalDependencies:
|
||||
'@zxing/text-encoding': 0.9.0
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
|
|
@ -5101,6 +5382,16 @@ snapshots:
|
|||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
which-typed-array@1.1.19:
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.7
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
for-each: 0.3.5
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
|
@ -5144,6 +5435,13 @@ snapshots:
|
|||
|
||||
ws@8.18.3: {}
|
||||
|
||||
xml2js@0.6.2:
|
||||
dependencies:
|
||||
sax: 1.4.1
|
||||
xmlbuilder: 11.0.1
|
||||
|
||||
xmlbuilder@11.0.1: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
-- Banatie Database Initialization Script
|
||||
-- This script creates the database schema for the Banatie image generation service
|
||||
|
||||
-- Enable UUID extension for generating UUIDs
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- Organizations table - for multi-tenant support
|
||||
CREATE TABLE organizations (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
settings JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Users table - users within organizations
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
username VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(255),
|
||||
role VARCHAR(50) DEFAULT 'user',
|
||||
settings JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(organization_id, username)
|
||||
);
|
||||
|
||||
-- Images table - metadata for generated and uploaded images
|
||||
CREATE TABLE images (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(500), -- Legacy: local file path (for backward compatibility)
|
||||
minio_key VARCHAR(500), -- MinIO object key
|
||||
url VARCHAR(1000), -- Public or presigned URL to access the image
|
||||
original_prompt TEXT,
|
||||
enhanced_prompt TEXT,
|
||||
model_used VARCHAR(100),
|
||||
file_size BIGINT,
|
||||
content_type VARCHAR(100),
|
||||
category VARCHAR(50) DEFAULT 'generated', -- 'generated', 'references', 'temp'
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Sessions table - for tracking user upload sessions
|
||||
CREATE TABLE upload_sessions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
session_data JSONB NOT NULL,
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Create indexes for better query performance
|
||||
CREATE INDEX idx_users_org_id ON users(organization_id);
|
||||
CREATE INDEX idx_users_username ON users(username);
|
||||
CREATE INDEX idx_images_user_id ON images(user_id);
|
||||
CREATE INDEX idx_images_created_at ON images(created_at);
|
||||
CREATE INDEX idx_images_category ON images(category);
|
||||
CREATE INDEX idx_images_minio_key ON images(minio_key);
|
||||
CREATE INDEX idx_upload_sessions_user_id ON upload_sessions(user_id);
|
||||
CREATE INDEX idx_upload_sessions_expires_at ON upload_sessions(expires_at);
|
||||
|
||||
-- Insert demo organization and user for development/testing
|
||||
INSERT INTO organizations (id, name, slug, settings) VALUES
|
||||
('00000000-0000-0000-0000-000000000001', 'Demo Organization', 'demo', '{"description": "Default demo organization for testing"}');
|
||||
|
||||
INSERT INTO users (id, organization_id, username, email, role, settings) VALUES
|
||||
('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000001', 'guest', 'guest@demo.banatie.app', 'user', '{"description": "Default guest user for testing"}');
|
||||
|
||||
-- Create a function to update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Create triggers to automatically update updated_at
|
||||
CREATE TRIGGER update_organizations_updated_at
|
||||
BEFORE UPDATE ON organizations
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_users_updated_at
|
||||
BEFORE UPDATE ON users
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_images_updated_at
|
||||
BEFORE UPDATE ON images
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Display initialization completion message
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Banatie database initialization completed successfully!';
|
||||
RAISE NOTICE 'Created tables: organizations, users, images, upload_sessions';
|
||||
RAISE NOTICE 'Created demo organization (id: 00000000-0000-0000-0000-000000000001) with guest user';
|
||||
END $$;
|
||||
|
|
@ -48,7 +48,7 @@ export const validateGenerateRequest = (
|
|||
try {
|
||||
enhancementOptions = JSON.parse(enhancementOptions);
|
||||
req.body.enhancementOptions = enhancementOptions;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
errors.push("enhancementOptions must be valid JSON");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { GoogleGenAI } from "@google/genai";
|
||||
import mime from "mime";
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const mime = require("mime") as any;
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import {
|
||||
|
|
|
|||
Loading…
Reference in New Issue