diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/main_porta-main-platform-core.yml similarity index 81% rename from .forgejo/workflows/deploy.yml rename to .forgejo/workflows/main_porta-main-platform-core.yml index e24e53ac..b32bf566 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/main_porta-main-platform-core.yml @@ -22,9 +22,9 @@ jobs: git remote set-url origin ssh://git@git.poweron.swiss:2222/PowerOn/plattform-core.git git fetch origin main git reset --hard origin/main - test -f env-gateway-prod-forgejo.env - cp env-gateway-prod-forgejo.env .env - rm -f env-gateway-dev.env env-gateway-int.env env-gateway-prod.env env-gateway-prod-forgejo.env + test -f env-prod.env + cp env-prod.env .env + rm -f env-dev.env env-int.env env-prod.env source .venv/bin/activate pip install -r requirements.txt --no-cache-dir python -m pytest tests/ --ignore=tests/demo @@ -49,9 +49,9 @@ jobs: git remote set-url origin ssh://git@git.poweron.swiss:2222/PowerOn/plattform-core.git git fetch origin main git reset --hard origin/main - test -f env-gateway-prod-forgejo.env - cp env-gateway-prod-forgejo.env .env - rm -f env-gateway-dev.env env-gateway-int.env env-gateway-prod.env env-gateway-prod-forgejo.env + test -f env-prod.env + cp env-prod.env .env + rm -f env-dev.env env-int.env env-prod.env source .venv/bin/activate pip install -r requirements.txt --no-cache-dir sudo systemctl restart gateway diff --git a/.github/workflows/update-requirements-lock.yml b/.forgejo/workflows/update-requirements-lock.yml similarity index 67% rename from .github/workflows/update-requirements-lock.yml rename to .forgejo/workflows/update-requirements-lock.yml index 3d21839f..367bb9ce 100644 --- a/.github/workflows/update-requirements-lock.yml +++ b/.forgejo/workflows/update-requirements-lock.yml @@ -1,7 +1,3 @@ -# Generates requirements.lock from requirements.txt using Python 3.11 (same as build). -# Run manually (workflow_dispatch) or on changes to requirements.txt. -# After running, commit the generated requirements.lock so builds use it for fast installs. - name: Update requirements.lock on: @@ -13,7 +9,6 @@ on: paths: - 'requirements.txt' -# Cancel in-progress runs when a new run is triggered (saves logs/storage) concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -22,13 +17,13 @@ jobs: update-lock: runs-on: ubuntu-latest permissions: - contents: write # push requirements.lock + contents: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v5 with: python-version: '3.11' @@ -41,9 +36,9 @@ jobs: - name: Set environment file run: | if [ "${{ github.ref }}" == "refs/heads/int" ]; then - ENV_FILE="env-gateway-int.env" + ENV_FILE="env-int.env" else - ENV_FILE="env-gateway-prod.env" + ENV_FILE="env-prod.env" fi test -f "$ENV_FILE" cp "$ENV_FILE" .env @@ -59,8 +54,8 @@ jobs: - name: Commit and push requirements.lock run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "forgejo-actions[bot]" + git config user.email "forgejo-actions[bot]@noreply.git.poweron.swiss" git add requirements.lock if git diff --staged --quiet; then echo "No changes to requirements.lock" diff --git a/.github/scripts/load_config_key_from_azure.py b/.github/scripts/load_config_key_from_azure.py deleted file mode 100644 index 08da7be4..00000000 --- a/.github/scripts/load_config_key_from_azure.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Patrick Motsch -"""Load CONFIG_KEY from Azure App Service for CI pytest (Kudu API + publish profile).""" -from __future__ import annotations - -import base64 -import json -import os -import sys -import urllib.request -import xml.etree.ElementTree as ET - - -def main() -> None: - profile_xml = os.environ.get("AZURE_PUBLISH_PROFILE") - setting_name = os.environ.get("SETTING_NAME", "CONFIG_KEY") - if not profile_xml: - print("::error::AZURE_PUBLISH_PROFILE is not set", file=sys.stderr) - sys.exit(1) - - root = ET.fromstring(profile_xml) - pub = None - for element in root.findall(".//publishProfile"): - url = (element.get("publishUrl") or "").lower() - if "scm" in url: - pub = element - break - if pub is None: - pub = root.find(".//publishProfile") - if pub is None: - print("::error::No publishProfile in publish profile XML", file=sys.stderr) - sys.exit(1) - - host = (pub.get("publishUrl") or "").split(":")[0] - user = pub.get("userName") - pwd = pub.get("userPWD") - if not (host and user and pwd): - print("::error::Could not parse SCM credentials from publish profile", file=sys.stderr) - sys.exit(1) - - api = f"https://{host}/api/settings" - req = urllib.request.Request(api) - cred = base64.b64encode(f"{user}:{pwd}".encode()).decode() - req.add_header("Authorization", f"Basic {cred}") - try: - with urllib.request.urlopen(req, timeout=60) as resp: - settings = json.load(resp) - except Exception as exc: - print(f"::error::Kudu settings request failed: {exc}", file=sys.stderr) - sys.exit(1) - - if not isinstance(settings, dict) or setting_name not in settings: - preview = sorted(settings.keys())[:25] if isinstance(settings, dict) else [] - print( - f"::error::{setting_name} not in Azure App Service application settings " - f"(sample keys: {preview})", - file=sys.stderr, - ) - sys.exit(1) - - value = settings[setting_name] - if not value or not str(value).strip(): - print(f"::error::{setting_name} is empty in Azure App Service", file=sys.stderr) - sys.exit(1) - - github_env = os.environ.get("GITHUB_ENV") - if github_env: - with open(github_env, "a", encoding="utf-8") as handle: - handle.write(f"{setting_name}<> $GITHUB_OUTPUT - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Set environment file - run: | - ENV_FILE="${{ steps.env.outputs.env_file }}" - test -f "$ENV_FILE" - cp "$ENV_FILE" .env - rm -f env-gateway-dev.env env-gateway-int.env env-gateway-prod.env env-gateway-prod-forgejo.env - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.lock ]; then - pip install -r requirements.lock --no-cache-dir - else - pip install -r requirements.txt --no-cache-dir - fi - - - name: Run tests - run: python -m pytest tests/ --ignore=tests/demo - - deploy: - runs-on: ubuntu-latest - needs: test - permissions: - contents: read - id-token: write # Required for Workload Identity Federation - - steps: - - name: Checkout code - uses: actions/checkout@v5 - - - name: Determine environment - id: env - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - ENV_TYPE="${{ github.event.inputs.environment }}" - elif [ "${{ github.ref }}" == "refs/heads/int" ]; then - ENV_TYPE="int" - else - ENV_TYPE="prod" - fi - echo "env_type=$ENV_TYPE" >> $GITHUB_OUTPUT - echo "service_name=gateway-$ENV_TYPE" >> $GITHUB_OUTPUT - echo "env_file=env-gateway-${ENV_TYPE}.env" >> $GITHUB_OUTPUT - echo "Determined environment: $ENV_TYPE" - echo "Service name: gateway-$ENV_TYPE" - echo "Env file: env-gateway-${ENV_TYPE}.env" - - - name: Authenticate to Google Cloud - uses: google-github-actions/auth@v2 - with: - credentials_json: ${{ secrets.GCP_SA_KEY }} - # Alternative: Use Workload Identity Federation (more secure) - # workload_identity_provider: ${{ secrets.WIF_PROVIDER }} - # service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }} - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2 - - - name: Configure Docker for GCR - run: | - gcloud auth configure-docker - - - name: Set environment file - run: | - cd gateway - ENV_FILE="${{ steps.env.outputs.env_file }}" - if [ -f "$ENV_FILE" ]; then - echo "Using $ENV_FILE" - cp "$ENV_FILE" .env - else - echo "Warning: $ENV_FILE not found, using env-gateway-prod.env as fallback" - cp env-gateway-prod.env .env - fi - # Clean up other env files (optional, for security) - rm -f env-*.env - - - name: Build and push container image - working-directory: ./gateway - run: | - # Build container image using Cloud Build - # If Dockerfile exists, it will be used; otherwise Cloud Buildpacks will be used - SERVICE_NAME="${{ steps.env.outputs.service_name }}" - gcloud builds submit \ - --tag gcr.io/${{ env.PROJECT_ID }}/$SERVICE_NAME:${{ github.sha }} \ - --tag gcr.io/${{ env.PROJECT_ID }}/$SERVICE_NAME:latest \ - --project ${{ env.PROJECT_ID }} - - - name: Deploy to Cloud Run - run: | - SERVICE_NAME="${{ steps.env.outputs.service_name }}" - ENV_TYPE="${{ steps.env.outputs.env_type }}" - gcloud run deploy $SERVICE_NAME \ - --image gcr.io/${{ env.PROJECT_ID }}/$SERVICE_NAME:${{ github.sha }} \ - --region ${{ env.REGION }} \ - --platform managed \ - --allow-unauthenticated \ - --project ${{ env.PROJECT_ID }} \ - --set-env-vars "APP_ENV_TYPE=$ENV_TYPE" \ - --set-secrets "CONFIG_KEY=CONFIG_KEY:latest" \ - --memory 2Gi \ - --cpu 2 \ - --timeout 300 \ - --max-instances 10 \ - --min-instances 1 \ - --port 8000 \ - --service-account ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} - - - name: Get service URL - id: service-url - run: | - SERVICE_NAME="${{ steps.env.outputs.service_name }}" - SERVICE_URL=$(gcloud run services describe $SERVICE_NAME \ - --region ${{ env.REGION }} \ - --project ${{ env.PROJECT_ID }} \ - --format 'value(status.url)') - echo "url=$SERVICE_URL" >> $GITHUB_OUTPUT - - - name: Output deployment URL - run: | - echo "🚀 Deployment successful!" - echo "Service URL: ${{ steps.service-url.outputs.url }}" diff --git a/.github/workflows/int_gateway-int.yml b/.github/workflows/int_gateway-int.yml deleted file mode 100644 index d9fa4d6a..00000000 --- a/.github/workflows/int_gateway-int.yml +++ /dev/null @@ -1,121 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions -# More info on Python, GitHub Actions, and Azure App Service: https://aka.ms/python-webapps-actions - -name: Build and deploy Python app to Azure Web App - gateway-int - -on: - push: - branches: - - int - workflow_dispatch: - -# Cancel in-progress runs when a new run is triggered (saves logs/storage) -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-latest - environment: Production - steps: - - uses: actions/checkout@v5 - - - name: Set up Python version - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Set environment file - run: | - test -f env-gateway-int.env - cp env-gateway-int.env .env - rm -f env-gateway-dev.env env-gateway-int.env env-gateway-prod.env env-gateway-prod-forgejo.env - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.lock ]; then - pip install -r requirements.lock --no-cache-dir - else - pip install -r requirements.txt --no-cache-dir - fi - - - name: Load CONFIG_KEY from Azure App Service - env: - AZURE_PUBLISH_PROFILE: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_GATEWAY_INT }} - run: python .github/scripts/load_config_key_from_azure.py - - - name: Run tests - run: python -m pytest tests/ --ignore=tests/demo - - build: - runs-on: ubuntu-latest - needs: test - permissions: - contents: read #This is required for actions/checkout - - steps: - - uses: actions/checkout@v5 - - - name: Set up Python version - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Create and start virtual environment - run: | - python -m venv venv - source venv/bin/activate - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.lock ]; then - pip install -r requirements.lock --no-cache-dir - else - pip install -r requirements.txt --no-cache-dir - fi - - - name: Zip artifact for deployment - run: zip release.zip ./* -r - - - name: Upload artifact for deployment jobs - uses: actions/upload-artifact@v6 - with: - name: python-app - path: | - release.zip - !venv/ - retention-days: 5 - - deploy: - runs-on: ubuntu-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v7 - with: - name: python-app - - - name: Unzip artifact for deployment - run: unzip release.zip - - - name: Set productive environment - run: cp env-gateway-int.env .env - - - name: Clean up environment files - run: rm -f env-*.env - - - name: 'Deploy to Azure Web App' - uses: azure/webapps-deploy@v3 - id: deploy-to-webapp - with: - app-name: 'gateway-int' - slot-name: 'Production' - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_GATEWAY_INT }} \ No newline at end of file diff --git a/.github/workflows/main_gateway-prod.yml b/.github/workflows/main_gateway-prod.yml deleted file mode 100644 index 60de29ff..00000000 --- a/.github/workflows/main_gateway-prod.yml +++ /dev/null @@ -1,121 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions -# More info on Python, GitHub Actions, and Azure App Service: https://aka.ms/python-webapps-actions - -name: Build and deploy Python app to Azure Web App - gateway-prod - -on: - push: - branches: - - main - workflow_dispatch: - -# Cancel in-progress runs when a new run is triggered (saves logs/storage) -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-latest - environment: Production - steps: - - uses: actions/checkout@v5 - - - name: Set up Python version - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Set environment file - run: | - test -f env-gateway-prod.env - cp env-gateway-prod.env .env - rm -f env-gateway-dev.env env-gateway-int.env env-gateway-prod.env env-gateway-prod-forgejo.env - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.lock ]; then - pip install -r requirements.lock --no-cache-dir - else - pip install -r requirements.txt --no-cache-dir - fi - - - name: Load CONFIG_KEY from Azure App Service - env: - AZURE_PUBLISH_PROFILE: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_GATEWAY_PROD }} - run: python .github/scripts/load_config_key_from_azure.py - - - name: Run tests - run: python -m pytest tests/ --ignore=tests/demo - - build: - runs-on: ubuntu-latest - needs: test - permissions: - contents: read #This is required for actions/checkout - - steps: - - uses: actions/checkout@v5 - - - name: Set up Python version - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Create and start virtual environment - run: | - python -m venv venv - source venv/bin/activate - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.lock ]; then - pip install -r requirements.lock --no-cache-dir - else - pip install -r requirements.txt --no-cache-dir - fi - - - name: Zip artifact for deployment - run: zip release.zip ./* -r - - - name: Upload artifact for deployment jobs - uses: actions/upload-artifact@v6 - with: - name: python-app - path: | - release.zip - !venv/ - retention-days: 5 - - deploy: - runs-on: ubuntu-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v7 - with: - name: python-app - - - name: Unzip artifact for deployment - run: unzip release.zip - - - name: Set productive environment - run: cp env-gateway-prod.env .env - - - name: Clean up environment files - run: rm -f env-*.env - - - name: 'Deploy to Azure Web App' - uses: azure/webapps-deploy@v3 - id: deploy-to-webapp - with: - app-name: 'gateway-prod' - slot-name: 'Production' - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_GATEWAY_PROD }} \ No newline at end of file diff --git a/env-gateway-dev.env b/env-dev.env similarity index 100% rename from env-gateway-dev.env rename to env-dev.env diff --git a/env-gateway-prod.env b/env-gateway-prod.env deleted file mode 100644 index c6979c1c..00000000 --- a/env-gateway-prod.env +++ /dev/null @@ -1,92 +0,0 @@ -# Production Environment Configuration - -# System Configuration -APP_ENV_TYPE = prod -APP_ENV_LABEL = Production Instance -APP_KEY_SYSVAR = CONFIG_KEY -APP_INIT_PASS_ADMIN_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3UnJRV0sySFlDblpXUlREclREaW1WbUt6bGtQYkdrNkZDOXNOLXFua1hqeFF2RHJnRXJ5VlVGV3hOZm41QjZOMlNTb0duYXNxZi05dXVTc2xDVkx0SVBFLUhncVo5T0VUZHE0UTZLWWw3ck09 -APP_INIT_PASS_EVENT_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3QVpIY19DQVZSSzJmc2F0VEZvQlU1cHBhTEgxdHdnR3g4eW01aTEzYTUxc1gxTDR1RVVpSHRXYjV6N1BLZUdCUGlfOW1qdy0xSHFVRkNBcGZvaGlSSkZycXRuUllaWnpyVGRoeFg1dGEyNUk9 -APP_API_URL = https://gateway-prod.poweron.swiss -APP_COOKIE_SECURE = true - -# PostgreSQL DB Host -DB_HOST=gateway-prod-server.postgres.database.azure.com -DB_USER=gzxxmcrdhn -DB_PASSWORD_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3Y1JScGxjZG9TdUkwaHRzSHZhRHpNcDV3N1U2TnIwZ21PRG5TWFFfR1k0N3BiRk5WelVadjlnXzVSTDZ6NXFQNFpqbnJ1R3dNVkJocm1zVEgtSk0xaDRiR19zNDBEbVIzSk51ekNlQ0Z3b0U9 -DB_PORT=5432 - -# Security Configuration -APP_JWT_KEY_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3elhfV0Rnd2pQRjlMdkVwX1FnSmRhSzNZUlV5SVpaWXBNX1hpa2xPZGdMSWpnN2ZINHQxeGZnNHJweU5pZjlyYlY5Qm9zOUZEbl9wUEgtZHZXd1NhR19JSG9kbFU4MnFGQnllbFhRQVphRGQyNHlFVWR5VHQyUUpqN0stUmRuY2QyTi1oalczRHpLTEJqWURjZWs4YjZvT2U5YnFqcXEwdEpxV05fX05QMmtrPQ== -APP_TOKEN_EXPIRY=300 - -# CORS Configuration -APP_ALLOWED_ORIGINS=http://localhost:8080,http://localhost:5176,https://nyla.poweron.swiss,https://nyla-int.poweron.swiss,https://nyla.poweron-center.net,https://nyla-int.poweron-center.net - -# Logging configuration -APP_LOGGING_LOG_LEVEL = DEBUG -APP_LOGGING_LOG_DIR = /home/site/wwwroot/ -APP_LOGGING_FORMAT = %(asctime)s - %(levelname)s - %(name)s - %(message)s -APP_LOGGING_DATE_FORMAT = %Y-%m-%d %H:%M:%S -APP_LOGGING_CONSOLE_ENABLED = True -APP_LOGGING_FILE_ENABLED = True -APP_LOGGING_ROTATION_SIZE = 10485760 -APP_LOGGING_BACKUP_COUNT = 5 - -# OAuth: Auth app (login/JWT) vs Data app (Graph / Google APIs) -Service_MSFT_AUTH_CLIENT_ID = 840b759a-4d79-4a7a-9598-f3ed204d99d8 -Service_MSFT_AUTH_CLIENT_SECRET = PROD_ENC:Z0FBQUFBQnFBa1kySFR2NjBKM084QTNpeUlyUmM4R0N0SU1BZ2x4MmVTZTVHQkVzRE9GdmFkV041MzhudFhobjU0RWNnd3lqeXpKUXA5aGtNZkhtYU12QjBtX0NjemVmdEZBdC1TbXVBSXJTcF9vMlJXd0ZNRTRKRFBMUXNjTF85eTBxakR4RVNfYmU= -Service_MSFT_AUTH_REDIRECT_URI = https://gateway-prod.poweron.swiss/api/msft/auth/login/callback -Service_MSFT_DATA_CLIENT_ID = 840b759a-4d79-4a7a-9598-f3ed204d99d8 -Service_MSFT_DATA_CLIENT_SECRET = PROD_ENC:Z0FBQUFBQnFBa1kyNVU4cVRIZFdjS3l2S1RJVTVlc1ozQ1liZXZDX1VwdFZQUzFtS0N6UWYyeGxkNGNmY1hoaWxEUDBXVU5QR2t3Vi1ZV1A2QkxqbnpobzJwOXdzYTBZaFZYdnNkeDE1VVl0bm4weHFiLXdON2gtZzAwMTkxNWRoZldFM2djSkNHVS0= -Service_MSFT_DATA_REDIRECT_URI = https://gateway-prod.poweron.swiss/api/msft/auth/connect/callback - -Service_GOOGLE_AUTH_CLIENT_ID = 813678306829-3f23dnf1cs4aaftubjfickt46tlmkgjm.apps.googleusercontent.com -Service_GOOGLE_AUTH_CLIENT_SECRET = PROD_ENC:Z0FBQUFBQnFBa1kyUmJleVpTOF9OaFV3NGVfcWVBX2oxSjUwMWRGOFZRWFRIN1FZRzZ6U3VQMlg5a21RY1drTHh3U254LW4zM1A1cXQ1TTFWYlNoek9hSHJIeE4tbm1wU1lKRXlKNU5HVWI4VGZwTVE0VnJGaV8wZmNvdkVrMjJGeXdmZ3UyNmVXN1E= -Service_GOOGLE_AUTH_REDIRECT_URI = https://gateway-prod.poweron.swiss/api/google/auth/login/callback -Service_GOOGLE_DATA_CLIENT_ID = 813678306829-3f23dnf1cs4aaftubjfickt46tlmkgjm.apps.googleusercontent.com -Service_GOOGLE_DATA_CLIENT_SECRET = PROD_ENC:Z0FBQUFBQnFBa1kyY2pxMDh0U0RqWERianBMTTNtSUZPSzhKUzh4S0RTenR2MmxnRDlvQzJjbDVTczRWLUJtVnhxWTE2MmUxQjJia2xJcVUzVlFlUnpma040NFdHRzVNRUt0OXR0c2JkTkRmQ1RIYllXbXFFaExIQWNycFVHbUxHbmtYOVhOVUV2MFY= -Service_GOOGLE_DATA_REDIRECT_URI = https://gateway-prod.poweron.swiss/api/google/auth/connect/callback - -# ClickUp OAuth (Verbindungen / automation). Create an app in ClickUp: Settings → Apps → API; set redirect URL to Service_CLICKUP_OAUTH_REDIRECT_URI exactly. -Service_CLICKUP_CLIENT_ID = O3FX3H602A30MQN4I4SBNGJLIDBD5SL4 -Service_CLICKUP_CLIENT_SECRET = PROD_ENC:Z0FBQUFBQnB5dkd6VGw5WDdhdDRsVENSalhSSUV0OFFxbEx0V1l6aktNV0E5Y18xU3JHLUlqMWVJdmxyajAydVZRaDJkZzJOVXhxRV9ROFRZbWxlRjh4c3NtQnRFMmRtZWpzTWVsdngtWldlNXRKTURHQjJCOEt6alMwQlkwOFYyVVJWNURJUGJIZDIxYVlfNnBrMU54M0Q3TVdVbFZqRkJKTUtqa05wUkV4eGZvbXNsVi1nNVdBPQ== -Service_CLICKUP_OAUTH_REDIRECT_URI = https://gateway-prod.poweron.swiss/api/clickup/auth/connect/callback - -# Infomaniak: no OAuth client. Users paste a Personal Access Token (kdrive + mail) per UI. - -# Stripe Billing (both end with _SECRET for encryption script) -STRIPE_SECRET_KEY_SECRET = PROD_ENC:Z0FBQUFBQnB5dkd6aVA3R3VRS3VHMUgzUEVjYkR4eUZKWFhPUzFTTVlHNnBvT3FienNQaUlBWVpPLXJyVGpGMWk4LXktMXphX0J6ZTVESkJxdjNNa3ZJbF9wX2ppYzdjYlF0cmdVamlEWWJDSmJYYkJseHctTlh4dnNoQWs4SG5haVl2TTNDdXpuaFpqeDBtNkFCbUxMa0RaWG14dmxyOEdILTNrZ2licmNpbXVkN2lFSWoxZW1BODNpV0ZTQ0VaeXRmR1d4RjExMlVFS3MtQU9zZXZlZE1mTmY3OWctUXJHdz09 -STRIPE_WEBHOOK_SECRET = PROD_ENC:Z0FBQUFBQnBudkpGNUpTWldsakYydFhFelBrR1lSaWxYT3kyMENOMUljZTJUZHBWcEhhdWVCMzYxZXQ5b3VlTFVRalFiTVdsbGxrdUx0RDFwSEpsOC1sTDJRTEJNQlA3S3ZaQzBtV1h6bWp5VnlMZUgwUlF3cXYxcnljZVE5SWdzLVg3V0syOWRYS08= -STRIPE_API_VERSION = 2026-01-28.clover -STRIPE_AUTOMATIC_TAX_ENABLED = false -STRIPE_TAX_RATE_ID_CH_VAT = txr_1TOQZG8WqlVsabrfFEu49pah - - -# AI configuration -Connector_AiOpenai_API_SECRET = PROD_ENC:Z0FBQUFBQnFCdlFmcDVyOGNwbVkwWFJCWmFkZS12RkhLaFhLSF9kWWpEZ0d0NDBqV2FnWlpnYmpSckdLSGpjbmh6aHJXVUZxMElwY1MzcVg1MzBOdURUZXhnZ3pqNEZyQ1JWMVA0YmxhNWJlenNpa1A3TjZkYVZSclFONjU4MF9jMTJaS2d0ZDNnXzJKSmhSRVhyckJpTUlDa0RRWHN5cWVkOUJMTUp5aFRHcDV5Z1A1aWhSUnFNOHBJTDFPdzAzcVJ3bmhueTBmVkJDZTdJakhMOEFRdHBvWFduUzdRV2dNQVdpaXdFSVlHMDJ4NnZRUTBZZ3pOakxPLUdjNlNNQnJQMXpfSWR3NmFodDdDbkEtVmRjdVBhMjRWT1NOV1BYbU15VHRSWFR0UVBBMWtKRTRkS25KMFk9 -Connector_AiAnthropic_API_SECRET = PROD_ENC:Z0FBQUFBQnFCdlFmMGhla2xoZWowNjJzc1EzMWJYRXRTcGdWWWctU3hhcXNUbVVaOTJiRFJuSGM5S3ZGZ0M4RFotTGxOQ3loa3l4aVZ2T3FsRVVMck83RTlURFNOdWxHb0JfNVEtRGJ4X193dV9Bd0EtNlVGV0h4SWk2bldfWThxNVVnOGctSkNFR3FXa2pmY2ROcV9EVE1oMndFY1d4MjdLeWtUd0VEeW5CTlFwX2FOcW9DaWVXYWVfMy1ZUnFFUEZnanFOUGZILUpUZU8yUHNSODE3OXBSWVJFNlpBdTJtUT09 -Connector_AiPerplexity_API_SECRET = PROD_ENC:Z0FBQUFBQnFCdlFmRm9saTZuR1VSZV9pQllKRGFURmN4cDNNanpsVFM3TVItdDNtNWdoWC1zVllrLUVPeGZDRXF1S3Rxd0tVUGV6bl9Ob0JMa3U5ZUNlRjRVQ1dRWXZDTXlsRU13b2o2R1paalU4RXB6SWxYVEJPa2NmaDRFdzExRXU1X2VnNDlhQzQ3cTE1RlJrSlB5elRMZ2w3NmxlV2l3PT0= -Connector_AiTavily_API_SECRET = PROD_ENC:Z0FBQUFBQnFCdlFmZGdyWkJibS03akJtSjF0U2doYXZVVDM1em1kY2ZpRGJISmVCUURfVkw3c2Z3OEFQd1h1SzE0cTExSUtVejRPY3VmWF9XT1ZyS3RxRmVRYktJeDR6OWhYaEM0bkNLVEI1cl9VZ1VFOG9IRTFWc2FUemh0UmNHTGprQ0FweThlSGpSSDAyZmw2YmR0OFREQWxpNERHWm1nPT0= -Connector_AiPrivateLlm_API_SECRET = PROD_ENC:Z0FBQUFBQnBudkpGanZ6U3pzZWkwXzVPWGtIQ040XzFrTXc5QWRnazdEeEktaUJ0akJmNnEzbWUzNHczLTJfc2dIdzBDY0FTaXZYcDhxNFdNbTNtbEJTb2VRZ0ZYd05hdlNLR1h6SUFzVml2Z1FLY1BjTl90UWozUGxtak1URnhhZmNDRWFTb0dKVUo= -Connector_AiMistral_API_SECRET = PROD_ENC:Z0FBQUFBQnFCdlFmcEVpVmFuWkk4eTJTc3VtRFg4cE9QU3R5NVg0eVFIR29RSVhmXy1rR0pPTm4wbFhIVFFpckx5UmhvSGxqSWV4S0xoTzdESE55R2k5eHowZEprdGhrbEU3eG5JWGpaNWJIdDRqT05zZGNCQVpXd2xTek1teHRBS3NRU2FuUTlSQ2Q= - -Service_MSFT_TENANT_ID = common - -# Google Cloud Speech Services configuration -Connector_GoogleSpeech_API_KEY_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z4NFQxaF9uN3h1cVB6dnZid1c1R1VfNDlSQ1NHMEVDZWtKanpMQ29CLXc1MXBqRm1hQ0YtWVhaejBMY1ZTOEFEVlpWQ3hrYkFza1E2RDNsYkdMMndNR0VGNTMwVDRGdURJY3hyaVFxVjEtSEYwNHJzeWM3WmlpZW9jU2E3NTgycEV2allqQ3dJRTNyRFAzaDJ6dklKeXpNRkJhYjFzUkptN2dpbkNpMklrcGxuZl9vTkt3T0JvNm1YTXd5UlkwZWptUXdWVFpnV2J4X3J2WUhIUlFkSElFVnlqMnlJRnNHTnlpMWs2R1dZc2ROWjNYZG85cndmd1E5cUZnVmZRYnVjTG43dXFmSWd2bGFfVWFWSmtpWkpndWNlSUNwcnFNU2NqZXFaV0xsY3l3SElLRkVHcHZGZERKV1ltcGhTS0dhTko1VTJLYzNoZjRkSGVEX3dTMWVVTmdDczV5cE1JQUdSbUJGUm11eFhTVjJHbkt0SzB4UG1Dc2xmbnp1Y041Y2RTeWRuWGdmQy1sTGx0MGtnM2VJQ3EyLXViRlNhTU9ybzZkR1N1bXE5SXhlZENWRFpWSGlYOWx4SUQ3UlR0ZEVxQkxNakRUVFRiUmFnbklOalphLUZkRFVVaXBRUk5NZW5PaUZydTFmQkNPSTdTVTNZd0plWXllNVFJdmN4MVcyTGlwMGFtVjBzOGRxR1FjbzhfYW5zdTB0ZEZBTTJhakltazh1dktNMUZsOUItdFdTb1pIaUxySllXNkdlY20zUS0wTnpFNTB2SU5acG1VcXhyaHBmME8takw3RDh5T043T2VGOV92TzNya2pWSlpYVjZDdXlZcjM3a0hPTlhkaW9oQmxqQlpGRFYyTTY4WmZmT3k4Tk1tdXRuSGdTUVpNT2NKenhXb05PdXBfSEdhMTNxNjdpNXlKUUI2YUgydFFPX1VvXzVJb0UxWTU2YVNiNDQ0QndZanhMMHR1cGdHWGhvcEg1QXEtSXZJdTdZUE12ZEVVWkF4QmtsQS1GYnY3SFIxSHlsOGVfcEpGS1A4QUVEQWNEOFZYYlljQ3ByTU03YU16Y0UzUnJQZEprSWNjT1ZXVEtDWi03Y3ZzRVdYUTlabXJISEo5THRHVXVuM0xqbzA4bGVlZVpOMk1QMmptb21tV0pTMlVoOXdWVU95UW1iQmttc2w1RG9mMWwxXzg1T2IxYUVmTUJEZkpUdTFDTzZ3RlBFeUFiX01iRTZNWkNaSG45TkFOM2pzbUJRZ2N0VFpoejJUTG1RODY3TzZpSzVkYUQzaEpfY2pSTkRzU0VpanlkdXVQQmJ2WU5peno4QWNLTDVxZTlhSHI3NnNiM0k0Y3JkQ0xaOU05bGtsQl8zQklvaktWSDZ4aVp2MHlYelJuUDJyTU9CZC1OZjJxNFc1dDcwSUlxaVh1LTMyWWFwU0IwUU9kOUFpMWpnOERtLTh1VmJiNGVwcXBMbU5fMjVZc0hFbmxQT2puSFd1ZGpyTkphLU5sVlBZWWxrWEZrWGJQWmVkN19tZFZfZ1l1V3pSWlA0V0ZxM2lrWnl2NU9WeTdCbDROSmhfeENKTFhMVXk1d195S2JMUFJoRXZjcVo4V2g0MTNKRnZhUE1wRkNPM3FZOGdVazJPeW5PSGpuZnFGTTdJMkRnam5rUlV6NFlqODlIelRYaEN5VjdJNnVwbllNODNCTFRHMWlXbmM1VlRxbXB3Wm9LRjVrQUpjYzRNMThUMWwwSVhBMUlyamtPZnE4R0o4bEdHay1zMjR5RDJkZ1lYRHZaNHVHU2otR3ZpN25LZlEySEU0UmdTNzJGVHNWQXMyb0dVMV9WUE13ODhZWUFaakxGOWZieGNXZkNYRnV5djEyWTZLcmdrajRBLU1rS1Z0VVRkOWlDMU9fMGVmYXFhZXJGMUhpNkdmb2hkbzZ1OWV6VlNmVzNISjVYTFh6SjJNdWR5MWZidE8yVEo2dnRrZXhMRXBPczUwTG13OGhNUVpIQm0zQmRKRnJ0Nl8wNW1Ob0dHRDVpU0NWREV3TkY2SjktdVBkMFU1ZXBmSFpHQ3FHNTRZdTJvaExpZVEtLTU4YTVyeFBpNDdEajZtWUc4c1dBeUJqQ3NIY1NLS0FIMUxGZzZxNFNkOG9ORGNHWWJCVnZuNnJVTEtoQi1mRTZyUl81ZWJJMi1KOGdERzBhNVRZeHRYUUlqY2JvMFlaNHhWMU9pWFFiZjdaLUhkaG15TTBPZVlkS2R5UVdENTI4QVFiY1RJV0ZNZnlpVWxfZmlnN1BXbGdrbjFGUkhzYl9qeHBxVVJacUE4bjZETENHVFpSamh0NVpOM2hMYTZjYzBuS3J0a3hhZGxSM1V5UHd2OTU3ZHY0Yy1xWDBkWUk0Ymp0MWVrS3YzSktKODhQZnY3QTZ1Wm1VZkZJbS1jamdreks1ZlhpQjFOUDFiOHJ2Nm9NcmdTdU5LQXV2RkZWZEFNZnVKUjVwcVY3dDdhQnpmRVJ6SmlvVXpDM0ZiYXh5bGE2X04tTE9qZ3BiTnN3TF9ZaFRxSUpjNjB1dXZBcy1TZHRHTjFjSUR3WUl4cE9VNzB5Rkk4U3Z1SVZYTl9sYXlZVk83UnFrMlVmcnBpam9lRUlCY19DdVJwOXl2TVVDV1pMRFZTZk9MY3Z1eXA0MnhGazc5YllQaWtOeTc4NjlOa2lGY05RRzY1cG9nbGpYelc4c3FicWxWRkg0YzRSamFlQ19zOU14YWJreU9pNDREZVJ3a0REMUxGTzF1XzI1bEF3VXVZRjlBeWFiLXJsOXgza3VZem1WckhWSnVNbDBNcldadU8xQ3RwOTl5NGgtVlR0QklCLWl5WkE4V1FlQTBCOVU1RE9sQlRrYUNZOGdfUmEwbEZvUTFGUEFWVmQ4V1FhOU9VNjZqemRpZm1sUDhZQTJ0YVBRbWZldkF5THV4QXpfdUtNZ0tlcGdSRFM3c0lDOTNQbnBxdmxYYWNpTmI3MW9BMlZIdTQ5RldudHpNQWQ5NDNPLVVTLXVVNzdHZXh4UXpZa3dVa2J4dTFDV1RkYjRnWXU2M3lJekRYWGNMcWU5OVh6U2xZWDh6MmpqcnpiOHlnMjA5S3RFQm1NZjNSM21adkVnTUpSYVhkTzNkNnJCTmljY0x1cl9kMkx3UHhySjZEdHREanZERzNEUTFlTkR0NWlBczAtdmFGTjdZNVpTMlkxV2czYW5RN2lqemg4eUViZDV6RjdKNXdFcUlvcVhoNkJ6eVJkR1pua1hnNzQwOEs2TXJYSlpGcW9qRDU2QjBOWFFtdXBJRkRKbmdZUF9ZSmRPVEtvUjVhLTV1NjdXQjRhS0duaEtJb2FrQnNjUTRvdFMxdkdTNk1NYlFHUFhhYTJ1eUN3WHN4UlJ4UjdrZjY0SzFGYWVFN1k0cGJnc1RjNmFUenR4NHljbVhablZSWHZmUVN3cXRHNjhsX1BSZWEzdTJUZFA0S2pTaU9YMnZIQ1ZPcGhWMFJqZkVEMWRMR1h3SnU0Z2FzZ3VGM3puNzdhVjhaQXNIWHFsbjB0TDVYSFdSNV9rdWhUUUhSZHBGYkJIVDB5SDdlMC13QTVnS0g5Qkg5RGNxSGJlelVndUhPcEQ0QkRKMTJTZUM1OXJhVm0zYjU0OVY2dk9MQVBheklIQXpVNW9Yc0ROVjEzaFZTWmVxYlBWMlNlSzladzJ6TmNuMG5FVVZkN1VZN1pfS2ZHa0lQcE80S24wSnQtVlJVV09OVWJ3M09YMkZpV2ktVF9ENHhKU2dfYUQ2aUVyamk0VHJHQmVfVHU4clpUTFoteW5aSWRPV1M0RDRMTms4NGRoYmJfVE82aUl2X3VieVJOdDhBQmRwdzdnRTVBNzZwaW93dUlZb3ZRYUtOeG9ULWxvNVp5a0haSjdkcUhRb3d6UGIxRUpCVkVYX2d6TkRqQVozUWxkNGFoc1FXYVd2YWNkME9Qclo0bjYxMFRWTy1nbnI5NTBJNzRMMDluUXRKYTFqQUN4d0d5aHVlamN3Tkk3NWJXeXR0TW9BeUg5Vnp4Q2RnZUY3b3AtMDlrNmlrSGR0eGRtbUdUd2lFRWg4MklEeWJHN2wwZEpVSXMxNDNOWjRFS0tPdWxhMmFCckhfRENIY184aEFDZXNrRDl2dHQtQW12UnRuQXJjaDJoTUpiYkNWQUtfRG9GMUZoNWM4UnBYZ29RWWs2NHcyUm5kdTF3Vk1GeFpiRUJLaVZ2UGFjbi1jV3lMV0N2ZDl4VERPN295X01NNG56ZjZkRzZoYUtmY1E5NlVXemx2SnVfb19iSXg0R2M3Mjd1a2JRPT0= - -# Feature SyncDelta JIRA configuration -Feature_SyncDelta_JIRA_DELTA_TOKEN_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z4d3Z4d2x6N1FhUktMU0RKbkxfY2pTQkRzXzJ6UXVEbDNCaFM3UHMtQVFGYzNmYWs4N0lMM1R2SFJuZTVFVmx6MGVEbXc5U3NOTnY1TWN0ZDNaamlHQWloalM3VldmREJNSHQ1TlVkSVFJMTVhQWVGSVRMTGw4UTBqNGlQZFVuaHp4WUlKemR5UnBXZlh0REJFLXJ4ejR3PT0= - -# Teamsbot Browser Bot Service -TEAMSBOT_BROWSER_BOT_URL = https://cae-poweron-shared.redwater-53d21339.switzerlandnorth.azurecontainerapps.io - -# Debug Configuration -APP_DEBUG_CHAT_WORKFLOW_ENABLED = FALSE -APP_DEBUG_CHAT_WORKFLOW_DIR = ./test-chat -APP_DEBUG_ACCOUNTING_SYNC_ENABLED = FALSE -APP_DEBUG_ACCOUNTING_SYNC_DIR = ./debug/sync - -# Azure Communication Services Email Configuration -MESSAGING_ACS_CONNECTION_STRING = endpoint=https://mailing-poweron-prod.switzerland.communication.azure.com/;accesskey=4UizRfBKBgMhDgQ92IYINM6dJsO1HIeL6W1DvIX9S0GtaS1PjIXqJQQJ99CAACULyCpHwxUcAAAAAZCSuSCt -MESSAGING_ACS_SENDER_EMAIL = DoNotReply@poweron.swiss diff --git a/env-gateway-int.env b/env-int.env similarity index 100% rename from env-gateway-int.env rename to env-int.env diff --git a/env-gateway-prod-forgejo.env b/env-prod.env similarity index 100% rename from env-gateway-prod-forgejo.env rename to env-prod.env