Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
39 KiB
JSON

{"repo": "arieldrighi/tarotflavia", "files": {".github/workflows/e2e-manual.yml": {"6828fb9d1bad6b106d8da69a9ab5b05d4d2ded32": {"t": 1785747042.6851206, "n": 5704, "h": "5e943e6ba9a55c6c", "c": "name: E2E Tests (Manual Trigger)\n\n# Permite ejecutar E2E tests manualmente desde GitHub UI\n# Útil para: verificar E2E antes de merge crítico, testing de hotfix, validación de release\non:\n workflow_dispatch:\n inputs:\n branch:\n description: \"Branch to test (default: current branch)\"\n required: false\n default: \"\"\n maxWorkers:\n description: \"Max parallel workers (1=sequential, 2=parallel)\"\n required: false\n default: \"1\"\n type: choice\n options:\n - \"1\"\n - \"2\"\n\njobs:\n e2e-manual:\n name: E2E Tests on ${{ github.event.inputs.branch || github.ref_name }}\n runs-on: ubuntu-latest\n\n services:\n postgres:\n image: postgres:16-alpine\n env:\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n ports:\n - 5436:5432\n options: >-\n --health-cmd pg_isready\n --health-interval 10s\n --health-timeout 5s\n --health-retries 5\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v4\n with:\n ref: ${{ github.event.inputs.branch || github.ref }}\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: \"20\"\n cache: \"npm\"\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run database migrations\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_e2e_user\n TAROT_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_DB_NAME: tarot_e2e\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_e2e_user\n TAROT_E2E_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_E2E_DB_NAME: tarot_e2e\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n NODE_ENV: test\n run: npm run migration:run\n\n - name: Run E2E tests\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_e2e_user\n TAROT_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_DB_NAME: tarot_e2e\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_e2e_user\n TAROT_E2E_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_E2E_DB_NAME: tarot_e2e\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n OPENAI_API_KEY: sk-test-key-for-ci-only-not-real-12345\n DEEPSEEK_API_KEY: sk-test-key-for-ci-only-not-real-12345\n NODE_ENV: test\n PORT: 3001\n RATE_LIMIT_TTL: 60\n RATE_LIMIT_MAX: 1000\n CI: true\n run: npm run test:e2e -- --maxWorkers=${{ github.event.inputs.maxWorkers || '1' }}\n\n - name: Upload E2E test results\n uses: actions/upload-artifact@v4\n if: failure()\n with:\n name: e2e-test-results-manual-${{ github.run_number }}\n path: backend/tarot-app/test-results\n retention-days: 7\n\n - name: Comment on PR (if from PR)\n uses: actions/github-script@v7\n if: github.event_name == 'pull_request' && failure()\n with:\n script: |\n github.rest.issues.createComment({\n issue_number: context.issue.number,\n owner: context.repo.owner,\n repo: context.repo.repo,\n body: '❌ E2E tests failed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.'\n })\n\n - name: Success summary\n if: success()\n run: |\n echo \"✅ E2E Tests passed successfully!\"\n echo \"Branch: ${{ github.event.inputs.branch || github.ref_name }}\"\n echo \"Workers: ${{ github.event.inputs.maxWorkers || '1' }}\"\n echo \"Total suites: 41\"\n"}, "64a8b4d0cec27d1e6cbfe1f333c530468ea040c6": {"t": 1785769998.6536973, "n": 5704, "h": "5e943e6ba9a55c6c", "c": "name: E2E Tests (Manual Trigger)\n\n# Permite ejecutar E2E tests manualmente desde GitHub UI\n# Útil para: verificar E2E antes de merge crítico, testing de hotfix, validación de release\non:\n workflow_dispatch:\n inputs:\n branch:\n description: \"Branch to test (default: current branch)\"\n required: false\n default: \"\"\n maxWorkers:\n description: \"Max parallel workers (1=sequential, 2=parallel)\"\n required: false\n default: \"1\"\n type: choice\n options:\n - \"1\"\n - \"2\"\n\njobs:\n e2e-manual:\n name: E2E Tests on ${{ github.event.inputs.branch || github.ref_name }}\n runs-on: ubuntu-latest\n\n services:\n postgres:\n image: postgres:16-alpine\n env:\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n ports:\n - 5436:5432\n options: >-\n --health-cmd pg_isready\n --health-interval 10s\n --health-timeout 5s\n --health-retries 5\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v4\n with:\n ref: ${{ github.event.inputs.branch || github.ref }}\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: \"20\"\n cache: \"npm\"\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run database migrations\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_e2e_user\n TAROT_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_DB_NAME: tarot_e2e\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_e2e_user\n TAROT_E2E_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_E2E_DB_NAME: tarot_e2e\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n NODE_ENV: test\n run: npm run migration:run\n\n - name: Run E2E tests\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_e2e_user\n POSTGRES_PASSWORD: tarot_e2e_password_secure\n POSTGRES_DB: tarot_e2e\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_e2e_user\n TAROT_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_DB_NAME: tarot_e2e\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_e2e_user\n TAROT_E2E_DB_PASSWORD: tarot_e2e_password_secure\n TAROT_E2E_DB_NAME: tarot_e2e\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n OPENAI_API_KEY: sk-test-key-for-ci-only-not-real-12345\n DEEPSEEK_API_KEY: sk-test-key-for-ci-only-not-real-12345\n NODE_ENV: test\n PORT: 3001\n RATE_LIMIT_TTL: 60\n RATE_LIMIT_MAX: 1000\n CI: true\n run: npm run test:e2e -- --maxWorkers=${{ github.event.inputs.maxWorkers || '1' }}\n\n - name: Upload E2E test results\n uses: actions/upload-artifact@v4\n if: failure()\n with:\n name: e2e-test-results-manual-${{ github.run_number }}\n path: backend/tarot-app/test-results\n retention-days: 7\n\n - name: Comment on PR (if from PR)\n uses: actions/github-script@v7\n if: github.event_name == 'pull_request' && failure()\n with:\n script: |\n github.rest.issues.createComment({\n issue_number: context.issue.number,\n owner: context.repo.owner,\n repo: context.repo.repo,\n body: '❌ E2E tests failed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.'\n })\n\n - name: Success summary\n if: success()\n run: |\n echo \"✅ E2E Tests passed successfully!\"\n echo \"Branch: ${{ github.event.inputs.branch || github.ref_name }}\"\n echo \"Workers: ${{ github.event.inputs.maxWorkers || '1' }}\"\n echo \"Total suites: 41\"\n"}, "1b1929445174adfdd64129ce4a955b4e57197a38": {"t": 1785770006.0857205, "n": 5648, "h": "1e1f17bd4e5489f0", "c": "name: E2E Tests (Manual Trigger)\n\n# Permite ejecutar E2E tests manualmente desde GitHub UI\n# Útil para: verificar E2E antes de merge crítico, testing de hotfix, validación de release\non:\n workflow_dispatch:\n inputs:\n branch:\n description: \"Branch to test (default: current branch)\"\n required: false\n default: \"\"\n maxWorkers:\n description: \"Max parallel workers (1=sequential, 2=parallel)\"\n required: false\n default: \"1\"\n type: choice\n options:\n - \"1\"\n - \"2\"\n\njobs:\n e2e-manual:\n name: E2E Tests on ${{ github.event.inputs.branch || github.ref_name }}\n runs-on: ubuntu-latest\n\n services:\n postgres:\n image: postgres:16-alpine\n env:\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n ports:\n - 5436:5432\n options: >-\n --health-cmd pg_isready\n --health-interval 10s\n --health-timeout 5s\n --health-retries 5\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v4\n with:\n ref: ${{ github.event.inputs.branch || github.ref }}\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: \"20\"\n cache: \"npm\"\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run database migrations\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_test_user\n TAROT_DB_PASSWORD: tarot_test_pass\n TAROT_DB_NAME: tarot_test\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_test_user\n TAROT_E2E_DB_PASSWORD: tarot_test_pass\n TAROT_E2E_DB_NAME: tarot_test\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n NODE_ENV: test\n run: npm run migration:run\n\n - name: Run E2E tests\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_test_user\n TAROT_DB_PASSWORD: tarot_test_pass\n TAROT_DB_NAME: tarot_test\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_test_user\n TAROT_E2E_DB_PASSWORD: tarot_test_pass\n TAROT_E2E_DB_NAME: tarot_test\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n OPENAI_API_KEY: sk-test-key-for-ci-only-not-real-12345\n DEEPSEEK_API_KEY: sk-test-key-for-ci-only-not-real-12345\n NODE_ENV: test\n PORT: 3001\n RATE_LIMIT_TTL: 60\n RATE_LIMIT_MAX: 1000\n CI: true\n run: npm run test:e2e -- --maxWorkers=${{ github.event.inputs.maxWorkers || '1' }}\n\n - name: Upload E2E test results\n uses: actions/upload-artifact@v4\n if: failure()\n with:\n name: e2e-test-results-manual-${{ github.run_number }}\n path: backend/tarot-app/test-results\n retention-days: 7\n\n - name: Comment on PR (if from PR)\n uses: actions/github-script@v7\n if: github.event_name == 'pull_request' && failure()\n with:\n script: |\n github.rest.issues.createComment({\n issue_number: context.issue.number,\n owner: context.repo.owner,\n repo: context.repo.repo,\n body: '❌ E2E tests failed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.'\n })\n\n - name: Success summary\n if: success()\n run: |\n echo \"✅ E2E Tests passed successfully!\"\n echo \"Branch: ${{ github.event.inputs.branch || github.ref_name }}\"\n echo \"Workers: ${{ github.event.inputs.maxWorkers || '1' }}\"\n echo \"Total suites: 41\"\n"}, "2b488ee1f1817df47b46b7d13de1d9aae7e40407": {"t": 1785770011.5711198, "n": 4716, "h": "dc336d6290ca755b", "c": "name: E2E Tests (Manual Trigger)\n\n# Permite ejecutar E2E tests manualmente desde GitHub UI\n# Útil para: verificar E2E antes de merge crítico, testing de hotfix, validación de release\non:\n workflow_dispatch:\n inputs:\n branch:\n description: 'Branch to test (default: current branch)'\n required: false\n default: ''\n maxWorkers:\n description: 'Max parallel workers (1=sequential, 2=parallel)'\n required: false\n default: '1'\n type: choice\n options:\n - '1'\n - '2'\n\njobs:\n e2e-manual:\n name: E2E Tests on ${{ github.event.inputs.branch || github.ref_name }}\n runs-on: ubuntu-latest\n\n services:\n postgres:\n image: postgres:16-alpine\n env:\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n ports:\n - 5436:5432\n options: >-\n --health-cmd pg_isready\n --health-interval 10s\n --health-timeout 5s\n --health-retries 5\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v4\n with:\n ref: ${{ github.event.inputs.branch || github.ref }}\n\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: \"20\"\n cache: 'npm'\n\n - name: Install dependencies\n run: npm ci\n\n - name: Run database migrations\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_test_user\n TAROT_DB_PASSWORD: tarot_test_pass\n TAROT_DB_NAME: tarot_test\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_test_user\n TAROT_E2E_DB_PASSWORD: tarot_test_pass\n TAROT_E2E_DB_NAME: tarot_test\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n NODE_ENV: test\n run: npm run migration:run\n\n - name: Run E2E tests\n working-directory: ./backend/tarot-app\n env:\n POSTGRES_HOST: localhost\n POSTGRES_PORT: 5436\n POSTGRES_USER: tarot_test_user\n POSTGRES_PASSWORD: tarot_test_pass\n POSTGRES_DB: tarot_test\n TAROT_DB_HOST: localhost\n TAROT_DB_PORT: 5436\n TAROT_DB_USER: tarot_test_user\n TAROT_DB_PASSWORD: tarot_test_pass\n TAROT_DB_NAME: tarot_test\n TAROT_E2E_DB_HOST: localhost\n TAROT_E2E_DB_PORT: 5436\n TAROT_E2E_DB_USER: tarot_test_user\n TAROT_E2E_DB_PASSWORD: tarot_test_pass\n TAROT_E2E_DB_NAME: tarot_test\n TAROT_E2E_DB_SYNCHRONIZE: false\n TAROT_E2E_DB_LOGGING: false\n JWT_SECRET: test-jwt-secret-for-ci-only-minimum-32-characters-required\n JWT_EXPIRES_IN: 1h\n GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}\n OPENAI_API_KEY: sk-test-key-for-ci-only-not-real-12345\n DEEPSEEK_API_KEY: sk-test-key-for-ci-only-not-real-12345\n NODE_ENV: test\n PORT: 3001\n RATE_LIMIT_TTL: 60\n RATE_LIMIT_MAX: 1000\n CI: true\n run: npm run test:e2e -- --maxWorkers=${{ github.event.inputs.maxWorkers || '1' }}\n\n - name: Upload E2E test results\n uses: actions/upload-artifact@v4\n if: failure()\n with:\n name: e2e-test-results-manual-${{ github.run_number }}\n path: backend/tarot-app/test-results\n retention-days: 7\n\n - name: Comment on PR (if from PR)\n uses: actions/github-script@v7\n if: github.event_name == 'pull_request' && failure()\n with:\n script: |\n github.rest.issues.createComment({\n issue_number: context.issue.number,\n owner: context.repo.owner,\n repo: context.repo.repo,\n body: '❌ E2E tests failed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.'\n })\n\n - name: Success summary\n if: success()\n run: |\n echo \"✅ E2E Tests passed successfully!\"\n echo \"Branch: ${{ github.event.inputs.branch || github.ref_name }}\"\n echo \"Workers: ${{ github.event.inputs.maxWorkers || '1' }}\"\n echo \"Total suites: 41\"\n"}}, "backend/tarot-app/.env.example": {"6828fb9d1bad6b106d8da69a9ab5b05d4d2ded32": {"t": 1786068544.3267744, "n": 15942, "h": "bde62e27170b8f40", "c": "# =============================================================================\n# TAROT - DOCKER ENVIRONMENT CONFIGURATION\n# =============================================================================\n# This file contains all environment variables needed for Docker services.\n# Copy this file to .env and update the values according to your setup.\n#\n# IMPORTANT: Never commit your .env file to version control!\n# =============================================================================\n\n# -----------------------------------------------------------------------------\n# PostgreSQL Database Configuration (Development)\n# -----------------------------------------------------------------------------\n# Database connection settings for Tarot PostgreSQL container\n\n# Port exposed on your host machine (avoid conflicts with other PostgreSQL instances)\n# Default: 5435 (other projects use 5432, 5433, 5434)\nTAROT_DB_PORT=5435\n\n# PostgreSQL superuser credentials\nTAROT_DB_USER=tarot_user\nTAROT_DB_PASSWORD=tarot_password_2024\n\n# Database name\nTAROT_DB_NAME=tarot_db\n\n# PostgreSQL version (referenced in docker-compose.yml)\nTAROT_POSTGRES_VERSION=16-alpine\n\n# -----------------------------------------------------------------------------\n# pgAdmin Configuration (Optional)\n# -----------------------------------------------------------------------------\n# Web interface for PostgreSQL database management\n# Access at: http://localhost:5050 (or your configured port)\n\n# Port exposed on your host machine for pgAdmin web interface\nTAROT_PGADMIN_PORT=5050\n\n# pgAdmin login credentials\nTAROT_PGADMIN_EMAIL=admin@tarot.local\nTAROT_PGADMIN_PASSWORD=change_me_to_secure_password\n\n# -----------------------------------------------------------------------------\n# NestJS Backend Configuration (for connecting to Docker PostgreSQL)\n# -----------------------------------------------------------------------------\n# These variables should be used in your backend .env file\n\n# Database connection string\nTAROT_DATABASE_URL=postgresql://tarot_user:tarot_password_2024@localhost:5435/tarot_db\n\n# Individual database connection parameters (for TypeORM)\nTAROT_DB_HOST=localhost\nTAROT_DB_PORT_INTERNAL=5435\nTAROT_DB_USERNAME=tarot_user\nTAROT_DB_PASSWORD_VALUE=tarot_password_2024\nTAROT_DB_DATABASE=tarot_db\n\n# TypeORM specific settings (backward compatibility)\nPOSTGRES_HOST=localhost\nPOSTGRES_PORT=5435\nPOSTGRES_USER=tarot_user\nPOSTGRES_PASSWORD=tarot_password_2024\nPOSTGRES_DB=tarot_db\n\n# TypeORM specific settings\nTAROT_DB_SYNCHRONIZE=false\nTAROT_DB_LOGGING=true\n\n# -----------------------------------------------------------------------------\n# Database Connection Pooling Configuration (OPTIONAL)\n# -----------------------------------------------------------------------------\n# Optimize database connection pooling for efficient concurrent access\n# See docs/DATABASE_POOLING.md for detailed configuration guide\n\n# Maximum number of connections in the pool\n# Development: 10, Production: 25-50 (adjust based on load)\n# Default: 10 (development), 25 (production)\nDB_POOL_SIZE=10\n\n# Maximum query execution time in milliseconds before logging warning\n# Queries exceeding this threshold will be logged for performance analysis\n# Default: 5000ms (5 seconds)\nDB_MAX_QUERY_TIME=5000\n\n# Connection timeout in milliseconds\n# Maximum time to wait for a database connection from the pool\n# Default: 30000ms (30 seconds)\nDB_CONNECTION_TIMEOUT=30000\n\n# -----------------------------------------------------------------------------\n# Testing Database Configuration (E2E Tests)\n# -----------------------------------------------------------------------------\n# Dedicated database for E2E tests (isolated from development)\n\n# Port exposed on your host machine for E2E test database\nTAROT_E2E_DB_PORT=5436\n\n# PostgreSQL credentials for E2E tests\nTAROT_E2E_DB_USER=tarot_e2e_user\nTAROT_E2E_DB_PASSWORD=tarot_e2e_password_2024\n\n# E2E test database name\nTAROT_E2E_DB_NAME=tarot_e2e\n\n# E2E test database host\nTAROT_E2E_DB_HOST=localhost\n\n# TypeORM specific settings for E2E\nTAROT_E2E_DB_SYNCHRONIZE=false\nTAROT_E2E_DB_LOGGING=false\n\n# -----------------------------------------------------------------------------\n# JWT Authentication Configuration (REQUIRED)\n# -----------------------------------------------------------------------------\n# JSON Web Token settings for user authentication\n\n# JWT secret key - MUST be at least 32 characters for security\n# Generate a secure random string with: openssl rand -base64 32\n# Or use: node -e \"console.log(require('crypto').randomBytes(32).toString('base64'))\"\nJWT_SECRET=your_jwt_secret_min_32_characters_use_openssl_rand_base64_32\n\n# JWT token expiration time (Examples: '15m', '1h', '7d', '30d')\nJWT_EXPIRES_IN=7d\n\n# -----------------------------------------------------------------------------\n# AI Provider Configuration\n# -----------------------------------------------------------------------------\n# Multiple AI providers supported with cost-optimized strategy\n# See docs/AI_PROVIDERS.md for detailed setup guide and cost comparison\n\n# === GROQ (PRIMARY - REQUIRED - FREE) ===\n# Groq provides ultra-fast inference with Llama models\n# Get your free API key at: https://console.groq.com\n# Limits: 14,400 requests/day, 30 requests/min (FREE TIER)\nGROQ_API_KEY=gsk_your_groq_api_key_here\nGROQ_MODEL=llama-3.3-70b-versatile\n\n# === DEEPSEEK (GROWTH - OPTIONAL - LOW COST) ===\n# DeepSeek offers cost-effective scaling (~$0.80 per 1000 interpretations)\n# Get your API key at: https://platform.deepseek.com\n# Uncomment when scaling beyond free tier\n# DEEPSEEK_API_KEY=sk_your_deepseek_api_key_here\n# DEEPSEEK_MODEL=deepseek-chat\n\n# === OPENAI (FALLBACK/PREMIUM - OPTIONAL) ===\n# OpenAI provides highest quality but higher cost (~$4.50 per 1000 interpretations)\n# Get your API key at: https://platform.openai.com/api-keys\n# Use for fallback or premium features only\n# OPENAI_API_KEY=sk-your_openai_api_key_here\n# OPENAI_MODEL=gpt-4o-mini\n\n# === GEMINI (FREE TIER - OPTIONAL) ===\n# Google Gemini provides generous free tier (15 RPM, 1M TPM, 1500 RPD)\n# Get your free API key at: https://ai.google.dev/\n# Used as secondary fallback after Groq, before DeepSeek and OpenAI\n# GEMINI_API_KEY=AIza_your_gemini_api_key_here\n# GEMINI_MODEL=gemini-1.5-flash\n\n# -----------------------------------------------------------------------------\n# AI Quota Configuration (OPTIONAL - Has Defaults)\n# -----------------------------------------------------------------------------\n# Monthly request quotas for AI-powered interpretations per user plan\n# Regla de negocio (T-FBK-006): la IA es exclusiva de Premium.\n\n# FREE plan: NO consume IA (cuota fija = 0, no configurable por env).\n# Las interpretaciones de Free se sirven desde contenido existente en la DB.\n# AI_QUOTA_FREE_MONTHLY quedó obsoleta y ya no se lee.\n\n# PREMIUM plan: Maximum AI requests per month (Default: -1 = unlimited)\n# Set to -1 for unlimited or specify a number for a hard cap\nAI_QUOTA_PREMIUM_MONTHLY=-1\n\n# -----------------------------------------------------------------------------\n# Application Configuration (OPTIONAL - Has Defaults)\n# -----------------------------------------------------------------------------\n\n# Node environment: 'development', 'production', or 'test' (Default: development)\nNODE_ENV=development\n\n# Application server port (Default: 3000)\nPORT=3000\n\n# -----------------------------------------------------------------------------\n# CORS Configuration (OPTIONAL)\n# -----------------------------------------------------------------------------\n\n# Allowed origins - comma-separated list of URLs (Default: http://localhost:3000)\n# Production example: https://auguriatarot.com,https://www.auguriatarot.com\nCORS_ORIGINS=http://localhost:3000\n\n# -----------------------------------------------------------------------------\n# Rate Limiting Configuration (OPTIONAL - Has Defaults)\n# -----------------------------------------------------------------------------\n\n# Time window in seconds (Default: 60)\nRATE_LIMIT_TTL=60\n\n# Maximum requests per time window (Default: 100)\nRATE_LIMIT_MAX=100\n\n# Number of trusted proxies in front of the app (Default: 1 — Railway's edge).\n# It decides where request.ip comes from, i.e. the IP EVERY rate limit is counted against.\n# - Too low -> a client can spoof X-Forwarded-For and slip past every rate limit.\n# - Too high -> request.ip becomes the proxy's IP (the same for everyone) and the app\n# starts 429-ing real users.\n# Set it to the real chain: no proxy = 0, Railway = 1, Cloudflare in front of Railway = 2.\n# TRUST_PROXY_HOPS=1\n\n# -----------------------------------------------------------------------------\n# Email Configuration\n# -----------------------------------------------------------------------------\n# SMTP settings for sending emails (password reset, welcome, quota + cost alerts).\n#\n# OPTIONAL in development/test: if the 5 variables below are not complete, the app\n# falls back to jsonTransport (emails are logged to the console, not sent).\n#\n# MANDATORY in production: an incomplete SMTP setup FAILS THE BOOT (T-PROD-012).\n# Before, it fell back to jsonTransport silently: the app looked healthy while every\n# email was dropped — including password resets, which lock users out of their account.\n\n# SMTP server hostname (production: Resend)\n# SMTP_HOST=smtp.resend.com\n\n# SMTP server port (587 for STARTTLS, 465 for implicit TLS)\n# SMTP_PORT=587\n\n# SMTP authentication username (Resend uses the literal \"resend\")\n# SMTP_USER=resend\n\n# SMTP authentication password (Resend API key)\n# SMTP_PASS=re_your_api_key\n\n# Email address used as sender (From: field)\n# EMAIL_FROM=noreply@auguriatarot.com\n\n# Mailbox that receives the users' replies to noreply@ (Reply-To: field).\n# Optional: if unset, replies go back to EMAIL_FROM, where nobody reads them.\n# EMAIL_REPLY_TO=consultas@auguriatarot.com\n\n# Recipient of the AI provider cost alerts (80% and 100% of the monthly limit).\n# If unset, the alerts are skipped with a warning: if the spend spikes, nobody finds out.\n# ADMIN_EMAIL_COST_ALERTS=consultas@auguriatarot.com\n\n# Mailbox that receives the messages sent from the public contact form (T-PROD-014).\n# MANDATORY in production: the boot FAILS without it, because every message a client\n# sends would otherwise go nowhere. In development it falls back to EMAIL_REPLY_TO /\n# EMAIL_FROM and the mailer just logs the email to the console.\n# CONTACT_EMAIL_TO=consultas@auguriatarot.com\n\n# Frontend URL for password reset links and back_url de MercadoPago.\n# OBLIGATORIA en producción, y no puede apuntar a localhost: el boot falla si no lo está.\n# Antes caía al default en silencio y los links de todos los emails salían a localhost.\nFRONTEND_URL=http://localhost:3001\n\n# -----------------------------------------------------------------------------\n# Staging Access Control\n# -----------------------------------------------------------------------------\n# These variables control access restrictions for staging environments.\n# Remove or leave empty for production (open registration, anonymous access enabled).\n\n# Comma-separated list of allowed emails for registration (staging whitelist)\n# When set: only listed emails can register\n# When empty or undefined: registration is open for everyone (production behavior)\n# REGISTRATION_WHITELIST=tester1@gmail.com,tester2@gmail.com,tester3@gmail.com\n\n# Comma-separated list of emails allowed to PURCHASE (premium subscription +\n# holistic services) during the trial stage. Registration stays open for everyone;\n# only these emails can buy. When empty or undefined: purchases open for all.\n# PURCHASE_WHITELIST=tester1@gmail.com,tester2@gmail.com\n\n# Enable/disable anonymous access to public tarot endpoints\n# false = POST /public/daily-reading returns 403 (force login for staging)\n# true or undefined = anonymous access enabled (production behavior)\n# ANONYMOUS_ACCESS_ENABLED=false\n\n# Backend public URL for webhook notification_url de MercadoPago (REQUIRED for webhooks in production)\n# Must be publicly accessible (use ngrok in local development)\n# Example: https://api.auguriatarot.com\n# BACKEND_URL=http://localhost:3000\n\n# -----------------------------------------------------------------------------\n# MercadoPago Configuration\n# -----------------------------------------------------------------------------\n# Credentials and settings for MercadoPago payment integration (pagos holísticos + suscripciones Premium)\n# Get your credentials at: https://www.mercadopago.com.ar/developers/panel\n\n# === REQUIRED for any payment functionality ===\n# Access token for MercadoPago API calls\n# Use TEST-xxx token for sandbox, and APP_USR-xxx for production\n# MP_ACCESS_TOKEN=TEST-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx\n\n# === REQUIRED in production for webhook signature validation ===\n# Secret key to validate x-signature header on incoming webhooks from MP\n# Get it from: https://www.mercadopago.com.ar/developers/panel/webhooks\n# MP_WEBHOOK_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n# === REQUIRED for Premium subscriptions ===\n# ID del plan de preapproval creado en MercadoPago para suscripciones Premium\n# Create the plan once and store the resulting ID here\n# NOTE: Automated script (e.g. `npm run mp:create-plan`) is TBD / pending T-QA-02\n# For now, create the plan manually at: https://www.mercadopago.com.ar/subscription-plans\n# MP_PREAPPROVAL_PLAN_ID=2c9380849xxxxxxxxxxxxxxxxxxxxxxx\n\n# -----------------------------------------------------------------------------\n# Logging Configuration (OPTIONAL - Has Defaults)\n# -----------------------------------------------------------------------------\n# Structured logging with Winston\n\n# Log level: 'error', 'warn', 'info', 'http', 'verbose', 'debug' (Default: info)\nLOG_LEVEL=info\n\n# Log files directory (Default: ./logs)\nLOG_DIR=./logs\n\n# Log file retention period (Default: 14d)\n# Examples: '7d', '14d', '30d', '60d'\nLOG_MAX_FILES=14d\n\n# Maximum log file size (Default: 20m)\n# Examples: '10m', '20m', '50m', '100m'\nLOG_MAX_SIZE=20m\n\n# -----------------------------------------------------------------------------\n# Development vs Production\n# -----------------------------------------------------------------------------\n# NODE_ENV=development # Use this for local development with Docker\n# NODE_ENV=production # Use this for production deployments\n\n# -----------------------------------------------------------------------------\n# Notes & Security Best Practices\n# -----------------------------------------------------------------------------\n# 1. Update passwords with secure values before deploying to production\n# 2. Port 5435 is used for development DB, 5436 for E2E tests to avoid conflicts with:\n# - Port 5432: ecommerce-postgres\n# - Port 5433: microservices-postgres\n# - Port 5434: go-api-postgres\n# 3. To start only PostgreSQL (dev): docker-compose up -d tarot-postgres\n# 4. To start E2E test database: docker-compose up -d tarot-postgres-e2e\n# 5. To start with pgAdmin: docker-compose --profile tools up -d\n# 6. All container names, volumes, and networks have 'tarot' prefix\n# to maintain consistency with the tarot-app container\n#\n# VALIDATION:\n# - The application will NOT start if required variables are missing or invalid\n# - Error messages will clearly indicate which variables need to be corrected\n# - All variables are validated on application startup\n# - See src/config/env.validation.ts for validation rules\n#\n# SECURITY:\n# - Use strong, unique passwords for production environments\n# - Regenerate JWT_SECRET for each environment (min 32 characters)\n# - Never expose your .env file publicly\n# - Store production secrets in a secure vault (AWS Secrets Manager, etc.)\n# - Use different credentials for development and production\n#\n# FOR MORE INFORMATION:\n# - See docs/MIGRATIONS.md for database migration setup\n# - See README-DOCKER.md for Docker-specific configuration\n# - See README.md for general application setup\n\n"}}}}