Commit Graph

11 Commits

Author SHA1 Message Date
Serreau Jovann
95d33a9a6d feat: gestion complete Devis + Avis de paiement + DocuSeal signature + mails
Devis :
- Entity DevisLine (pos, title, description, priceHt) liee a Devis (OneToMany cascade/orphanRemoval)
- Champs ajoutes sur Devis : customer (ManyToOne), submissionId, state machine (created/send/accepted/refused/cancel), raisonMessage, totaux HT/TVA/TTC, updatedAt, setUpdatedAt public
- Relation Devis <-> Advert changee de ManyToOne a OneToOne nullable
- Vich Attribute (migration Annotation -> Attribute) pour unsignedPdf/signedPdf/auditPdf
- DevisController CRUD complet : create (form repeater lignes + boutons rapides TarificationService), edit, cancel (libere OrderNumber), generate-pdf, send, resend, create-advert, events
- DevisPdf (FPDF/FPDI) : header legacy (logo, num, date, client), body lignes, summary totaux, footer SITECONSEIL + pagination, champ signature DocuSeal sur page devis + derniere page CGV
- OrderNumberService : preview() et generate() reutilisent les OrderNumber non utilises (isUsed=false) en priorite
- OrderNumber::markAsUnused() ajoute

DocuSeal integration devis :
- DocuSealService : sendDevisForSignature (avec completed_redirect_url), resendDevisSignature (archive ancienne submission), getSubmitterSlug, downloadSignedDevis (sauvegarde via Vich UploadedFile test=true)
- WebhookDocuSealController : dispatch par doc_type devis/attestation, handleDevisEvent (form.completed -> STATE_ACCEPTED + download PDF signe/audit, form.declined -> STATE_REFUSED + raison)
- DocusealEvent entity pour tracer form.viewed/started/completed/declined en temps reel
- Page evenements admin /admin/devis/{id}/events avec badges et payload JSON

Signature client :
- DevisProcessController : page publique /devis/process/{id}/{hmac} securisee par HMAC, boutons Signer (redirect DocuSeal) / Refuser (motif optionnel)
- Pages confirmation : signed.html.twig (merci + recap) et refused.html.twig (confirmation refus + motif)
- Nelmio whitelist : signature.esy-web.dev + signature.siteconseil.fr

Avis de paiement :
- Entity AdvertLine (pos, title, description, priceHt) liee a Advert
- Advert refactorise : customer, state, totaux, raisonMessage, submissionId, advertFile (Vich mapping advert_pdf), lines collection, updatedAt
- AdvertController : generate-pdf, send (mail + PJ + lien paiement), resend (rappel), cancel (delie devis, libere OrderNumber), search Meilisearch
- AdvertPdf (FPDF/FPDI) : QR code Endroid pointant vers /order/{numOrder}, texte "Scannez pour payer"
- OrderPaymentController : page publique /order/{numOrder} avec detail prestations, totaux, options paiement (placeholder)
- Creation auto depuis devis signe : copie client, totaux, lignes, meme OrderNumber

Meilisearch :
- Index customer_devis et customer_advert avec searchable (numOrder, customerName, customerEmail, state) et filterable (customerId, state)
- CRUD indexation sur chaque action (create, edit, send, cancel, create-advert)
- Recherche AJAX dans tabs Devis et Avis avec debounce + dropdown glassmorphism
- Sync admin : boutons syncDevis / syncAdverts + compteurs dans /admin/sync

Emails :
- MailerService : VCF auto (fiche contact SARL SITECONSEIL) en PJ sur tous les mails, bloc HTML pieces jointes injecte automatiquement (exclut .asc/.p7z/smime) avec icone trombone + taille fichier
- Templates : devis_to_sign, devis_signed_client/admin (PJ signed+audit), devis_refused_client/admin, advert_send (PJ + bouton paiement), ndd_expiration
- TestMailCommand : option --force-dsn pour envoyer via un DSN SMTP specifique (test prod depuis dev)

Commande NDD :
- app:ndd:check : verifie expiration domaines <= 30j, envoie mail groupe a monitor@siteconseil.fr
- Cron quotidien 8h (docker + ansible)

