{
"forms": {
"upload_dir_error": "Erreur lors de la création du dossier d'upload",
"file_create_error": "Erreur lors de la création du fichier",
"multipart_stream_error": "Erreur dans le flux multipart",
"file_write_error": "Erreur lors de l'écriture du fichier",
"required": "Ce champ est obligatoire",
"too_short": "Trop court (min {})",
"too_long": "Trop long (max {})",
"email_invalid": "Format d'adresse email invalide",
"url_invalid": "Veuillez entrer une URL valide",
"phone_invalid": "Numéro de téléphone invalide (chiffres, +, espaces, tirets autorisés, 7-15 chiffres)",
"hash_error": "Erreur de hachage : {}",
"password_empty": "Le mot de passe ne peut pas être vide",
"filter_invalid_value": "Le filtre static/media a reçu une valeur invalide ({}) au lieu d'un chemin de fichier.",
"number_invalid": "Nombre invalide",
"number_required": "Requis",
"integer_required": "Doit être un entier",
"decimal_required": "Doit être au format décimal",
"min_value": "Min {} requis",
"max_value": "Max {} dépassé",
"precision_max": "Précision max {} chiffres après virgule",
"precision_min": "Précision min {} chiffres après virgule",
"color_invalid": "Couleur invalide (format: #RRGGBB ou #RGB)",
"color_no_hash": "La couleur doit commencer par #",
"color_bad_hex": "Contient des caractères non hexadécimaux",
"slug_invalid": "Slug invalide",
"slug_no_dash": "Le slug ne doit pas commencer ou finir par un tiret",
"uuid_invalid": "Format UUID invalide (attendu: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
"json_invalid": "JSON invalide : {}",
"ipv4_only": "Seules les adresses IPv4 sont acceptées",
"ipv6_only": "Seules les adresses IPv6 sont acceptées",
"ip_invalid": "Adresse IP invalide",
"date_invalid": "Format de date invalide",
"date_too_old": "Trop ancien (min : {})",
"date_too_far": "Trop loin (max : {})",
"time_invalid": "Format de temps invalide",
"file_required": "Veuillez sélectionner au moins un fichier",
"data_invalid": "Valeur invalide pour « {} »",
"data_required": "« {} » est obligatoire",
"data_password": "Le mot de passe de « {} » n'a pas pu être haché : rien n'a été enregistré",
"file_extension_blocked": "Fichier '{}' non autorisé. Extensions : {}",
"finalize_error": "Erreur lors de la finalisation du champ '{}': {}",
"template_missing": "Template manquant: {}",
"render_js_error": "Erreur rendu JS: {}",
"tera_not_configured": "Tera non configuré",
"config_not_found": "Configuration introuvable dans les extensions",
"hint_slug": "Format : lettres-chiffres-tirets",
"hint_uuid": "Format : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"hint_json": "Format JSON valide requis",
"hint_ip_v4": "Format IPv4 : 192.168.1.1",
"hint_ip_v6": "Format IPv6 : 2001:0db8:85a3::8a2e:0370:7334",
"hint_ip": "Format IPv4 ou IPv6",
"validation_overflow": "Stack overflow détecté : récursion infinie dans la validation",
"choice_invalid": "Choix invalide",
"choice_invalid_value": "Choix invalide : {}",
"select_required": "Veuillez sélectionner une option",
"checkbox_required": "Veuillez sélectionner au moins une option",
"multipart_error": "Erreur multipart",
"body_error": "Erreur lecture du body",
"aegis_query_error": "Échec parsing query string : {}",
"aegis_urlencoded_error": "Échec parsing urlencoded : {}",
"aegis_json_error": "Échec parsing JSON : {}",
"auth_required": "Authentification requise",
"role_insufficient": "Rôle insuffisant",
"unknown_group": "GuardRules : groupe(s) inexistant(s) dans roles([...]) : {}",
"time_too_old": "Trop tôt (min : {})",
"time_too_far": "Trop tard (max : {})",
"datetime_too_old": "Trop tôt (min : {})",
"datetime_too_far": "Trop tard (max : {})",
"duration_invalid": "Durée invalide (nombre de secondes attendu)",
"duration_too_short": "Durée minimale : {} secondes",
"duration_too_long": "Durée maximale : {} secondes",
"file_max_count": "Maximum {} fichiers autorisés",
"file_too_large": "Fichier '{}' trop volumineux ({}MB > {}MB max)",
"file_invalid_image": "Le fichier '{}' n'est pas une image valide",
"image_too_wide": "L'image '{}' est trop large ({}px > {}px)",
"image_too_tall": "L'image '{}' est trop haute ({}px > {}px)",
"boolean_required": "Vous devez accepter ce champ",
"slug_unicode_invalid": "Seules les lettres, chiffres, tirets et underscores sont autorisés",
"unique_field_taken": "Ce {} est déjà utilisé.",
"unique_value_taken": "La valeur du champ '{}' est déjà utilisée.",
"unique_constraint_violated": "Une contrainte d'unicité a été violée.",
"db_error": "Erreur DB : {}",
"text_field_too_large": "Champ texte trop volumineux (max 1 Mo)",
"upload_too_large": "Fichier trop volumineux (max {}Mo)"
},
"csrf": {
"missing": "Token CSRF manquant",
"invalid": "Token CSRF invalide",
"invalid_or_missing": "Token CSRF invalide ou manquant",
"forbidden": "Token CSRF invalide",
"session_write_error": "Erreur d'écriture de session"
},
"error": {
"source": "Source: {}",
"AppError": "Erreur d'application",
"build": "Erreur de build: {}",
"internal": "Erreur interne",
"forbidden": "Accès interdit",
"not_found": "Ressource introuvable",
"validation": "Erreur de validation: {}",
"database": "Erreur base de données: {}",
"io": "Erreur IO: {}",
"template": "Erreur template: {}",
"custom": "Erreur custom: {}",
"title": {
"bad_request": "Requête invalide",
"not_found": "Page non trouvée",
"forbidden": "Accès interdit",
"validation": "Erreur de validation",
"database": "Erreur base de données",
"template": "Erreur de rendu de template",
"internal": "Erreur serveur interne"
},
"invalid_query": "Paramètres d'URL invalides : {}",
"path_not_found": "Le chemin demandé '{}' n'a pas été trouvé",
"internal_occurred": "Une erreur interne est survenue",
"context_occurred": "Erreur AppError survenue"
},
"title": {
"template": "Erreur de template dans '{}'"
},
"build": {
"subscriber_already_installed": "Un subscriber tracing est déjà installé ; la configuration de log Runique est inactive (RUST_LOG / with_log sans effet)",
"external_outputs_ignored": "`with_log(|l| l.external())` est défini ; les sorties de log configurées sont ignorées (l'application possède le subscriber)",
"validation_failed": "Échec de la validation du build : {}",
"check_failed": "Échec du build avec {} erreur(s) de vérification",
"template_failed": "Échec du chargement du template : {}",
"driver_not_enabled": "Driver {} non activé : Runique a été compilé sans la feature '{}'.\n\nDans le Cargo.toml de votre projet :\nrunique = { version = \"{}\", features = [\"{}\"] }\n\nPour la CLI runique :\ncargo install runique --features {} --locked --force\n\nPour prendre en charge tous les moteurs, utilisez la feature 'all-databases'.",
"db_missing": "Connexion à la base de données requise lorsque la feature 'orm' est activée",
"component_not_ready": "Le composant '{}' n'est pas prêt",
"check": {
"db_required": "Connexion ou configuration de base de données requise (feature `orm` activée)",
"db_required_hint": "Ajoutez .with_database(db) ou .with_database_config(config) à votre chaîne de construction",
"admin_prefix_empty": "Le préfixe de route de l'admin ne peut pas être vide",
"admin_prefix_empty_hint": "Utilisez .prefix(\"/admin\") ou gardez la valeur par défaut",
"extra_route_unknown": "La route supplémentaire `{}` désigne la ressource `{}`, qui n'est pas enregistrée",
"extra_route_unknown_hint": "Utilisez la clé d'une ressource déclarée dans admin!{}",
"cache_control_invalid": "Valeur d'en-tête Cache-Control invalide : '{}'",
"cache_control_invalid_hint": "N'utilisez que des caractères ASCII visibles (pas de caractères de contrôle ni de retours à la ligne).",
"media_root_unusable": "Impossible de créer ou d'accéder au dossier MEDIA_ROOT '{}' : {}",
"media_root_unusable_hint": "Définissez MEDIA_ROOT sur un chemin absolu accessible en écriture dans votre .env (ex. MEDIA_ROOT=/var/www/monapp/media) et vérifiez que le processus peut y écrire.",
"secret_key_weak": "SECRET_KEY est absente, vide, à sa valeur par défaut, ou fait moins de 32 caractères",
"secret_key_weak_hint": "Définissez SECRET_KEY à une chaîne aléatoire d'au moins 32 caractères dans votre .env (la CLI `runique` peut en générer une)",
"public_url_missing": "Aucune URL publique : les liens de reset seraient construits à partir de l'en-tête Host de la requête",
"public_url_missing_hint": "Définissez-la dans le builder : .with_public_url(\"https://monsite.fr\")",
"acme_domain_missing": "ACME_ENABLED=true mais ACME_DOMAIN n'est pas défini",
"acme_domain_missing_hint": "Définissez ACME_DOMAIN à votre domaine de production dans votre .env",
"acme_email_missing": "ACME_ENABLED=true mais ACME_EMAIL n'est pas défini",
"acme_email_missing_hint": "Définissez ACME_EMAIL à votre email de contact Let's Encrypt dans votre .env",
"suggestion": "Suggestion",
"context": "Contexte"
}
},
"server": {
"operational": "Runique est opérationnel",
"launched": "Serveur lancé sur {}",
"connected_db": "Connecté à la base de données {} -> {}",
"stop_hint": "ctrl + c pour arrêter",
"shutting_down": "Arrêt du serveur Runique...",
"acme_not_compiled": "ACME_ENABLED=true mais la feature `acme` n'est pas compilée.",
"acme_add_feature": "Ajoute la feature `acme` à ton Cargo.toml.",
"test_utils_feature_enabled": "Feature `test-utils` compilée dans ce build — assure-toi qu'elle est bien sous [dev-dependencies], jamais [dependencies], avant un déploiement en production."
},
"middleware": {
"bad_request": "Mauvaise requête",
"slot_collision": "Collision de slot middleware Runique : « {} » et « {} » revendiquent tous les deux le slot {}. Enregistrez moins de middlewares custom ou donnez à celui-ci un slot explicite."
},
"html": {
"400_title": "400",
"400_text": "Requête invalide : les paramètres de l'adresse ne sont pas valides.",
"404_title": "404",
"404_text": "Page non trouvée",
"500_title": "500",
"500_text": "Une erreur est survenue sur le serveur",
"500_notice": "Nos équipes ont été notifiées et travaillent sur le problème.",
"429_title": "429",
"429_text": "Trop de requêtes. Veuillez patienter un moment avant de réessayer.",
"503_title": "503",
"503_text": "Service temporairement indisponible en raison d'une forte charge. Veuillez réessayer dans un instant.",
"back_home": "Retour à l'accueil",
"critical_error_title": "Erreur critique",
"critical_error_text": "Le système de gestion d'erreurs a lui-même rencontré une erreur.",
"critical_error_contact": "Cette situation ne devrait jamais se produire. Veuillez contacter l'administrateur système."
},
"debug": {
"stack_trace_title": "Trace d'erreur détaillée",
"stack_trace_tip": "L'erreur la plus haute (niveau 0) est généralement la cause racine. Les erreurs suivantes montrent comment l'erreur s'est propagée dans le code."
},
"flash": {
"welcome": "Bienvenue {}, votre compte est créé !",
"fix_errors": "Veuillez corriger les erreurs",
"success_demo": "Ceci est un message de succès.",
"info_demo": "Ceci est un message d'information.",
"warning_demo": "Ceci est un message d'avertissement.",
"error_demo": "Ceci est un message d'erreur."
},
"cli": {
"creating_project": "Création du projet '{}'...",
"admin_detected": "Admin détecté → génération du code admin",
"add_admin_hint": "Ajoutez .with_admin(...) dans votre builder pour activer le panneau admin.",
"daemon_error": "[Daemon] Erreur : {}",
"cargo_run_failed": "Le serveur applicatif n'a pas démarré correctement (cargo run)",
"file_not_found": "Fichier non trouvé : {}\nAssurez-vous d'être à la racine de votre projet Runique.",
"admin_not_found": "Fichier admin non trouvé : {}\nCréez src/admin.rs avec la macro admin!{}.",
"name_empty": "Le nom du projet ne peut pas être vide",
"name_invalid": "Le nom du projet ne doit contenir que des lettres, chiffres, _ ou -",
"name_dash": "Le nom du projet ne peut pas commencer par -",
"folder_exists": "Le dossier '{}' existe déjà",
"cargo_run_expect": "Échec du lancement de cargo run",
"project_created": "Projet '{}' créé avec succès !",
"getting_started": "Pour démarrer :",
"cd_hint": "cd {}",
"cargo_run_hint": "cargo run",
"fmt_failed": "cargo fmt a échoué — formatage ignoré : {}"
},
"daemon": {
"unable_read": "Impossible de lire : {}",
"parse_error": "Erreur d'analyse : {}",
"no_resource": "Aucune ressource dans admin!{} — rien à générer",
"operational": "Daemon opérationnel → src/admins/admin.rs",
"generation_error": "Erreur de génération : {}",
"generated_header": "GÉNÉRÉ AUTOMATIQUEMENT — NE PAS MODIFIER MANUELLEMENT",
"generated_notice": "Produit par `runique start` depuis src/admin.rs. Toute modification sera écrasée."
},
"macro": {
"named_fields_only": "Structs à champs nommés uniquement",
"structs_only": "Fonctionne uniquement sur des structs",
"forms_field_required": "Struct '{}' doit avoir un champ 'Forms'",
"field_no_name": "Champ sans nom",
"model_form_named_only": "DeriveModelForm : structs avec champs nommés uniquement",
"model_form_structs_only": "DeriveModelForm : structs uniquement"
},
"parser": {
"multiple_admin_blocks": "admin!: un seul bloc admin! est autorisé par fichier (premier bloc ligne {}, second ligne {}) — fusionnez-les",
"title_required": "admin!: 'title' est requis",
"list_display_exclude_exclusive": "admin!: 'list_display' et 'list_exclude' sont mutuellement exclusifs"
},
"TemplateMessage": {
"debug_info_title": "Informations de debug",
"debug_field_title": "Titre",
"debug_field_count": "Nombre de champs",
"debug_error_count": "Erreurs",
"debug_main_message": "Message principal",
"debug_root_cause": "Cause racine",
"debug_details": "Détails supplémentaires",
"debug_request_info": "Informations de la requête",
"debug_http_method": "Méthode HTTP",
"debug_path": "Chemin",
"debug_query_params": "Paramètres de requête",
"debug_http_headers": "En-têtes HTTP",
"debug_template_info": "Informations du template",
"debug_template_name": "Nom du template",
"debug_error_line": "Ligne de l'erreur",
"debug_template_source": "Code source du template",
"debug_available_templates": "Templates disponibles",
"debug_stack_trace_title": "Trace d'erreur détaillée",
"debug_stack_trace_tip": "L'erreur la plus haute (niveau 0) est généralement la cause racine. Les erreurs suivantes montrent comment l'erreur s'est propagée dans le code.",
"debug_environment": "Environnement",
"debug_debug_mode": "Mode debug",
"debug_enabled": "Activé",
"debug_disabled": "Désactivé",
"debug_rust_version": "Version Rust",
"debug_app_version": "Version App",
"debug_status_code": "Code de statut",
"debug_header_name": "Nom",
"debug_header_value": "Valeur"
},
"admin": {
"group": "Groupe",
"groups": "Groupes",
"resource": "Ressource",
"resources": "Ressources",
"can_create": "Créer",
"can_read": "Lire",
"can_update": "Modifier",
"can_delete": "Supprimer",
"can_update_own": "Modifier",
"can_delete_own": "Supprimer",
"name": "Nom",
"username": "Nom d'utilisateur",
"email": "Email",
"staff": "Staff",
"superuser": "Superutilisateur",
"active": "Actif",
"user": {
"username_too_short": "Le nom d'utilisateur est trop court (min 3 car.)",
"invalid_email": "Format d'adresse email invalide",
"not_activated": "Ce compte n'a pas encore été activé par son utilisateur : il le sera quand celui-ci aura choisi son mot de passe via l'email reçu."
},
"login": {
"title": "Connexion",
"subtitle": "Connectez-vous pour accéder au panneau d'administration",
"label_username": "Nom d'utilisateur",
"label_password": "Mot de passe",
"btn_submit": "Se connecter",
"error_session": "Erreur lors de l'ouverture de session.",
"error_credentials": "Identifiants incorrects ou droits insuffisants.",
"error_locked": "Trop de tentatives. Compte temporairement verrouillé. Réessayez dans {} secondes."
},
"logout": {
"success": "Déconnexion réussie."
},
"access": {
"insufficient_rights": "Droits insuffisants pour accéder à l'administration"
},
"dashboard": {
"title": "Tableau de bord",
"subtitle": "Vue d'ensemble de l'application",
"card_resources": "Ressources",
"th_resource": "Ressource",
"th_key": "Clé",
"th_permissions": "Permissions",
"th_actions": "Actions",
"btn_list": "Liste",
"btn_create": "Créer",
"see_list": "Voir la liste →",
"empty_title": "Aucune ressource enregistrée",
"empty_desc": "Déclarez vos ressources dans src/admin.rs avec le macro admin!{{}} puis lancez runique start",
"kpi_resources": "Ressources",
"kpi_entries": "Entrées totales",
"kpi_largest": "Plus grande",
"th_count": "Entrées"
},
"list": {
"breadcrumb_admin": "Administration",
"entries_count_one": "entrée",
"entries_count_many": "entrées",
"btn_create": "Créer",
"th_id": "id",
"th_actions": "Actions",
"bool_true": "Oui",
"bool_false": "Non",
"btn_detail": "Détail",
"btn_edit": "Modifier",
"btn_delete": "Supprimer",
"confirm_delete": "Vraiment supprimer ?",
"empty_title": "Aucune entrée",
"empty_desc": "Commencez par créer un élément.",
"btn_create_first": "Créer le premier",
"search_placeholder": "Rechercher..."
},
"create": {
"title": "Créer",
"breadcrumb": "Créer",
"card_info": "Informations",
"no_fields": "Aucun champ disponible pour le moment.",
"btn_cancel": "Annuler",
"btn_submit": "Créer",
"success": "Entrée créée avec succès !"
},
"edit": {
"title": "Modifier",
"breadcrumb": "Modifier",
"card_info": "Informations",
"no_fields": "Aucun champ disponible pour le moment.",
"btn_cancel": "Annuler",
"btn_submit": "Enregistrer",
"success": "Entrée mise à jour avec succès !"
},
"detail": {
"title": "Détail",
"breadcrumb": "Détail",
"entry_label": "Entrée",
"btn_list": "← Liste",
"btn_edit": "Modifier",
"btn_delete": "Supprimer",
"confirm_delete": "Supprimer cette entrée ?",
"btn_reset_password": "Réinitialiser le mot de passe",
"btn_reset_password_short": "Réinitialiser"
},
"reset_password": {
"btn": "Réinitialiser le mot de passe",
"success_email": "Lien de réinitialisation envoyé à {}.",
"success_link": "Lien de réinitialisation (mailer non configuré) : {}",
"error_no_email": "Aucun champ email trouvé pour cet utilisateur.",
"error_unavailable": "Réinitialisation du mot de passe impossible pour cet élément.",
"error_send": "Erreur lors de l'envoi de l'email : {}",
"email_subject": "Réinitialisation de votre mot de passe",
"email_title": "Réinitialisation du mot de passe",
"email_greeting": "Bonjour,",
"email_body": "Cliquez sur le lien ci-dessous pour réinitialiser votre mot de passe (valide 1 heure) :",
"email_btn": "Réinitialiser mon mot de passe",
"email_ignore": "Si vous n'avez pas demandé cette réinitialisation, ignorez ce message."
},
"user_created": {
"email_subject": "Bienvenue — définissez votre mot de passe",
"email_sent": "Email de bienvenue envoyé à {}.",
"email_greeting": "Bienvenue,",
"email_body": "Un compte a été créé pour vous. Cliquez sur le lien ci-dessous pour définir votre mot de passe :",
"email_btn": "Définir mon mot de passe",
"email_validity": "Ce lien est valide 1 heure. Si vous n'attendiez pas ce message, ignorez-le."
},
"delete": {
"title": "Supprimer",
"breadcrumb": "Supprimer",
"heading": "Confirmer la suppression",
"btn_cancel": "← Annuler",
"btn_confirm": "Oui, supprimer définitivement",
"success": "Entrée supprimée avec succès !",
"not_found": "Ressource introuvable.",
"warning": {
"title": "Attention !",
"desc": "Vous êtes sur le point de supprimer l'entrée",
"of": "de la ressource",
"irreversible": "Cette action est irréversible."
}
},
"bulk": {
"no_selection": "Aucun élément sélectionné.",
"no_field_selected": "Aucun champ modifié.",
"delete_success": "élément(s) supprimé(s).",
"update_success": "élément(s) mis à jour."
},
"base": {
"title": "Administration",
"breadcrumb": "Admin",
"toggle": "Réduire le menu",
"logout_title": "Déconnexion",
"theme_toggle": "Basculer le thème",
"back_to_site": "← Site"
},
"superuser_wizard": {
"title": "=== Créer un superutilisateur ===",
"algo_prompt": "[1/5] Algorithme de hachage",
"algo_argon2": "Argon2 (recommandé)",
"algo_bcrypt": "Bcrypt",
"algo_scrypt": "Scrypt",
"algo_custom": "Fournisseur personnalisé",
"provider_path": "Chemin du fournisseur",
"invalid_path": "Chemin invalide.",
"username_prompt": "[2/5] Nom d'utilisateur",
"username_empty": "Le nom d'utilisateur ne peut pas être vide.",
"username_taken": "Un utilisateur avec ce nom existe déjà.",
"email_prompt": "[3/5] Email",
"email_invalid": "Email invalide.",
"email_taken": "Un utilisateur avec cet email existe déjà.",
"password_prompt": "[4/5] Mot de passe",
"password_too_short": "Le mot de passe doit contenir au moins 12 caractères.",
"password_weak": "Le mot de passe doit contenir au moins une minuscule, une majuscule, un chiffre et un caractère spécial.",
"confirm_prompt": "[5/5] Confirmer le mot de passe",
"password_mismatch": "Les mots de passe ne correspondent pas. Veuillez réessayer.",
"review_algo": " Algorithme : {}",
"review_username": " Utilisateur : {}",
"review_email": " Email : {}",
"review_password": " Mot de passe : ••••••••",
"review_action": "Action",
"confirm_create": "Confirmer et créer",
"change_algo": "Changer d'algorithme",
"modify_password": "Modifier le mot de passe",
"success": "✓ Superutilisateur créé avec succès !",
"id_line": " ID : {}",
"username_line": " Utilisateur : {}",
"email_line": " Email : {}"
},
"builtin": {
"invalid_id": "Identifiant invalide.",
"droit_resource_required": "Veuillez sélectionner au moins une ressource.",
"droit_exists": "Le droit \"{}\" existe déjà.",
"groupe_exists": "Un groupe nommé « {} » existe déjà.",
"user_username_exists": "Le nom d'utilisateur « {} » est déjà pris.",
"user_email_exists": "L'adresse e-mail « {} » est déjà utilisée."
}
},
"reset": {
"forgot_title": "Mot de passe oublié",
"reset_title": "Nouveau mot de passe",
"success_title": "Mot de passe réinitialisé",
"email_label": "Adresse email",
"new_password_label": "Nouveau mot de passe",
"confirm_label": "Confirmer le mot de passe",
"email_mismatch": "L'adresse email ne correspond pas au lien.",
"invalid_link": "Lien invalide.",
"invalid_or_expired": "Lien de réinitialisation invalide ou expiré.",
"password_min_length": "Le mot de passe doit contenir au moins {} caractères.",
"password_weak": "Le mot de passe doit contenir au moins une majuscule, une minuscule, un chiffre et un caractère spécial (!@#$%...).",
"password_mismatch": "Les mots de passe ne correspondent pas.",
"check_inbox": "Si cette adresse est associée à un compte, vous recevrez un email avec la marche à suivre.",
"blocked_subject": "Votre compte est bloqué",
"blocked_body": "<p>Bonjour {},</p><p>Une demande de réinitialisation de mot de passe a été faite pour votre compte, mais ce compte est bloqué. Contactez l'administrateur du site pour le débloquer.</p><p>Si vous n'êtes pas à l'origine de cette demande, ignorez cet email.</p>",
"email_subject": "Réinitialisation de votre mot de passe",
"email_body": "<p>Bonjour {},</p><p>Cliquez sur le lien suivant pour réinitialiser votre mot de passe (valide 1 heure) :</p><p><a href=\"{}\">{}</a></p>"
},
"makemigrations": {
"destructive_detected": "Changements destructifs détectés :",
"destructive_require_force": "Utilisez --force pour appliquer ces changements destructifs.",
"long_identifier_detected": "Identifiants SQL générés trop longs (limite MariaDB/MySQL : 64 caractères) :",
"long_identifier_rename_required": "Raccourcissez les noms de table/colonne concernés — aucune troncature automatique n'est appliquée.",
"files_ready": "{} fichier(s) prêt(s) à migrer.",
"snapshots_upgraded": "{} snapshot(s) mis à jour pour enregistrer les longueurs de colonnes (aucune migration)."
},
"migrate": {
"applying": "Application des migrations depuis '{}'...",
"complete_up": "Migration terminé.",
"crate_missing": "Crate de migrations introuvable : '{}' ne contient pas de Cargo.toml."
},
"permission": {
"col": {
"id": "ID",
"can_create": "Créer",
"can_delete": "Supprimer",
"can_delete_own": "Supprimer (propre)",
"can_read": "Lire",
"can_update": "Modifier",
"can_update_own": "Modifier (propre)",
"groupes": "Groupes",
"resource_key": "Ressource",
"actions": "Actions"
}
},
"runique_test": {
"connect_failed": "connexion impossible : {}",
"begin_failed": "impossible d'ouvrir la transaction de test : {}",
"env_read_failed": "impossible de lire {} : {}",
"env_parse_failed": "impossible d'analyser {} : {}",
"env_line_malformed": "impossible d'analyser {} : une ligne est mal formée au caractère {} (la ligne n'est pas affichée, elle peut contenir un mot de passe)",
"no_panic_message": "aucun message",
"query_failed": "échec",
"panicked": "panique : {}",
"rollback_failed": "rollback : {}",
"test_failed": "{} a échoué, voir la sortie ci-dessus",
"clone_outlived": "un clone de la connexion de test a survécu au handler ; la transaction sera annulée quand ce clone sera libéré",
"not_a_transaction": "le test ne s'est pas exécuté dans une transaction : rien n'a pu être annulé",
"nested": "runique_test ne peut pas tourner à l'intérieur d'un autre runique_test : il attendrait indéfiniment son propre appelant",
"timed_out": "le handler n'a pas fini en {} s : un interblocage, ou une ligne verrouillée par une autre connexion ? RUNIQUE_TEST_TIMEOUT dans le fichier env change la limite",
"bad_timeout": "{} doit être un nombre entier de secondes supérieur à 0, reçu \"{}\"",
"transaction_ended": "la transaction du test a été terminée depuis le test lui-même (un COMMIT, ou du DDL sous MariaDB/MySQL) : tout ce qui a été écrit avant est maintenant en base",
"swallowed_failures": "requêtes en échec : {}, et pourtant le handler a renvoyé Ok : une erreur a été avalée quelque part (entourez les échecs attendus avec expect_db_error)",
"rollback_timed_out": "le rollback n'a pas fini en {} s",
"expected": "attendu",
"not_refused": "la base a accepté ce que le test s'attendait à la voir refuser",
"no_db_config": "le fichier env ne définit ni DATABASE_URL ni DB_ENGINE : la base de test doit y être nommée, rien n'est repris du shell",
"in_memory": "en mémoire : chaque test part d'une base vide"
},
"test_runner": {
"no_cargo_toml": "Pas de Cargo.toml ici : lancez `runique test` depuis la racine de votre projet.",
"test_utils_missing": "La feature `test-utils` n'est pas activée pour runique dans Cargo.toml.\nAjoutez-la en dev-dependency pour qu'elle n'arrive jamais dans un build de release :\n cargo add --dev runique --features test-utils",
"test_utils_shipped": "Cargo.toml active `test-utils` en dehors de [dev-dependencies] : le builder de test finirait dans votre build de release.\nRetirez-la de [dependencies] (et de toute entrée [features]), puis ajoutez-la uniquement en dev-dependency :\n cargo add --dev runique --features test-utils",
"no_mod_file": "Pas de src/runique_test/mod.rs : créez-le, puis déclarez-y chaque fichier de test (`mod user;`).",
"module_not_declared": "src/main.rs ne déclare pas le module de test. Ajoutez :\n #[cfg(test)]\n mod runique_test;",
"module_not_gated": "Le module runique_test n'est pas derrière `cfg(test)` : il finirait dans chaque build.\nPlacez `#[cfg(test)]` juste au-dessus de `mod runique_test;` dans src/main.rs.",
"file_not_declared_warning": "attention : src/runique_test/{}.rs n'est pas déclaré dans mod.rs, ses tests ne seront pas lancés. Ajoutez `mod {};` à mod.rs.",
"no_test_file": "Pas de src/runique_test/{}.rs. Fichiers de test : {}",
"file_not_declared": "src/runique_test/{}.rs n'est pas déclaré dans mod.rs : ajoutez-y `mod {};`.",
"cargo_spawn_failed": "Impossible de lancer cargo.",
"output_failed": "Impossible d'afficher la sortie de cargo.",
"cargo_wait_failed": "cargo test ne s'est pas terminé correctement.",
"tests_failed": "cargo test a échoué, voir la sortie ci-dessus.",
"build_failed": "cargo n'a pas pu compiler les tests, voir les erreurs ci-dessus.",
"no_such_test": "Aucun test \"{}\" dans {}.rs. Tests disponibles : {}",
"dir_read_failed": "Impossible de lire {}"
},
"auth": {
"login_cannot_sign_in": "Ce compte ne peut pas se connecter : il est inactif ou n'a jamais été activé.",
"login_session_failed": "La session n'a pas pu être enregistrée : {}"
}
}