v1.6.25 — intégration IA éditeur, onglet admin IA, corrections CSP #98

Merged
cedricAbonnel merged 16 commits from dev into main 2026-05-16 12:07:34 +00:00

16 Commits

Author SHA1 Message Date
cedricAbonnel 84d4b12fb2 docs : mise à jour CHANGELOG v1.6.25 — corrections IA wizard + bouton unique
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 14:06:03 +02:00
cedricAbonnel c979238b0c refactor : IA éditeur — un seul bouton analyse+réécriture combinées
Un seul appel API retourne l'analyse critique ET la proposition d'article
via le séparateur ===CRITIQUE===/===REWRITE===. Le panneau affiche les deux
sections avec un bouton « Appliquer la proposition ».

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 13:06:23 +02:00
cedricAbonnel e03594c22e fix : boutons IA dans wizard/step1.php (éditeur réel) + adaptation ids textarea
post_form.php n'était jamais inclus — les boutons IA sont ajoutés dans la vraie
page d'édition (wizard/step1.php). ai-editor.js cherche #wz-content en priorité
et extrait le titre depuis la première ligne # du Markdown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 13:01:46 +02:00
cedricAbonnel 298f18dabe feat & fix : intégration IA éditeur + onglet admin IA + corrections CSP (v1.6.24-25)
- #96 : boutons IA sidebar éditeur (analyse critique / réécriture) via Anthropic API
- #97 : onglet admin /admin/ia — provider anthropic/claude_code, modèle, procédure CLI
- #95 : extraction scripts inline vers fichiers JS (comments.js, post_confirm.js, admin.js)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 12:18:38 +02:00
cedricAbonnel fabe5a9f53 fix : formulaires imbriqués dans bulk-form (toggle à la une + dupliquer)
Les <form> admin_toggle_featured et duplicate étaient imbriqués dans
#bulk-form — HTML invalide, le navigateur soumettait le form parent
(suppression) au lieu du bon. Fix : attribut form="id" HTML5 + forms
cachés placés après le bulk-form. Ajoute note CSP + nested forms dans
consignes.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:30:12 +02:00
cedricAbonnel 430b7ddd6f feat : historique des révisions dans la sidebar article (v1.6.23)
- post_view.php : section Historique dans la sidebar pour les connectés
  liste les 10 dernières révisions avec date + commentaire → lien diff (#82)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:21:54 +02:00
cedricAbonnel e2d218f364 feat : widget notation étoiles + admin onglet flux RSS (v1.6.22)
- post_view.php : widget ★ 1-5 étoiles pour les connectés, moyenne + nb votes pour tous (#13)
- admin : onglet /admin/flux liste tous les flux rss_feeds avec suppression (#87)
- case 'admin_delete_feed' : suppression admin d'un flux sans contrainte email (#87)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:18:55 +02:00
cedricAbonnel ca6cfa4ebf fix & feat : SEO desc, feed cover, livres slug auto + filtre (v1.6.21)
- buildAutoSeoDesc() : entités HTML décodées + titre supprimé en tête (#91)
- post_confirm.js : guard null sur #confirm-slug absent (#91)
- feed.php : <media:thumbnail> avec image de couverture RSS (#90)
- admin livres : slug auto depuis le titre + filtre articles (#89)
- BookManager::sanitizeSlug() passé public

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:05:01 +02:00
cedricAbonnel 3b22be94e8 feat : barre de partage articles + déduplication images uploadées (v1.6.20)
- post_view.php : barre de partage (mail, X, LinkedIn, Mastodon, copier, Web Share) sur articles publiés (#47)
- share.js : logique clipboard + navigator.share sans script tiers, compatible CSP (#47)
- addFile() : hardlink vers fichier identique si même hash16-size.ext dans un autre article (#35)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:56:43 +02:00
cedricAbonnel 5ce91da06a perf & ux : cache getAll, fingerprint assets, Last-Modified, 404 log, row-click bulk (v1.6.19)
- getAll() : cache fichier articles_list.json, invalidé à chaque écriture (#16)
- layout.php : fingerprinting ?v=<hash> sur CSS/JS pour invalidation navigateur (#18)
- case 'view' : Last-Modified + 304 Not Modified pour les articles publiés (#18)
- case 'not_found' : logging JSON des 404 dans _logs/not_found.jsonl (#52)
- case 'view' : echo nu → templates/404.php pour brouillons/privés (#52)
- admin.js : clic sur ligne tableau → toggle bulk-check (#86)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:44:08 +02:00
cedricAbonnel 11399a54a6 feat : magic link confirm, notif auteur, rate-limit IP, duplicate, cache MD, lazy img (v1.6.18)
- magic.php : GET=confirmation page, POST=consommation (protège vs scanners) (#27)
- verify_comment : email de notification à l'auteur de l'article (#44)
- login/index.php : rate limit par IP (MAGIC_MAX_PER_IP_HOUR=10) (#23)
- ArticleManager::duplicate() + route POST /duplicate/{uuid} + bouton ⧉ admin/articles (#7)
- post_view.php : cache JSON du rendu Markdown (invalidé sur mtime index.md) (#17)
- post_view.php : loading="lazy" sur toutes les <img> du contenu (#21)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:30:55 +02:00
cedricAbonnel 51055b7321 feat : RSS content, feed catégorie, cookie commentaires, flux erreurs, email preview (v1.6.17)
- RSS : content:encoded (HTML complet) + fix description via plain (#42)
- RSS : flux filtré par ?category=nom (#43)
- Commentaires : cookie nom/email pour pré-remplir le formulaire (#51)
- flux/ : bandeau admin des feeds en erreur (#45)
- admin/emails : bouton « Voir ↗ » vers /admin/email-preview/{id} en nouvel onglet (#37)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:00:37 +02:00
cedricAbonnel dc4701d667 feat : visiteurs uniques, filtre jours, redirect 404→search, edit_tags (v1.6.16)
- SearchLogParser : visiteurs uniques par terme (IPs distinctes) au lieu de hits bruts (#41)
- SearchLogParser : paramètre $days (7/14), cache distinct par période, filtre logFiles par date (#46)
- admin/searches : boutons 7 j / 14 j, label dynamique, colonne « Visiteurs » (#41, #46)
- URL inconnue / slug absent : redirect 302 /search?q=… au lieu de page 404 (#57)
- edit_tags : masquer abbrev/camel si des valeurs connues existent pour le type (#48)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 09:50:56 +02:00
cedricAbonnel ae4ac11305 feat : recherche titre, toggle à la une, date modif, retour sources (v1.6.15)
- admin/articles : champ filter_search (titre, insensible casse) cumulable avec auteur/catégorie/statut (#85)
- admin/articles : colonne ★ avec toggle rapide featured + filtre filter_featured (#84)
- post/ : date de modification sous la date de publication si modifié après mise en ligne (#81)
- sources/ : bouton ← Retour à l'article vers post/<slug> au lieu de /edit/<uuid> (#83)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 09:40:43 +02:00
cedricAbonnel 347e4be0b7 perf : getAll() sans contenu, search_index + featured, excerpts via plain (v1.6.14)
- loadArticle($dir, false) dans loadAll() — meta.json seulement, pas d'index.md
- loadAll() enrichit les articles avec plain depuis search_index (1 lecture JSON)
- rebuildSearchIndex() lit index.md directement + ajoute featured au schéma
- getSearchIndex() rebuilde automatiquement si featured absent
- post_list, author_articles, author_profile : excerpts via plain, plus de Parsedown
- Ferme #24

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:50:58 +02:00
cedricAbonnel c17cad9c66 nettoyage & typo : dead code, helpers factorisés, guillemets courbes (v1.6.13)
- #19 : suppression AuthService / UserRepository / Domain\User — dead code incompatible session
- #22 : env() et db() centralisés dans src/helpers.php, chargé par config/config.php
- #15 : typographieHtml() appliquée après Parsedown dans post_view.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:36:09 +02:00