The application is published at horaires.ita-ito.com. One origin serves both the panel and the browser, so the OIDC callback, the image URL the device is handed and the documentation all follow from this single name. Port 3000 is already taken by the facture_ocr stack on the development machine, so the app listens on 3010 there and the reason is written next to the setting rather than left to be rediscovered. The fixtures and the frozen payload snapshot move to the real domain too: a contract snapshot carrying a hostname that never existed is a small puzzle left for whoever reads it next. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012cSY9pVhZmJUKNN7wf1Myd
98 lines
4.9 KiB
Bash
98 lines
4.9 KiB
Bash
# =============================================================================
|
|
# ITA ITO — Panneau d'administration des horaires (écran e-ink TRMNL, BYOS)
|
|
# Copiez ce fichier en `.env` et renseignez les valeurs. `.env` n'est JAMAIS commité.
|
|
# =============================================================================
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Application
|
|
# -----------------------------------------------------------------------------
|
|
# Nom de domaine public de l'app sur le VPS. Un seul domaine sert à la fois
|
|
# l'écran et le navigateur : le callback OIDC, l'URL d'image envoyée au panneau
|
|
# et les liens du README en dépendent tous. Doit rester cohérent avec AUTH_URL.
|
|
APP_DOMAIN=horaires.ita-ito.com
|
|
# Port publié sur l'hôte. 3000 est déjà pris par la stack facture_ocr sur la
|
|
# machine de développement, d'où 3010 ; en production Traefik s'en charge et
|
|
# aucun port n'est publié.
|
|
APP_PORT=3010
|
|
APP_BIND=127.0.0.1
|
|
TZ=Europe/Zurich
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Base de données (PostgreSQL 16)
|
|
# -----------------------------------------------------------------------------
|
|
POSTGRES_DB=horaires
|
|
POSTGRES_USER=horaires
|
|
POSTGRES_PASSWORD=
|
|
DATABASE_URL=postgresql://horaires:CHANGEME@db:5432/horaires?schema=public
|
|
# Only needed to run the integration tests. They truncate every table, so this
|
|
# must never point at a database holding anything you want to keep.
|
|
TEST_DATABASE_URL=
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Authentification — Authentik (OIDC, Authorization Code + PKCE)
|
|
# -----------------------------------------------------------------------------
|
|
# Noms de variables imposés par Auth.js v5, identiques au projet api_llm_loxi :
|
|
# le provider est découvert automatiquement à partir d'AUTH_AUTHENTIK_*.
|
|
#
|
|
# URI de redirection à déclarer dans Authentik (correspondance stricte) :
|
|
# <AUTH_URL>/api/auth/callback/authentik
|
|
AUTH_URL=https://horaires.ita-ito.com
|
|
# Générer avec : openssl rand -base64 33
|
|
AUTH_SECRET=
|
|
|
|
AUTH_AUTHENTIK_ID=
|
|
AUTH_AUTHENTIK_SECRET=
|
|
# Doit correspondre EXACTEMENT à l'`issuer` du document de découverte, slash
|
|
# final compris :
|
|
# https://auth.loxi.ch/application/o/<SLUG>/.well-known/openid-configuration
|
|
AUTH_AUTHENTIK_ISSUER=https://auth.loxi.ch/application/o/horaires-ita-ito/
|
|
# Libellé du bouton sur la page de connexion.
|
|
AUTHENTIK_DISPLAY_NAME=Loxi
|
|
# Groupe Authentik dont les membres sont administrateurs. Tout autre utilisateur
|
|
# authentifié est en lecture seule (rôle `viewer`).
|
|
AUTHENTIK_ADMIN_GROUP=horaires-admins
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Écran e-ink — API appareil (BYOS)
|
|
# -----------------------------------------------------------------------------
|
|
# Format d'image servi à l'appareil. Le firmware Seeed référence des .bmp ;
|
|
# basculer sur `png` si l'appareil refuse le BMP.
|
|
DEVICE_IMAGE_FORMAT=bmp
|
|
# Autorise l'appareil à appeler l'API en clair (HTTP). À n'activer que si le
|
|
# firmware ESP32 échoue sur la chaîne TLS. Le jeton d'appareil circulerait alors
|
|
# en clair : il est distinct de tout autre secret et révocable depuis /admin/parametres.
|
|
DEVICE_ALLOW_HTTP=false
|
|
# Intervalles de réveil, en secondes. Court quand la boutique est ouverte ou sur le
|
|
# point de changer d'état, long la nuit et les jours de fermeture.
|
|
DEVICE_REFRESH_OPEN_SEC=600
|
|
DEVICE_REFRESH_CLOSED_SEC=7200
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Traduction FR -> EN — api.loxi.ch (projet api_llm_loxi)
|
|
# -----------------------------------------------------------------------------
|
|
# ATTENTION : cette API n'est ni Anthropic- ni OpenAI-compatible.
|
|
# Contrat réel : POST {TRANSLATION_API_URL}/api/generate {"model_id": <int>, "prompt": "..."}
|
|
# -> 200 {"stdout": "...", "stderr": "...", "exit_code": 0}
|
|
# Un échec du CLI renvoie quand même HTTP 200 : c'est `exit_code` qui fait foi.
|
|
TRANSLATION_API_URL=https://api.loxi.ch
|
|
# Clé API créée depuis la page « API keys » du dashboard api-llm-loxi (format llk_...).
|
|
TRANSLATION_API_KEY=
|
|
TRANSLATION_API_FLAVOR=loxi
|
|
# Nom du modèle, résolu en `model_id` au démarrage via GET /api/models.
|
|
# L'alias `haiku` pointe toujours vers la dernière version.
|
|
TRANSLATION_MODEL_NAME=haiku
|
|
# Le backend lance réellement le CLI Claude Code : prévoir large.
|
|
TRANSLATION_TIMEOUT_MS=30000
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Jours fériés — OpenHolidays (aucune clé requise)
|
|
# -----------------------------------------------------------------------------
|
|
HOLIDAYS_API_URL=https://openholidaysapi.org
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Déploiement (production, docker-compose.prod.yml)
|
|
# -----------------------------------------------------------------------------
|
|
TRAEFIK_NETWORK=web
|
|
TRAEFIK_ENTRYPOINT=websecure
|
|
TRAEFIK_CERTRESOLVER=myresolver
|