Add mobile overflow nav, law check feature, and favicon

Nav: "Fonctionnement" and "Flyer QR" restored on mobile via a ···
overflow dropdown (click-outside closes); other links always visible

Law check: new POST /api/check-law endpoint (5/min, 20/h) calls
mistral-small with a new LAW_CHECK_PROMPT to detect if a proposal is
already covered by French or EU law. Informational only, non-blocking.
Frontend: "Vérifier le cadre légal existant" button below textarea in
home.tsx; result displayed with Scale icon; resets on content change.

Favicon: replaced placeholder red square with a petrol rounded square
containing a serif "V" (for Voix) in warm cream — matches brand palette

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 17:57:29 +02:00
parent 5c5152a387
commit 2ef14ac765
6 changed files with 179 additions and 7 deletions
+24 -1
View File
@@ -9,7 +9,7 @@ import json
import os
import logging
from openai import OpenAI, BadRequestError
from legal_framework import LEGAL_FILTER_PROMPT, SYNTHESIS_PROMPT
from legal_framework import LEGAL_FILTER_PROMPT, SYNTHESIS_PROMPT, LAW_CHECK_PROMPT
logger = logging.getLogger(__name__)
@@ -107,6 +107,29 @@ def filter_idea(content: str) -> dict:
return {"accepted": False, "reason": "Service temporairement indisponible"}
def check_existing_law(content: str) -> str:
"""
Vérifie si une proposition citoyenne est déjà couverte par une loi
française ou un règlement européen en vigueur.
Retourne une phrase informative (non bloquante).
"""
try:
client = get_client()
model = os.environ.get("FILTER_MODEL", os.environ.get("OPENAI_FILTER_MODEL", "mistral-small-latest"))
response = client.chat.completions.create(
model=model,
max_tokens=200,
messages=[
{"role": "system", "content": LAW_CHECK_PROMPT},
{"role": "user", "content": f'Proposition : "{content}"'},
],
)
return (response.choices[0].message.content or "").strip()
except Exception:
logger.exception("Erreur lors de la vérification du cadre légal existant")
return ""
def synthesize_ideas(ideas: list[str]) -> str:
"""
Synthétise une liste d'idées acceptées en un texte collectif