feat: feedback hub widget in Settings Logs card #100
No reviewers
Labels
No labels
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#100
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-67-feedback-widget"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #67
Summary
Adds an opt-in Feedback Hub widget to
Simpl'Résultat, integrated inside the existing Logs card on the Settings page. The same card now covers both diagnostics capture (logs) and diagnostics forwarding (feedback).Implementation follows the cross-app conventions documented in
la-compagnie-maximus/docs/feedback-hub-ops.md— wording, payload shape, context whitelist, Loi 25 opt-in checkboxes.Design choices
LogViewerCardnext to Copy/Clear. Justified by the app's minimalist privacy-first UI and the fact that logs — the exact thing a user might want to attach — live right next to the button.send_feedbackcommand): bypasses CORS (the Tauri origin is not inFEEDBACK_CORS_ORIGINSby design), aligns with the existing OAuth / license / updater patterns, and centralises the audit of what leaves the machine. Zero server-side change required.feedbackConsentAcceptedpersisted inlocalStorage.page,locale,theme,viewport,userAgent,timestamp).app_version+ OS packed intouserAgentvia aget_feedback_user_agenthelper so we don't add a new Tauri plugin.invalid,rate_limit,server_error,network_error) mapped to i18n toasts on the frontend.connect-srcextended withhttps://feedback.lacompagniemaximus.com(unused today since we proxy via Rust, but kept for forward compatibility).Files
src-tauri/src/commands/feedback_commands.rs(new),src-tauri/src/commands/mod.rs,src-tauri/src/lib.rssrc-tauri/tauri.conf.jsonsrc/services/feedbackService.ts(new),src/services/logService.ts(addedgetRecentErrorLogs)src/hooks/useFeedback.ts(new)src/components/settings/FeedbackDialog.tsx(new),src/components/settings/FeedbackConsentDialog.tsx(new),src/components/settings/LogViewerCard.tsxsrc/i18n/locales/{fr,en}.json— newfeedback.*namespace + updateddocs.settingsto disclose the external channeldocs/guide-utilisateur.md,CHANGELOG.md,CHANGELOG.fr.mdTest plan
cargo test --lib— 3 new Rust tests (context serde skip-none, userAgent camelCase, empty-content short-circuit) + 34 total passingnpm test— 13 new TS tests (feedbackService error-code type guard,getRecentErrorLogsformatting & filtering,feedbackReducerstate machine) + 100 total passingnpm run build— tsc + vite build greencargo check— greenfeedback_hub.feedbackswithapp_id=simpl-resultatand only whitelisted context keysFollow-ups
maximus/la-compagnie-maximus#100— addsimpl-resultatto thedocs/feedback-hub-ops.mdapps registry once this PR lands.maximus/simpl-liste#68— sibling issue for the mobile version, independent.Review adversariale — PR #100
Verdict : APPROVE
Summary
PR bien architecturée qui ajoute un widget Feedback Hub opt-in dans la carte Logs des Settings. Le code respecte les principes privacy-first (consent gate one-time, opt-in par défaut, proxy via Rust), la couverture de tests est solide (3 tests Rust + 13 tests TS), et la doc/i18n sont à jour dans les deux langues. Aucun problème bloquant.
Checklist
reqwestdéjà présent dansCargo.toml.localStorage, opt-in par défaut, le checkboxidentifyest caché quand déconnecté, auto-close après succès, désactivation des contrôles pendantsending.cargo test --lib,npm test,npm run build,cargo checktous verts. Aucun.skip/.only.feedback.*ajouté dans FR et EN. Le remaniementreports.trends(déplacement dans la sectionreports) est cohérent avec les usages existants (ReportsTrendsPage.tsxutilise déjàreports.trends.subviewGlobal).## [Unreleased] / Added.Suggestions (non bloquantes)
src-tauri/src/commands/feedback_commands.rs:78-82— le testempty_content_is_rejected_locallyfait un vrai appelsend_feedbacket s'appuie sur le fait que le checkis_empty()arrive avant la construction du client. Extraire la validation dans une fonction pure (fn validate_content(s: &str) -> Result<&str, &'static str>) rendrait le test indépendant de l'ordre d'exécution.src-tauri/src/commands/feedback_commands.rs:95,103—map_err(|_| "network_error")avale toutes les causes (timeout, DNS, TLS, reset). Unlog::warn!("feedback transport failed: {e}")avant le mapping permettrait de diagnostiquer via les logs in-app — d'autant plus utile que c'est précisément le flow utilisé pour remonter des problèmes.src/components/settings/FeedbackDialog.tsx:82—rawLogs.slice(-LOGS_SUFFIX_MAX)tronque au milieu d'une ligne. Tronquer au dernier\navant la limite rendrait le suffixe plus lisible côté reviewer Feedback Hub.src/components/settings/FeedbackDialog.tsx:96-100— en cas d'échec degetFeedbackUserAgent(), la string fallback"Simpl'Résultat"est envoyée sans version ni OS. Mieux vaudrait laisseruserAgentabsent du contexte (il estOptional<String>côté Rust donc propre).src/components/settings/LogViewerCard.tsx:20-22—localStorage.getItem(...)n'est pas entouré d'un try/catch. OK en Tauri aujourd'hui, mais peu coûteux à défendre.src-tauri/src/commands/feedback_commands.rs:16-19—feedback_endpoint()litFEEDBACK_HUB_URLà chaque appel. UnOnceLock<String>éviterait la re-lecture. Cosmétique.🤖 Review réalisée via
/pr-review