From bc775301a3fe39d9d243f2f9913db0fc1d33834d Mon Sep 17 00:00:00 2001 From: DevSven <184159789+S540d@users.noreply.github.com> Date: Tue, 3 Nov 2026 10:25:37 +0100 Subject: [PATCH] Release v1.9.0 (versionCode 71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release-PR für **v1.9.0 / versionCode 71**: Play Store steht auf 1.8.0 / vc69, vc70 wurde nie veröffentlicht. > ⚠️ **Nicht mergen ohne ausdrückliche Freigabe.** Merge auf `main` löst sofort den GitHub-Pages-Deploy aus (`deploy.yml`). Die Web-Demo geht damit zu 100 % live, unabhängig vom gestaffelten Play-Store-Rollout. ## Inhalt Vollständige Liste im `CHANGELOG.md` unter `[1.9.0]`. Die wichtigsten Punkte: **Neu:** Pause-Vorschlag alle 5 Level, Impressum/Datenschutz im Über-Dialog (7 Sprachen), Micro-Animationen, Web-Auffindbarkeit und Play-Store-Attribution **Geändert:** neues App-Icon/Splash (Haus-Motiv), Design-System Blau statt Violett, Einstellungen gruppiert, Startseite entschlackt, ruhiger Merke-Timer, Replay- und Web-Canvas-Performance **Behoben:** Konfetti/Abzeichen bei gleicher Sternzahl, Darkmode-Sichtbarkeit, Galerie-Status beim Neustart, Web-Fills bei gebrochener Canvas-Breite, PWA-Tags/Icons **Security:** diverse `npm audit fix`, Audit-Gate mit befristeter Allowlist ## Status vor Merge - [x] `package.json` / `app.json`: 1.9.0, versionCode 71 - [x] Lokal: `tsc` ✅, Lint ✅, 52 Suites / 482 Tests ✅ - [ ] **Audit-Gate:** neue High-Advisories seit 2026-10-29 - node-forge → Fix in #374 (gegen `testing`) - decode-uri-component (GHSA-qr28-fpjm-wq7f, via expo-router → query-string) → Entscheidung offen - [ ] CHANGELOG-Datum `[1.9.0] - TBD` setzen - [ ] Dependabot-PR #373 (zod/expo, gegen `main`) schließen; zod ist bereits auf `testing` adressiert ## Nach dem Merge 1. AAB aus `main` bauen (production, vc71) 2. Play Console: Produktion, **gestaffelte Einführung 10 %** 3. Tag `v1.9.0` setzen 4. Android Vitals einige Tage beobachten, dann Anteil erhöhen 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: S540d Co-authored-by: Claude Opus 4.8 --- .audit-allowlist.json | 17 + ".claude/commands/aufr\303\244umen.md" | 83 +- .github/dependabot.yml | 34 + .github/workflows/ci-cd.yml | 16 +- .github/workflows/codeql.yml | 53 + .github/workflows/deploy.yml | 2 +- .github/workflows/standards-audit.yml | 6 +- .gitignore | 2 +- CHANGELOG.md | 35 +- CLAUDE.md | 350 +- README.md | 72 +- THIRD_PARTY_LICENSES.md | 1 - app.json | 26 +- app/+html.tsx | 2 +- app/_layout.tsx | 6 +- app/creative.tsx | 28 +- app/gallery.tsx | 31 +- app/game.tsx | 200 +- app/index.tsx | 315 +- app/levels.tsx | 16 +- app/settings.tsx | 3 +- .../4c81a955-e90c-44e6-b702-458e53525e14.jpg | Bin 110042 -> 0 bytes .../610931c7-7481-468b-a0bb-fedb223c3fd1.jpg | Bin 257625 -> 0 bytes .../ChatGPT Image 6. Dez. 2025, 09_38_05.png | Bin 1201227 -> 0 bytes assets/icons/IMG_2709.JPG | Bin 223258 -> 0 bytes assets/icons/IMG_2710.JPG | Bin 230754 -> 0 bytes assets/icons/IMG_2711.PNG | Bin 1079903 -> 0 bytes assets/icons/IMG_2712.PNG | Bin 1088851 -> 0 bytes .../ad017699-a59f-43c1-a101-60d51d5f6eca.jpg | Bin 188372 -> 0 bytes assets/icons/adaptive-icon-foreground.svg | 34 + assets/icons/adaptive-icon.png | Bin 48568 -> 41095 bytes assets/icons/app-icon-512.png | Bin 23374 -> 25000 bytes assets/icons/app-icon.png | Bin 48568 -> 52829 bytes assets/icons/app-icon.svg | 64 +- .../dead4a07-3cd3-4527-a9ba-a704cabb56e3.jpg | Bin 207599 -> 0 bytes assets/icons/favicon.png | Bin 48568 -> 52829 bytes assets/icons/feature-graphic.png | Bin 47948 -> 49701 bytes assets/icons/feature-graphic.svg | 33 +- assets/icons/splash-icon.png | Bin 0 -> 41095 bytes assets/icons/splash-icon.svg | 34 + assets/splash.png | Bin 1104100 -> 0 bytes components/AnimatedHero.tsx | 137 - components/AnimatedPrimitives.tsx | 53 - components/AnimatedSplashScreen.tsx | 65 +- components/Badge.tsx | 10 +- components/BadgesModal.tsx | 2 +- components/DrawingCanvas.native.tsx | 190 +- components/DrawingCanvas.web.tsx | 209 +- components/LevelImageDisplay.tsx | 5547 +---------------- components/ParentDashboard.tsx | 2 +- components/QuickStatsCards.tsx | 211 +- components/SettingsModal.tsx | 109 +- components/TutorialOverlay.tsx | 1 - components/WebInstallBanner.tsx | 52 +- components/__tests__/AnimatedHero.test.tsx | 76 - .../__tests__/DrawingCanvas.web.test.tsx | 244 + components/__tests__/GalleryScreen.test.tsx | 8 - .../__tests__/GamePhaseComponents.test.tsx | 37 +- components/__tests__/GameScreen.test.tsx | 149 +- components/__tests__/HomeScreen.test.tsx | 5 - .../__tests__/LevelImageDisplay.test.tsx | 38 + components/__tests__/LevelsScreen.test.tsx | 29 +- components/__tests__/QuickStatsCards.test.tsx | 80 +- .../__tests__/WebInstallBanner.test.tsx | 10 +- components/game/DrawPhase.tsx | 27 +- components/game/MemorizePhase.tsx | 7 +- components/game/ResultPhase.tsx | 29 +- components/game/TimerArc.native.tsx | 105 - components/game/TimerArc.tsx | 3 - components/game/TimerArc.web.tsx | 84 - components/game/TimerBar.tsx | 65 + components/levelImages/essen-01-popsicle.tsx | 39 + components/levelImages/essen-02-cookie.tsx | 27 + .../levelImages/essen-03-strawberry.tsx | 37 + components/levelImages/essen-04-pizza.tsx | 34 + components/levelImages/essen-05-cupcake.tsx | 41 + components/levelImages/essen-06-banana.tsx | 52 + components/levelImages/essen-07-carrot.tsx | 64 + components/levelImages/essen-08-cake.tsx | 63 + components/levelImages/essen-09-hamburger.tsx | 73 + .../levelImages/essen-10-watermelon.tsx | 35 + .../levelImages/extra-01-stick-figure.tsx | 59 + components/levelImages/extra-02-car.tsx | 80 + components/levelImages/extra-03-flower.tsx | 88 + components/levelImages/extra-04-bird.tsx | 77 + components/levelImages/fahrzeuge-01-bus.tsx | 85 + .../levelImages/fahrzeuge-02-airplane.tsx | 37 + .../levelImages/fahrzeuge-03-sailboat.tsx | 60 + .../levelImages/fahrzeuge-04-tractor.tsx | 86 + .../levelImages/fahrzeuge-05-helicopter.tsx | 60 + .../levelImages/fahrzeuge-06-firetruck.tsx | 84 + .../levelImages/fahrzeuge-07-ambulance.tsx | 78 + .../levelImages/fahrzeuge-08-submarine.tsx | 84 + .../levelImages/fahrzeuge-09-speedboat.tsx | 102 + .../levelImages/fahrzeuge-10-spaceshuttle.tsx | 47 + components/levelImages/level-01-sun.tsx | 84 + components/levelImages/level-02-01-house.tsx | 37 + components/levelImages/level-02-02-apple.tsx | 19 + components/levelImages/level-02-03-rocket.tsx | 25 + .../levelImages/level-02-04-balloon.tsx | 22 + components/levelImages/level-02-face.tsx | 27 + components/levelImages/level-03-cloud.tsx | 15 + components/levelImages/level-04-house.tsx | 56 + components/levelImages/level-05-01-lion.tsx | 64 + .../levelImages/level-05-02-landscape.tsx | 32 + components/levelImages/level-05-03-castle.tsx | 85 + components/levelImages/level-05-tree.tsx | 33 + components/levelImages/level-06-dog.tsx | 90 + components/levelImages/level-07-cat.tsx | 59 + components/levelImages/level-08-sheep.tsx | 89 + components/levelImages/level-09-fish.tsx | 32 + components/levelImages/level-10-butterfly.tsx | 116 + .../levelImages/level-11-cat-simple.tsx | 37 + .../levelImages/level-12-dog-simple.tsx | 51 + .../levelImages/level-13-bird-simple.tsx | 50 + components/levelImages/level-14-car-v2.tsx | 103 + components/levelImages/level-15-train.tsx | 117 + components/levelImages/level-16-bicycle.tsx | 115 + .../levelImages/level-17-tree-detailed.tsx | 67 + .../levelImages/level-18-flower-detailed.tsx | 109 + .../levelImages/level-19-fish-tropical.tsx | 68 + .../levelImages/level-20-house-detailed.tsx | 138 + components/levelImages/maerchen-01-crown.tsx | 41 + components/levelImages/maerchen-02-wand.tsx | 49 + .../levelImages/maerchen-03-wizardhat.tsx | 49 + components/levelImages/maerchen-04-fairy.tsx | 48 + .../levelImages/maerchen-05-frogprince.tsx | 50 + .../maerchen-06-pumpkincarriage.tsx | 52 + .../levelImages/maerchen-07-spellbook.tsx | 44 + .../levelImages/maerchen-08-unicorn.tsx | 89 + components/levelImages/maerchen-09-dragon.tsx | 60 + .../levelImages/maerchen-10-castletower.tsx | 70 + components/levelImages/natur-01-rainbow.tsx | 57 + components/levelImages/natur-02-mushroom.tsx | 53 + components/levelImages/natur-03-seashell.tsx | 32 + components/levelImages/natur-04-cactus.tsx | 53 + components/levelImages/natur-05-bee.tsx | 56 + components/levelImages/natur-06-ladybug.tsx | 55 + components/levelImages/natur-07-snowflake.tsx | 75 + components/levelImages/natur-08-palmtree.tsx | 73 + components/levelImages/natur-09-waterfall.tsx | 49 + components/levelImages/natur-10-volcano.tsx | 37 + components/levelImages/registry.ts | 170 + components/levelImages/tiere-01-frog.tsx | 53 + components/levelImages/tiere-02-rabbit.tsx | 31 + components/levelImages/tiere-03-duck.tsx | 54 + components/levelImages/tiere-04-owl.tsx | 57 + components/levelImages/tiere-05-bear.tsx | 37 + components/levelImages/tiere-06-penguin.tsx | 51 + components/levelImages/tiere-07-snail.tsx | 47 + components/levelImages/tiere-08-horse.tsx | 92 + components/levelImages/tiere-09-elephant.tsx | 90 + components/levelImages/tiere-10-fox.tsx | 72 + constants/Colors.ts | 26 +- constants/ExternalLinks.ts | 7 + constants/WebAccessibility.ts | 103 - .../issue-304/alternative-b-1024.png | Bin 0 -> 205614 bytes .../issue-304/vorschlag-icon-1024.png | Bin 0 -> 204112 bytes .../issue-304/vorschlag-icon-48.png | Bin 0 -> 3711 bytes .../issue-304/vorschlag-icon.svg | 45 + docs/ARCHITECTURE.md | 146 + docs/DESIGN_SYSTEM.md | 70 + docs/ROADMAP.md | 51 + jest.config.js | 11 +- locales/de/translations.json | 18 +- locales/en/translations.json | 18 +- locales/es/translations.json | 18 +- locales/fr/translations.json | 18 +- locales/it/translations.json | 18 +- locales/nl/translations.json | 18 +- locales/pl/translations.json | 18 +- package-lock.json | 632 +- package.json | 3 +- public/apple-touch-icon.png | Bin 241570 -> 25000 bytes public/feature-graphic.png | Bin 56025 -> 49701 bytes scripts/__tests__/validate-svg-counts.test.ts | 21 +- scripts/audit-gate.mjs | 91 + scripts/generate-icon-assets.js | 29 +- scripts/prepare-release.sh | 192 - scripts/validate-release.sh | 263 +- scripts/validate-svg-counts.js | 40 +- services/DailyChallengeManager.ts | 30 +- services/NativeFillLayerService.ts | 109 +- services/OnboardingManager.ts | 26 +- services/RatingManager.ts | 29 +- services/SentryService.ts | 4 +- services/SessionTracker.ts | 7 +- services/ShareService.native.ts | 38 +- services/ShareService.ts | 33 +- services/SoundManager.ts | 12 +- services/StorageManager.ts | 26 +- services/ThemeContext.tsx | 17 +- .../__tests__/NativeFillLayerService.test.ts | 122 +- services/__tests__/OnboardingManager.test.ts | 4 +- services/__tests__/useGameFeedback.test.ts | 62 + services/__tests__/useGamePhase.test.ts | 18 + services/useGameFeedback.ts | 95 + services/useGamePhase.ts | 1 + utils/confirmDestructive.test.ts | 76 + utils/drawingTransform.test.ts | 121 + utils/drawingTransform.ts | 64 + utils/platform.ts | 33 +- 202 files changed, 8461 insertions(+), 8447 deletions(-) create mode 100644 .audit-allowlist.json create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql.yml delete mode 100644 assets/icons/4c81a955-e90c-44e6-b702-458e53525e14.jpg delete mode 100644 assets/icons/610931c7-7481-468b-a0bb-fedb223c3fd1.jpg delete mode 100644 assets/icons/ChatGPT Image 6. Dez. 2025, 09_38_05.png delete mode 100644 assets/icons/IMG_2709.JPG delete mode 100644 assets/icons/IMG_2710.JPG delete mode 100644 assets/icons/IMG_2711.PNG delete mode 100644 assets/icons/IMG_2712.PNG delete mode 100644 assets/icons/ad017699-a59f-43c1-a101-60d51d5f6eca.jpg create mode 100644 assets/icons/adaptive-icon-foreground.svg delete mode 100644 assets/icons/dead4a07-3cd3-4527-a9ba-a704cabb56e3.jpg create mode 100644 assets/icons/splash-icon.png create mode 100644 assets/icons/splash-icon.svg delete mode 100644 assets/splash.png delete mode 100644 components/AnimatedHero.tsx delete mode 100644 components/__tests__/AnimatedHero.test.tsx create mode 100644 components/__tests__/DrawingCanvas.web.test.tsx delete mode 100644 components/game/TimerArc.native.tsx delete mode 100644 components/game/TimerArc.tsx delete mode 100644 components/game/TimerArc.web.tsx create mode 100644 components/game/TimerBar.tsx create mode 100644 components/levelImages/essen-01-popsicle.tsx create mode 100644 components/levelImages/essen-02-cookie.tsx create mode 100644 components/levelImages/essen-03-strawberry.tsx create mode 100644 components/levelImages/essen-04-pizza.tsx create mode 100644 components/levelImages/essen-05-cupcake.tsx create mode 100644 components/levelImages/essen-06-banana.tsx create mode 100644 components/levelImages/essen-07-carrot.tsx create mode 100644 components/levelImages/essen-08-cake.tsx create mode 100644 components/levelImages/essen-09-hamburger.tsx create mode 100644 components/levelImages/essen-10-watermelon.tsx create mode 100644 components/levelImages/extra-01-stick-figure.tsx create mode 100644 components/levelImages/extra-02-car.tsx create mode 100644 components/levelImages/extra-03-flower.tsx create mode 100644 components/levelImages/extra-04-bird.tsx create mode 100644 components/levelImages/fahrzeuge-01-bus.tsx create mode 100644 components/levelImages/fahrzeuge-02-airplane.tsx create mode 100644 components/levelImages/fahrzeuge-03-sailboat.tsx create mode 100644 components/levelImages/fahrzeuge-04-tractor.tsx create mode 100644 components/levelImages/fahrzeuge-05-helicopter.tsx create mode 100644 components/levelImages/fahrzeuge-06-firetruck.tsx create mode 100644 components/levelImages/fahrzeuge-07-ambulance.tsx create mode 100644 components/levelImages/fahrzeuge-08-submarine.tsx create mode 100644 components/levelImages/fahrzeuge-09-speedboat.tsx create mode 100644 components/levelImages/fahrzeuge-10-spaceshuttle.tsx create mode 100644 components/levelImages/level-01-sun.tsx create mode 100644 components/levelImages/level-02-01-house.tsx create mode 100644 components/levelImages/level-02-02-apple.tsx create mode 100644 components/levelImages/level-02-03-rocket.tsx create mode 100644 components/levelImages/level-02-04-balloon.tsx create mode 100644 components/levelImages/level-02-face.tsx create mode 100644 components/levelImages/level-03-cloud.tsx create mode 100644 components/levelImages/level-04-house.tsx create mode 100644 components/levelImages/level-05-01-lion.tsx create mode 100644 components/levelImages/level-05-02-landscape.tsx create mode 100644 components/levelImages/level-05-03-castle.tsx create mode 100644 components/levelImages/level-05-tree.tsx create mode 100644 components/levelImages/level-06-dog.tsx create mode 100644 components/levelImages/level-07-cat.tsx create mode 100644 components/levelImages/level-08-sheep.tsx create mode 100644 components/levelImages/level-09-fish.tsx create mode 100644 components/levelImages/level-10-butterfly.tsx create mode 100644 components/levelImages/level-11-cat-simple.tsx create mode 100644 components/levelImages/level-12-dog-simple.tsx create mode 100644 components/levelImages/level-13-bird-simple.tsx create mode 100644 components/levelImages/level-14-car-v2.tsx create mode 100644 components/levelImages/level-15-train.tsx create mode 100644 components/levelImages/level-16-bicycle.tsx create mode 100644 components/levelImages/level-17-tree-detailed.tsx create mode 100644 components/levelImages/level-18-flower-detailed.tsx create mode 100644 components/levelImages/level-19-fish-tropical.tsx create mode 100644 components/levelImages/level-20-house-detailed.tsx create mode 100644 components/levelImages/maerchen-01-crown.tsx create mode 100644 components/levelImages/maerchen-02-wand.tsx create mode 100644 components/levelImages/maerchen-03-wizardhat.tsx create mode 100644 components/levelImages/maerchen-04-fairy.tsx create mode 100644 components/levelImages/maerchen-05-frogprince.tsx create mode 100644 components/levelImages/maerchen-06-pumpkincarriage.tsx create mode 100644 components/levelImages/maerchen-07-spellbook.tsx create mode 100644 components/levelImages/maerchen-08-unicorn.tsx create mode 100644 components/levelImages/maerchen-09-dragon.tsx create mode 100644 components/levelImages/maerchen-10-castletower.tsx create mode 100644 components/levelImages/natur-01-rainbow.tsx create mode 100644 components/levelImages/natur-02-mushroom.tsx create mode 100644 components/levelImages/natur-03-seashell.tsx create mode 100644 components/levelImages/natur-04-cactus.tsx create mode 100644 components/levelImages/natur-05-bee.tsx create mode 100644 components/levelImages/natur-06-ladybug.tsx create mode 100644 components/levelImages/natur-07-snowflake.tsx create mode 100644 components/levelImages/natur-08-palmtree.tsx create mode 100644 components/levelImages/natur-09-waterfall.tsx create mode 100644 components/levelImages/natur-10-volcano.tsx create mode 100644 components/levelImages/registry.ts create mode 100644 components/levelImages/tiere-01-frog.tsx create mode 100644 components/levelImages/tiere-02-rabbit.tsx create mode 100644 components/levelImages/tiere-03-duck.tsx create mode 100644 components/levelImages/tiere-04-owl.tsx create mode 100644 components/levelImages/tiere-05-bear.tsx create mode 100644 components/levelImages/tiere-06-penguin.tsx create mode 100644 components/levelImages/tiere-07-snail.tsx create mode 100644 components/levelImages/tiere-08-horse.tsx create mode 100644 components/levelImages/tiere-09-elephant.tsx create mode 100644 components/levelImages/tiere-10-fox.tsx delete mode 100644 constants/WebAccessibility.ts create mode 100644 design/icon-proposals/issue-304/alternative-b-1024.png create mode 100644 design/icon-proposals/issue-304/vorschlag-icon-1024.png create mode 100644 design/icon-proposals/issue-304/vorschlag-icon-48.png create mode 100644 design/icon-proposals/issue-304/vorschlag-icon.svg create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/DESIGN_SYSTEM.md create mode 100644 docs/ROADMAP.md create mode 100644 scripts/audit-gate.mjs delete mode 100755 scripts/prepare-release.sh create mode 100644 services/__tests__/useGameFeedback.test.ts create mode 100644 services/useGameFeedback.ts create mode 100644 utils/confirmDestructive.test.ts create mode 100644 utils/drawingTransform.test.ts create mode 100644 utils/drawingTransform.ts diff --git a/.audit-allowlist.json b/.audit-allowlist.json new file mode 100644 index 0000000..d1f1ed0 --- /dev/null +++ b/.audit-allowlist.json @@ -0,0 +1,17 @@ +{ + "_comment": "Befristete Ausnahmen für scripts/audit-gate.mjs. Grundsätzlich nur Findings ohne Upstream-Fix im Build-Tooling (nicht im App-Bundle); Ausnahmen davon sind im reason begründet. Nach Ablauf schlägt das Gate fehl -> neu bewerten (DrawFromMemory#348).", + "advisories": [ + { + "id": "GHSA-mrhx-c7xc-m3w5", + "package": "zod", + "reason": "Speicher-DoS bei übergroßen Collections: nur noch zod@3 via expo -> @expo/cli (Build-Tooling, validiert lokale Konfiguration); kein gepatchter 3.x-Release, @expo/cli verlangt ^3.25.76. Root-zod (eslint-plugin-react-hooks) auf 4.6.7 gehoben.", + "expires": "2026-12-31" + }, + { + "id": "GHSA-qr28-fpjm-wq7f", + "package": "decode-uri-component", + "reason": "Quadratische Laufzeit bei langen %-kodierten Sequenzen. AUSNAHME: im App-Bundle (expo-router -> query-string@7 -> decode-uri-component@0.2.2). Fix erst in 0.5.1 (ESM-only, inkompatibel mit query-string@7); npm audit schlägt nur expo-router 58 (SDK-Major) vor. Risiko gering: betrifft nur das Parsen von App-URLs/Deep-Links auf dem Gerät des Nutzers selbst (kein Server). Mit dem nächsten SDK-Upgrade auflösen.", + "expires": "2026-12-31" + } + ] +} diff --git "a/.claude/commands/aufr\303\244umen.md" "b/.claude/commands/aufr\303\244umen.md" index fd2bb4f..8180233 100644 --- "a/.claude/commands/aufr\303\244umen.md" +++ "b/.claude/commands/aufr\303\244umen.md" @@ -4,6 +4,13 @@ Führe den täglichen Cleanup-Workflow durch: ## 0. Branch-Übersicht: testing vs. main (alle Repos) +**Nur lokal anwendbar** — der Pfad `/Users/svenstrohkark/...` existiert nur auf +diesem Mac. In Remote-Execution-Sessions trifft `[ -d "$dir/.git" ]` nie zu, die +Schleife läuft ohne Ausgabe und ohne Fehler durch. Läuft die Session nicht lokal +auf diesem Rechner: Abschnitt überspringen und dem Nutzer explizit sagen, dass +diese Prüfung hier nicht durchgeführt werden konnte — nicht stillschweigend +weiterlaufen. + Erstelle zu Beginn eine Tabelle aller Repositories mit dem Stand von `testing` gegenüber `main`: ```bash @@ -40,9 +47,47 @@ Zeige das Ergebnis als Markdown-Tabelle: ## 2. Branches aufräumen -- Liste alle merged Feature Branches (lokal und remote) -- Frage ob diese gelöscht werden sollen -- Lösche approved Branches +**Wichtig:** `git branch --merged` und `git merge-base --is-ancestor` sind bei +Squash-Merge-Policy unbrauchbar — sie melden gemergte Branches als „nicht gemergt". +Maßgeblich ist die PR-Historie, und dort das Feld `merged_at` (nicht `merged`; +letzteres ist über MCP-GitHub-Tools unzuverlässig und liefert teils `false` +auch bei nachweislich gemergten PRs). + +```bash +git fetch --all --prune -q +for b in $(git branch -r --format='%(refname:short)' \ + | grep -vE 'origin/(HEAD|main|testing|staging|gh-pages)$'); do + br=${b#origin/} + pr=$(gh pr list --head "$br" --state merged --json number,mergedAt --limit 1) + if [ "$(echo "$pr" | jq 'length')" -gt 0 ]; then + echo "✅ $br → PR #$(echo "$pr" | jq -r '.[0].number') gemergt" + else + echo "⚠️ $br → kein gemergter PR — Inhalt prüfen" + fi +done +``` + +Bei `⚠️` zweite Stufe, bevor gelöscht wird — prüft, ob der Branch-Inhalt +inhaltlich schon im Ziel liegt (z.B. bei umbenanntem Squash-Commit): + +```bash +mb=$(git merge-base origin/testing origin/$br) +files=$(git diff --name-only $mb origin/$br) +[ -n "$files" ] && git diff --name-only origin/testing origin/$br -- $files +# leere Ausgabe = Inhalt vollständig in testing → löschbar +``` + +- **Vor dem Löschen fragen**, nur bestätigte Branches löschen +- `main`, `testing`, `staging`, `gh-pages` **nie** löschen — auch nicht beim Bulk-Delete +- Schlägt `git push --delete` mit HTTP 403 fehl (Remote-Execution-Umgebungen): + Exit-Code ist trotzdem 0 und die letzte Zeile lautet „Everything up-to-date". + Nicht als Erfolg werten — stattdessen den fertigen Löschbefehl für die lokale + Ausführung ausgeben. +- Feature-Branches nach Merge löschen: `gh pr merge --delete-branch` explizit + verwenden. `scripts/apply-rulesets.sh` setzt `delete_branch_on_merge=false` + zentral (seit Issue #122 Korrektur 4, siehe `dev-standards/global-policy.md`, + „Merge-Methode zentral erzwingen") — GitHubs Auto-Delete löscht sonst auch + den Head-Branch von Release-PRs (`testing → main`), also `testing` selbst ## 3. GitHub Actions Status @@ -62,6 +107,38 @@ Zeige das Ergebnis als Markdown-Tabelle: - Zeige kürzlich geschlossene Issues (heute) - Weise auf Issues ohne Label hin +### 5a. Erledigte Issues aufspüren (Issue #111) + +`Closes #X` schließt ein Issue nur beim Merge in den **Default-Branch** (`main`). +Da alle PRs nach `testing` gehen, greift das Keyword faktisch nie — Issues bleiben +offen, obwohl der Code längst gemergt ist. + +Gemergte `testing`-PRs gegen die offenen Issues abgleichen: + +```bash +SLUG=$(git remote get-url origin | sed -E 's#.*github.com[:/]##; s#\.git$##') +OPEN=$(gh issue list -R "$SLUG" --state open --limit 100 --json number -q '.[].number' | tr '\n' ' ') +gh pr list -R "$SLUG" --state merged --base testing --limit 60 --json number,body \ + --jq '.[] | (.body // "") as $b + | ($b|[scan("(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#(\\d+)")]|flatten|unique) as $r + | select($r|length>0) | "\(.number) \($r|join(" "))"' | +while read -r pr refs; do + for i in $refs; do + case " $OPEN " in *" $i "*) echo "Issue #$i erledigt durch PR #$pr";; esac + done +done +``` + +**Nur vorschlagen, nicht automatisch schließen.** Sammel-/Meta-Issues ("Backlog", +"Maßnahmenkatalog", "Tracking") werden von Teil-PRs oft fälschlich mit `Closes` +referenziert, sind aber nicht erledigt. Vor dem Schließen den Issue-Titel lesen. + +Beim Schließen den Grund vermerken, damit die Historie nachvollziehbar bleibt: + +```bash +gh issue close -R "$SLUG" -c "Umgesetzt in #, gemergt nach \`testing\`." +``` + ## 6. Dependencies & Security - Prüfe ob `package.json` Updates braucht (via npm outdated) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ecdbfb7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,34 @@ +# Dependabot – kostenlose Dependency-Updates + Security-Alerts. +# Ersetzt zusammen mit codeql.yml den kostenpflichtigen Anthropic-API-Scan. + +version: 2 +updates: + # GitHub-Actions-Versionen (gilt für ALLE Repos, auch ohne package.json). + - package-ecosystem: 'github-actions' + directory: '/' + target-branch: 'testing' + schedule: + interval: 'monthly' + open-pull-requests-limit: 5 + commit-message: + prefix: 'ci' + groups: + # Kein update-types-Filter → Major landet mit im Sammel-PR. + actions-all: + patterns: + - '*' + + # NPM/Yarn/PNPM-Abhängigkeiten. + - package-ecosystem: 'npm' + directory: '/' + target-branch: 'testing' + schedule: + interval: 'monthly' + open-pull-requests-limit: 5 + commit-message: + prefix: 'chore' + groups: + # Kein update-types-Filter → Major landet mit im Sammel-PR. + npm-all: + patterns: + - '*' diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 3a0fd02..c5cdb1a 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -4,13 +4,20 @@ on: push: branches: [main, testing] pull_request: - branches: [main] + branches: [main, testing] # Security: Explicitly set minimal permissions permissions: contents: read jobs: + # ============================================================================ + # JOB 0: Workflow-Linting (Issue #445) + # ============================================================================ + actionlint: + name: ⚙️ Workflow Linting + uses: S540d/project-templates/.github/workflows/reusable-actionlint.yml@v2 + # ============================================================================ # JOB 1: Code Quality & Linting # ============================================================================ @@ -82,7 +89,7 @@ jobs: run: npm run validate:svg-counts - name: TypeScript Type Check - run: npx tsc --noEmit || true + run: npx tsc --noEmit # ============================================================================ # JOB 2: Unit Tests & Coverage @@ -196,8 +203,9 @@ jobs: with: node-version: '20' - - name: Run npm audit - run: npm audit --audit-level=high + # Gate mit befristeter Allowlist (.audit-allowlist.json) für Findings ohne Upstream-Fix (#348). + - name: Run npm audit (Gate) + run: node scripts/audit-gate.mjs --level=high - name: Check for sensitive data run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..515a43e --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,53 @@ +name: 'CodeQL' + +# Kostenlose statische Code-Analyse (SAST) via GitHub CodeQL. +# Zusammen mit .github/dependabot.yml der Ersatz für den kostenpflichtigen +# Anthropic-API-Scan. build-mode: none — CodeQL analysiert den Quellcode +# direkt, ohne Autobuild (bei RN-/Expo-Projekten schlägt Autobuild sonst fehl). + +on: + push: + branches: [main] + pull_request: + branches: [main, testing] + schedule: + # Wöchentlicher Full-Scan: fängt neu bekannt gewordene CVEs ohne Code-Änderung. + - cron: '30 5 * * 1' + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + include: + - language: javascript-typescript + build-mode: none + - language: actions + build-mode: none + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: '/language:${{matrix.language}}' diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 01d8c12..61968c0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,7 +38,7 @@ jobs: run: node scripts/update-cache-version.js - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./dist diff --git a/.github/workflows/standards-audit.yml b/.github/workflows/standards-audit.yml index f8832e0..7623fb2 100644 --- a/.github/workflows/standards-audit.yml +++ b/.github/workflows/standards-audit.yml @@ -21,12 +21,12 @@ permissions: jobs: security-scan: - uses: S540d/project-templates/.github/workflows/reusable-security-scan.yml@v1 + uses: S540d/project-templates/.github/workflows/reusable-security-scan.yml@v2 with: fail_on_findings: true gitignore-audit: - uses: S540d/project-templates/.github/workflows/reusable-gitignore-audit.yml@v1 + uses: S540d/project-templates/.github/workflows/reusable-gitignore-audit.yml@v2 with: fail_on_missing: true @@ -35,4 +35,4 @@ jobs: # auf uses:-Jobs nicht erlaubt – die Non-Blocking-Semantik muss daher im Template # bleiben; security-scan und gitignore-audit (fail_on_*: true) gaten den Merge. dev-standards-audit: - uses: S540d/project-templates/.github/workflows/reusable-dev-standards-audit.yml@v1 + uses: S540d/project-templates/.github/workflows/reusable-dev-standards-audit.yml@v2 diff --git a/.gitignore b/.gitignore index 53d392a..214bd19 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,7 @@ yarn-error.log* .claude/CLAUDE.md .claude/settings.json .claude/settings.local.json -.claude/memory/ +.claude/memory.md .claude/todos/ .claude/cache/ .claude/data/ diff --git a/CHANGELOG.md b/CHANGELOG.md index cc64686..81384af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,20 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.9.0] - 2026-11-03 (versionCode 71) + +Änderungen seit der Play-Store-Version 1.8.0 (versionCode 69). + ### Added -- Auffindbarkeit außerhalb des Play Stores: Play-Store-Badge + deutsche Kurzbeschreibung im README, Web-only Install-Banner (`WebInstallBanner`) im sichtbaren Bereich der Startseite, deutsche Keywords/Open-Graph-/JSON-LD-Auszeichnung der Landing Page +- Pause-Vorschlag nach jedem 5. abgeschlossenen Level (5, 10, 15) mit „Hauptmenü" und „Weiter" (#337) +- Impressum und Datenschutz im Über-Dialog der Einstellungen, in allen 7 Sprachen (#330) +- Micro-Animationen auf den Kern-Screens: Press-Feedback auf Kacheln und Buttons, `prefers-reduced-motion`-aware (`PressableScale`, `PulseView`) +- Auffindbarkeit außerhalb des Play Stores: Play-Store-Badge + deutsche Kurzbeschreibung im README, Web-only Install-Hinweis auf der Startseite, deutsche Keywords/Open-Graph-/JSON-LD-Auszeichnung der Landing Page - Attributions-Parameter (`referrer` mit UTM-Tags) an allen Play-Store-Links — Installationen aus der Web-Demo werden in der Play Console als eigene Quelle sichtbar (`constants/ExternalLinks.ts`) - Crawlbarer `