Compare commits

...

188 Commits

Author SHA1 Message Date
morgane bcecc2430d Actualiser Dockerfile
CI / PHP Syntax Check (push) Waiting to run
CI / JavaScript Lint (push) Waiting to run
CI / Docker Build Test (push) Waiting to run
CI / Validate Translation Files (push) Waiting to run
CI / Auto-merge develop → main (push) Blocked by required conditions
CI / Create GitHub Release (push) Blocked by required conditions
Security Scan (Trivy) / Trivy — Docker image scan (push) Waiting to run
Security Scan (Trivy) / Trivy — Filesystem scan (push) Waiting to run
2026-06-30 11:37:51 +00:00
morgane 33d5c4c370 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Waiting to run
CI / JavaScript Lint (push) Waiting to run
CI / Docker Build Test (push) Waiting to run
CI / Validate Translation Files (push) Waiting to run
CI / Auto-merge develop → main (push) Blocked by required conditions
CI / Create GitHub Release (push) Blocked by required conditions
2026-06-29 18:22:25 +00:00
morgane ddef591108 Actualiser .htaccess
CI / PHP Syntax Check (push) Waiting to run
CI / JavaScript Lint (push) Waiting to run
CI / Docker Build Test (push) Waiting to run
CI / Validate Translation Files (push) Waiting to run
CI / Auto-merge develop → main (push) Blocked by required conditions
CI / Create GitHub Release (push) Blocked by required conditions
2026-06-29 15:44:24 +00:00
morgane ca98acc1f2 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 17:49:17 +00:00
morgane 616818998d Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 17:43:03 +00:00
morgane ef73630cad Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 17:31:38 +00:00
morgane a6369765b0 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 17:16:56 +00:00
morgane 5a50403e52 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 17:05:42 +00:00
morgane 865cb561be Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 16:57:43 +00:00
morgane 18169417d3 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 16:49:56 +00:00
morgane 22dd77c879 Actualiser README.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 16:28:57 +00:00
morgane bcbdf669a1 Actualiser README.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 16:28:06 +00:00
morgane c513b0b4ef Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-27 16:25:46 +00:00
morgane 3bfa89e61d Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-25 20:21:34 +00:00
morgane 427bcd20a4 Actualiser docker-compose.yml
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-24 17:05:55 +00:00
morgane 9b026408e2 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-21 15:31:32 +00:00
morgane 5abf5f9adf Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-21 15:30:02 +00:00
morgane e58eb0501a Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-20 09:06:50 +00:00
morgane ecf7ec53fd Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-20 08:59:36 +00:00
morgane 78310f9fe9 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-20 08:50:31 +00:00
morgane b73748346e Actualiser manifest.json
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-20 08:08:12 +00:00
morgane 833afb3cfd Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 16:32:41 +00:00
morgane 726d371d26 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 16:30:31 +00:00
morgane a4267ee420 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 16:29:00 +00:00
morgane fef70cb97c Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 16:20:53 +00:00
morgane ca285f7a9d Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 16:19:56 +00:00
morgane 8176237b93 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-19 15:50:05 +00:00
morgane 5ce935de49 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 17:30:45 +00:00
morgane 751b18ba3c Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 17:20:16 +00:00
morgane 55d562e0a3 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 17:14:19 +00:00
morgane 7c3fb41b43 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 17:09:55 +00:00
morgane a84824327d Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:59:24 +00:00
morgane 409ea5d2e5 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:57:10 +00:00
morgane 0de44ae341 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 16:56:24 +00:00
morgane 5a4e16c30d Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:49:19 +00:00
morgane cfcc3ce49f Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:47:57 +00:00
morgane 3965c6ef44 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 16:47:10 +00:00
morgane 99b65900c4 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 16:46:19 +00:00
morgane 1505550a16 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:24:29 +00:00
morgane b23edc39b3 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 16:13:13 +00:00
morgane 371dda46f0 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 15:50:41 +00:00
morgane 3c68ce0dd1 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 15:47:45 +00:00
morgane 94f5649183 Actualiser translations/fr.json
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 14:07:40 +00:00
morgane cff250055c Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:33:59 +00:00
morgane 477978aed9 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:26:15 +00:00
morgane bf08556556 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:25:29 +00:00
morgane 594c9fa115 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:06:56 +00:00
morgane 8c471c1b7f Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 13:05:58 +00:00
morgane 9075740454 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 13:03:41 +00:00
morgane 3f242c1836 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 13:02:58 +00:00
morgane 9c97798a21 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 12:57:25 +00:00
morgane 0fb887756f Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 12:55:21 +00:00
morgane 37bf403412 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 12:54:20 +00:00
morgane 3676793194 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 12:53:49 +00:00
morgane 3f410022a7 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 12:53:14 +00:00
morgane 7631018929 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 12:52:51 +00:00
morgane bb16e441f5 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 11:40:33 +00:00
morgane bacb98b4eb Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 11:12:44 +00:00
morgane b739cb3a47 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 11:05:03 +00:00
morgane 754daa9989 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 09:07:17 +00:00
morgane 80a915ac35 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:58:56 +00:00
morgane b28c6591a9 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:58:15 +00:00
morgane 1e40da7235 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 08:56:27 +00:00
morgane 046355d6b0 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 08:55:35 +00:00
morgane 3a33dc7173 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:44:06 +00:00
morgane c0c1a312c6 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 08:43:08 +00:00
morgane 8ae455d82c Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 08:38:06 +00:00
morgane 0c8eee404e Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-18 08:36:21 +00:00
morgane e746c3d05b Actualiser README.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 06:49:37 +00:00
morgane 6f1966113d Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-18 06:31:37 +00:00
morgane f1e07f4151 Actualiser README.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 22:32:45 +00:00
morgane 7d4b881d7c Supprimer README.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 22:32:30 +00:00
morgane 63faf402c2 Ajouter READMI.md
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 22:32:17 +00:00
morgane 8543106fed Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 22:26:09 +00:00
morgane 4d1a4be0ea Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Commentaires de la ligne modifier la fiche produit (catégorie)
Ligne 20087
2026-06-17 22:17:16 +00:00
morgane 0065987050 Supprimer test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:46:16 +00:00
morgane ad101cc58f Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:41:10 +00:00
morgane 3a08929353 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:39:07 +00:00
morgane f935790ab2 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:38:04 +00:00
morgane 45ea60e305 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:36:45 +00:00
morgane d364588011 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:26:58 +00:00
morgane 9fc1dd3614 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:23:05 +00:00
morgane 68484b8323 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:22:21 +00:00
morgane e534ea2e96 Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:20:01 +00:00
morgane 08bb293963 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:16:52 +00:00
morgane ae3254c195 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 21:14:28 +00:00
morgane 77b053c573 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:13:07 +00:00
morgane ab79339e8c Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 21:10:27 +00:00
morgane 6cba7132d5 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:44:36 +00:00
morgane 32da374e57 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:42:07 +00:00
morgane 8fda93044d Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:34:28 +00:00
morgane a97907dbe1 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:28:29 +00:00
morgane 94eeba280a Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:24:11 +00:00
morgane 978088ae23 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:20:33 +00:00
morgane d4c5b5b97c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:15:50 +00:00
morgane 0ec2620926 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:13:28 +00:00
morgane f65f65d38f Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:06:17 +00:00
morgane f3c1fd2e7b Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 20:05:07 +00:00
morgane 69eb319aa1 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:59:26 +00:00
morgane 02bfc82e2b Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:51:49 +00:00
morgane b8e43388b6 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:46:28 +00:00
morgane 6e532ebdd1 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:45:11 +00:00
morgane 56a10bd1c4 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:40:02 +00:00
morgane 621fb4f96e Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:37:17 +00:00
morgane 57ec6af58c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:35:18 +00:00
morgane 11886578ab Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:33:41 +00:00
morgane a02abce26e Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:28:50 +00:00
morgane 79d1ca06c7 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:28:02 +00:00
morgane d1ba63d9a0 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:25:55 +00:00
morgane 0ca4df0d27 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:23:56 +00:00
morgane fc324d55f5 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:22:09 +00:00
morgane 99c35e4c18 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:19:33 +00:00
morgane b12cd76acc Supprimer reconcile.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:19:27 +00:00
morgane 477139d47c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:12:37 +00:00
morgane 8b44432244 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 19:08:18 +00:00
morgane 4f1717c4b1 Ajouter reconcile.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 18:22:35 +00:00
morgane c2002977cd Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 18:00:35 +00:00
morgane f7fb4e8f33 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:57:44 +00:00
morgane ef9c26bed6 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:52:05 +00:00
morgane aaf4de5e6b Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:50:58 +00:00
morgane 56bc6a709f Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:48:35 +00:00
morgane b60994d745 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:45:21 +00:00
morgane 6e86c19262 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:43:46 +00:00
morgane 619b7b4517 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:42:18 +00:00
morgane ca2e39bc49 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:40:49 +00:00
morgane 42fcbef95b Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:39:18 +00:00
morgane 0619d1487c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:38:21 +00:00
morgane 79fff10b48 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:36:59 +00:00
morgane a6f59cabfb Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:35:47 +00:00
morgane eaf9ebc52e Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:33:07 +00:00
morgane df8211c8ac Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:29:12 +00:00
morgane 7fae0e08bf Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:27:18 +00:00
morgane 450095376c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:25:31 +00:00
morgane 257fa4797d Supprimer test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:25:23 +00:00
morgane 9acf952c10 Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:23:12 +00:00
morgane e0deb3481b Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:21:02 +00:00
morgane d35f975ab9 Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:18:05 +00:00
morgane 0502a4d132 Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:16:28 +00:00
morgane 2ea69fd223 Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:15:02 +00:00
morgane 01f28a2b09 Actualiser test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:12:47 +00:00
morgane 4bedfdd0f4 Ajouter test2.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:11:20 +00:00
morgane 6c63bb17a3 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:08:03 +00:00
morgane 665d3097e7 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:06:50 +00:00
morgane 43047276a6 Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:05:24 +00:00
morgane 51ad25926a Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:03:26 +00:00
morgane 33e552373c Actualiser test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 17:00:36 +00:00
morgane fc124c87bf Ajouter test.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:57:34 +00:00
morgane b166a305f2 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:55:39 +00:00
morgane 6377c45eaa Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:53:51 +00:00
morgane 8d18362d83 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:52:13 +00:00
morgane cabb8b28d4 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:50:34 +00:00
morgane 27257caa3e Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:46:48 +00:00
morgane 3d744f256a Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:43:50 +00:00
morgane 8e504cad28 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:41:39 +00:00
morgane e6b3328fe9 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:38:46 +00:00
morgane db7fc0df18 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:33:23 +00:00
morgane 3bb6dc7155 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:32:14 +00:00
morgane d75a6e76c6 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:29:19 +00:00
morgane b28aca5e55 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:28:49 +00:00
morgane 2fb782f8e1 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 16:23:16 +00:00
morgane c08798d462 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 14:10:10 +00:00
morgane f6fe0a55bd Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 14:00:42 +00:00
morgane fecbbafd38 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:59:24 +00:00
morgane c0ad69cf11 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:52:58 +00:00
morgane a2a1a5ba77 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:51:54 +00:00
morgane 98553c7600 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:49:34 +00:00
morgane 7d89d61b95 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:37:39 +00:00
morgane 6b1d5f4c45 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:34:20 +00:00
morgane 288e0c05f6 Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 13:30:48 +00:00
morgane e52aa6d699 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:27:42 +00:00
morgane 9512e3a8df Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 13:14:46 +00:00
morgane 4a729d2d10 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 13:04:08 +00:00
morgane 6ecb881d9f Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 12:59:46 +00:00
morgane 662c27d7b4 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 12:55:31 +00:00
morgane df9624ad75 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 12:54:33 +00:00
morgane df0a47e336 Actualiser assets/js/app.js
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 12:40:27 +00:00
morgane b97845553e Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 12:25:06 +00:00
morgane 495d7a22eb Actualiser api/database.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 10:30:37 +00:00
morgane a1511c608a Actualiser api/index.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 08:42:34 +00:00
morgane a3a3b54a85 Actualiser api/lib/env.php
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 08:26:35 +00:00
morgane 4ee2e5638b Actualiser backup.sh
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-17 08:07:28 +00:00
morgane a9f0527769 Actualiser Dockerfile
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
Security Scan (Trivy) / Trivy — Docker image scan (push) Has been cancelled
Security Scan (Trivy) / Trivy — Filesystem scan (push) Has been cancelled
2026-06-17 07:57:39 +00:00
morgane bf27f7f462 Actualiser index.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
2026-06-16 21:42:38 +00:00
dadaloop82 85ccdaa6f6 Release v1.7.42: shopping totals, waste learning, stability fixes.
Document waste reason picker, stable price estimates, DB retry, and kiosk CI fixes in CHANGELOG and README.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 12:50:13 +00:00
dadaloop82 16993135b9 Merge branch 'main' of github-evershelf:dadaloop82/EverShelf 2026-06-14 12:43:44 +00:00
dadaloop82 d1716fa6ff Fix shopping estimates, waste reasons, and recurring DB/timeouts.
Price each list line as one retail purchase; learn from discard reasons to cap restock suggestions. Retry inventory_use/shopping_add on SQLITE_BUSY; extend smart_shopping time limit. Reopen feature issues #98/#125; close auto-report bugs #201–#204.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 12:43:03 +00:00
github-actions[bot] 3ac42f7767 chore(kiosk): publish APK v1.7.19 for LAN OTA 2026-06-11 05:48:36 +00:00
dadaloop82 eb19265586 Kiosk: auto-discover on setup, LAN OTA, English-only GitHub triage.
Auto-run LAN discovery on server step; serve kiosk updates from releases/ via kiosk_update API; check LAN before GitHub for OTA in-place upgrades. Docker CI retries hub timeouts. Remove non-English feature issue comments; triage script English-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 05:46:12 +00:00
27 changed files with 3643 additions and 875 deletions
+15 -1
View File
@@ -77,7 +77,21 @@ jobs:
sleep 3
gh release create kiosk-latest \
--title "EverShelf Kiosk Latest" \
--notes "Alias automatico → kiosk-${{ steps.version.outputs.name }} (versionCode ${{ steps.version.outputs.code }})" \
--notes "Auto alias → kiosk-${{ steps.version.outputs.name }} (versionCode ${{ steps.version.outputs.code }})" \
--prerelease \
artifacts/evershelf-kiosk.apk
- name: Publish APK to releases/ for LAN OTA
env:
GH_TOKEN: ${{ secrets.WORKFLOW_PAT || secrets.GITHUB_TOKEN }}
run: |
cp artifacts/evershelf-kiosk.apk releases/evershelf-kiosk.apk
printf '{"version":"%s","version_code":%s}\n' \
"${{ steps.version.outputs.name }}" "${{ steps.version.outputs.code }}" \
> releases/kiosk-version.json
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add releases/evershelf-kiosk.apk releases/kiosk-version.json
git diff --staged --quiet || git commit -m "chore(kiosk): publish APK v${{ steps.version.outputs.name }} for LAN OTA"
git push origin HEAD:${{ github.ref_name }}
+12 -1
View File
@@ -43,7 +43,18 @@ jobs:
- uses: actions/checkout@v6
- name: Build Docker image
run: docker build -t evershelf-test .
run: |
set -e
for attempt in 1 2 3; do
echo "Docker build attempt $attempt/3..."
if docker build -t evershelf-test .; then
exit 0
fi
echo "Attempt $attempt failed — retrying in 20s..."
sleep 20
done
echo "Docker build failed after 3 attempts"
exit 1
- name: Test container starts
run: |
+3 -3
View File
@@ -15,9 +15,9 @@ RewriteEngine On
</FilesMatch>
# Force HTTPS (skip when terminated TLS is forwarded — Traefik, Caddy, NPM, …)
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#RewriteCond %{HTTPS} !=on
#RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ [NC]
#RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# API routing
RewriteCond %{REQUEST_FILENAME} !-f
+14
View File
@@ -11,6 +11,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Recipe scraps tips** — During cooking steps, detect "waste" generated (peels, cores, bones, eggshells, coffee grounds, citrus zest, etc.) and surface AI-powered tips on how to reuse them (compost, natural cleaner, broth, candied peel, etc.). Could be shown as an optional collapsible hint card below the step that generates the scrap.
## [1.7.42] - 2026-06-11
### Added
- **Waste reason picker** — Discarding a product prompts for why (expired, spoiled, wrong storage, kept too long, bought too much, forgotten, bad quality, other) in IT/EN/DE/FR/ES.
- **Waste learning** — Reasons are stored per product in `app_settings.waste_learning`; caps smart-shopping suggested quantities, surfaces preferred storage location, and tightens expiry alerts after repeated spoilage.
- **`scripts/github-issue-triage.php`** — Reopens wrongly closed feature backlog items; closes resolved auto-report bugs with English comments.
### Fixed
- **Inflated shopping total** — Price each Bring!/shopping line as **one retail purchase**; convert AI €/kg prices to estimated piece weight (200 g default) instead of multiplying by piece count; cap smart-shopping conf/pz suggestions used for pricing context.
- **SQLite database locked (#201#202)** — `inventory_use` and `shopping_add` (including Bring mode) wrapped in `dbWithRetry()`.
- **Smart shopping timeout (#203#204)** — `set_time_limit(120)` on `smartShopping()` / `smartShoppingCached()` for large inventories.
- **Android kiosk CI** — Escaped apostrophes in locale `strings.xml` (de/es/fr/it); fixed Kotlin JSON string escaping in `SetupActivity.finishSetup()`.
- **GitHub triage** — `triage-open-issues.php` no longer bulk-closes enhancement/feature backlog; reopened #98 (pin products) and #125 (cooking voice commands) where not yet implemented.
## [1.7.41] - 2026-06-08
### Fixed
+4 -1
View File
@@ -6,10 +6,12 @@ RUN apt-get update && apt-get upgrade -y && apt-get install -y \
libcurl4-openssl-dev \
libonig-dev \
libgd-dev \
libzip-dev \
libicu-dev \
tesseract-ocr \
tesseract-ocr-ita \
tesseract-ocr-eng \
&& docker-php-ext-install pdo_sqlite curl mbstring gd \
&& docker-php-ext-install pdo_sqlite curl mbstring gd zip intl \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Enable Apache mod_rewrite and mod_headers
@@ -28,6 +30,7 @@ RUN mkdir -p /var/www/html/data/backups \
# Create .env from example if it doesn't exist (will be overridden by volume mount)
RUN [ ! -f /var/www/html/.env ] && cp /var/www/html/.env.example /var/www/html/.env || true
RUN chown www-data:www-data /var/www/html/.env && chmod 664 /var/www/html/.env
# Apache configuration: serve from app root
RUN echo '<Directory /var/www/html>\n\
+157 -485
View File
@@ -1,551 +1,223 @@
# 🏠 EverShelf
# 🏠 EverShelf for Ricardo
> **Self-hosted pantry management system** — Track your food inventory, scan barcodes, get AI-powered recipe suggestions, and reduce waste.
---
<div align="center">
### 🚀 Try the live demo — no installation required!
**[▶ Open Live Demo](https://evershelfproject.dadaloop.it/demo)**
&nbsp;·&nbsp;
[🌐 Project Website](https://evershelfproject.dadaloop.it/)
&nbsp;·&nbsp;
[📖 Wiki](https://github.com/dadaloop82/EverShelf/wiki)
*The demo runs with mock pantry data. AI features are fully enabled. All write operations are safely sandboxed.*
</div>
> Fork personnalisé d'EverShelf, adapté pour servir de backend stock/recettes à **Ricardo**, l'application bartender. Garde toutes les fonctionnalités d'EverShelf, avec des ajustements pour la gestion de bar (catégorie boissons, sous-catégories alcools, intégration directe avec Ricardo).
---
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![PHP](https://img.shields.io/badge/PHP-8.0+-blue.svg)](https://www.php.net/)
[![SQLite](https://img.shields.io/badge/SQLite-3-blue.svg)](https://www.sqlite.org/)
[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED.svg)](Dockerfile)
[![i18n](https://img.shields.io/badge/i18n-IT%20%7C%20EN%20%7C%20DE%20%7C%20FR%20%7C%20ES-orange.svg)](translations/)
[![Version](https://img.shields.io/badge/version-1.7.41-brightgreen.svg)](CHANGELOG.md)
[![GitHub stars](https://img.shields.io/github/stars/dadaloop82/EverShelf?style=social)](https://github.com/dadaloop82/EverShelf/stargazers)
[![Last commit](https://img.shields.io/github/last-commit/dadaloop82/EverShelf/main)](https://github.com/dadaloop82/EverShelf/commits/main)
[![Contributors](https://img.shields.io/github/contributors/dadaloop82/EverShelf)](https://github.com/dadaloop82/EverShelf/graphs/contributors)
[![GitHub Discussions](https://img.shields.io/github/discussions/dadaloop82/EverShelf)](https://github.com/dadaloop82/EverShelf/discussions)
[![CI](https://github.com/dadaloop82/EverShelf/actions/workflows/ci.yml/badge.svg)](https://github.com/dadaloop82/EverShelf/actions/workflows/ci.yml)
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/J3J01ZNETZ)
[![Docker](https://img.shields.io/badge/Docker-Compatible-2496ED.svg)](Dockerfile)
---
> **⚠️ Name disambiguation:** There is an unrelated iOS app also called **EverShelf**, developed and published by [Joshumi Technologies LLC](https://evershelf.joshumi.com/) on the [Apple App Store](https://apps.apple.com/app/evershelf/id6759439940). That application is a **completely separate, independent product** with no affiliation, association, or collaboration with this open-source project. This repository has no connection to Joshumi Technologies LLC, its products, or its services.
## ✨ Fonctionnalités principales
### 📦 Gestion des stocks
- Inventaire alimentaire complet
- Gestion des emplacements :
- 🏠 Placard
- ❄️ Réfrigérateur
- 🧊 Congélateur
- 📍 Emplacements personnalisés, entièrement gérés depuis une page **🔧 Configuration** dédiée (ajout, modification, suppression sans toucher au code)
- Sous-catégorie dédiée aux boissons (vin, bière, spiritueux, soda, jus, eau...) pour filtrer et trier l'inventaire plus précisément
- Scan de codes-barres avec la caméra du téléphone
- Ajout rapide de produits
- Suivi des dates de péremption
- Gestion des produits ouverts
- Support des produits sous vide
- Détection des incohérences de stock
---
## ✨ Features
## 🤖 Intelligence artificielle (Google Gemini)
### 🏠 NEW — Home Assistant Integration
EverShelf peut utiliser l'IA pour :
EverShelf has a **native Home Assistant integration** available on HACS.
Connect your pantry to your smart home in minutes — no YAML, no manual sensor setup.
- 📸 Identifier un produit depuis une photo
- 📅 Lire automatiquement une date limite de consommation
- 🧊 Proposer un stockage adapté
- 🍳 Générer des recettes selon votre inventaire
- 💬 Répondre aux questions sur vos produits
- 🛒 Améliorer les suggestions de courses
[![Install via HACS](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=dadaloop82&repository=ha-evershelf&category=integration)
&nbsp;
[![Add Integration](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=evershelf)
**What you get:**
| | |
|---|---|
| **16 sensors** | Expiry counts, stock levels by location (pantry / fridge / freezer), shopping list total, AI API usage, last backup timestamp, days to next expiry |
| **6 binary sensors** | Expired items, expiring items, expiring today, shopping list active, backup overdue, Bring! connected |
| **5 action buttons** | Refresh data, Refresh prices, **Suggest Recipe** (AI — result as HA notification), Sync smart shopping, Clear expired rows |
| **Shopping list todo** | Bidirectional sync — add, remove, check off items directly from HA |
| **Expiry calendar** | Every product's expiry date as a native HA calendar event — works with the calendar card and any calendar automation |
| **Quick-add text entity** | Type a product name in HA to instantly add it to the shopping list (great for voice assistants / Assist) |
| **6 services** | `add_to_shopping`, `mark_used`, `refresh`, `suggest_recipe`, `refresh_prices`, `clear_expired` |
| **Auto-discovery** | Detected automatically via Zeroconf/mDNS when `avahi-daemon` runs on the EverShelf host |
| **5 languages** | English, Italian, German, French, Spanish |
> **Requires a self-hosted EverShelf instance.** The integration talks directly to your server — no cloud involved.
> Full documentation: [ha-evershelf on GitHub](https://github.com/dadaloop82/ha-evershelf)
> L'IA est optionnelle. EverShelf fonctionne sans clé Gemini.
---
### 📦 Inventory Management
- **Export inventory** — Download the full inventory as a UTF-8 CSV (Excel-compatible) or open a print-ready page to save as PDF; export button always visible in the inventory page header
- **Barcode scanning** — Scan products with your phone camera using QuaggaJS; last 20 scanned products saved as tappable chips so you can re-select them without rescanning
- **AI identification** — Take a photo and let Google Gemini identify the product, with suggestions from your existing inventory; gracefully shows a friendly message when AI quota is exhausted instead of a raw API error
- **Smart locations** — Track items across Pantry, Fridge, Freezer, and custom locations
- **Expiry tracking** — Automatic shelf-life estimation based on product type and storage
- **Opened product tracking** — Reduced shelf-life calculation when packages are opened; opened-product expiry is now also checked when building banner alerts (not just the dashboard section)
- **Vacuum-sealed support** — Extended expiry dates for vacuum-sealed items; products sealed under vacuum are only flagged as expired after a configurable grace period past the printed date (`VACUUM_EXPIRY_EXTENSION_DAYS`, default 30 days, configurable in `.env`)
- **Anomaly detection** — Banner alerts for suspicious quantities and consumption predictions with inline correction; dismiss button now shows the current inventory quantity so the action is unambiguous ("Quantity is correct (2 pcs)")
## 🛒 Liste de courses intelligente
### 🤖 AI-Powered (Google Gemini)
- **Expiry date reading** — Photograph a label and extract the expiry date automatically
- **Product identification** — Point your camera at any product for instant recognition
- **Existing product matching** — AI scan shows matching products already in your pantry before suggesting new ones
- **Storage & shelf-life hint** — When adding a new product, Gemini suggests the optimal storage location and shelf-life in the background; shown as an inline AI badge next to the expiry estimate
- **Recipe generation** — Get personalized recipes based on what's in your pantry; streams live via Server-Sent Events so results appear as they are generated
- **Recipe stock hints** — Each pantry ingredient shows how much you have and what remains after use; when the leftover would be less than 5% of the full sealed package (10% for an already-opened partial pack), the recipe automatically uses everything on hand to avoid waste
- **Smart chat assistant** — Ask questions about your inventory, get cooking tips
- **Shopping suggestions with tips** — AI-powered purchase recommendations, each enriched with a short practical buying/storing tip
- **Anomaly explanation** — "Explain" button on anomaly banners explains in plain language why a discrepancy likely occurred and what to do
- **Model fallback** — All AI endpoints try `gemini-2.5-flash` first and fall back to `gemini-2.0-flash` automatically
- **Graceful no-key state** — When no Gemini key is configured, AI entry points show a friendly message; the header button is visually greyed with an amber dot
### 🛒 Shopping List
- **Bring! integration** — Sync with the [Bring!](https://www.getbring.com/) shopping list app
- **Generic shopping names** — Products are grouped by type (e.g. "Milk", "Cold cuts", "Cooking cream") rather than brand, keeping the Bring! list clean and consolidated
- **Smart predictions** — Know what you'll need before you run out
- **Auto-add on depletion** — When a product reaches zero the app adds it to Bring! automatically, no confirmation needed
- **Auto-remove on scan** — Products are removed from the shopping list when scanned in - **Auto-migration** — Items already on the Bring! list are silently renamed to their generic name in the background (throttled, runs on list load)
- **Catalog coverage** — All product types resolve to a German Bring! catalog key for icon and category display in the Bring! app
### 🍳 Cooking Mode
- **♻️ Zero-waste tips** — For each cooking step that generates reusable scraps (peels, cooking water, egg whites, cheese rinds, bread crusts, vegetable tops, etc.), a dismissible ♻️ tip card appears with a practical reuse idea; tips are generated by Gemini as part of the recipe at no extra API cost; opt-in toggle in Settings (default OFF)
- **Step-by-step guidance** — Follow recipes with a hands-free cooking interface
- **Text-to-Speech** — Voice readout of recipe steps; supports browser Web Speech API, native Android TTS (kiosk), or a custom REST endpoint (Home Assistant, etc.); retries voice loading for up to 10 seconds with a fallback refresh button; TTS activates automatically without requiring the global TTS setting to be enabled
- **Auto-read on navigate** — Each step is read aloud automatically when you tap Next or Previous; the first step is read when entering cooking mode
- **Timer voice alerts** — 10-second countdown warning spoken aloud before each timer expires; expiry announced vocally when time is up
- **Recipe completion** — "Bon appétit!" announced via TTS when the last step is confirmed
- **Built-in timer** — Automatic timer suggestions based on recipe instructions
- **Ingredient tracking** — Mark ingredients as used during cooking; leftover quantities prompt a "move to another location" flow
### 📊 Dashboard
- **Waste tracking** — Monitor consumed vs. wasted products over 30 days
- **Anti-waste report** — Personalised waste rate vs. national average with annual kg estimate; shown above the expiring-items list
- **Expiry alerts** — Visual warnings for expired and soon-to-expire items
- **Opened products panel** — Tracks partially-used items; expiry is recalculated from the opening date using AI (Gemini) + per-category rule fallback; whole sealed packages always keep their original manufacturer expiry; conf items with mixed whole + fractional units are shown as two separate entries
- **Freezer shelf-life** — Granular per-product estimates (USDA/EFSA): fish 120 d, poultry 270 d, whole red-meat cuts 365 d, mince 120 d, vegetables/fruit 270 d, generic 180 d; AI + cache still take priority over rules
- **Safety ratings** — Smart assessment of expired product safety (by category and location); expired unsafe items shown with a red danger banner and a discard action as the primary action
- **Expired product banner** — Products that have passed their effective shelf-life (including opened-product reduced expiry) appear in the top notification banner; icon, colour and title adapt to the actual safety level (✅ green for safe, 👀 amber to check, 🚫 red for danger); high-risk items get a prominent discard action
- **Quick recipe bar** — One-tap recipe suggestion using expiring products
- **Anomaly banner** — Scrollable banner with suspicious quantities and consumption prediction mismatches, with one-tap correction or inline edit
- **Expired/expiring alerts** — Priority-sorted banner notifications for expired and soon-to-expire products with use, throw, edit, and dismiss actions
- **Swipe navigation** — Touch swipe or tap arrows/dots to browse banner notifications
- **Quick-access buttons** — Recently used and most popular products shown on the inventory page for fast access
### 🌙 Appearance
- **Dark mode** — Three modes: Light, Dark, and Auto (time-based: dark from 20:00 to 07:00, light otherwise); applies immediately without page reload; auto mode re-evaluates every 5 minutes, so night/day transitions happen automatically even on always-on kiosk displays; theme is applied before the first render to prevent a white flash
- **Global settings tab** — A dedicated **⚙️ General** tab groups all system-wide settings (language, currency, theme, screensaver, zero-waste tips, export) at the top of the Settings panel
### Database Maintenance
- **Automatic cleanup** — Recipes older than `RECIPE_RETENTION_DAYS` (default 7) and transactions older than `TRANSACTION_RETENTION_DAYS` (default 7) are deleted automatically on every cron cycle; SQLite `VACUUM` runs after each cleanup to keep the file compact
- **Manual cleanup** — Trigger immediately via `GET /api/?action=db_cleanup`
- **Compact by default** — Fresh installs stay small; large accumulated databases shrink back to a few hundred KB within one cron cycle
### 📱 Progressive Web App
- **Mobile-first design** — Optimized for phones, works on tablets and desktop
- **Installable** — Add to home screen for a native app experience
- **Multi-device** — All user data (shopping tags, pinned items, location preferences, scan history) is stored server-side in SQLite and shared across every device on the same instance; no data is siloed in a single browser's localStorage
### 📶 Offline Mode
- **Automatic detection** — Full-screen overlay appears immediately on network loss; shows a "Continue offline" button after 3 s, and auto-enters offline mode after 8 s
- **Local inventory cache** — Inventory is synced to `localStorage` at every startup and on each successful API call; the offline view always reflects the last known state
- **Write queue** — Add, use, update and delete operations performed while offline are queued locally and synced to the server automatically on reconnect (including after a page refresh)
- **Optimistic UI** — Queued writes are applied immediately to the local cache so the interface stays responsive
- **Offline-computed stats** — Expiring and expired items are derived client-side from the cache; dashboard stat cards show real counts instead of zeros
- **AI/network sections hidden** — Anti-waste chart, nutrition analysis, recipe generator, price fetching, and Gemini chat are hidden in offline mode; the inventory, history, and manually-managed shopping list remain fully functional
- **Broken image fallback** — External product images (Open Food Facts, etc.) that fail to load are replaced with a neutral grey placeholder, keeping the layout intact
- **Startup recovery** — If the page is refreshed while operations are queued, they are detected and synced automatically on the next successful startup
- **Buffered error reporting** — `remoteLog` and `reportError` calls made while offline are stored locally and flushed to the server (and to GitHub issues) when the connection is restored
### ⚖️ Smart Scale Integration (Add-on)
- **Bluetooth gateway** — Connects a BLE smart scale to EverShelf via local WebSocket
- **SSE relay** — Server-side relay avoids mixed-content (HTTPS→WS) issues
- **Auto-discovery** — Server scans LAN to find the gateway automatically
- **Auto weight reading** — When adding/using a product with unit g/ml, weight fills automatically
- **10g threshold** — Ignores readings that haven't changed enough between products - **Duplicate-reading prevention** — Server-side 12-second dedup window rejects a second scale-triggered deduction of the same product, guarding against BLE multi-fire- **ml conversion hint** — Shows "weight in grams → will be converted to ml" when product unit is ml
- **Stability + auto-confirm** — 10s stable wait + 5s countdown before confirming
- **Real-time status** — Scale connection indicator always visible in the header
- **Multi-protocol** — Supports Bluetooth SIG Weight Scale, Body Composition, Xiaomi Mi Scale 2 and 100+ models
- **Built into kiosk (v1.6.0+)** — BLE gateway runs as an integrated foreground service inside the [EverShelf Kiosk](evershelf-kiosk/) app; no separate APK needed.
### 📺 Android Kiosk Mode (Add-on)
- **Dedicated tablet app** — Full-screen WebView wrapper for wall-mounted kitchen tablets
- **True kiosk lock** — Screen pinning blocks home/recent buttons
- **Setup wizard** — 6-step guided configuration (language, welcome, permissions, server URL, BLE scale scan, screensaver, summary)
- **Smart auto-discovery** — Scans the LAN in parallel (60 threads, TCP pre-check, ports 80/443/8080/8443) with real-time UI feedback; correctly identifies the device's Wi-Fi/Ethernet subnet (VPN and cellular interfaces are filtered out)
- **Built-in BLE scale gateway** — `GatewayService` foreground service; BLE scanning + WebSocket server `:8765` run directly inside the kiosk app. Select your scale in step 5 of the wizard — no external app required
- **Scale auto-configuration** — After selecting the BLE device, the wizard writes `scale_enabled` and `scale_gateway_url=ws://127.0.0.1:8765` to the server automatically
- **Camera & mic permissions** — Full hardware access for barcode scanning and voice; grant button transforms to a green confirmation after granting
- **Native TTS bridge** — Cooking mode voice readout uses the Android TextToSpeech engine directly, bypassing Web Speech API voice limitations; no offline voice packs required
- **Hard refresh** — ↻ button clears WebView cache to pick up web app updates
- **Update notifications** — Checks GitHub releases every 6h, shows banner when updates available
- **SSL support** — Accepts self-signed certificates
- **Android kiosk app** — [`evershelf-kiosk/`](evershelf-kiosk/) — downloadable APK
- Création automatique depuis les ruptures de stock
- Prévisions de besoins
- Synchronisation avec Bring!
- Nettoyage automatique des doublons
- Suggestions d'achat personnalisées
---
## 🚀 Quick Start
## 🍳 Mode cuisine
### Prerequisites
- **Web server** with PHP 8.0+ (Apache or Nginx)
- **PHP extensions**: `pdo_sqlite`, `curl`, `mbstring`, `json`
- **HTTPS** recommended (required for camera access on mobile)
- Recettes étape par étape
- Mode mains libres
- Synthèse vocale (TTS)
- Minuteurs automatiques
- Suivi des ingrédients utilisés
- Conseils anti-gaspillage
### Installation
---
#### Option A: Docker (recommended)
## ♻️ Réduction du gaspillage
- Suivi des aliments consommés ou jetés
- Analyse des pertes
- Alertes de péremption
- Suggestions pour utiliser les produits bientôt périmés
---
## 🏡 Intégrations
### Home Assistant
Intégration native disponible :
- Capteurs de stock
- Dates de péremption
- Liste de courses
- Calendrier des produits
- Actions personnalisées
- Suggestions de recettes IA
Compatible avec une installation 100% locale.
---
## 📱 Application mobile / PWA
- Interface adaptée smartphone
- Installation comme une application
- Synchronisation multi-appareils
- Mode hors-ligne :
- consultation du stock
- actions mises en attente
- synchronisation automatique au retour réseau
---
## 📺 Mode tablette (Kiosque Android)
- Affichage plein écran
- Verrouillage kiosque
- Scan caméra
- Support TTS natif Android
- Découverte automatique du serveur
- Support des balances Bluetooth
---
## 🚀 Installation rapide
### Prérequis
- PHP 8.0+
- SQLite 3
- Extensions PHP :
- `pdo_sqlite`
- `curl`
- `mbstring`
- `json`
Docker est recommandé.
---
### 🐳 Installation Docker (CLI)
```bash
# 1. Clone the repository
git clone https://github.com/dadaloop82/EverShelf.git
git clone https://git.mashome.fr/morgane/EverShelf.git
cd EverShelf
# 2. Create configuration file
cp .env.example .env
nano .env
# 3. Start with Docker Compose
docker compose up -d
# → Open http://localhost:8080
```
#### Option B: Manual
Puis ouvrez :
http://localhost:8080
```bash
# 1. Clone the repository
git clone https://github.com/dadaloop82/EverShelf.git
cd EverShelf
---
### 🐳 Déploiement via Portainer
# 2. Create configuration file
cp .env.example .env
1. Dans Portainer, va dans **Stacks****Add stack**
2. Donne un nom à la stack (ex : `evershelf`)
3. Colle le contenu de ton `docker-compose.yml` dans l'éditeur web (ou utilise l'option **Repository** en pointant vers `https://git.mashome.fr/morgane/EverShelf.git` et le chemin du fichier compose)
4. Renseigne tes variables d'environnement dans la section **Environment variables** (ou via un fichier `.env` à la racine du repo)
5. Clique sur **Deploy the stack**
# 3. Set permissions
chmod 755 data/
chmod 664 data/.gitkeep
chown -R www-data:www-data data/
Pour mettre à jour après une modification de code :
- Va dans **Stacks** → ta stack → **Update the stack**
- Coche bien **« Re-pull image »** / **« Re-build image »** avant de valider — sinon Portainer redémarre le conteneur avec l'image déjà construite en cache, sans prendre en compte tes changements.
# 4. Edit your configuration
nano .env
```
---
### Configuration (.env)
## ⚙️ Configuration
```ini
# Required for AI features (get a key at https://aistudio.google.com/app/apikey)
GEMINI_API_KEY=your_api_key_here
Exemple de fichier `.env` :
# Optional: Bring! shopping list integration
BRING_EMAIL=your_email@example.com
BRING_PASSWORD=your_password
```env
# IA Google Gemini (optionnel)
GEMINI_API_KEY=votre_cle
# Optional: Text-to-Speech for cooking mode
TTS_URL=http://your-home-assistant:8123/api/events/tts_speak
TTS_TOKEN=your_long_lived_token
TTS_ENABLED=true
# Bring! (optionnel)
BRING_EMAIL=email@example.com
BRING_PASSWORD=motdepasse
# Optional: DB retention and cleanup (applied automatically each cron cycle)
RECIPE_RETENTION_DAYS=7 # delete recipe plans older than N days
TRANSACTION_RETENTION_DAYS=90 # delete stock transactions older than N days (min 30 enforced)
# Optional: Vacuum-sealed expiry grace period
VACUUM_EXPIRY_EXTENSION_DAYS=30 # extra days before vacuum-sealed items are flagged expired
# Optional: Gemini cost rates (USD per million tokens, for the Info tab cost estimate)
GEMINI_COST_25F_IN=0.15
GEMINI_COST_25F_OUT=0.60
GEMINI_COST_20F_IN=0.10
GEMINI_COST_20F_OUT=0.40
# Optional: Security — protect all API endpoints
# Set a strong random string; clients send it as X-API-Token header (or ?api_token= for HA)
# Sécurité API
API_TOKEN=
# Optional: Legacy alias for API_TOKEN (settings save only)
SETTINGS_TOKEN=
# Optional: Demo mode — block all write operations at the router level
DEMO_MODE=false
# Optional: Logging
# LOG_LEVEL sets the minimum severity written to disk (DEBUG / INFO / WARN / ERROR)
# DEBUG also logs every SQL query executed against the database
LOG_LEVEL=INFO
LOG_ROTATE_HOURS=24 # hours before opening a new log file (default: 24)
LOG_MAX_FILES=14 # maximum number of rotated files to keep (default: 14)
# Nettoyage automatique
RECIPE_RETENTION_DAYS=7
TRANSACTION_RETENTION_DAYS=90
```
### Web Server Configuration
<details>
<summary><strong>Apache (.htaccess)</strong></summary>
The app works out of the box with Apache if placed in the web root or a subdirectory. Make sure `mod_rewrite` is enabled and `AllowOverride All` is set.
```apache
<Directory /var/www/html/evershelf>
AllowOverride All
Require all granted
</Directory>
```
</details>
<details>
<summary><strong>Nginx</strong></summary>
```nginx
server {
listen 80;
server_name your-server.local;
root /var/www/html/evershelf;
index index.html;
location /api/ {
try_files $uri $uri/ =404;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
# Deny access to sensitive files
location ~ /\.env { deny all; }
location ~ /data/ { deny all; }
location ~ /backup\.sh { deny all; }
}
```
</details>
### HTTPS Setup (Recommended)
Camera access requires HTTPS on most mobile browsers. Options:
- **Let's Encrypt** with Certbot (for public-facing servers)
- **Self-signed certificate** (for local network only)
- **Reverse proxy** (e.g., Caddy, Traefik) with automatic TLS
### Cron Job (Optional)
Set up a cron job for smart shopping predictions:
```bash
# Run every 5 minutes
*/5 * * * * php /path/to/evershelf/api/cron_smart_shopping.php >> /path/to/evershelf/data/cron.log 2>&1
```
### Backup (Optional)
The included `backup.sh` creates local daily backups of your database:
```bash
# Run daily at 3 AM
0 3 * * * /path/to/evershelf/backup.sh
```
### Google Drive Backup (Optional)
EverShelf supports automatic daily backups to Google Drive via OAuth 2.0. This works on any server, including private IP / local network setups (no public domain required).
**Setup:**
1. Go to [console.cloud.google.com](https://console.cloud.google.com) and select or create a project.
2. Enable the **Google Drive API** (`APIs & Services → Enable APIs → Google Drive API`).
3. Go to `APIs & Services → Credentials → Create Credentials → OAuth client ID`.
4. Application type: **Web application**.
5. Add **`http://localhost`** as an Authorized Redirect URI (this is the key — it works even without a real domain).
6. Copy **Client ID** and **Client Secret** into EverShelf Settings → Backup.
7. Enter your **Google Drive Folder ID** (the last part of the folder URL).
8. Click **Authorize with Google** and sign in.
9. The browser will redirect to `http://localhost` and may show a connection error — **this is expected**. Copy the full URL from the address bar (e.g. `http://localhost/?code=4%2F0A...`) and paste it into the field that appears in EverShelf, then click **Submit**.
> **Note:** While the OAuth app is in *Testing* status in Google Cloud Console, you must add your Google account as a test user under `APIs & Services → OAuth consent screen → Test users`.
---
## 🏗️ Architecture
## 🔒 Vie privée
```
evershelf/
├── index.html # Single-page application (SPA)
├── manifest.json # PWA manifest
├── .env.example # Configuration template
├── backup.sh # Local database backup script
├── LICENSE # MIT License
├── api/
│ ├── index.php # Main API router (all endpoints)
│ ├── database.php # SQLite schema, migrations, helpers
│ └── cron_smart_shopping.php # Background job for predictions
├── assets/
│ ├── css/style.css # All application styles
│ ├── js/app.js # All application logic
│ └── img/ # Static images
└── data/ # Runtime data (gitignored)
├── evershelf.db # SQLite database (auto-created)
├── backups/ # Local DB backups
└── *.json # Token/cache files
EverShelf est conçu pour fonctionner en auto-hébergement :
evershelf-scale-gateway/ # ⚖️ Android BLE gateway [DEPRECATED — integrated into kiosk v1.6.0+]
├── README.md # Deprecation notice + legacy docs
└── app/src/ # Kotlin Android source (WebSocket + BLE)
evershelf-kiosk/ # 📺 Android kiosk app (add-on)
├── README.md # Setup & feature docs
└── app/src/ # Kotlin Android source (WebView wrapper)
```
### API Endpoints
| Category | Action | Method | Description |
|----------|--------|--------|-------------|
| **Products** | `search_barcode` | GET | Find product by barcode |
| | `lookup_barcode` | GET | Look up barcode on Open Food Facts |
| | `product_save` | POST | Create or update a product |
| | `products_list` | GET | List all products |
| **Inventory** | `inventory_list` | GET | List inventory items |
| | `inventory_add` | POST | Add product to inventory |
| | `inventory_use` | POST | Use/consume from inventory |
| | `inventory_summary` | GET | Count by location |
| **AI** | `gemini_identify` | POST | Identify product from photo |
| | `gemini_expiry` | POST | Read expiry date from photo |
| | `gemini_chat` | POST | Chat with AI assistant |
| | `generate_recipe` | POST | Generate recipe from inventory |
| | `gemini_product_hint` | POST | Storage location + shelf-life hint |
| | `gemini_shopping_enrich` | POST | Enrich shopping suggestions with tips |
| | `gemini_anomaly_explain` | POST | Plain-language anomaly explanation |
| **Shopping** | `bring_list` | GET | Get Bring! shopping list |
| | `bring_add` | POST | Add items to Bring! |
| | `smart_shopping` | GET | Smart shopping predictions |
| **Settings** | `get_settings` | GET | Get server configuration |
| | `save_settings` | POST | Update server configuration |
- Pas de compte obligatoire
- Pas de cloud imposé
- Données stockées localement
- SQLite comme base de données
- Les fonctions IA utilisent uniquement les services configurés par l'utilisateur
---
## 🔒 Security Notes
## 🛠️ Développement
- **Credentials** are stored in `.env` (server-side, never committed to Git)
- **Database** stays local — never pushed to remote repositories
- **Apache/Nginx hardening** — `.env`, `data/`, and `logs/` are blocked from direct HTTP access
- **API token** — set `API_TOKEN` in `.env` to require `X-API-Token` on all API calls (Home Assistant: `?api_token=`)
- **API keys are never exposed to the browser** — `get_settings` returns only boolean flags (`gemini_key_set`, `ha_token_set`, …)
- **GitHub Issues token** — stored encrypted as `GH_ISSUE_TOKEN_ENC` + `GH_ISSUE_TOKEN_KEY` (see `scripts/encrypt-gh-token.php`)
- **Settings write protection** — `save_settings` requires the same API token when configured; validated with `hash_equals`
- **Demo / public mode** — set `DEMO_MODE=true` to block all write operations at the PHP router level before any business logic runs
- The API uses **parameterized SQL queries** (PDO prepared statements) against injection
- **Input validation** on all inventory operations (quantity bounds, location whitelist)
- Consider adding **reverse-proxy authentication** (e.g. Authelia, Nginx `auth_basic`) if the server is accessible from the internet
Technologies principales :
- PHP
- SQLite
- JavaScript
- HTML/CSS
- Docker
---
## 🛠️ Development
## 📜 Licence
```bash
# Run PHP's built-in server for local development
php -S localhost:8080 -t /path/to/evershelf
# Check PHP syntax
php -l api/index.php
php -l api/database.php
```
The application uses no build tools — edit files directly and refresh.
Projet sous licence MIT.
---
## 📋 Roadmap
## 🙏 Crédits
Feature requests, bug reports and planned work are tracked in the [**EverShelf Roadmap**](https://github.com/users/dadaloop82/projects/2) GitHub Project.
Ce fork, **EverShelf for Ricardo**, est maintenu par Morgane pour servir de système de gestion de stock/recettes à l'application **Ricardo**.
---
Projet original :
## 🌐 Translations
https://github.com/dadaloop82/EverShelf
The app supports multiple languages via JSON translation files in the `translations/` folder.
| Language | Status |
|----------|--------|
| 🇮🇹 Italian (it) | ✅ Complete (base) |
| 🇬🇧 English (en) | ✅ Complete |
| 🇩🇪 German (de) | ✅ Complete |
| 🇫🇷 French (fr) | ✅ Complete |
| 🇪🇸 Spanish (es) | ✅ Complete |
**Want to add your language?** See the [Translation Guide](CONTRIBUTING.md#-adding-translations) — just copy `translations/it.json`, translate the values, and submit a PR!
---
## 🤝 Contributing
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Commit your changes (`git commit -m 'Add my feature'`)
4. Push to the branch (`git push origin feature/my-feature`)
5. Open a Pull Request
### Easiest way to start — translate EverShelf into your language
Translations are just JSON files. No coding, no setup — fork → edit → PR.
```
translations/
├── it.json ✅ Italian (base)
├── en.json ✅ English
├── de.json ✅ German
├── fr.json ✅ French
├── es.json ✅ Spanish
├── pt.json ❌ Portuguese — wanted!
├── nl.json ❌ Dutch — wanted!
└── ... ❌ Your language here!
```
👉 See [issue #93](https://github.com/dadaloop82/EverShelf/issues/93) to claim a language.
### Other ways to contribute
| What | Skill needed |
|---|---|
| 🐛 Report a bug | None |
| 📖 Improve the wiki | Markdown |
| 🌍 Add a translation | JSON editing |
| 🎨 Fix a CSS/UI issue | CSS / HTML |
| ⚙️ Implement a feature | PHP / JS |
| ⭐ Star the repo | Clicking |
👉 Browse [`help wanted`](https://github.com/dadaloop82/EverShelf/labels/help%20wanted) issues for good starting points.
Read [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide (branch naming, code style, how to run locally).
---
## 💬 Community
Join the conversation in [GitHub Discussions](https://github.com/dadaloop82/EverShelf/discussions):
- **Vote on upcoming features** — tell us what to build next
- **Show your setup** — share your kitchen kiosk
- **Ask questions** — get help from the community
---
## 📄 License
This project is licensed under the **MIT License** — see the [LICENSE](LICENSE) file for details.
---
## 👨‍💻 Author
**Stimpfl Daniel** — [evershelfproject@gmail.com](mailto:evershelfproject@gmail.com)
- Website: [evershelfproject.dadaloop.it](https://evershelfproject.dadaloop.it/)
- GitHub: [@dadaloop82](https://github.com/dadaloop82)
---
## 📸 Screenshots
<div align="center">
![EverShelf demo — barcode scan, inventory management and AI recipe generation](assets/img/demo.gif)
</div>
For a live walkthrough with real data and full AI enabled, visit the **[live demo](https://evershelfproject.dadaloop.it/demo)** — no installation required.
> Want to contribute additional screenshots? See [CONTRIBUTING.md](CONTRIBUTING.md) — PRs welcome!
Ce dépôt contient des améliorations et adaptations personnelles, incluant un système d'export/import avec fusion intelligente des données.
+231
View File
@@ -186,6 +186,10 @@ function migrateDB(PDO $db): void {
try { $db->exec("ALTER TABLE products ADD COLUMN shopping_name TEXT DEFAULT ''"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
if (!in_array('subcategory', $colNames)) {
try { $db->exec("ALTER TABLE products ADD COLUMN subcategory TEXT DEFAULT NULL"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
// Empty barcode strings break UNIQUE (only one '' allowed); normalize to NULL.
$db->exec("UPDATE products SET barcode = NULL WHERE barcode IS NOT NULL AND TRIM(barcode) = ''");
@@ -319,6 +323,227 @@ function migrateDB(PDO $db): void {
$db->exec("CREATE INDEX IF NOT EXISTS idx_transactions_type_date ON transactions(type, created_at)");
$db->exec("CREATE INDEX IF NOT EXISTS idx_transactions_pid_type_undone ON transactions(product_id, type, undone)");
// Custom locations table (v1.9.0) — dynamic inventory locations managed from Settings
$locTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='locations'")->fetchAll();
if (empty($locTables)) {
$db->exec("
CREATE TABLE locations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
label TEXT NOT NULL,
icon TEXT DEFAULT '📦',
sort_order INTEGER DEFAULT 0,
is_builtin INTEGER DEFAULT 0
);
");
$db->exec("INSERT INTO locations (key, label, icon, sort_order, is_builtin) VALUES
('dispensa', 'Dispensa', '🗄️', 1, 1),
('frigo', 'Frigo', '🧊', 2, 1),
('freezer', 'Freezer', '❄️', 3, 1),
('altro', 'Altro', '📦', 4, 1)
");
}
// Custom subcategories table (v2.0) — sous-catégories par catégorie, gérables depuis Config
$subcatTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='subcategories'")->fetchAll();
if (empty($subcatTables)) {
$db->exec("
CREATE TABLE subcategories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category TEXT NOT NULL,
key TEXT NOT NULL,
label TEXT NOT NULL,
sort_order INTEGER DEFAULT 0,
UNIQUE(category, key)
);
");
$db->exec("INSERT INTO subcategories (category, key, label, sort_order) VALUES
('latticini', 'lait', '🥛 Lait', 1),
('latticini', 'yaourt', '🥣 Yaourt', 2),
('latticini', 'fromage', '🧀 Fromage', 3),
('latticini', 'beurre', '🧈 Beurre', 4),
('latticini', 'creme', '🍦 Crème', 5),
('latticini', 'oeufs', '🥚 Œufs', 6),
('latticini', 'autre', '📦 Autre', 7),
('carne', 'poulet', '🍗 Poulet', 1),
('carne', 'boeuf', '🐄 Bœuf', 2),
('carne', 'porc', '🐖 Porc', 3),
('carne', 'agneau', '🐑 Agneau', 4),
('carne', 'charcuterie', '🥓 Charcuterie', 5),
('carne', 'autre', '📦 Autre', 6),
('pesce', 'poisson_frais', '🐟 Poisson frais', 1),
('pesce', 'poisson_surgele', '🧊 Poisson surgelé', 2),
('pesce', 'fruits_mer', '🦐 Fruits de mer', 3),
('pesce', 'conserve_poisson', '🥫 Conserve', 4),
('pesce', 'autre', '📦 Autre', 5),
('frutta', 'agrumes', '🍊 Agrumes', 1),
('frutta', 'baies', '🫐 Baies', 2),
('frutta', 'fruits_noyau', '🍑 Fruits à noyau', 3),
('frutta', 'fruits_tropicaux', '🍍 Fruits tropicaux', 4),
('frutta', 'autre', '📦 Autre', 5),
('verdura', 'legumes_feuilles', '🥬 Légumes feuilles', 1),
('verdura', 'legumes_racines', '🥕 Légumes racines', 2),
('verdura', 'legumineuses_fraiches', '🌱 Légumineuses fraîches', 3),
('verdura', 'autre', '📦 Autre', 4),
('pasta', 'pates', '🍝 Pâtes', 1),
('pasta', 'riz', '🍚 Riz', 2),
('pasta', 'semoule', '🌾 Semoule', 3),
('pasta', 'autre', '📦 Autre', 4),
('pane', 'pain_frais', '🍞 Pain frais', 1),
('pane', 'biscottes', '🥖 Biscottes', 2),
('pane', 'viennoiserie', '🥐 Viennoiserie', 3),
('pane', 'autre', '📦 Autre', 4),
('surgelati', 'plats_prepares', '🍱 Plats préparés', 1),
('surgelati', 'legumes_surgeles', '🧊 Légumes surgelés', 2),
('surgelati', 'glaces', '🍨 Glaces', 3),
('surgelati', 'viande_poisson_surgele', '🧊 Viande/poisson surgelé', 4),
('surgelati', 'autre', '📦 Autre', 5),
('bevande', 'vin', '🍷 Vin', 1),
('bevande', 'biere', '🍺 Bière', 2),
('bevande', 'spiritueux', '🥃 Spiritueux', 3),
('bevande', 'soda', '🥤 Soda', 4),
('bevande', 'jus', '🧃 Jus', 5),
('bevande', 'eau', '💧 Eau', 6),
('bevande', 'autre', '📦 Autre', 7),
('condimenti', 'huile', '🫒 Huile', 1),
('condimenti', 'vinaigre', '🍶 Vinaigre', 2),
('condimenti', 'sauce', '🥫 Sauce', 3),
('condimenti', 'epice', '🌿 Épice', 4),
('condimenti', 'autre', '📦 Autre', 5),
('snack', 'chocolat', '🍫 Chocolat', 1),
('snack', 'biscuit', '🍪 Biscuit', 2),
('snack', 'chips', '🥔 Chips', 3),
('snack', 'bonbon', '🍬 Bonbon', 4),
('snack', 'autre', '📦 Autre', 5),
('conserve', 'legumes_conserve', '🥫 Légumes', 1),
('conserve', 'fruits_conserve', '🥫 Fruits', 2),
('conserve', 'poisson_conserve', '🥫 Poisson', 3),
('conserve', 'confiture', '🍯 Confiture', 4),
('conserve', 'autre', '📦 Autre', 5),
('cereali', 'cereales_petitdej', '🥣 Céréales petit-déj', 1),
('cereali', 'legumineuses_seches', '🫘 Légumineuses sèches', 2),
('cereali', 'farine', '🌾 Farine', 3),
('cereali', 'autre', '📦 Autre', 4)
");
}
// Custom categories table (v2.1) — catégories produit, gérables depuis Config
$catTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='categories'")->fetchAll();
if (empty($catTables)) {
$db->exec("
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
label TEXT NOT NULL,
icon TEXT DEFAULT '📦',
keywords TEXT DEFAULT '',
sort_order INTEGER DEFAULT 0,
is_builtin INTEGER DEFAULT 0
);
");
$db->exec("INSERT INTO categories (key, label, icon, sort_order, is_builtin) VALUES
('latticini', 'Latticini', '🥛', 1, 1),
('carne', 'Carne', '🥩', 2, 1),
('pesce', 'Pesce', '🐟', 3, 1),
('frutta', 'Frutta', '🍎', 4, 1),
('verdura', 'Verdura', '🥬', 5, 1),
('pasta', 'Pasta', '🍝', 6, 1),
('pane', 'Pane', '🍞', 7, 1),
('surgelati', 'Surgelati', '🧊', 8, 1),
('bevande', 'Bevande', '🥤', 9, 1),
('condimenti', 'Condimenti', '🧂', 10, 1),
('snack', 'Snack', '🍪', 11, 1),
('conserve', 'Conserve', '🥫', 12, 1),
('cereali', 'Cereali', '🌾', 13, 1),
('igiene', 'Igiene', '🧴', 14, 1),
('pulizia', 'Pulizia', '🧹', 15, 1),
('altro', 'Altro', '📦', 16, 1)
");
}
// Recipe library (v2.2) — recettes ajoutées manuellement (cocktails, boissons...), distinctes du planning repas
$recipeLibTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='recipe_library'")->fetchAll();
if (empty($recipeLibTables)) {
$db->exec("
CREATE TABLE recipe_library (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
recipe_json TEXT NOT NULL,
is_favorite INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
");
}
// Recipe tags (v2.3) — tags pour trier/filtrer "Mes recettes", gérables depuis Config
$recipeTagsTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='recipe_tags'")->fetchAll();
if (empty($recipeTagsTables)) {
$db->exec("
CREATE TABLE recipe_tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
label TEXT NOT NULL,
icon TEXT DEFAULT '🏷️',
sort_order INTEGER DEFAULT 0
);
");
$db->exec("INSERT INTO recipe_tags (key, label, icon, sort_order) VALUES
('cocktail', 'Cocktail', '🍹', 1),
('sans_alcool', 'Sans alcool', '🚫', 2),
('shot', 'Shot', '🥃', 3),
('long_drink', 'Long drink', '🍺', 4),
('aperitif', 'Apéritif', '🍾', 5),
('digestif', 'Digestif', '❄️', 6),
('rhum', 'Rhum', '🥃', 7),
('vodka', 'Vodka', '🍸', 8),
('gin', 'Gin', '🌿', 9),
('whisky', 'Whisky', '🥃', 10),
('tequila', 'Tequila', '🌵', 11),
('vin', 'Vin', '🍷', 12),
('champagne', 'Champagne / Mousseux', '🍾', 13),
('acidule', 'Acidulé', '🍋', 14),
('sucre', 'Sucré', '🍬', 15),
('amer', 'Amer', '☕', 16),
('epice', 'Épicé', '🌶️', 17),
('fruite', 'Fruité', '🍊', 18),
('herbace', 'Herbacé', '🌿', 19),
('ete', 'Été', '☀️', 20),
('hiver', 'Hiver', '❄️', 21),
('soiree', 'Soirée', '🎉', 22),
('brunch', 'Brunch', '🥂', 23)
");
}
// Migration: add keywords column to recipe_tags if missing
$rtCols = array_column($db->query("PRAGMA table_info(recipe_tags)")->fetchAll(), 'name');
if (!in_array('keywords', $rtCols)) {
try { $db->exec("ALTER TABLE recipe_tags ADD COLUMN keywords TEXT DEFAULT ''"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
// Custom quantity units (v2.4) — unités personnalisées (ex: kg, L) avec facteur de conversion vers pz/g/ml, gérables depuis Config
$customUnitsTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='custom_units'")->fetchAll();
if (empty($customUnitsTables)) {
$db->exec("
CREATE TABLE custom_units (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT UNIQUE NOT NULL,
label TEXT NOT NULL,
icon TEXT DEFAULT '📏',
base_unit TEXT NOT NULL DEFAULT 'g',
factor REAL NOT NULL DEFAULT 1,
sort_order INTEGER DEFAULT 0
);
");
}
// Add display_unit_key column to products if missing — unité personnalisée a afficher pour ce produit
$prodColsUnits = array_column($db->query("PRAGMA table_info(products)")->fetchAll(), 'name');
if (!in_array('display_unit_key', $prodColsUnits)) {
try { $db->exec("ALTER TABLE products ADD COLUMN display_unit_key TEXT DEFAULT NULL"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
// Internal shopping list table (v1.8.0) — used when SHOPPING_MODE=internal
// Internal shopping list table (v1.8.0) — used when SHOPPING_MODE=internal
$shopTables = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='shopping_list'")->fetchAll();
if (empty($shopTables)) {
@@ -348,6 +573,12 @@ function migrateDB(PDO $db): void {
try { $db->exec("ALTER TABLE products ADD COLUMN nutriments_json TEXT DEFAULT NULL"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
// Add tags column to products if missing (bugfix: insert referenced a column never created)
if (!in_array('tags', $prodCols2)) {
try { $db->exec("ALTER TABLE products ADD COLUMN tags TEXT DEFAULT NULL"); }
catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column') === false) throw $e; }
}
}
/**
+1152 -36
View File
File diff suppressed because it is too large Load Diff
+9 -4
View File
@@ -2,7 +2,6 @@
/**
* EverShelf — environment variable loader (.env).
*/
function loadEnv(): array {
static $cache = null;
if ($cache !== null) {
@@ -22,12 +21,18 @@ function loadEnv(): array {
}
return $cache;
}
function env(string $key, string $default = ''): string {
$vars = loadEnv();
return $vars[$key] ?? $default;
if (isset($vars[$key]) && $vars[$key] !== '') {
return $vars[$key];
}
// Fallback to system/Docker environment variables (e.g. set via Portainer)
$sysVal = getenv($key);
if ($sysVal !== false && $sysVal !== '') {
return $sysVal;
}
return $default;
}
/** Push a single key into the in-memory env cache (after .env write). */
function envCacheSet(string $key, string $value): void {
loadEnv();
+1528 -159
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -3,7 +3,7 @@
# Retention follows BACKUP_RETENTION_DAYS from .env (default 3)
set -euo pipefail
INSTALL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKUP_DIR="${INSTALL_DIR}/data/backups"
ENV_FILE="${INSTALL_DIR}/.env"
+9 -2
View File
@@ -5,14 +5,21 @@ services:
ports:
- "8080:80"
volumes:
# Persist database and runtime data
- evershelf_data:/var/www/html/data
# Mount your local .env configuration
- ./.env:/var/www/html/.env:ro
restart: unless-stopped
environment:
- TZ=Europe/Rome
networks:
- backend
- frontend
volumes:
evershelf_data:
driver: local
networks:
frontend:
external: true
backend:
external: true
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId = "it.dadaloop.evershelf.kiosk"
minSdk = 24
targetSdk = 35
versionCode = 19
versionName = "1.7.18"
versionCode = 20
versionName = "1.7.19"
}
signingConfigs {
@@ -643,6 +643,79 @@ class KioskActivity : AppCompatActivity() {
webView.evaluateJavascript("$jsCallback($escaped)", null)
}
}
val currentKiosk = try {
packageManager.getPackageInfo(packageName, 0).versionName ?: ""
} catch (_: Exception) { "" }
val installedVc: Long = try {
val pi = packageManager.getPackageInfo(packageName, 0)
if (Build.VERSION.SDK_INT >= 28) pi.longVersionCode
else @Suppress("DEPRECATION") pi.versionCode.toLong()
} catch (_: Exception) { -1L }
fun semverNewer(remote: String, local: String): Boolean {
val r = remote.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 }
val l = local.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 }
for (i in 0 until maxOf(r.size, l.size)) {
val rv = r.getOrElse(i) { 0 }
val lv = l.getOrElse(i) { 0 }
if (rv != lv) return rv > lv
}
return false
}
fun needsUpdate(remoteVersion: String, remoteVc: Long): Boolean = when {
remoteVc > 0 && installedVc >= 0 -> remoteVc > installedVc
currentKiosk.isNotEmpty() && remoteVersion.matches(Regex("\\d+\\.\\d+.*")) ->
semverNewer(remoteVersion, currentKiosk)
else -> false
}
fun applyUpdate(remoteVersion: String, apkUrl: String) {
val result = JSONObject()
.put("has_update", true)
.put("current", currentKiosk)
.put("latest", remoteVersion)
.put("apk_url", apkUrl)
notifyJs(result)
prefs.edit()
.putString(KEY_PENDING_UPDATE_VERSION, remoteVersion)
.putString(KEY_PENDING_UPDATE_URL, apkUrl)
.apply()
runOnUiThread { showNativeUpdateBanner("🔄 Kiosk $currentKiosk$remoteVersion", apkUrl) }
}
// 1) Prefer LAN/self-hosted update (no GitHub required)
val baseUrl = (prefs.getString(KEY_URL, "") ?: "").trim().trimEnd('/')
if (baseUrl.isNotEmpty()) {
try {
val localApi = "$baseUrl/api/index.php?action=kiosk_update"
val conn = openTrustedConnection(localApi)
conn.connectTimeout = 5000
conn.readTimeout = 5000
if (conn.responseCode == 200) {
val localJson = JSONObject(conn.inputStream.bufferedReader().readText())
conn.disconnect()
if (localJson.optBoolean("success")) {
val remoteVersion = localJson.optString("version", "")
val remoteVc = localJson.optLong("version_code", -1L)
val apkUrl = localJson.optString("apk_url", "")
if (apkUrl.isNotEmpty() && needsUpdate(remoteVersion, remoteVc)) {
applyUpdate(remoteVersion, apkUrl)
return@Thread
}
if (!needsUpdate(remoteVersion, remoteVc)) {
notifyJs(JSONObject().put("has_update", false).put("source", "local"))
prefs.edit().remove(KEY_PENDING_UPDATE_VERSION).remove(KEY_PENDING_UPDATE_URL).apply()
return@Thread
}
}
} else conn.disconnect()
} catch (_: Exception) { /* fall through to GitHub */ }
}
// 2) GitHub release fallback (requires internet)
try {
val conn = URL(GITHUB_RELEASES_API).openConnection() as java.net.HttpURLConnection
conn.setRequestProperty("Accept", "application/vnd.github+json")
@@ -657,51 +730,16 @@ class KioskActivity : AppCompatActivity() {
val body = conn.inputStream.bufferedReader().readText()
conn.disconnect()
val json = JSONObject(body)
val latestTag = json.optString("tag_name", "")
if (latestTag.isEmpty()) {
notifyJs(JSONObject().put("has_update", false).put("error", "no tag"))
return@Thread
}
val currentKiosk = try {
packageManager.getPackageInfo(packageName, 0).versionName ?: ""
} catch (_: Exception) { "" }
val installedVc: Long = try {
val pi = packageManager.getPackageInfo(packageName, 0)
if (Build.VERSION.SDK_INT >= 28) pi.longVersionCode
else @Suppress("DEPRECATION") pi.versionCode.toLong()
} catch (_: Exception) { -1L }
// The kiosk-latest release uses a non-semver tag ("kiosk-latest").
// Extract the actual kiosk version from the release body text.
// Body format: "Alias automatico → kiosk-X.Y.Z (versionCode N)".
val bodyText = json.optString("body", "")
val norm = { v: String -> v.replace(Regex("^[^0-9]*"), "") }
val remoteKioskVersion = Regex("""kiosk-v?(\d+\.\d+(?:\.\d+)?)""")
.find(bodyText)?.groupValues?.get(1)
?.takeIf { it.isNotEmpty() }
?: norm(latestTag)
?: norm(json.optString("tag_name", ""))
val remoteVc = Regex("""versionCode[=:\s(]+(\d+)""", RegexOption.IGNORE_CASE)
.find(bodyText)?.groupValues?.get(1)?.toLongOrNull() ?: -1L
// Compare semver: returns true if `remote` is strictly greater than `local`
fun semverNewer(remote: String, local: String): Boolean {
val r = remote.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 }
val l = local.split(".").map { it.filter(Char::isDigit).toIntOrNull() ?: 0 }
val len = maxOf(r.size, l.size)
for (i in 0 until len) {
val rv = r.getOrElse(i) { 0 }
val lv = l.getOrElse(i) { 0 }
if (rv != lv) return rv > lv
}
return false
}
val isSemver = remoteKioskVersion.matches(Regex("\\d+\\.\\d+.*"))
// Get APK URL from assets; fall back to the hardcoded KIOSK_DOWNLOAD_URL
val assets = json.optJSONArray("assets")
var kioskApkUrl = ""
if (assets != null) {
@@ -715,39 +753,35 @@ class KioskActivity : AppCompatActivity() {
}
if (kioskApkUrl.isEmpty()) kioskApkUrl = KIOSK_DOWNLOAD_URL
val kioskNeedsUpdate = when {
remoteVc > 0 && installedVc >= 0 -> remoteVc > installedVc
currentKiosk.isNotEmpty() && isSemver -> semverNewer(remoteKioskVersion, currentKiosk)
else -> false
}
val result = JSONObject()
.put("has_update", kioskNeedsUpdate)
.put("current", currentKiosk)
.put("latest", remoteKioskVersion)
.put("apk_url", kioskApkUrl)
notifyJs(result)
if (!kioskNeedsUpdate) {
// Clear any stale pending update if the current version is now up to date
if (!needsUpdate(remoteKioskVersion, remoteVc)) {
notifyJs(JSONObject().put("has_update", false))
prefs.edit().remove(KEY_PENDING_UPDATE_VERSION).remove(KEY_PENDING_UPDATE_URL).apply()
return@Thread
}
// Persist the pending update so the banner reappears after a crash/restart
prefs.edit()
.putString(KEY_PENDING_UPDATE_VERSION, remoteKioskVersion)
.putString(KEY_PENDING_UPDATE_URL, kioskApkUrl)
.apply()
runOnUiThread { showNativeUpdateBanner("🔄 Kiosk $currentKiosk$remoteKioskVersion", kioskApkUrl) }
applyUpdate(remoteKioskVersion, kioskApkUrl)
} catch (e: Exception) {
notifyJs(JSONObject().put("has_update", false).put("error", e.message ?: "network error"))
}
}.start()
}
/** HTTPS with self-signed cert support (LAN servers). */
private fun openTrustedConnection(urlStr: String): java.net.HttpURLConnection {
val conn = URL(urlStr).openConnection()
if (conn is javax.net.ssl.HttpsURLConnection) {
val trustAll = arrayOf<javax.net.ssl.TrustManager>(object : javax.net.ssl.X509TrustManager {
override fun checkClientTrusted(c: Array<java.security.cert.X509Certificate>?, t: String?) {}
override fun checkServerTrusted(c: Array<java.security.cert.X509Certificate>?, t: String?) {}
override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> = arrayOf()
})
val sc = javax.net.ssl.SSLContext.getInstance("TLS")
sc.init(null, trustAll, java.security.SecureRandom())
conn.sslSocketFactory = sc.socketFactory
conn.hostnameVerifier = javax.net.ssl.HostnameVerifier { _, _ -> true }
}
return conn as java.net.HttpURLConnection
}
/**
* On resume: if a previous session detected an available update and saved it to prefs,
* restore the update banner immediately without a network round-trip.
@@ -540,6 +540,11 @@ class SetupActivity : AppCompatActivity() {
// Cancel auto-discover when leaving server step
if (step != 3) discoverCancelled.set(true)
// Auto-discover when entering server step (empty URL only)
if (step == 3 && urlEdit.text.toString().trim().isEmpty()) {
autoDiscover()
}
// Scroll to top
try { findViewById<ScrollView>(R.id.setupScrollView).scrollTo(0, 0) } catch (_: Exception) {}
}
+152 -50
View File
@@ -94,7 +94,7 @@
<div id="preloader-warnings" class="preloader-warnings" style="display:none"></div>
<div id="preloader-error-msg" class="preloader-error-msg" style="display:none"></div>
<button id="preloader-retry-btn" class="preloader-retry-btn" style="display:none" onclick="_startupRetry()">🔄 <span data-i18n="startup.retry">Riprova</span></button>
<span class="app-preloader-version" id="preloader-version">v1.7.41</span>
<span class="app-preloader-version" id="preloader-version">v1.7.42</span>
</div>
</div>
@@ -107,7 +107,7 @@
<!-- Title — left-aligned; grows to fill space -->
<div class="header-title-wrap">
<h1 class="header-title" onclick="showPage('dashboard')">
<img src="assets/img/logo/logo_icon.png" alt="" class="header-logo-icon" aria-hidden="true" /><span data-i18n="nav.title">EverShelf</span><span class="header-version">v1.7.41</span>
<img src="assets/img/logo/logo_icon.png" alt="" class="header-logo-icon" aria-hidden="true" /><span data-i18n="nav.title">EverShelf</span><span class="header-version">v1.7.42</span>
</h1>
<!-- Update badge — shown alongside title, never replaces it -->
<span class="header-update-badge" id="header-update-badge" style="display:none"></span>
@@ -126,6 +126,7 @@
<button class="header-btn header-gemini-btn" onclick="showPage('chat')" title="Chat con Gemini" data-i18n-title="chat.title">
<svg class="gemini-icon" viewBox="0 0 24 24" width="24" height="24" fill="white"><path d="M12 0C12 6.627 6.627 12 0 12c6.627 0 12 5.373 12 12 0-6.627 5.373-12 12-12-6.627 0-12-5.373-12-12z"/></svg>
</button>
<button class="header-btn" onclick="startManualEntry()" title="Ajouter manuellement">✏️</button>
<button class="header-btn header-scan-btn" id="btn-header-scan"
title="Scansiona prodotto (tieni premuto per modalità spesa)" data-i18n-title="scan.hint">
📷
@@ -147,21 +148,6 @@
<!-- ===== DASHBOARD ===== -->
<section class="page active" id="page-dashboard">
<div class="dashboard-stats" id="dashboard-stats">
<div class="stat-card" onclick="showPage('inventory', 'dispensa')">
<span class="stat-icon">🗄️</span>
<span class="stat-value" id="stat-dispensa">-</span>
<span class="stat-label" data-i18n="locations.dispensa">Dispensa</span>
</div>
<div class="stat-card" onclick="showPage('inventory', 'frigo')">
<span class="stat-icon">🧊</span>
<span class="stat-value" id="stat-frigo">-</span>
<span class="stat-label" data-i18n="locations.frigo">Frigo</span>
</div>
<div class="stat-card" onclick="showPage('inventory', 'freezer')">
<span class="stat-icon">❄️</span>
<span class="stat-value" id="stat-freezer">-</span>
<span class="stat-label" data-i18n="locations.freezer">Freezer</span>
</div>
<div class="stat-card" onclick="showPage('shopping')">
<span class="stat-icon">🛒</span>
<span class="stat-value" id="stat-spesa">-</span>
@@ -404,7 +390,7 @@
<form class="form" onsubmit="submitAdd(event)">
<div class="form-group">
<label data-i18n="add.location_label">📍 Dove lo metti?</label>
<div class="location-selector">
<div class="location-selector" id="location-selector-add">
<button type="button" class="loc-btn active" onclick="selectLocation(this, 'dispensa')">🗄️ <span data-i18n="locations.dispensa">Dispensa</span></button>
<button type="button" class="loc-btn" onclick="selectLocation(this, 'frigo')">🧊 <span data-i18n="locations.frigo">Frigo</span></button>
<button type="button" class="loc-btn" onclick="selectLocation(this, 'freezer')">❄️ <span data-i18n="locations.freezer">Freezer</span></button>
@@ -452,8 +438,7 @@
<p class="form-hint" id="add-vacuum-hint" style="display:none" data-i18n="add.vacuum_hint">La scadenza verrà estesa automaticamente</p>
</div>
<div class="form-group" id="add-expiry-section">
<!-- Populated dynamically by showAddForm() -->
</div>
</div>
<button type="submit" class="btn btn-large btn-success full-width" data-i18n="add.submit">✅ Aggiungi</button>
</form>
</section>
@@ -660,6 +645,12 @@
<option value="altro">📦 Altro</option>
</select>
</div>
<div class="form-group" id="pf-subcategory-group" style="display:none">
<label>📂 Sous-catégorie <span class="subcategory-required-mark" style="display:none;color:#e74c3c">*</span></label>
<select id="pf-subcategory" class="form-input">
<option value="">-- Aucune --</option>
</select>
</div>
<div class="form-row">
<div class="form-group flex-1">
<label data-i18n="product.unit_label">📏 Unità di misura</label>
@@ -728,6 +719,15 @@
✨ Genera nuova ricetta
</button>
<div id="recipe-archive" class="recipe-archive"></div>
<div class="settings-section" style="margin-top:24px">
<h3 class="settings-section-title">📖 Mes recettes</h3>
<p class="settings-hint">Tes propres recettes (cocktails, boissons...), ajoutées à la main.</p>
<button class="btn btn-large btn-accent full-width" style="margin-top:10px" onclick="openRecipeLibraryForm()"> Ajouter une recette</button>
<button class="btn btn-large btn-secondary full-width" style="margin-top:8px" onclick="openRecipeLibraryImportForm()">📋 Importer texte brut</button>
<div id="recipe-library-tag-filter" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:14px"></div>
<div id="recipe-library-list" style="margin-top:14px"></div>
</div>
</div>
</section>
@@ -1590,6 +1590,17 @@
</div>
<button class="btn btn-large btn-accent full-width" onclick="_backupNow()" id="btn-backup-now" data-i18n="settings.backup.backup_now">💾 Backup Ora</button>
<div id="backup-status" style="display:none;margin-top:8px" class="settings-status"></div>
<div style="margin-top:14px;padding-top:14px;border-top:1px solid var(--border,#e2e8f0)">
<h4 style="margin-bottom:6px">📦 Export / Import complet</h4>
<p class="settings-hint">Exporte la DB + config en un .zip, ou importe un export pour fusionner sans doublons.</p>
<a href="api/index.php?action=export_full" class="btn btn-large btn-accent full-width" style="text-decoration:none;display:block;text-align:center;margin-top:8px">📤 Exporter tout</a>
<div style="margin-top:8px">
<input type="file" id="import-merge-file" accept=".zip" style="display:none" onchange="_importMergeFile(this)">
<button class="btn btn-large btn-secondary full-width" onclick="document.getElementById('import-merge-file').click()">📥 Importer (fusion)</button>
</div>
<div id="import-merge-status" style="display:none;margin-top:8px" class="settings-status"></div>
</div>
<!-- List of backups -->
<div id="backup-list-container" style="margin-top:14px">
<p class="settings-hint" data-i18n="settings.info.loading">Caricamento…</p>
@@ -1696,18 +1707,6 @@
</div>
</div>
<!-- Kiosk app download banner (hidden inside kiosk WebView) -->
<div id="kiosk-download-banner" style="background:linear-gradient(135deg,rgba(16,185,129,0.08),rgba(5,150,105,0.12));border:1.5px solid rgba(16,185,129,0.25);border-radius:12px;padding:16px;margin-top:16px">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">
<span style="font-size:1.6rem">📺</span>
<div>
<p style="margin:0;font-weight:700;font-size:0.95rem;color:#065f46">EverShelf Kiosk</p>
<p class="settings-hint" style="margin:2px 0 0" data-i18n="settings.kiosk.hint">Trasforma un tablet Android in un pannello EverShelf sempre acceso, con bilancia BLE integrata.</p>
</div>
</div>
<a href="https://github.com/dadaloop82/EverShelf/releases/download/kiosk-latest/evershelf-kiosk.apk" target="_blank" rel="noopener noreferrer" class="btn btn-large btn-accent full-width" style="text-decoration:none;display:block;text-align:center;background:linear-gradient(135deg,#059669,#10b981);color:#fff" data-i18n="settings.kiosk.download_btn">📥 Scarica EverShelf Kiosk (APK)</a>
<p class="settings-hint" style="margin-top:8px" data-i18n="settings.kiosk.download_sub">Modalità kiosk full-screen + gateway bilancia integrato. Sorgente: <code>evershelf-kiosk/</code></p>
</div>
<!-- Kiosk native settings panel (visible only inside kiosk WebView) -->
<div id="kiosk-native-settings-panel" style="display:none;background:rgba(99,102,241,0.06);border:1.5px solid rgba(99,102,241,0.2);border-radius:12px;padding:16px;margin-top:16px">
@@ -1740,25 +1739,124 @@
<button class="btn btn-large btn-success full-width mt-2" onclick="saveSettings()" data-i18n="btn.save_config">💾 Salva Configurazione</button>
<div id="settings-status" class="settings-status" style="display:none"></div>
<!-- About & Support -->
<div class="settings-section" style="margin-top:24px">
<h3 class="settings-section-title" data-i18n="about.title">About</h3>
<div class="settings-row" style="justify-content:space-between;align-items:center">
<span class="settings-label" data-i18n="about.version">Version</span>
<span id="about-version-label" class="settings-hint" style="font-family:monospace"></span>
</section>
<!-- ===== CONFIGURATION PAGE ===== -->
<section class="page" id="page-config">
<div class="page-header">
<h2>🔧 Configuration</h2>
</div>
<div class="config-tabs" style="display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap">
<button class="btn btn-small btn-primary config-tab-btn" data-tab="locations" onclick="showConfigTab('locations')">📍 Emplacements</button>
<button class="btn btn-small btn-secondary config-tab-btn" data-tab="categories" onclick="showConfigTab('categories')">📁 Catégories</button>
<button class="btn btn-small btn-secondary config-tab-btn" data-tab="subcategories" onclick="showConfigTab('subcategories')">📂 Sous-catégories</button>
<button class="btn btn-small btn-secondary config-tab-btn" data-tab="recipetags" onclick="showConfigTab('recipetags')">🏷️ Tags recettes</button>
<button class="btn btn-small btn-secondary config-tab-btn" data-tab="units" onclick="showConfigTab('units')">📏 Unités</button>
</div>
<div class="config-tab-content" id="config-tab-locations">
<div class="settings-card">
<h4>📍 Emplacements de stockage</h4>
<p class="settings-hint">Gère les emplacements disponibles pour ranger tes produits (Frigo, Cave, Bar...).</p>
<div id="locations-list-container" style="margin-top:10px">
<p class="settings-hint">Chargement…</p>
</div>
<div class="form-group mt-2">
<label> Nouvel emplacement</label>
<div class="barcode-input-row">
<input type="text" id="new-location-icon" class="form-input" style="max-width:70px;text-align:center" placeholder="📦" maxlength="4">
<input type="text" id="new-location-label" class="form-input" placeholder="Es: Cave, Bar, Garage..." onkeydown="if(event.key==='Enter'){event.preventDefault();addLocation()}">
<button class="btn btn-accent" onclick="addLocation()"></button>
</div>
</div>
</div>
<div style="margin-top:10px;display:flex;flex-direction:column;gap:8px">
<button class="btn btn-outline full-width" onclick="reportBugManual()" id="btn-report-bug">
🐛 <span data-i18n="about.report_bug">Segnala un problema</span>
</button>
<p class="settings-hint" style="text-align:center;margin:0" data-i18n="about.report_bug_hint">Qualcosa non funziona? Inviaci una segnalazione direttamente dall'app.</p>
<div style="display:flex;gap:8px">
<a class="btn btn-outline full-width" style="text-decoration:none;text-align:center"
href="https://github.com/dadaloop82/EverShelf/blob/main/CHANGELOG.md"
target="_blank" rel="noopener" data-i18n="about.changelog">Changelog</a>
<a class="btn btn-outline full-width" style="text-decoration:none;text-align:center"
href="https://github.com/dadaloop82/EverShelf"
target="_blank" rel="noopener" data-i18n="about.github">GitHub</a>
</div>
<div class="config-tab-content" id="config-tab-categories" style="display:none">
<div class="settings-card">
<h4>📁 Catégories</h4>
<p class="settings-hint">Gère les catégories de produits : icône, libellé, et mots-clés de détection automatique à partir du nom du produit.</p>
<div id="categories-list-container" style="margin-top:10px">
<p class="settings-hint">Chargement…</p>
</div>
<div class="form-group mt-2">
<label> Nouvelle catégorie</label>
<div class="barcode-input-row">
<input type="text" id="new-category-icon" class="form-input" style="max-width:70px;text-align:center" placeholder="📦" maxlength="4">
<input type="text" id="new-category-label" class="form-input" placeholder="Es: Apéritifs, Bébé...">
<button class="btn btn-accent" onclick="addCategory()"></button>
</div>
<input type="text" id="new-category-keywords" class="form-input mt-1" placeholder="Mots-clés séparés par des virgules (ex: chips, apéro, biscuit salé)">
</div>
</div>
</div>
<div class="config-tab-content" id="config-tab-subcategories" style="display:none">
<div class="settings-card">
<h4>📂 Sous-catégories</h4>
<p class="settings-hint">Gère les sous-catégories disponibles pour chaque catégorie de produit.</p>
<div class="form-group">
<label>Catégorie</label>
<select id="subcat-config-category" class="form-input" onchange="onSubcatConfigCategoryChange()"></select>
</div>
<div class="form-group" style="display:flex;align-items:center;gap:8px">
<input type="checkbox" id="subcat-config-required" onchange="toggleSubcategoryRequired()" style="width:auto">
<label for="subcat-config-required" style="margin:0">Sous-catégorie obligatoire pour cette catégorie</label>
</div>
<div id="subcat-list-container" style="margin-top:10px">
<p class="settings-hint">Chargement…</p>
</div>
<div class="form-group mt-2">
<label> Nouvelle sous-catégorie (pour la catégorie sélectionnée)</label>
<div class="barcode-input-row">
<input type="text" id="new-subcat-label" class="form-input" placeholder="Es: 🍷 Vin, 🍗 Poulet..." onkeydown="if(event.key==='Enter'){event.preventDefault();addSubcategoryRow()}">
<button class="btn btn-accent" onclick="addSubcategoryRow()"></button>
</div>
</div>
</div>
</div>
<div class="config-tab-content" id="config-tab-recipetags" style="display:none">
<div class="settings-card">
<h4>🏷️ Tags recettes</h4>
<p class="settings-hint">Gère les tags utilisés pour trier/filtrer "Mes recettes" (cocktails, boissons...).</p>
<div id="recipe-tags-list-container" style="margin-top:10px">
<p class="settings-hint">Chargement…</p>
</div>
<div class="form-group mt-2">
<label> Nouveau tag</label>
<div class="barcode-input-row">
<input type="text" id="new-recipe-tag-icon" class="form-input" style="max-width:70px;text-align:center" placeholder="🏷️" maxlength="4">
<input type="text" id="new-recipe-tag-label" class="form-input" placeholder="Es: Tiki, Sans alcool...">
<input type="text" id="new-recipe-tag-keywords" class="form-input" placeholder="Mots-clés (ex: citron, lime, vinaigre)" onkeydown="if(event.key==='Enter'){event.preventDefault();addRecipeTagConfig()}">
<button class="btn btn-accent" onclick="addRecipeTagConfig()"></button>
</div>
</div>
</div>
</div>
<div class="config-tab-content" id="config-tab-units" style="display:none">
<div class="settings-card">
<h4>📏 Unités</h4>
<p class="settings-hint">Ajoute des unités personnalisées (ex: kg, L) qui se convertissent automatiquement en g/ml/pz pour le stockage, mais s'affichent dans leur propre unité partout dans l'app.</p>
<div id="custom-units-list-container" style="margin-top:10px">
<p class="settings-hint">Chargement…</p>
</div>
<div class="form-group mt-2">
<label> Nouvelle unité</label>
<div class="barcode-input-row">
<input type="text" id="new-unit-icon" class="form-input" style="max-width:70px;text-align:center" placeholder="📏" maxlength="4">
<input type="text" id="new-unit-key" class="form-input" style="max-width:80px" placeholder="Es: kg" maxlength="10">
<input type="text" id="new-unit-label" class="form-input" placeholder="Es: kg (Kilogrammes)">
</div>
<div class="barcode-input-row" style="margin-top:8px">
<select id="new-unit-base" class="form-input">
<option value="g">g (poids)</option>
<option value="ml">ml (volume)</option>
<option value="pz">pz (pièces)</option>
</select>
<input type="number" id="new-unit-factor" class="form-input" placeholder="Facteur (ex: 1000)" min="0.001" step="any">
<button class="btn btn-accent" onclick="addCustomUnitConfig()"></button>
</div>
</div>
</div>
</div>
@@ -1820,6 +1918,10 @@
<span class="nav-icon">📋</span>
<span class="nav-label" data-i18n="nav.log">Storico</span>
</button>
<button class="nav-btn" onclick="showPage('config')" data-page="config">
<span class="nav-icon">🔧</span>
<span class="nav-label">Config.</span>
</button>
<button class="nav-btn" onclick="showPage('settings')" data-page="settings">
<span class="nav-icon">⚙️</span>
<span class="nav-label" data-i18n="nav.settings">Config</span>
+2 -2
View File
@@ -2,8 +2,8 @@
"name": "EverShelf",
"short_name": "EverShelf",
"description": "Gestione completa della dispensa di casa con scansione barcode",
"version": "1.7.41",
"start_url": "/evershelf/",
"version": "1.7.42",
"start_url": "/",
"display": "standalone",
"background_color": "#f0f4e8",
"theme_color": "#2d5016",
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"version":"1.7.19","version_code":20}
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env php
<?php
/** Delete all comments on open feature/enhancement backlog issues (English-only tracker policy). */
declare(strict_types=1);
define('CRON_MODE', true);
require_once __DIR__ . '/../api/bootstrap.php';
require_once __DIR__ . '/../api/lib/github.php';
require_once __DIR__ . '/../api/lib/constants.php';
$token = _ghToken();
if ($token === '') {
fwrite(STDERR, "ERROR: GH_ISSUE_TOKEN not configured\n");
exit(1);
}
function ghRequest(string $token, string $method, string $url, ?array $body = null): array {
$ch = curl_init($url);
$headers = [
'Authorization: token ' . $token,
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: EverShelf-Triage/1.0',
];
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 30,
]);
if ($method === 'DELETE') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
} elseif ($method === 'GET') {
// default
}
if ($body !== null) {
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$raw = curl_exec($ch);
$code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['code' => $code, 'body' => $raw];
}
$issues = [122, 121, 120, 119, 118, 117, 116, 115, 114, 106, 105, 104, 103, 102, 101, 97, 93, 81, 80, 79, 69, 67, 65];
$deleted = 0;
foreach ($issues as $num) {
$page = 1;
while (true) {
$url = 'https://api.github.com/repos/' . GH_REPO . "/issues/$num/comments?per_page=100&page=$page";
$r = ghRequest($token, 'GET', $url);
if ($r['code'] !== 200) {
fwrite(STDERR, "#$num list comments HTTP {$r['code']}\n");
break;
}
$comments = json_decode($r['body'], true);
if (!is_array($comments) || empty($comments)) {
break;
}
foreach ($comments as $c) {
$id = (int)($c['id'] ?? 0);
if ($id <= 0) continue;
$dr = ghRequest($token, 'DELETE', 'https://api.github.com/repos/' . GH_REPO . "/issues/comments/$id");
if ($dr['code'] === 204) {
$deleted++;
echo "deleted comment $id on #$num\n";
} else {
fwrite(STDERR, "FAIL delete comment $id on #$num HTTP {$dr['code']}\n");
}
usleep(200000);
}
if (count($comments) < 100) break;
$page++;
}
}
echo "Done. Deleted $deleted comments.\n";
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env php
<?php
/** Reopen wrongly closed feature issues; close resolved auto-report bugs (English). */
declare(strict_types=1);
define('CRON_MODE', true);
require_once __DIR__ . '/../api/bootstrap.php';
require_once __DIR__ . '/../api/lib/github.php';
require_once __DIR__ . '/../api/lib/constants.php';
$token = _ghToken();
if ($token === '') {
fwrite(STDERR, "ERROR: GH_ISSUE_TOKEN not configured\n");
exit(1);
}
function ghApi(string $token, string $method, string $url, array $payload = []): array {
$ch = curl_init($url);
$headers = [
'Authorization: token ' . $token,
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: EverShelf-Triage/1.0',
'Content-Type: application/json',
];
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 20,
]);
if ($method === 'PATCH') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
} elseif ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
}
$raw = curl_exec($ch);
$code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['http_code' => $code, 'body' => json_decode($raw ?: '{}', true) ?: []];
}
function comment(string $token, int $num, string $body): void {
$r = ghApi($token, 'POST', 'https://api.github.com/repos/' . GH_REPO . "/issues/$num/comments", ['body' => $body]);
echo $r['http_code'] >= 200 && $r['http_code'] < 300 ? "OK comment #$num\n" : "FAIL comment #$num\n";
}
function closeIssue(string $token, int $num): void {
$r = ghApi($token, 'PATCH', 'https://api.github.com/repos/' . GH_REPO . "/issues/$num", ['state' => 'closed']);
echo $r['http_code'] >= 200 && $r['http_code'] < 300 ? "OK close #$num\n" : "FAIL close #$num\n";
}
function reopenIssue(string $token, int $num): void {
$r = ghApi($token, 'PATCH', 'https://api.github.com/repos/' . GH_REPO . "/issues/$num", ['state' => 'open']);
echo $r['http_code'] >= 200 && $r['http_code'] < 300 ? "OK reopen #$num\n" : "FAIL reopen #$num\n";
}
$reopen = [
125 => "Reopened: **voice commands in cooking mode** are not implemented yet (only TTS readout exists). This was closed by mistake during bulk triage — the feature backlog should stay open until hands-free step navigation ships.",
98 => "Reopened: **pin favourite products to the top of inventory** is not implemented yet (recipe favourites #124 are done, but product pinning is a separate request). Closed by mistake — keeping on the backlog.",
];
foreach ($reopen as $num => $msg) {
comment($token, $num, $msg);
reopenIssue($token, $num);
}
$bugs = [
201 => 'Fixed in latest develop: `inventory_use` and `shopping_add` now retry on `SQLITE_BUSY` via `dbWithRetry()` (same pattern as #198).',
202 => 'Fixed: Bring/internal `shopping_add` wrapped in `dbWithRetry()` to survive cron + PWA concurrent writes.',
203 => 'Fixed: `smartShopping()` / `smartShoppingCached()` now call `set_time_limit(120)` so large pantries no longer hit the 30s PHP fatal.',
204 => 'Fixed: same as #203 — smart shopping timeout caused HTTP 500; extended execution limit resolves the crash.',
];
foreach ($bugs as $num => $msg) {
comment($token, $num, $msg . "\n\n_Closed after triage — fix shipped in develop._");
closeIssue($token, $num);
}
echo "Done.\n";
+14 -56
View File
@@ -1,7 +1,8 @@
#!/usr/bin/env php
<?php
/**
* One-shot triage: comment + close resolved auto-report bugs; reply on #200 (keep open).
* Triage resolved auto-report bugs only (English comments).
* Feature/enhancement backlog issues are never bulk-closed here.
* Usage: php scripts/triage-open-issues.php [--dry-run]
*/
declare(strict_types=1);
@@ -75,66 +76,23 @@ function closeIssue(string $token, string $repo, int $num, bool $dryRun): bool {
return false;
}
// ── #200: reply only, keep OPEN ─────────────────────────────────────────────
$body200 = <<<'MD'
Ciao Marco, grazie per la segnalazione dettagliata.
Il messaggio **«Impossibile contattare il server»** compare quando il browser **non riesce a completare** la richiesta a `api/index.php?action=health_check`. Quindi phpinfo funziona, ma **l'endpoint API no** (404, redirect, TLS, path sbagliato, ecc.).
### Check rapidi (dalla macchina dove apri il browser)
```bash
curl -sv "https://TUO-DOMINIO/api/index.php?action=ping"
curl -sv "https://TUO-DOMINIO/api/index.php?action=health_check"
```
Se uno dei due fallisce: DevTools → **Network** → URL esatto e **status code** della richiesta `health_check`.
### Cause frequenti con Traefik + Docker Swarm
1. **Routing incompleto** — Traefik deve inoltrare `/` **e** `/api/*`, non solo la homepage.
2. **Redirect HTTPS** — dietro Traefik serve `X-Forwarded-Proto: https`, oppure disabilitare il redirect in `.htaccess`. Nelle immagini recenti il Dockerfile imposta `SetEnvIf X-Forwarded-Proto "https" HTTPS=on`.
3. **Sottopath** — EverShelf usa URL relativi (`api/index.php`); se l'app è su `/sottocartella/`, l'URL pubblico deve essere coerente.
4. **Volume `data/`** — al primo avvio può essere quasi vuoto; assicurati permessi scrivibili:
```bash
docker exec -it CONTAINER chown -R www-data:www-data /var/www/html/data
docker exec -it CONTAINER chmod -R 775 /var/www/html/data
```
5. **`API_TOKEN` in `.env`** — se impostato, compare un prompt token (non «server non raggiungibile»).
### Per il passo successivo
Puoi condividere:
- URL pubblico esatto (con path)
- Output dei due `curl` sopra
- Screenshot Network tab su `health_check`
- Labels Traefik del servizio (router + middlewares)
Resta aperta finché non confermi che `ping`/`health_check` rispondono — poi chiudiamo insieme.
MD;
commentIssue($token, $repo, 200, $body200, $dryRun);
// ── Resolved auto-report bugs ───────────────────────────────────────────────
$bugs = [
198 => "Risolto in develop: `PRAGMA busy_timeout` portato a 10s e `dbWithRetry()` su `updateInventory` per ritentare su SQLITE_BUSY quando cron smart-shopping e PWA scrivono in parallelo.",
199 => "Duplicato di #198 — stesso evento (`inventory_update` → database locked). Fix: retry + busy_timeout aumentato.",
196 => "Risolto in v1.7.38+: `saveProduct` intercetta `UNIQUE constraint failed: products.barcode`, fa merge sul prodotto esistente o risponde 409 JSON (`barcode_already_used`) invece di HTTP 500.",
197 => "Conseguenza lato PWA del crash PHP #196 — risolto con gestione barcode duplicato in `saveProduct`.",
195 => "Risolto: `EverLog::request()` ora riceve sempre stringhe — `\$method = (string)(\$_SERVER['REQUEST_METHOD'] ?? 'GET')` (fix CLI/cron che passavano null).",
193 => "Stesso root cause di #195 (fatal TypeError su `EverLog::request` con method null da CLI). Fix già in develop.",
194 => "Risolto: `_applySpesaScanUI` usava `currentPage` (inesistente) → corretto in `_currentPageId`.",
192 => "Risolto: in `renderShoppingItems` la variabile `enriched` veniva referenziata prima della dichiarazione (TDZ). Ora `enrichedRaw` → `_dedupeShoppingByGeneric` → `enriched`.",
191 => "Risolto: in `_runStartupCheck` `setProgress` è dichiarata prima delle chiamate e `barEl` inizializzato prima dell'uso (niente più TDZ).",
134 => "Segnalazione auto-report su volume Docker non scrivibile. Mitigazioni: `_ensureDataDir()`, `_ensureDbWritable()`, Dockerfile `chown www-data`. Su Swarm: `chown -R www-data:www-data data` al primo boot.",
184 => "Correlato a #134: SQLite readonly quando `data/` o `evershelf.db` non sono scrivibili. Fix operativo + chmod WAL/SHM sidecar in `_ensureDbWritable()`.",
198 => 'Fixed in develop: `PRAGMA busy_timeout` raised to 10s and `dbWithRetry()` on `updateInventory` retries SQLITE_BUSY when cron and PWA write in parallel.',
199 => 'Duplicate of #198 — same event (`inventory_update` → database locked). Fix: retry + longer busy_timeout.',
196 => 'Fixed in v1.7.38+: `saveProduct` handles duplicate barcodes (merge or 409 JSON) instead of HTTP 500.',
197 => 'PWA side-effect of PHP crash #196 — fixed with duplicate barcode handling in `saveProduct`.',
195 => 'Fixed: `EverLog::request()` always receives strings — `(string)($_SERVER[\'REQUEST_METHOD\'] ?? \'GET\')`.',
193 => 'Same root cause as #195 (TypeError when method was null from CLI).',
194 => 'Fixed: `_applySpesaScanUI` referenced `currentPage` → corrected to `_currentPageId`.',
192 => 'Fixed: TDZ on `enriched` in `renderShoppingItems`.',
191 => 'Fixed: TDZ on `setProgress` / `barEl` in `_runStartupCheck`.',
134 => 'Auto-report for non-writable Docker volume. Mitigations: `_ensureDataDir()`, `_ensureDbWritable()`, Dockerfile chown.',
184 => 'Related to #134: SQLite readonly when `data/` is not writable.',
];
foreach ($bugs as $num => $msg) {
commentIssue($token, $repo, $num, $msg . "\n\n_Chiuso dopo triage — fix in develop._", $dryRun);
commentIssue($token, $repo, $num, $msg . "\n\n_Closed after triage — fix shipped in develop._", $dryRun);
closeIssue($token, $repo, $num, $dryRun);
}
// Feature/enhancement issues stay OPEN — do not bulk-close backlog items here.
echo "Done.\n";
+12
View File
@@ -353,6 +353,18 @@
"throw_all_confirm_btn": "🗑️ Ja, entsorgen",
"locations_short": "Orte"
},
"waste": {
"reason_title": "Warum wirfst du es weg?",
"reason_subtitle": "Das hilft uns, ähnliche Verschwendung zu vermeiden.",
"reason_expired": "⏰ Abgelaufen",
"reason_spoiled": "🦠 Verdorben",
"reason_wrong_location": "📍 Falscher Lagerort",
"reason_kept_too_long": "⏳ Zu lange aufbewahrt",
"reason_bought_too_much": "🛒 Zu viel gekauft",
"reason_forgotten": "😴 Vergessen / nicht rechtzeitig genutzt",
"reason_bad_quality": "👎 Schlechte Qualität beim Kauf",
"reason_other": "❓ Sonstiges"
},
"product": {
"title_new": "Neues Produkt",
"title_edit": "Produkt bearbeiten",
+12
View File
@@ -353,6 +353,18 @@
"throw_all_confirm_btn": "🗑️ Yes, discard",
"locations_short": "places"
},
"waste": {
"reason_title": "Why are you discarding it?",
"reason_subtitle": "This helps us prevent similar waste next time.",
"reason_expired": "⏰ Expired",
"reason_spoiled": "🦠 Spoiled / gone bad",
"reason_wrong_location": "📍 Wrong storage (fridge/freezer/pantry)",
"reason_kept_too_long": "⏳ Kept too long",
"reason_bought_too_much": "🛒 Bought too much",
"reason_forgotten": "😴 Forgotten / not used in time",
"reason_bad_quality": "👎 Poor quality when bought",
"reason_other": "❓ Other"
},
"product": {
"title_new": "New Product",
"title_edit": "Edit Product",
+12
View File
@@ -353,6 +353,18 @@
"throw_all_confirm_btn": "🗑️ Sí, desechar",
"locations_short": "ubicaciones"
},
"waste": {
"reason_title": "¿Por qué lo tiras?",
"reason_subtitle": "Nos ayuda a evitar desperdicios similares.",
"reason_expired": "⏰ Caducado",
"reason_spoiled": "🦠 Estropeado",
"reason_wrong_location": "📍 Lugar de guardado incorrecto",
"reason_kept_too_long": "⏳ Guardado demasiado tiempo",
"reason_bought_too_much": "🛒 Comprado de más",
"reason_forgotten": "😴 Olvidado / no usado a tiempo",
"reason_bad_quality": "👎 Mala calidad al comprar",
"reason_other": "❓ Otro"
},
"product": {
"title_new": "Nuevo producto",
"title_edit": "Editar producto",
+19 -1
View File
@@ -353,6 +353,18 @@
"throw_all_confirm_btn": "🗑️ Oui, jeter",
"locations_short": "emplacements"
},
"waste": {
"reason_title": "Pourquoi le jetez-vous ?",
"reason_subtitle": "Cela nous aide à éviter des gaspillages similaires.",
"reason_expired": "⏰ Périmé",
"reason_spoiled": "🦠 Abîmé / gâté",
"reason_wrong_location": "📍 Mauvais emplacement",
"reason_kept_too_long": "⏳ Conservé trop longtemps",
"reason_bought_too_much": "🛒 Acheté en trop grande quantité",
"reason_forgotten": "😴 Oublié / pas utilisé à temps",
"reason_bad_quality": "👎 Mauvaise qualité à l'achat",
"reason_other": "❓ Autre"
},
"product": {
"title_new": "Nouveau produit",
"title_edit": "Modifier le produit",
@@ -459,7 +471,13 @@
"storage_immediately": "À consommer immédiatement",
"stream_interrupted": "Génération interrompue (réponse serveur incomplète). Vérifiez les logs ou réessayez.",
"ing_stock_line": "Vous avez {have} · il reste {remain} après usage",
"ing_use_all_note": "tout utiliser (<5% du conditionnement entier)"
"ing_use_all_note": "tout utiliser (<5% du conditionnement entier)",
"shopping_suggestions_intro": "Pour une variante, il faudrait (pas dans le garde-manger — optionnel) :",
"shopping_suggestions_add": "Ajouter à la liste de courses",
"shopping_suggestions_added": "Ajouté à la liste de courses",
"frozen_badge": "surgelé — du congélateur",
"unit_for_input": "Unité de mesure",
"enter_in": "Saisie en"
},
"shopping": {
"title": "🛒 Liste de courses",
+12
View File
@@ -353,6 +353,18 @@
"throw_all_confirm_btn": "🗑️ Sì, butta",
"locations_short": "posti"
},
"waste": {
"reason_title": "Perché lo butti?",
"reason_subtitle": "Ci aiuta a evitare sprechi simili in futuro.",
"reason_expired": "⏰ Scaduto",
"reason_spoiled": "🦠 Andato a male / deperito",
"reason_wrong_location": "📍 Posto sbagliato (frigo/freezer/dispensa)",
"reason_kept_too_long": "⏳ Tenuto troppo a lungo",
"reason_bought_too_much": "🛒 Comprato troppo",
"reason_forgotten": "😴 Dimenticato / non usato in tempo",
"reason_bad_quality": "👎 Qualità scadente all'acquisto",
"reason_other": "❓ Altro"
},
"product": {
"title_new": "Nuovo Prodotto",
"title_edit": "Modifica Prodotto",