Divers :
- Titles templates : CRM SITECONSEIL -> SARL SITECONSEIL (52 fichiers)
- VAULT_URL dev = https://kms.esy-web.dev (comme prod)
- app.js : initDevisLines (repeater + drag & drop), initTabSearch, toggle refus devis
- app.scss : styles drag & drop
- setasign/fpdi-fpdf installe pour fusion PDF
- 5 migrations Doctrine

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 09:44:35 +02:00
Serreau Jovann
d3e76f00de fix: corriger HMAC des logs + PDF style attestation + pagination glassmorphism + purge logs
src/Entity/AppLog.php:
- createdAt initialise avec date('Y-m-d H:i:s') au lieu de
  new DateTimeImmutable() pour tronquer les microsecondes
  (PostgreSQL arrondit les microsecondes differemment de PHP,
  ce qui causait des HMAC invalides a la relecture)
- generateHmac(): format Y-m-d\TH:i:s sans microsecondes

templates/admin/logs/pdf.html.twig (reecrit):
- Meme style que les attestations RGPD (templates/pdf/rgpd_*.html.twig):
  banniere gold avec logo, doc-type badge indigo, titre italic uppercase,
  info-grid avec cellules bordure indigo, tableaux data avec header dark,
  bloc HMAC avec encadre vert/rouge, footer SARL SITECONSEIL
- Logo passe au template via base64

src/Controller/Admin/LogsController.php:
- pdf(): injection de kernel.project_dir, chargement du logo en base64
  et passage au template

src/Command/PurgeEmailTrackingCommand.php:
- Ajout de la purge des AppLog de plus de 90 jours (meme seuil
  que EmailTracking), affiche le nombre de logs supprimes

templates/components/pagination/glass.html.twig (nouveau):
- Template de pagination KnpPaginator style glassmorphism:
  boutons glass avec hover, page active en glass-gold,
  fleches precedent/suivant

config/packages/knp_paginator.yaml (nouveau):
- Configuration KnpPaginator pour utiliser le template glass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:15:00 +02:00
Serreau Jovann
1c82da99f3 fix: utiliser /uploads/devis comme URL pour les PDFs de devis
src/Controller/DevisPdfController.php:
- Route changee de /devis/pdf/{id}/{type} vers /uploads/devis/{id}/{type}
  pour garder une URL coherente avec le dossier uploads

config/packages/vich_uploader.yaml:
- uri_prefix change de /devis/pdf vers /uploads/devis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:35:11 +02:00
Serreau Jovann
88053611a4 feat: controller securise pour servir les PDFs de devis + stockage prive
src/Controller/DevisPdfController.php (nouveau):
- Route /devis/pdf/{id}/{type} avec type = unsigned|signed|audit
- Requiert ROLE_USER minimum
- checkAccess(): les ROLE_EMPLOYE ont toujours acces,
  pour les clients un TODO est prepare pour verifier que le
  client connecte est bien lie au devis (a implementer quand
  la relation Customer sera ajoutee sur Devis)
- Sert le fichier via BinaryFileResponse en inline (affichage
  dans le navigateur) avec nom de telechargement propre
  (ex: signed-04-2026-00001.pdf)

config/packages/vich_uploader.yaml:
- Mapping devis_pdf: stockage deplace de public/uploads/devis
  vers var/uploads/devis (hors du dossier public, inaccessible
  directement par URL)
- uri_prefix change en /devis/pdf (pointe vers le controller)

config/packages/security.yaml:
- Suppression de la regle access_control sur /uploads/devis
  (remplacee par le controller avec verification plus fine)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:34:54 +02:00
Serreau Jovann
09148b5b33 feat: ajout champs submitter + PDFs Vich sur Devis + protection uploads
src/Entity/Devis.php:
- submitterSiteconseilId (int nullable): ID du soumetteur cote SITECONSEIL
  dans DocuSeal apres signature
- submitterCustomerId (int nullable): ID du soumetteur cote client
  dans DocuSeal apres signature
- unsignedPdf (string nullable) + unsignedPdfFile (Vich): PDF non signe
- signedPdf (string nullable) + signedPdfFile (Vich): PDF signe
- auditPdf (string nullable) + auditPdfFile (Vich): certificat d'audit
- updatedAt (DateTimeImmutable nullable): mis a jour automatiquement
  a chaque upload de fichier via les setters *File()
- Annotation #[Vich\Uploadable] sur la classe
- Les 3 champs fichier utilisent le mapping 'devis_pdf'

