diff --git a/.env b/.env index 8c95c73..ef74838 100644 --- a/.env +++ b/.env @@ -56,23 +56,23 @@ STRIPE_WEBHOOK_SECRET_CONNECT= STRIPE_MODE=test STRIPE_FEE_RATE=0.015 STRIPE_FEE_FIXED=25 -ADMIN_EMAIL=contact@e-cosplay.fr +ADMIN_EMAIL=contact@siteconseil.fr ###> SonarQube ### SONARQUBE_URL=https://sn.esy-web.dev -SONARQUBE_BADGE_TOKEN= -SONARQUBE_PROJECT_KEY=crm-ecosplay +SONARQUBE_BADGE_TOKEN=sqb_bf06d32640147db064c99d2e893ca63a072630d7 +SONARQUBE_PROJECT_KEY=crm_siteconseil ###< SonarQube ### -###> SSO E-Cosplay (Keycloak OIDC) ### -OAUTH_KEYCLOAK_CLIENT_ID=e-ticket -OAUTH_KEYCLOAK_CLIENT_SECRET=changeme +###> SSO SITECONSEIL (Keycloak OIDC) ### +OAUTH_KEYCLOAK_CLIENT_ID=crm_siteconseil +OAUTH_KEYCLOAK_CLIENT_SECRET=kh1WBbnEzcEZVriXmU7IaxizChReHmIx OAUTH_KEYCLOAK_URL=https://auth.esy-web.dev -OAUTH_KEYCLOAK_REALM=e-cosplay -###< SSO E-Cosplay (Keycloak OIDC) ### +OAUTH_KEYCLOAK_REALM=master +###< SSO SITECONSEIL (Keycloak OIDC) ### ###> Keycloak Admin Service Account ### -KEYCLOAK_ADMIN_CLIENT_ID=crm-ecosplay-admin +KEYCLOAK_ADMIN_CLIENT_ID=crm-siteconseil-admin KEYCLOAK_ADMIN_CLIENT_SECRET= ###< Keycloak Admin Service Account ### diff --git a/.gitea/CODEOWNERS b/.gitea/CODEOWNERS index 3f559b2..a1785b5 100644 --- a/.gitea/CODEOWNERS +++ b/.gitea/CODEOWNERS @@ -1 +1 @@ -* @jovann @e-cosplay +* @jovann @siteconseil diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index fb48a29..1febe69 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -40,7 +40,7 @@ Infra/Docker — Trivy en remplacement ou complément de Hadolint. Hadolint lint les Dockerfiles, Trivy scanne les images buildées (CVE dans les packages OS + dépendances). Vu ton stack multi-container c'est pertinent. - Frontend — Lighthouse CI si tu as des pages publiques côté E-Cosplay. Perf, accessibilité, SEO en une step. + Frontend — Lighthouse CI si tu as des pages publiques côté SITECONSEIL. Perf, accessibilité, SEO en une step. En résumé les ajouts concrets : @@ -176,9 +176,9 @@ env: POSTGRES_USER: app POSTGRES_PASSWORD: secret - POSTGRES_DB: crm_ecosplay + POSTGRES_DB: crm_siteconseil options: >- - --health-cmd "pg_isready -U app -d crm_ecosplay" + --health-cmd "pg_isready -U app -d crm_siteconseil" --health-interval 5s --health-timeout 5s --health-retries 5 @@ -195,7 +195,7 @@ MEILI_MASTER_KEY: test MEILI_ENV: development env: - DATABASE_URL: "postgresql://app:secret@database:5432/crm_ecosplay?serverVersion=16&charset=utf8" + DATABASE_URL: "postgresql://app:secret@database:5432/crm_siteconseil?serverVersion=16&charset=utf8" MESSENGER_TRANSPORT_DSN: "redis://redis:6379/messages" MAILER_DSN: "null://null" MEILISEARCH_URL: "http://meilisearch:7700" @@ -310,7 +310,7 @@ - name: OWASP Dependency-Check uses: dependency-check/Dependency-Check_Action@main with: - project: 'crm-ecosplay' + project: 'crm-siteconseil' path: '.' format: 'JSON,HTML' args: > diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml.disabled similarity index 67% rename from .gitea/workflows/deploy.yml rename to .gitea/workflows/deploy.yml.disabled index 0a65356..6f9a87b 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml.disabled @@ -17,4 +17,4 @@ jobs: ssh-keyscan 34.90.187.4 >> ~/.ssh/known_hosts - name: Deploy - run: ssh bot@34.90.187.4 "cd /var/www/crm-ecosplay && ansible-playbook ansible/deploy.yml -i ansible/hosts.ini --vault-password-file <(echo '${{ secrets.ANSIBLE_VAULT_PASSWORD }}')" + run: ssh bot@34.90.187.4 "cd /var/www/crm-siteconseil && ansible-playbook ansible/deploy.yml -i ansible/hosts.ini --vault-password-file <(echo '${{ secrets.ANSIBLE_VAULT_PASSWORD }}')" diff --git a/.gitea/workflows/discord-notify.yml b/.gitea/workflows/discord-notify.yml new file mode 100644 index 0000000..4abb7a7 --- /dev/null +++ b/.gitea/workflows/discord-notify.yml @@ -0,0 +1,70 @@ +name: Discord Notification + +on: + push: + +jobs: + notify: + runs_on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Send Discord Embed + run: | + REPO_NAME="${{ gitea.repository }}" + BRANCH="${{ gitea.ref_name }}" + AUTHOR="${{ gitea.actor }}" + COMMIT_SHA="${{ gitea.sha }}" + SHORT_SHA="${COMMIT_SHA:0:7}" + COMMIT_URL="${{ gitea.server_url }}/${REPO_NAME}/commit/${COMMIT_SHA}" + REPO_URL="${{ gitea.server_url }}/${REPO_NAME}" + TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + + COMMIT_MSG=$(git log -1 --pretty=format:'%s' | head -c 256) + COMMIT_BODY=$(git log -1 --pretty=format:'%b' | head -c 1024) + FILES_CHANGED=$(git diff --stat HEAD~1 HEAD 2>/dev/null | tail -1 || echo "N/A") + FILES_LIST=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | head -20 | sed 's/^/• /' || echo "N/A") + FILE_COUNT=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | wc -l || echo "0") + + if [ "$FILE_COUNT" -gt 20 ]; then + REMAINING=$((FILE_COUNT - 20)) + FILES_LIST="${FILES_LIST}\n... et ${REMAINING} autres fichiers" + fi + + DESCRIPTION="${COMMIT_MSG}" + if [ -n "$COMMIT_BODY" ]; then + DESCRIPTION="${DESCRIPTION}\n\n${COMMIT_BODY}" + fi + + FIELDS="[" + FIELDS="${FIELDS}{\"name\":\"Branche\",\"value\":\"\`${BRANCH}\`\",\"inline\":true}," + FIELDS="${FIELDS}{\"name\":\"Commit\",\"value\":\"[\`${SHORT_SHA}\`](${COMMIT_URL})\",\"inline\":true}," + FIELDS="${FIELDS}{\"name\":\"Auteur\",\"value\":\"${AUTHOR}\",\"inline\":true}," + FIELDS="${FIELDS}{\"name\":\"Statistiques\",\"value\":\"\`\`\`${FILES_CHANGED}\`\`\`\",\"inline\":false}," + FIELDS="${FIELDS}{\"name\":\"Fichiers modifies\",\"value\":\"\`\`\`${FILES_LIST}\`\`\`\",\"inline\":false}" + FIELDS="${FIELDS}]" + + PAYLOAD=$(cat <- - --health-cmd "pg_isready -U app -d crm_ecosplay" + --health-cmd "pg_isready -U app -d crm_siteconseil" --health-interval 5s --health-timeout 5s --health-retries 5 @@ -31,7 +31,7 @@ jobs: MEILI_MASTER_KEY: test MEILI_ENV: development env: - DATABASE_URL: "postgresql://app:secret@database:5432/crm_ecosplay?serverVersion=16&charset=utf8" + DATABASE_URL: "postgresql://app:secret@database:5432/crm_siteconseil?serverVersion=16&charset=utf8" MESSENGER_TRANSPORT_DSN: "redis://redis:6379/messages" MAILER_DSN: "null://null" MEILISEARCH_URL: "http://meilisearch:7700" @@ -95,7 +95,7 @@ jobs: - name: OWASP Dependency-Check uses: dependency-check/Dependency-Check_Action@main with: - project: 'crm-ecosplay' + project: 'crm-siteconseil' path: '.' format: 'JSON,HTML' args: > diff --git a/Makefile b/Makefile index 6647985..b630656 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,8 @@ install_prod: ## Install les dependances et build les assets pour la prod ## —— Tests ———————————————————————————————————————— test_db_create: ## Cree la base de donnees de test - docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_ecosplay -tc "SELECT 1 FROM pg_database WHERE datname = 'crm_ecosplay_test'" | grep -q 1 || \ - docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_ecosplay -c "CREATE DATABASE crm_ecosplay_test" + docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_siteconseil -tc "SELECT 1 FROM pg_database WHERE datname = 'crm_siteconseil_test'" | grep -q 1 || \ + docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_siteconseil -c "CREATE DATABASE crm_siteconseil_test" test_db_schema: ## Cree/met a jour le schema de la base de test docker compose -f docker-compose-dev.yml exec php php bin/console doctrine:schema:update --force --env=test @@ -59,8 +59,8 @@ test_db_migrate: ## Execute les migrations sur la base de test docker compose -f docker-compose-dev.yml exec php php bin/console doctrine:migrations:migrate --no-interaction --env=test test_db_reset: ## Supprime et recree la base de test depuis zero - docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_ecosplay -c "DROP DATABASE IF EXISTS crm_ecosplay_test" - docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_ecosplay -c "CREATE DATABASE crm_ecosplay_test" + docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_siteconseil -c "DROP DATABASE IF EXISTS crm_siteconseil_test" + docker compose -f docker-compose-dev.yml exec database psql -U app -d crm_siteconseil -c "CREATE DATABASE crm_siteconseil_test" $(MAKE) test_db_schema test_db_setup: ## Setup complet de la base de test (cree si besoin + schema) diff --git a/ansible/backup.sh.j2 b/ansible/backup.sh.j2 index 59969a7..4456186 100644 --- a/ansible/backup.sh.j2 +++ b/ansible/backup.sh.j2 @@ -1,14 +1,14 @@ #!/bin/bash -# CRM Ecosplay database backup script +# CRM SITECONSEIL database backup script # Runs every 30 minutes via cron -BACKUP_DIR="/var/backups/crm-ecosplay" +BACKUP_DIR="/var/backups/crm-siteconseil" DATE=$(date +%Y%m%d_%H%M%S) -FILENAME="crm_ecosplay_${DATE}.sql.gz" +FILENAME="crm_siteconseil_${DATE}.sql.gz" KEEP_DAYS=1 # Dump database via Docker -docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T db-master pg_dump -U {{ db_user | default('crm-ecosplay') }} {{ db_name | default('crm-ecosplay') }} | gzip > "${BACKUP_DIR}/${FILENAME}" +docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T db-master pg_dump -U {{ db_user | default('crm-siteconseil') }} {{ db_name | default('crm-siteconseil') }} | gzip > "${BACKUP_DIR}/${FILENAME}" # Check if backup was created if [ -f "${BACKUP_DIR}/${FILENAME}" ] && [ -s "${BACKUP_DIR}/${FILENAME}" ]; then @@ -20,7 +20,7 @@ fi # Backup uploads UPLOADS_FILENAME="uploads_${DATE}.tar.gz" -tar -czf "${BACKUP_DIR}/${UPLOADS_FILENAME}" -C /var/www/crm-ecosplay/public uploads 2>/dev/null +tar -czf "${BACKUP_DIR}/${UPLOADS_FILENAME}" -C /var/www/crm-siteconseil/public uploads 2>/dev/null if [ -f "${BACKUP_DIR}/${UPLOADS_FILENAME}" ]; then echo "[$(date)] Uploads Backup OK: ${UPLOADS_FILENAME} ($(du -h "${BACKUP_DIR}/${UPLOADS_FILENAME}" | cut -f1))" @@ -29,6 +29,6 @@ else fi # Remove backups older than KEEP_DAYS days -find "${BACKUP_DIR}" -name "crm_ecosplay_*.sql.gz" -mtime +${KEEP_DAYS} -delete +find "${BACKUP_DIR}" -name "crm_siteconseil_*.sql.gz" -mtime +${KEEP_DAYS} -delete find "${BACKUP_DIR}" -name "uploads_*.tar.gz" -mtime +${KEEP_DAYS} -delete echo "[$(date)] Cleaned backups older than ${KEEP_DAYS} days" diff --git a/ansible/caddy.j2 b/ansible/caddy.j2 index 3897c0c..ca809ee 100644 --- a/ansible/caddy.j2 +++ b/ansible/caddy.j2 @@ -1,17 +1,17 @@ -crm.e-cosplay.fr { +crm.siteconseil.fr { tls { dns cloudflare cfat_rIHZqzCm9GKK3xVnQDNGfu6J91TseIDdTKeuWSFUdf6ccd31 } @static path /logo.png /favicon.ico /favicon.png /marker.png /screen.png /manifest.json /site.webmanifest /sw.js /unavailable.html /workbox/* /idb/* /build/* /uploads/* /pwa/* handle @static { - root * /var/www/crm-crm-ecosplay/public + root * /var/www/crm-crm-siteconseil/public file_server } - @maintenance file /var/www/crm-ecosplay/public/.update + @maintenance file /var/www/crm-siteconseil/public/.update handle @maintenance { - root * /var/www/crm-ecosplay/public + root * /var/www/crm-siteconseil/public rewrite * /maintenance.html file_server { status 503 @@ -19,7 +19,7 @@ crm.e-cosplay.fr { } handle { - root * /var/www/crm-ecosplay/public + root * /var/www/crm-siteconseil/public php_fastcgi localhost:4568 localhost:4569 { root /app/public lb_policy round_robin @@ -35,7 +35,7 @@ crm.e-cosplay.fr { handle_errors { @unavailable expression `{err.status_code} in [502, 503]` handle @unavailable { - root * /var/www/crm-ecosplay/public + root * /var/www/crm-siteconseil/public rewrite * /unavailable.html file_server } @@ -48,6 +48,6 @@ crm.e-cosplay.fr { } log { - output file /var/log/caddy/ticket.e-cosplay.fr.log + output file /var/log/caddy/ticket.siteconseil.fr.log } } diff --git a/ansible/deploy.yml b/ansible/deploy.yml.disabled similarity index 60% rename from ansible/deploy.yml rename to ansible/deploy.yml.disabled index 67a0fdf..266f7be 100644 --- a/ansible/deploy.yml +++ b/ansible/deploy.yml.disabled @@ -1,6 +1,6 @@ --- # --- Server deployment --- -- name: Deploy crm-ecosplay to production +- name: Deploy crm-siteconseil to production hosts: production become: true vars_files: @@ -10,7 +10,7 @@ - name: Enable maintenance mode command: make maintenance_on args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Get Docker socket GID stat: @@ -29,14 +29,14 @@ - name: Deploy .env.local template: src: env.local.j2 - dest: /var/www/crm-ecosplay/.env.local + dest: /var/www/crm-siteconseil/.env.local owner: bot group: bot mode: "0600" - name: Ensure cert directory exists file: - path: /var/www/crm-ecosplay/config/cert + path: /var/www/crm-siteconseil/config/cert state: directory owner: bot group: bot @@ -45,7 +45,7 @@ - name: Deploy S/MIME private key copy: content: "{{ smime_private_key }}" - dest: /var/www/crm-ecosplay/config/cert/private-key.pem + dest: /var/www/crm-siteconseil/config/cert/private-key.pem owner: bot group: bot mode: "0600" @@ -53,13 +53,13 @@ - name: Pull latest code command: git pull origin master args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil become_user: bot - name: Deploy PgBouncer config template: src: pgbouncer.ini.j2 - dest: /var/www/crm-ecosplay/docker/pgsql/pgbouncer.ini + dest: /var/www/crm-siteconseil/docker/pgsql/pgbouncer.ini owner: bot group: bot mode: "0644" @@ -67,7 +67,7 @@ - name: Deploy PgBouncer userlist template: src: userlist.txt.j2 - dest: /var/www/crm-ecosplay/docker/pgsql/userlist.txt + dest: /var/www/crm-siteconseil/docker/pgsql/userlist.txt owner: bot group: bot mode: "0644" @@ -75,7 +75,7 @@ - name: Deploy docker-compose-prod.yml template: src: docker-compose-prod.yml.j2 - dest: /var/www/crm-ecosplay/docker-compose-prod.yml + dest: /var/www/crm-siteconseil/docker-compose-prod.yml owner: bot group: bot mode: "0600" @@ -83,79 +83,79 @@ - name: Build Docker images command: make build_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Pull Docker images command: make pull_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Stop production containers command: make stop_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Start production containers command: make start_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Install PHP dependencies command: composer install --no-dev --optimize-autoloader args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil become_user: bot - name: Install JS dependencies command: bun install args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil become_user: bot - name: Build assets command: bun run build args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil become_user: bot - name: Wait for database to be ready shell: | for i in $(seq 1 30); do - docker compose -f docker-compose-prod.yml exec -T php php -r "new PDO('pgsql:host=pgbouncer;port=6432;dbname=crm-ecosplay','crm-ecosplay','{{ db_password }}');" 2>/dev/null && exit 0 + docker compose -f docker-compose-prod.yml exec -T php php -r "new PDO('pgsql:host=pgbouncer;port=6432;dbname=crm-siteconseil','crm-siteconseil','{{ db_password }}');" 2>/dev/null && exit 0 sleep 1 done exit 1 args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Clear Symfony cache before migration command: docker compose -f docker-compose-prod.yml exec -T php php bin/console cache:clear --env=prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Clear Redis cache pool (Doctrine L2 + app cache) command: docker compose -f docker-compose-prod.yml exec -T php php bin/console cache:pool:clear cache.app --env=prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Run migrations command: make migrate_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Clear cache after migration command: make clear_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Compile PWA assets command: make pwa_prod args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil - name: Ensure uploads directories exist with correct permissions file: - path: "/var/www/crm-ecosplay/public/uploads/{{ item }}" + path: "/var/www/crm-siteconseil/public/uploads/{{ item }}" state: directory owner: "1000" group: "1000" @@ -166,7 +166,7 @@ - name: Ensure var/payouts directory exists file: - path: /var/www/crm-ecosplay/var/payouts + path: /var/www/crm-siteconseil/var/payouts state: directory owner: "1000" group: "1000" @@ -183,7 +183,7 @@ - name: Deploy Caddy config template: src: caddy.j2 - dest: /etc/caddy/sites/crm-ecosplay.conf + dest: /etc/caddy/sites/crm-siteconseil.conf owner: root group: root mode: "0644" @@ -191,7 +191,7 @@ - name: Create backup directory file: - path: /var/backups/crm-ecosplay + path: /var/backups/crm-siteconseil state: directory owner: bot group: bot @@ -200,75 +200,75 @@ - name: Deploy backup script template: src: backup.sh.j2 - dest: /var/backups/crm-ecosplay/backup.sh + dest: /var/backups/crm-siteconseil/backup.sh owner: bot group: bot mode: "0750" - name: Configure backup cron (every 30 minutes) cron: - name: "crm-ecosplay database backup" + name: "crm-siteconseil database backup" minute: "*/30" - job: "/var/backups/crm-ecosplay/backup.sh >> /var/log/crm-ecosplay-backup.log 2>&1" + job: "/var/backups/crm-siteconseil/backup.sh >> /var/log/crm-siteconseil-backup.log 2>&1" user: bot - name: Configure expire pending orders cron (every 5 minutes) cron: - name: "crm-ecosplay expire pending orders" + name: "crm-siteconseil expire pending orders" minute: "*/5" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:orders:expire-pending --env=prod >> /var/log/crm-ecosplay-expire-orders.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:orders:expire-pending --env=prod >> /var/log/crm-siteconseil-expire-orders.log 2>&1" user: bot - name: Configure messenger monitor cron (every hour) cron: - name: "crm-ecosplay messenger monitor" + name: "crm-siteconseil messenger monitor" minute: "0" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:monitor:messenger --env=prod >> /var/log/crm-ecosplay-messenger.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:monitor:messenger --env=prod >> /var/log/crm-siteconseil-messenger.log 2>&1" user: bot - name: Configure Meilisearch consistency check cron (daily at 3am) cron: - name: "crm-ecosplay meilisearch consistency" + name: "crm-siteconseil meilisearch consistency" minute: "0" hour: "3" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:meilisearch:check-consistency --fix --env=prod >> /var/log/crm-ecosplay-meilisearch.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:meilisearch:check-consistency --fix --env=prod >> /var/log/crm-siteconseil-meilisearch.log 2>&1" user: bot - name: Configure Stripe sync cron (every 6 hours) cron: - name: "crm-ecosplay stripe sync" + name: "crm-siteconseil stripe sync" minute: "0" hour: "*/6" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:stripe:sync --env=prod >> /var/log/crm-ecosplay-stripe-sync.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:stripe:sync --env=prod >> /var/log/crm-siteconseil-stripe-sync.log 2>&1" user: bot - name: Configure infra snapshot cron (every 5 minutes) cron: - name: "crm-ecosplay infra snapshot" + name: "crm-siteconseil infra snapshot" minute: "*/5" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:infra:snapshot --env=prod >> /var/log/crm-ecosplay-infra.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:infra:snapshot --env=prod >> /var/log/crm-siteconseil-infra.log 2>&1" user: bot - name: Configure attestations cleanup cron (daily at 4am) cron: - name: "crm-ecosplay attestations clean" + name: "crm-siteconseil attestations clean" minute: "0" hour: "4" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:attestations:clean --env=prod >> /var/log/crm-ecosplay-attestations.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:attestations:clean --env=prod >> /var/log/crm-siteconseil-attestations.log 2>&1" user: bot - name: Configure services health check cron (every 15 minutes) cron: - name: "crm-ecosplay services check" + name: "crm-siteconseil services check" minute: "*/15" - job: "docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec -T php php bin/console app:services:check --env=prod >> /var/log/crm-ecosplay-services.log 2>&1" + job: "docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec -T php php bin/console app:services:check --env=prod >> /var/log/crm-siteconseil-services.log 2>&1" user: bot post_tasks: - name: Disable maintenance mode command: make maintenance_off args: - chdir: /var/www/crm-ecosplay + chdir: /var/www/crm-siteconseil handlers: - name: Reload Caddy diff --git a/ansible/docker-compose-prod.yml.j2 b/ansible/docker-compose-prod.yml.j2 index 898e2ce..b915e0c 100644 --- a/ansible/docker-compose-prod.yml.j2 +++ b/ansible/docker-compose-prod.yml.j2 @@ -1,4 +1,4 @@ -name: crm-ecosplay +name: crm-siteconseil services: php: @@ -23,7 +23,7 @@ services: ports: - "4568-4569:9000" networks: - - crm_ecosplay + - crm_siteconseil depends_on: pgbouncer: condition: service_healthy @@ -42,9 +42,9 @@ services: cpus: "0.5" memory: 1G environment: - POSTGRES_USER: crm-ecosplay + POSTGRES_USER: crm-siteconseil POSTGRES_PASSWORD: {{ db_password }} - POSTGRES_DB: crm-ecosplay + POSTGRES_DB: crm-siteconseil command: - postgres - -c @@ -65,9 +65,9 @@ services: - db-master-data:/var/lib/postgresql/data - ./docker/pgsql/init-master.sh:/docker-entrypoint-initdb.d/init-master.sh networks: - - crm_ecosplay + - crm_siteconseil healthcheck: - test: ["CMD-SHELL", "pg_isready -U crm-ecosplay -d crm-ecosplay"] + test: ["CMD-SHELL", "pg_isready -U crm-siteconseil -d crm-siteconseil"] interval: 5s timeout: 5s retries: 5 @@ -84,9 +84,9 @@ services: cpus: "0.25" memory: 512M environment: - POSTGRES_USER: crm-ecosplay + POSTGRES_USER: crm-siteconseil POSTGRES_PASSWORD: {{ db_password }} - POSTGRES_DB: crm-ecosplay + POSTGRES_DB: crm-siteconseil PGDATA: /var/lib/postgresql/data volumes: - db-slave-data:/var/lib/postgresql/data @@ -94,12 +94,12 @@ services: entrypoint: ["/bin/bash", "/init-slave.sh"] command: ["postgres"] networks: - - crm_ecosplay + - crm_siteconseil depends_on: db-master: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "pg_isready -U crm-ecosplay -d crm-ecosplay"] + test: ["CMD-SHELL", "pg_isready -U crm-siteconseil -d crm-siteconseil"] interval: 5s timeout: 5s retries: 5 @@ -119,14 +119,14 @@ services: - ./docker/pgsql/pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini:ro - ./docker/pgsql/userlist.txt:/etc/pgbouncer/userlist.txt:ro networks: - - crm_ecosplay + - crm_siteconseil depends_on: db-master: condition: service_healthy db-slave: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 6432 -U crm-ecosplay"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 6432 -U crm-siteconseil"] interval: 5s timeout: 5s retries: 5 @@ -149,7 +149,7 @@ services: volumes: - .:/app networks: - - crm_ecosplay + - crm_siteconseil depends_on: pgbouncer: condition: service_healthy @@ -173,7 +173,7 @@ services: volumes: - redis-data:/data networks: - - crm_ecosplay + - crm_siteconseil healthcheck: test: ["CMD", "redis-cli", "-a", "{{ redis_password }}", "ping"] interval: 5s @@ -198,10 +198,10 @@ services: volumes: - meilisearch-data:/meili_data networks: - - crm_ecosplay + - crm_siteconseil networks: - crm_ecosplay: + crm_siteconseil: driver: bridge volumes: diff --git a/ansible/env.local.j2 b/ansible/env.local.j2 index 77783c6..27738a4 100644 --- a/ansible/env.local.j2 +++ b/ansible/env.local.j2 @@ -1,14 +1,14 @@ APP_ENV=prod APP_SECRET={{ app_secret }} -DATABASE_URL="postgresql://crm-ecosplay:{{ db_password }}@pgbouncer:6432/crm-ecosplay?serverVersion=16&charset=utf8" +DATABASE_URL="postgresql://crm-siteconseil:{{ db_password }}@pgbouncer:6432/crm-siteconseil?serverVersion=16&charset=utf8" MESSENGER_TRANSPORT_DSN=redis://:{{ redis_password }}@redis:6379/messages SESSION_HANDLER_DSN=redis://:{{ redis_password }}@redis:6379/1 REDIS_CACHE_DSN=redis://:{{ redis_password }}@redis:6379/2 MAILER_DSN={{ mailer_dsn }} -DEFAULT_URI=https://ticket.e-cosplay.fr +DEFAULT_URI=https://ticket.siteconseil.fr VITE_LOAD=1 REAL_MAIL=1 -OUTSIDE_URL=https://ticket.e-cosplay.fr +OUTSIDE_URL=https://ticket.siteconseil.fr STRIPE_PK={{ stripe_pk }} STRIPE_SK={{ stripe_sk }} STRIPE_WEBHOOK_SECRET={{ stripe_webhook_secret }} @@ -19,13 +19,13 @@ MEILISEARCH_URL=http://meilisearch:7700 MEILISEARCH_API_KEY={{ meilisearch_api_key }} SONARQUBE_URL=https://sn.esy-web.dev SONARQUBE_BADGE_TOKEN={{ sonarqube_badge_token }} -SONARQUBE_PROJECT_KEY=crm-ecosplay -OAUTH_KEYCLOAK_CLIENT_ID=crm_ecosplay -OAUTH_KEYCLOAK_CLIENT_SECRET=QiksEpHqDCHFPMM9CWb3RHfag31VJfIV +SONARQUBE_PROJECT_KEY=crm_siteconseil +OAUTH_KEYCLOAK_CLIENT_ID=crm_siteconseil +OAUTH_KEYCLOAK_CLIENT_SECRET=kh1WBbnEzcEZVriXmU7IaxizChReHmIx OAUTH_KEYCLOAK_URL=https://auth.esy-web.dev -OAUTH_KEYCLOAK_REALM=e-cosplay +OAUTH_KEYCLOAK_REALM=master SECRET_ANALYTICS={{ analytics_secret }} -KEYCLOAK_ADMIN_CLIENT_ID=crm-ecosplay-admin +KEYCLOAK_ADMIN_CLIENT_ID=crm-siteconseil-admin KEYCLOAK_ADMIN_CLIENT_SECRET={{ keycloak_admin_client_secret }} DOCUSEAL_URL=https://signature.esy-web.dev DOCUSEAL_API={{ docuseal_api }} diff --git a/ansible/hosts.ini b/ansible/hosts.ini index 937139e..f243f2c 100644 --- a/ansible/hosts.ini +++ b/ansible/hosts.ini @@ -2,4 +2,4 @@ 127.0.0.1 ansible_user=bot ansible_become=yes ansible_become_method=sudo ansible_connection=local [production:vars] -deploy_path=/var/www/crm.ecosplay/ +deploy_path=/var/www/crm.siteconseil/ diff --git a/ansible/messenger.j2 b/ansible/messenger.j2 index 5b218b5..7d23c3f 100644 --- a/ansible/messenger.j2 +++ b/ansible/messenger.j2 @@ -1,6 +1,6 @@ -[program:crm-ecosplay-messenger] -command=docker compose -f /var/www/crm-ecosplay/docker-compose-prod.yml exec php php bin/console messenger:consume async --time-limit=3600 --memory-limit=256M --limit=500 -directory=/var/www/crm-ecosplay +[program:crm-siteconseil-messenger] +command=docker compose -f /var/www/crm-siteconseil/docker-compose-prod.yml exec php php bin/console messenger:consume async --time-limit=3600 --memory-limit=256M --limit=500 +directory=/var/www/crm-siteconseil user=bot numprocs=2 process_name=%(program_name)s_%(process_num)02d @@ -8,5 +8,5 @@ autostart=true autorestart=true startsecs=0 startretries=10 -stdout_logfile=/var/log/supervisor/crm-ecosplay-messenger-%(process_num)02d.log -stderr_logfile=/var/log/supervisor/crm-ecosplay-messenger-%(process_num)02d-error.log +stdout_logfile=/var/log/supervisor/crm-siteconseil-messenger-%(process_num)02d.log +stderr_logfile=/var/log/supervisor/crm-siteconseil-messenger-%(process_num)02d-error.log diff --git a/ansible/pgbouncer.ini.j2 b/ansible/pgbouncer.ini.j2 index 9364b48..8c093df 100644 --- a/ansible/pgbouncer.ini.j2 +++ b/ansible/pgbouncer.ini.j2 @@ -1,6 +1,6 @@ [databases] -crm-ecosplay = host=db-master port=5432 dbname=crm-ecosplay -crm-ecosplay_readonly = host=db-slave port=5432 dbname=crm-ecosplay +crm-siteconseil = host=db-master port=5432 dbname=crm-siteconseil +crm-siteconseil_readonly = host=db-slave port=5432 dbname=crm-siteconseil [pgbouncer] listen_addr = 0.0.0.0 @@ -17,5 +17,5 @@ server_lifetime = 3600 server_idle_timeout = 600 log_connections = 0 log_disconnections = 0 -admin_users = crm-ecosplay -stats_users = crm-ecosplay +admin_users = crm-siteconseil +stats_users = crm-siteconseil diff --git a/ansible/userlist.txt.j2 b/ansible/userlist.txt.j2 index a878a4b..5fd391a 100644 --- a/ansible/userlist.txt.j2 +++ b/ansible/userlist.txt.j2 @@ -1 +1 @@ -"crm-ecosplay" "{{ db_password }}" +"crm-siteconseil" "{{ db_password }}" diff --git a/ansible/vault.yml b/ansible/vault.yml index 82b40f2..6e0723d 100644 --- a/ansible/vault.yml +++ b/ansible/vault.yml @@ -18,7 +18,7 @@ docuseal_webhooks_secret: CRM_COSLAY smime_private_key: | Bag Attributes localKeyID: 75 15 E3 C2 1D 7B 61 75 99 B9 22 D8 FD A4 19 AC 6B BE 1F 8F - friendlyName: contact@e-cosplay.fr + friendlyName: contact@siteconseil.fr Key Attributes: -----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC60+PtobUKQsjH diff --git a/assets/app.js b/assets/app.js index 4656108..7d55286 100644 --- a/assets/app.js +++ b/assets/app.js @@ -138,4 +138,24 @@ document.addEventListener('DOMContentLoaded', () => { setupSearch('search-customers', 'search-results', '/admin/clients/search', '/admin/clients/'); setupSearch('search-revendeurs', 'search-results-revendeurs', '/admin/revendeurs/search', '/admin/revendeurs/'); + + // Tarif tabs + const tarifTabs = document.getElementById('tarif-tabs'); + if (tarifTabs) { + const active = 'px-6 py-3 font-black uppercase text-sm tracking-widest bg-gray-900 text-white border-2 border-gray-900 border-b-0 cursor-pointer'; + const inactive = 'px-6 py-3 font-black uppercase text-sm tracking-widest bg-white text-gray-900 border-2 border-gray-900 border-b-0 cursor-pointer hover:bg-gray-100 transition-all'; + + tarifTabs.querySelectorAll('[data-tab]').forEach(btn => { + btn.addEventListener('click', () => { + const tab = btn.dataset.tab; + tarifTabs.querySelectorAll('[data-tab]').forEach(b => { + b.className = b.dataset.tab === tab ? active : inactive; + }); + document.querySelectorAll('[id^="content-"]').forEach(el => { + if (el.closest('#tarif-tabs')) return; + el.classList.toggle('hidden', el.id !== 'content-' + tab); + }); + }); + }); + } }); diff --git a/config/packages/liip_imagine.yaml b/config/packages/liip_imagine.yaml index 3a6a147..3eb0ca8 100644 --- a/config/packages/liip_imagine.yaml +++ b/config/packages/liip_imagine.yaml @@ -28,7 +28,6 @@ liip_imagine: format: 'webp' filters: strip: ~ - thumbnail: { size: [ 48, 48 ], mode: inset } avatar: quality: 80 format: 'webp' @@ -46,4 +45,3 @@ liip_imagine: format: 'webp' filters: strip: ~ - thumbnail: { size: [ 99, 56 ], mode: inset } diff --git a/config/packages/packages/cache.yaml b/config/packages/packages/cache.yaml index 024348e..56df9cd 100644 --- a/config/packages/packages/cache.yaml +++ b/config/packages/packages/cache.yaml @@ -3,7 +3,7 @@ framework: # Nom unique de votre application : utilisé pour calculer des espaces de noms stables pour les clés de cache. # Ceci est CRUCIAL pour éviter les collisions de clés si plusieurs applications partagent le même serveur de cache (ex: Redis). # Décommentez et remplacez par une valeur unique à votre projet (ex: "mon_entreprise/mon_app") - prefix_seed: 'e-cosplay/contest' # <-- REMPLACEZ CECI PAR UN NOM UNIQUE À VOTRE PROJET + prefix_seed: 'siteconseil/contest' # <-- REMPLACEZ CECI PAR UN NOM UNIQUE À VOTRE PROJET # En production, utilisez un adaptateur de cache rapide et performant comme Redis. # Assurez-vous que votre serveur Redis est accessible. diff --git a/config/packages/packages/framework.yaml b/config/packages/packages/framework.yaml index dbb8776..2cedce2 100644 --- a/config/packages/packages/framework.yaml +++ b/config/packages/packages/framework.yaml @@ -8,7 +8,7 @@ framework: stale_while_revalidate: 3600 stale_if_error: 3600 session: - name: ecosplay_session + name: siteconseil_session cookie_lifetime: 3600 cookie_secure: true diff --git a/config/packages/packages/pwa.yaml b/config/packages/packages/pwa.yaml index cbcb687..5117946 100644 --- a/config/packages/packages/pwa.yaml +++ b/config/packages/packages/pwa.yaml @@ -11,7 +11,7 @@ pwa: skip_waiting: true manifest: enabled: true - name: "E-Cosplay" + name: "SITECONSEIL" short_name: "PWA" start_url: "app_home" display: "standalone" diff --git a/config/packages/packages/vich_uploader.yaml b/config/packages/packages/vich_uploader.yaml index 32ded30..ee38a1b 100644 --- a/config/packages/packages/vich_uploader.yaml +++ b/config/packages/packages/vich_uploader.yaml @@ -24,16 +24,16 @@ vich_uploader: inject_on_load: true delete_on_update: true delete_on_remove: true - members_page_cosplay: + members_pagsiteconseil: uri_prefix: /storage/members_page_avatar upload_destination: '%kernel.project_dir%/public/storage/members_page_avatar' namer: Vich\UploaderBundle\Naming\UniqidNamer inject_on_load: true delete_on_update: true delete_on_remove: true - members_page_cosplay_details: - uri_prefix: /storage/members_page_cosplay_details - upload_destination: '%kernel.project_dir%/public/storage/members_page_cosplay_details' + members_pagsiteconseil_details: + uri_prefix: /storage/members_pagsiteconseil_details + upload_destination: '%kernel.project_dir%/public/storage/members_pagsiteconseil_details' namer: Vich\UploaderBundle\Naming\UniqidNamer inject_on_load: true delete_on_update: true diff --git a/config/packages/scheb_2fa.yaml b/config/packages/scheb_2fa.yaml index 8b064c6..281d28c 100644 --- a/config/packages/scheb_2fa.yaml +++ b/config/packages/scheb_2fa.yaml @@ -5,15 +5,15 @@ scheb_two_factor: email: enabled: true - sender_email: 'contact@e-cosplay.fr' - sender_name: 'CRM Ecosplay' + sender_email: 'contact@siteconseil.fr' + sender_name: 'CRM SITECONSEIL' digits: 6 template: 'security/2fa_email.html.twig' mailer: App\Security\TwoFactorCodeMailer google: enabled: true - issuer: 'CRM Ecosplay' + issuer: 'CRM SITECONSEIL' template: 'security/2fa_google.html.twig' backup_codes: diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 5578d1e..8b0ba08 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -55,6 +55,12 @@ security: when@test: security: + providers: + test_user_provider: + id: App\Tests\TestUserProvider + firewalls: + main: + provider: test_user_provider password_hashers: # Password hashers are resource-intensive by design to ensure security. # In tests, it's safe to reduce their cost to improve performance. diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 982c20e..fd634f0 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -3,7 +3,7 @@ services: build: context: ./docker/php/dev dockerfile: Dockerfile - container_name: crm_ecosplay_php + container_name: crm_siteconseil_php restart: unless-stopped group_add: - "${DOCKER_GID:-989}" @@ -20,24 +20,24 @@ services: database: image: postgres:16-alpine - container_name: crm_ecosplay_database + container_name: crm_siteconseil_database environment: POSTGRES_USER: app POSTGRES_PASSWORD: secret - POSTGRES_DB: crm_ecosplay + POSTGRES_DB: crm_siteconseil ports: - "5432:5432" volumes: - db-data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U app -d crm_ecosplay"] + test: ["CMD-SHELL", "pg_isready -U app -d crm_siteconseil"] interval: 5s timeout: 5s retries: 5 pgbouncer: image: edoburu/pgbouncer - container_name: crm_ecosplay_pgbouncer + container_name: crm_siteconseil_pgbouncer volumes: - ./docker/pgsql/pgbouncer-dev.ini:/etc/pgbouncer/pgbouncer.ini:ro - ./docker/pgsql/userlist-dev.txt:/etc/pgbouncer/userlist.txt:ro @@ -54,21 +54,21 @@ services: redis: image: redis:7-alpine - container_name: crm_ecosplay_redis - command: redis-server --requirepass crm_ecosplay + container_name: crm_siteconseil_redis + command: redis-server --requirepass crm_siteconseil ports: - "6379:6379" volumes: - redis-data:/data healthcheck: - test: ["CMD", "redis-cli", "-a", "crm_ecosplay", "ping"] + test: ["CMD", "redis-cli", "-a", "crm_siteconseil", "ping"] interval: 5s timeout: 5s retries: 5 caddy: image: caddy:2-alpine - container_name: crm_ecosplay_caddy + container_name: crm_siteconseil_caddy ports: - "8000:80" volumes: @@ -81,7 +81,7 @@ services: build: context: ./docker/php/dev dockerfile: Dockerfile - container_name: crm_ecosplay_messenger + container_name: crm_siteconseil_messenger command: php bin/console messenger:consume async -vv restart: unless-stopped volumes: @@ -96,7 +96,7 @@ services: bun: image: oven/bun:alpine - container_name: crm_ecosplay_bun + container_name: crm_siteconseil_bun working_dir: /app volumes: - .:/app @@ -107,18 +107,18 @@ services: mailpit: image: axllent/mailpit - container_name: crm_ecosplay_mailpit + container_name: crm_siteconseil_mailpit ports: - "1025:1025" - "8025:8025" vault: image: hashicorp/vault:latest - container_name: crm_ecosplay_vault + container_name: crm_siteconseil_vault cap_add: - IPC_LOCK environment: - VAULT_DEV_ROOT_TOKEN_ID: crm_ecosplay + VAULT_DEV_ROOT_TOKEN_ID: crm_siteconseil VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200 ports: - "8200:8200" @@ -127,7 +127,7 @@ services: ngrok: image: ngrok/ngrok:latest - container_name: crm_ecosplay_ngrok + container_name: crm_siteconseil_ngrok command: http caddy:80 --log stdout environment: NGROK_AUTHTOKEN: GXtZtKtRxRF5TFV5pCKD_25f1ALUyQQ9LkyQJgv1dr @@ -138,7 +138,7 @@ services: ngrok-sync: image: curlimages/curl:latest - container_name: crm_ecosplay_ngrok_sync + container_name: crm_siteconseil_ngrok_sync user: "0:0" volumes: - .:/app @@ -149,9 +149,9 @@ services: meilisearch: image: getmeili/meilisearch:latest - container_name: crm_ecosplay_meilisearch + container_name: crm_siteconseil_meilisearch environment: - MEILI_MASTER_KEY: crm_ecosplay + MEILI_MASTER_KEY: crm_siteconseil MEILI_ENV: development ports: - "7700:7700" @@ -162,7 +162,7 @@ services: build: context: ./docker/cron dockerfile: Dockerfile - container_name: crm_ecosplay_cron + container_name: crm_siteconseil_cron restart: unless-stopped group_add: - "${DOCKER_GID:-989}" @@ -177,7 +177,7 @@ services: redisinsight: image: redis/redisinsight:latest - container_name: crm_ecosplay_redisinsight + container_name: crm_siteconseil_redisinsight ports: - "5540:5540" depends_on: diff --git a/docker/cron/entrypoint.sh b/docker/cron/entrypoint.sh index edd5349..ab20df6 100644 --- a/docker/cron/entrypoint.sh +++ b/docker/cron/entrypoint.sh @@ -1,5 +1,5 @@ #!/bin/sh -echo "=== CRM Ecosplay Cron ===" +echo "=== CRM SITECONSEIL Cron ===" echo "Registered tasks:" echo " - */5 * * * * app:orders:expire-pending" echo " - 0 * * * * app:monitor:messenger" diff --git a/docker/pgsql/init-master.sh b/docker/pgsql/init-master.sh index fb0e5f5..49b7d6d 100755 --- a/docker/pgsql/init-master.sh +++ b/docker/pgsql/init-master.sh @@ -2,7 +2,7 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'crm-ecosplay'; + CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'crm-siteconseil'; SELECT pg_create_physical_replication_slot('slave_slot'); EOSQL diff --git a/docker/pgsql/init-master.sql b/docker/pgsql/init-master.sql index 76842fe..8cd4bb3 100644 --- a/docker/pgsql/init-master.sql +++ b/docker/pgsql/init-master.sql @@ -1,2 +1,2 @@ -CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'crm-ecosplay'; +CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'crm-siteconseil'; SELECT pg_create_physical_replication_slot('slave_slot'); diff --git a/docker/pgsql/init-slave.sh b/docker/pgsql/init-slave.sh index 9d25853..ef7488b 100755 --- a/docker/pgsql/init-slave.sh +++ b/docker/pgsql/init-slave.sh @@ -1,12 +1,12 @@ #!/bin/bash set -e -until pg_isready -h db-master -U crm-ecosplay; do +until pg_isready -h db-master -U crm-siteconseil; do echo "Waiting for master..." sleep 2 done -echo "db-master:5432:replication:replicator:crm-ecosplay" > /tmp/.pgpass +echo "db-master:5432:replication:replicator:crm-siteconseil" > /tmp/.pgpass chown postgres:postgres /tmp/.pgpass chmod 600 /tmp/.pgpass diff --git a/docker/pgsql/pgbouncer-dev.ini b/docker/pgsql/pgbouncer-dev.ini index db9621a..0c8bf74 100644 --- a/docker/pgsql/pgbouncer-dev.ini +++ b/docker/pgsql/pgbouncer-dev.ini @@ -1,6 +1,6 @@ [databases] -crm_ecosplay = host=database port=5432 dbname=crm_ecosplay -crm_ecosplay_test = host=database port=5432 dbname=crm_ecosplay_test +crm_siteconseil = host=database port=5432 dbname=crm_siteconseil +crm_siteconseil_test = host=database port=5432 dbname=crm_siteconseil_test [pgbouncer] listen_addr = 0.0.0.0 diff --git a/package.json b/package.json index e070733..dec5ad8 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "e-cosplay", + "name": "siteconseil", "private": true, "version": "0.0.0", "type": "module", diff --git a/public/Gemini_Generated_Image_q1z0qzq1z0qzq1z0.png:Zone.Identifier b/public/Gemini_Generated_Image_q1z0qzq1z0qzq1z0.png:Zone.Identifier deleted file mode 100644 index d6c1ec6..0000000 Binary files a/public/Gemini_Generated_Image_q1z0qzq1z0qzq1z0.png:Zone.Identifier and /dev/null differ diff --git a/public/JOAFE_PDF_Unitaire_20250013_00029.pdf b/public/JOAFE_PDF_Unitaire_20250013_00029.pdf deleted file mode 100644 index b14743c..0000000 Binary files a/public/JOAFE_PDF_Unitaire_20250013_00029.pdf and /dev/null differ diff --git a/public/avis-41866405800025-20260402172833.pdf b/public/avis-41866405800025-20260402172833.pdf new file mode 100644 index 0000000..2e294fd Binary files /dev/null and b/public/avis-41866405800025-20260402172833.pdf differ diff --git a/public/avis-94312151700016-20260401111834.pdf b/public/avis-94312151700016-20260401111834.pdf deleted file mode 100644 index c4fba40..0000000 Binary files a/public/avis-94312151700016-20260401111834.pdf and /dev/null differ diff --git a/public/bimi.svg b/public/bimi.svg deleted file mode 100644 index f685675..0000000 --- a/public/bimi.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - bimi-svg-tiny-12-ps - - - - - - - \ No newline at end of file diff --git a/public/favicon.png b/public/favicon.png index f5ed9d7..947a93c 100644 Binary files a/public/favicon.png and b/public/favicon.png differ diff --git a/public/logo.jpg b/public/logo.jpg deleted file mode 100644 index feb6bec..0000000 Binary files a/public/logo.jpg and /dev/null differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..4b9c86d Binary files /dev/null and b/public/logo.png differ diff --git a/public/Gemini_Generated_Image_p4g00sp4g00sp4g0.png:Zone.Identifier b/public/logo_facture-removebg-preview.png:Zone.Identifier similarity index 100% rename from public/Gemini_Generated_Image_p4g00sp4g00sp4g0.png:Zone.Identifier rename to public/logo_facture-removebg-preview.png:Zone.Identifier diff --git a/public/logo_facture.png b/public/logo_facture.png new file mode 100644 index 0000000..3c6d238 Binary files /dev/null and b/public/logo_facture.png differ diff --git a/public/marker.png b/public/marker.png index 0587826..bc0fcad 100644 Binary files a/public/marker.png and b/public/marker.png differ diff --git a/sonar-project.properties b/sonar-project.properties index 90e27d7..16d97c4 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=crm-ecosplay -sonar.projectName=CRM Ecosplay +sonar.projectKey=crm_siteconseil +sonar.projectName=CRM SITECONSEIL sonar.sources=src,assets,templates sonar.tests=tests diff --git a/src/Command/StripeSyncCommand.php b/src/Command/StripeSyncCommand.php index 3120831..b6a3bc1 100644 --- a/src/Command/StripeSyncCommand.php +++ b/src/Command/StripeSyncCommand.php @@ -43,18 +43,15 @@ class StripeSyncCommand extends Command return Command::SUCCESS; } - private function syncPayments(SymfonyStyle $io): void + protected function syncPayments(SymfonyStyle $io): void { $io->section('Paiements'); try { - $charges = \Stripe\Charge::all([ - 'limit' => 100, - 'created' => ['gte' => strtotime('-1 day')], - ]); + $charges = $this->fetchCharges(); $count = 0; - foreach ($charges->data as $charge) { + foreach ($charges as $charge) { $io->info('Paiement ID: '.$charge->id); ++$count; } @@ -65,18 +62,15 @@ class StripeSyncCommand extends Command } } - private function syncRefunds(SymfonyStyle $io): void + protected function syncRefunds(SymfonyStyle $io): void { $io->section('Remboursements'); try { - $refunds = \Stripe\Refund::all([ - 'limit' => 100, - 'created' => ['gte' => strtotime('-1 day')], - ]); + $refunds = $this->fetchRefunds(); $count = 0; - foreach ($refunds->data as $refund) { + foreach ($refunds as $refund) { $io->info('Remboursement ID: '.$refund->id); ++$count; } @@ -87,18 +81,15 @@ class StripeSyncCommand extends Command } } - private function syncPayouts(SymfonyStyle $io): void + protected function syncPayouts(SymfonyStyle $io): void { $io->section('Versements'); try { - $payouts = \Stripe\Payout::all([ - 'limit' => 100, - 'created' => ['gte' => strtotime('-7 days')], - ]); + $payouts = $this->fetchPayouts(); $count = 0; - foreach ($payouts->data as $payout) { + foreach ($payouts as $payout) { $io->info('Versement ID: '.$payout->id); ++$count; } @@ -109,15 +100,15 @@ class StripeSyncCommand extends Command } } - private function syncConnectAccounts(SymfonyStyle $io): void + protected function syncConnectAccounts(SymfonyStyle $io): void { $io->section('Comptes Connect'); try { - $accounts = \Stripe\Account::all(['limit' => 100]); + $accounts = $this->fetchConnectAccounts(); $count = 0; - foreach ($accounts->data as $account) { + foreach ($accounts as $account) { $status = $account->charges_enabled ? 'actif' : 'inactif'; $payoutsEnabled = $account->payouts_enabled ? 'oui' : 'non'; @@ -138,4 +129,40 @@ class StripeSyncCommand extends Command $io->error('Erreur comptes Connect : '.$e->getMessage()); } } + + /** + * @return iterable<\Stripe\Charge> + * @codeCoverageIgnore + */ + protected function fetchCharges(): iterable + { + return \Stripe\Charge::all(['limit' => 100, 'created' => ['gte' => strtotime('-1 day')]])->data; + } + + /** + * @return iterable<\Stripe\Refund> + * @codeCoverageIgnore + */ + protected function fetchRefunds(): iterable + { + return \Stripe\Refund::all(['limit' => 100, 'created' => ['gte' => strtotime('-1 day')]])->data; + } + + /** + * @return iterable<\Stripe\Payout> + * @codeCoverageIgnore + */ + protected function fetchPayouts(): iterable + { + return \Stripe\Payout::all(['limit' => 100, 'created' => ['gte' => strtotime('-7 days')]])->data; + } + + /** + * @return iterable<\Stripe\Account> + * @codeCoverageIgnore + */ + protected function fetchConnectAccounts(): iterable + { + return \Stripe\Account::all(['limit' => 100])->data; + } } diff --git a/src/Controller/Admin/MembresController.php b/src/Controller/Admin/MembresController.php index 5320d5a..e62e8cd 100644 --- a/src/Controller/Admin/MembresController.php +++ b/src/Controller/Admin/MembresController.php @@ -161,7 +161,7 @@ class MembresController extends AbstractController ): void { $mailer->sendEmail( $email, - 'CRM Ecosplay - Votre compte a ete cree', + 'CRM SITECONSEIL - Votre compte a ete cree', $twig->render('emails/membre_created.html.twig', [ 'firstName' => $firstName, 'lastName' => $lastName, @@ -192,7 +192,7 @@ class MembresController extends AbstractController $mailer->sendEmail( $user->getEmail(), - 'CRM Ecosplay - Rappel : votre compte a ete cree', + 'CRM SITECONSEIL - Rappel : votre compte a ete cree', $twig->render('emails/membre_created.html.twig', [ 'firstName' => $user->getFirstName(), 'lastName' => $user->getLastName(), diff --git a/src/Controller/Admin/RevendeursController.php b/src/Controller/Admin/RevendeursController.php index 7730a5e..a803783 100644 --- a/src/Controller/Admin/RevendeursController.php +++ b/src/Controller/Admin/RevendeursController.php @@ -86,7 +86,7 @@ class RevendeursController extends AbstractController $mailer->sendEmail( $email, - 'CRM Ecosplay - Bienvenue dans l\'espace revendeur', + 'CRM SITECONSEIL - Bienvenue dans l\'espace revendeur', $twig->render('emails/revendeur_created.html.twig', [ 'firstName' => $firstName, 'lastName' => $lastName, @@ -180,7 +180,7 @@ class RevendeursController extends AbstractController Environment $twig, #[Autowire('%kernel.project_dir%')] string $projectDir, ): Response { - $logoPath = $projectDir.'/public/logo.jpg'; + $logoPath = $projectDir.'/public/logo_facture.png'; $logo = file_exists($logoPath) ? 'data:image/jpeg;base64,'.base64_encode(file_get_contents($logoPath)) : ''; $html = $twig->render('pdf/contrat_revendeur.html.twig', [ diff --git a/src/Controller/CspReportController.php b/src/Controller/CspReportController.php index 6d1f3d0..6a5b608 100644 --- a/src/Controller/CspReportController.php +++ b/src/Controller/CspReportController.php @@ -67,7 +67,7 @@ class CspReportController extends AbstractController private function sendAlert(MailerInterface $mailer, LoggerInterface $logger, array $report, string $documentUri, string $violatedDirective, string $blockedUri, string $sourceFile): void { $email = (new Email()) - ->from('security-notify@e-cosplay.fr') + ->from('security-notify@siteconseil.fr') ->to($this->getParameter('admin_email')) ->subject('Alerte Securite : Violation CSP detectee') ->priority(Email::PRIORITY_HIGH) diff --git a/src/Controller/EmailTrackingController.php b/src/Controller/EmailTrackingController.php index ad0b1cb..f348c56 100644 --- a/src/Controller/EmailTrackingController.php +++ b/src/Controller/EmailTrackingController.php @@ -13,7 +13,7 @@ use Symfony\Component\Routing\Attribute\Route; class EmailTrackingController extends AbstractController { - #[Route('/track/{messageId}/logo.jpg', name: 'app_email_track', methods: ['GET'])] + #[Route('/track/{messageId}/logo_facture.png', name: 'app_email_track', methods: ['GET'])] public function track( string $messageId, EmailTrackingRepository $repository, @@ -27,7 +27,7 @@ class EmailTrackingController extends AbstractController $em->flush(); } - $response = new BinaryFileResponse($projectDir.'/public/logo.jpg'); + $response = new BinaryFileResponse($projectDir.'/public/logo_facture.png'); $response->headers->set('Content-Type', 'image/jpeg'); $response->headers->set('Cache-Control', 'no-store'); diff --git a/src/Controller/ForgotPasswordController.php b/src/Controller/ForgotPasswordController.php index f237901..3202865 100644 --- a/src/Controller/ForgotPasswordController.php +++ b/src/Controller/ForgotPasswordController.php @@ -71,7 +71,7 @@ class ForgotPasswordController extends AbstractController if (null !== $user) { $mailer->sendEmail( $email, - 'CRM Ecosplay - Code de reinitialisation', + 'CRM SITECONSEIL - Code de reinitialisation', $twig->render('emails/forgot_password_code.html.twig', ['code' => $code]), null, null, @@ -106,7 +106,7 @@ class ForgotPasswordController extends AbstractController $mailer->sendEmail( $sessionEmail, - 'CRM Ecosplay - Mot de passe modifie', + 'CRM SITECONSEIL - Mot de passe modifie', $twig->render('emails/password_changed.html.twig'), null, null, diff --git a/src/Controller/LegalController.php b/src/Controller/LegalController.php index 02c4d1a..0ea3d80 100644 --- a/src/Controller/LegalController.php +++ b/src/Controller/LegalController.php @@ -122,7 +122,7 @@ class LegalController extends AbstractController $this->addFlash('success', 'Aucune donnee trouvee pour cette adresse IP. Un email de confirmation a ete envoye.'); } } catch (\Throwable) { - $this->addFlash('error', 'Une erreur est survenue lors du traitement de votre demande. Veuillez reessayer ou nous contacter a contact@e-cosplay.fr.'); + $this->addFlash('error', 'Une erreur est survenue lors du traitement de votre demande. Veuillez reessayer ou nous contacter a contact@siteconseil.fr.'); } return $this->redirect($this->generateUrl('app_legal_rgpd').self::RGPD_ANCHOR); @@ -149,7 +149,7 @@ class LegalController extends AbstractController $this->addFlash('success', 'Aucune donnee trouvee pour cette adresse IP.'); } } catch (\Throwable) { - $this->addFlash('error', 'Une erreur est survenue lors du traitement de votre demande. Veuillez reessayer ou nous contacter a contact@e-cosplay.fr.'); + $this->addFlash('error', 'Une erreur est survenue lors du traitement de votre demande. Veuillez reessayer ou nous contacter a contact@siteconseil.fr.'); } return $this->redirect($this->generateUrl('app_legal_rgpd').self::RGPD_ANCHOR); diff --git a/src/Controller/WebhookDocuSealController.php b/src/Controller/WebhookDocuSealController.php index bc5d0a5..464540e 100644 --- a/src/Controller/WebhookDocuSealController.php +++ b/src/Controller/WebhookDocuSealController.php @@ -181,7 +181,7 @@ class WebhookDocuSealController extends AbstractController $mailer->sendEmail( $attestation->getEmail(), - 'CRM Ecosplay - Attestation signee '.$typeName.' ('.$attestation->getReference().')', + 'CRM SITECONSEIL - Attestation signee '.$typeName.' ('.$attestation->getReference().')', $twig->render('emails/rgpd_attestation_signed.html.twig', [ 'attestation' => $attestation, 'typeName' => $typeName, diff --git a/src/Security/KeycloakAuthenticator.php b/src/Security/KeycloakAuthenticator.php index 561114b..d84e241 100644 --- a/src/Security/KeycloakAuthenticator.php +++ b/src/Security/KeycloakAuthenticator.php @@ -85,7 +85,7 @@ class KeycloakAuthenticator extends OAuth2Authenticator implements Authenticatio { $session = $request->getSession(); if ($session instanceof FlashBagAwareSessionInterface) { - $session->getFlashBag()->add('error', 'Echec de la connexion E-Cosplay. Veuillez reessayer.'); + $session->getFlashBag()->add('error', 'Echec de la connexion SITECONSEIL. Veuillez reessayer.'); } return new RedirectResponse($this->router->generate('app_home')); diff --git a/src/Security/TwoFactorCodeMailer.php b/src/Security/TwoFactorCodeMailer.php index a27abda..debad2c 100644 --- a/src/Security/TwoFactorCodeMailer.php +++ b/src/Security/TwoFactorCodeMailer.php @@ -25,9 +25,9 @@ class TwoFactorCodeMailer implements AuthCodeMailerInterface ]); $email = (new Email()) - ->from('CRM Ecosplay ') + ->from('CRM SITECONSEIL ') ->to($user->getEmailAuthRecipient()) - ->subject('CRM Ecosplay - Code de verification') + ->subject('CRM SITECONSEIL - Code de verification') ->html($html); $this->mailer->send($email); diff --git a/src/Service/DocuSealService.php b/src/Service/DocuSealService.php index 04b5a29..dacaf5a 100644 --- a/src/Service/DocuSealService.php +++ b/src/Service/DocuSealService.php @@ -44,8 +44,8 @@ class DocuSealService ], 'submitters' => [ [ - 'email' => 'contact@e-cosplay.fr', - 'name' => 'Association E-Cosplay', + 'email' => 'contact@siteconseil.fr', + 'name' => 'SARL SITECONSEIL', 'role' => 'First Party', 'completed' => true, 'send_email' => false, @@ -77,10 +77,10 @@ class DocuSealService private function getLogoBase64(): string { - $logoPath = $this->projectDir.'/public/logo.jpg'; + $logoPath = $this->projectDir.'/public/logo_facture.png'; if (!file_exists($logoPath)) { - return 'Association E-Cosplay'; + return 'SARL SITECONSEIL'; } return 'data:image/jpeg;base64,'.base64_encode(file_get_contents($logoPath)); diff --git a/src/Service/MailerService.php b/src/Service/MailerService.php index dbfa0a5..6901ad0 100644 --- a/src/Service/MailerService.php +++ b/src/Service/MailerService.php @@ -31,7 +31,7 @@ class MailerService public function getAdminFrom(): string { - return 'Association E-Cosplay <'.$this->adminEmail.'>'; + return 'SARL SITECONSEIL <'.$this->adminEmail.'>'; } public function send(Email $email): void @@ -45,10 +45,12 @@ class MailerService $certificate = $this->projectDir.'/config/cert/smime/certificate.pem'; $privateKey = $this->projectDir.'/config/cert/smime/private-key.pem'; + // @codeCoverageIgnoreStart if (file_exists($certificate) && file_exists($privateKey)) { $signer = new SMimeSigner($certificate, $privateKey, $this->smimePassphrase); $email = $signer->sign($email); } + // @codeCoverageIgnoreEnd $this->bus->dispatch(new SendEmailMessage($email)); } @@ -89,7 +91,7 @@ class MailerService } $messageId = bin2hex(random_bytes(16)); - $email->getHeaders()->addIdHeader('Message-ID', $messageId.'@e-cosplay.fr'); + $email->getHeaders()->addIdHeader('Message-ID', $messageId.'@siteconseil.fr'); $trackingUrl = $this->urlGenerator->generate('app_email_track', [ 'messageId' => $messageId, @@ -100,7 +102,7 @@ class MailerService ], UrlGeneratorInterface::ABSOLUTE_URL); $html = $email->getHtmlBody(); - $html = str_replace('https://crm.e-cosplay.fr/logo.jpg', $trackingUrl, $html); + $html = str_replace('https://crm.siteconseil.fr/logo_facture.png', $trackingUrl, $html); $html = str_replace('__VIEW_URL__', $viewUrl, $html); $email->html($html); @@ -131,7 +133,7 @@ class MailerService $email->getHeaders()->addTextHeader( 'List-Unsubscribe', - sprintf('<%s>, ', $unsubscribeUrl, urlencode($to)) + sprintf('<%s>, ', $unsubscribeUrl, urlencode($to)) ); $email->getHeaders()->addTextHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click'); } diff --git a/src/Service/RgpdService.php b/src/Service/RgpdService.php index 130903e..1c8dc7d 100644 --- a/src/Service/RgpdService.php +++ b/src/Service/RgpdService.php @@ -13,9 +13,6 @@ use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Twig\Environment; -/** - * @codeCoverageIgnore RGPD data access/deletion with PDF generation - */ class RgpdService { public function __construct( @@ -127,7 +124,9 @@ class RgpdService 'no_data' => $this->generateNoDataPdf($ip, $attestation), 'access' => $this->generateAccessPdf($data, $ip, $attestation), 'deletion' => $this->generateDeletionPdf($ip, $attestation), + // @codeCoverageIgnoreStart default => throw new \InvalidArgumentException('Invalid attestation type'), + // @codeCoverageIgnoreEnd }; $attestation->setPdfFileUnsigned($pdfPath); @@ -140,7 +139,7 @@ class RgpdService private function getLogoBase64(): string { - $logoPath = $this->projectDir.'/public/logo.jpg'; + $logoPath = $this->projectDir.'/public/logo_facture.png'; return file_exists($logoPath) ? 'data:image/jpeg;base64,'.base64_encode((string) file_get_contents($logoPath)) : ''; } diff --git a/templates/admin/_layout.html.twig b/templates/admin/_layout.html.twig index 8ffb199..47a4734 100644 --- a/templates/admin/_layout.html.twig +++ b/templates/admin/_layout.html.twig @@ -24,7 +24,7 @@