Files
flowdeck/app/config.py
T
bruno ce0d561ade
FlowDeck CI / lint (push) Failing after 1m10s
FlowDeck CI / test (push) Successful in 9m55s
FlowDeck CI / docker (push) Successful in 1m11s
feat(share,permissions): partage de page par groupes (page_shares)
- app/db.py: ajout colonne shared_with_group_id (FK user_groups, migration
  backfill v5.x) dans page_shares
- app/routers/sharing.py: POST /api/pages/{id}/share accepte group_id
  (upsert, verif FK groupe), GET /shares expose kind/group_name, synchro
  bidirectionnelle avec page_permissions (mirror grant/revoke) pour que
  PermissionManager donne un acces effectif (view/comment/edit) aux membres
  du groupe; PUT/DELETE gardent le miroir a jour
- app/routers/board.py, library.py: received/made incluent les partages via
  groupes (JOIN group_members)
- app/templates/_page_editor_content.html, _page_editor_scripts.html:
  dialogue Share — invite groups (fetch /api/v2/groups, filtre deja partages),
  pickInviteGroup, shareInvite(group_id), rendu accessList avec avatar groupe
- tests/test_share_groups.py: 10 tests (CRUD groupe, kind, miroir ACL)

Chore: inclut evolutions v6.4.0 deja en working copy (webhooks prod,
migrations, sync, config/main) pour garder l'arbre coherent.
2026-09-21 06:38:02 -04:00

117 lines
4.1 KiB
Python

"""FlowDeck — Configuration via pydantic-settings."""
from __future__ import annotations
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env", env_file_encoding="utf-8", extra="ignore"
)
# Gitea
gitea_url: str = "https://git.dracodev.net"
gitea_token: str = "change-me"
gitea_oauth_client_id: str = "test-id"
gitea_oauth_client_secret: str = "test-secret"
gitea_webhook_secret: str = ""
# GitHub
github_oauth_client_id: str = ""
github_oauth_client_secret: str = ""
# Standalone mode
standalone: bool = False # FLOWDECK_STANDALONE=true in .env
# OAuth2 — empty = dynamic per-request redirect URI (Host + X-Forwarded-*),
# set this ONLY to pin an exact URI (must be registered in Gitea/GitHub)
oauth_redirect_uri: str = ""
# Webhook
webhook_base_url: str = "http://localhost:8080"
# App
app_secret_key: str = "change-me-to-random"
app_host: str = "0.0.0.0"
app_port: int = 8080
log_level: str = "INFO"
default_lang: str = "fr"
# Rate limiting
rate_limit_enabled: bool = True
rate_limit_requests: int = 60 # per minute
# Public API v2 (v6.3.0)
public_api_insecure_ok: bool = False # if True, fd-public-key is accepted (dev only)
api_v2_rate_limit_per_token: int = 300 # req/min per token for /api/v2
# Database
database_url: str = "sqlite:////data/flowdeck.db"
# Sync
sync_interval: int = 60
gitea_cache_ttl: int = 30
# Backup (v5.2.0) — scheduled daily snapshot of the SQLite file
backup_enabled: bool = True
backup_dir: str = "/data/backups"
backup_interval_hours: int = 24
backup_keep: int = 30
# Forge projects sync (v5.2.0) — periodic refresh of `projects` table
project_sync_enabled: bool = True
project_sync_interval_hours: int = 1
# Reminders (v5.8.0) — background scan for due date reminders
reminders_enabled: bool = True
reminder_scan_interval_seconds: int = 60
# Webhooks outbound (v6.4.0) — retry of failed deliveries
webhook_retry_enabled: bool = True
webhook_retry_interval_seconds: int = 60
# Email / SMTP notifications (v4.9.0) — optional. If smtp_host is empty,
# email notifications are skipped (only in-app notifications are delivered).
smtp_host: str = ""
smtp_port: int = 587
smtp_user: str = ""
smtp_password: str = ""
smtp_from: str = "FlowDeck <[email protected]>"
smtp_use_tls: bool = True
app_base_url: str = "http://localhost:8080"
# FlowDeck Agent (v4.10.0) — multi-LLM. Empty keys → offline/mock mode
# (deterministic rule-based planner so the agent works without any API key).
agent_enabled: bool = True
llm_provider: str = "offline" # any id from llm_client.PROVIDERS
# (openai, anthropic, mistral, cohere,
# google, groq, deepseek, openrouter,
# nvidia, together, perplexity, xai,
# qwencloud, minimax, morph, fireworks,
# cerebras, sambanova, chutes, xiaomi,
# sealion, sensenova, ollama, offline)
llm_model: str = "gpt-4o"
llm_api_key: str = ""
llm_api_base: str = "" # custom base URL (Ollama, OpenRouter, ...)
agent_max_iterations: int = 12
agent_max_tokens_budget: int = 500000
agent_run_timeout_seconds: int = 300
@property
def db_path(self) -> Path:
if self.database_url == "sqlite:///:memory:":
return Path(":memory:") # Special SQLite in-memory
if self.database_url.startswith("sqlite:///"):
p = self.database_url.replace("sqlite:///", "", 1)
# On Windows, don't prepend / if path starts with a drive letter
import re
if re.match(r'^[a-zA-Z]:', p):
return Path(p)
return Path("/" + p)
return Path("/data/flowdeck.db")
settings = Settings()