config/packages/vich_uploader.yaml:
- Nouveau mapping devis_pdf: stockage dans public/uploads/devis
  avec SmartUniqueNamer pour eviter les collisions de noms

config/packages/security.yaml:
- Nouvelle regle access_control: /uploads/devis requiert ROLE_USER
  (empeche l'acces aux PDF de devis sans etre connecte)

migrations/Version20260402203334.php:
- Ajout colonnes submitter_siteconseil_id, submitter_customer_id,
  unsigned_pdf, signed_pdf, audit_pdf, updated_at sur la table devis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:33:47 +02:00
Serreau Jovann
a9057374d4 fix: deplacer le pool dns_infra_cache dans le bon fichier cache.yaml
config/packages/cache.yaml:
- Ajout du pool dns_infra_cache avec adapter cache.app et TTL 3600s
- Le pool etait dans config/packages/packages/cache.yaml qui est
  surcharge par config/packages/cache.yaml, donc le service
  dns_infra_cache n'existait pas

config/packages/packages/cache.yaml:
- Suppression du pool dns_infra_cache (doublon)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:17:29 +02:00
Serreau Jovann
28b84f09d4 feat: cache DNS report + purge EmailTracking + crons mis a jour
src/Controller/DnsReportController.php:
- Injection du pool cache dns_infra_cache via #[Autowire]
- Les resultats des checks sont caches avec la cle dns_infra_check_{token}
  pendant 1 heure (3600s) pour eviter de rappeler toutes les APIs
  (Cloudflare, AWS SES, Mailcow, RDAP, dig) a chaque rechargement
- La date du rapport est stockee dans le cache au format ISO 8601

config/packages/packages/cache.yaml:
- Nouveau pool dns_infra_cache sur Redis avec default_lifetime 3600s

src/Command/PurgeEmailTrackingCommand.php (nouveau):
- Commande app:email-tracking:purge qui supprime les EmailTracking
  dont sentAt est anterieur au seuil (90 jours par defaut)
- Option --days pour changer la retention (ex: --days=30)
- Utilise une requete DQL DELETE pour performance

ansible/deploy.yml.disabled:
- Nouveau cron "crm-siteconseil email-tracking purge": tous les jours
  a 5h du matin, supprime les EmailTracking de plus de 90 jours

docker/cron/entrypoint.sh:
- Liste complete des taches cron mise a jour avec:
  - */5 min: expire-pending, infra:snapshot
  - */15 min: services:check
  - toutes les heures: monitor:messenger
  - toutes les 2h: dns:check
  - toutes les 6h: stripe:sync
  - 3h: meilisearch consistency
  - 4h: attestations clean
  - 5h: email-tracking purge
  - 6h: cloudflare clean

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:16:50 +02:00
Serreau Jovann
6fa970e60d refactor: rebrand project to CRM SITECONSEIL (SARL SITECONSEIL)
- Rename all references from E-Cosplay/Ecosplay to SITECONSEIL
- Update entity from Association to SARL SITECONSEIL (Siret: 418664058)
- Update address to 27 rue Le Serurier, 02100 Saint-Quentin
- Update emails: contact@siteconseil.fr, rgpd@siteconseil.fr
- Update hosting from GCP to OVHcloud (Roubaix, Gravelines, Strasbourg, Paris)
- Update legal pages: mentions legales, CGV, RGPD, conformite, hebergement, cookies, CGU
- Add tarifs page with tabs: Site Internet, E-Commerce, Nom de domaine, Esy-Mail, Esy-Mailer, Esy-Tchat, Esy-Meet, Esy-Defender
- Add Discord webhook notification workflow
- Disable deploy and sonarqube workflows
- Update OAuth Keycloak realm to master
- Update logo references to logo_facture.png
- Remove forced image sizing in Liip Imagine filters
- Update SonarQube project key and badge token
- Update tribunal competent to Saint-Quentin
- Move tarif tabs JS to app.js (CSP compliance)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:48:25 +02:00
Serreau Jovann
686de99909 init 2026-04-01 15:42:52 +02:00
Serreau Jovann
beb12d2b75 Add webapp packages 2026-03-30 18:52:03 +02:00
Serreau Jovann
c1485046af Add initial set of files 2026-03-30 18:51:57 +02:00