Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-08-29 11:29:12 +02:00
4 changed files with 192 additions and 5 deletions
+77 -2
View File
@@ -1,6 +1,8 @@
# AGENTS.md — Project state, review findings, open items, and working rules # AGENTS.md — Project state, review findings, open items, and working rules
**Last updated: 2026-08-23** (merged the `umsetzung-datametric360` branch — companion app phases **Last updated: 2026-08-29** (iOS signing prepared end to end — device build verified, signature
blocked on a device registration at Apple, see section AI; 2026-08-23: merged the
`umsetzung-datametric360` branch — companion app phases
110 done, see `UMSETZUNGSPLAN.md`; 2026-08-13: cleaned up remaining EU Data Act residue, fixed 110 done, see `UMSETZUNGSPLAN.md`; 2026-08-13: cleaned up remaining EU Data Act residue, fixed
oversized toggle switches, and fixed a desktop-layout audit (settings button / rings logo / popups oversized toggle switches, and fixed a desktop-layout audit (settings button / rings logo / popups
overflowing past the capped content column) — see `DESIGN_AUDIT_2026-08-13.md`; 2026-08-16: fixed overflowing past the capped content column) — see `DESIGN_AUDIT_2026-08-13.md`; 2026-08-16: fixed
@@ -1435,7 +1437,8 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
panel fix and feature from the six days since (HIG audit rounds, receipt upload, trip panel fix and feature from the six days since (HIG audit rounds, receipt upload, trip
editing, Inspektion forecast, ...) existed only in `homeassistant/www/audi-dashboard-app.js`. editing, Inspektion forecast, ...) existed only in `homeassistant/www/audi-dashboard-app.js`.
User decision: port everything now, before any native build work (Android build itself User decision: port everything now, before any native build work (Android build itself
deprioritized/uncertain per the user - Paul has an Apple Developer Program and will help with deprioritized/uncertain per the user - Paul has an Apple Developer Program **[WRONG, see
section AI: it is a free Personal Team, not a paid membership]** and will help with
iOS signing). Audited both codebases field-by-field (not by diffing the panel's CSS/markup, iOS signing). Audited both codebases field-by-field (not by diffing the panel's CSS/markup,
which doesn't transfer to `@audi-dash/ui` components) and found six real, mechanically which doesn't transfer to `@audi-dash/ui` components) and found six real, mechanically
distinct gaps, all fixed: distinct gaps, all fixed:
@@ -4601,6 +4604,78 @@ via log (single `audi_dashboard` loader warning, no traceback).
--- ---
## AI. iOS signing prepared, and the one thing that blocks it (2026-08-29)
Task was: build the iOS app, sign it, commit the result — `UMSETZUNGSPLAN.md` Phase 10 step 7, the
last open item of that phase. **Result: everything except the signature itself is done and
verified; the signature is blocked on a fact about the Apple account, not on this repo.**
What was verified on this machine (Xcode 26.4, Node 22.20, `main` at `2026.8.28.18`):
- `npm run typecheck` clean, `npm test` 146/146 green, `npm run build` clean, `npx cap sync ios`
clean (both plugins found: secure-storage 8.0.0, capgo/updater 8.51.14).
- **Simulator build (Release) succeeds.**
- **Device build (Release, `generic/platform=iOS`, arm64) succeeds** with signing switched off —
8.5 MB `App.app`. So the code, the plugins and the Swift-package graph are all fine on device;
nothing but provisioning is missing.
**The blocker, verbatim from Apple:** `Communication with Apple failed: Your team has no devices
from which to generate a provisioning profile.` The account authenticates fine (Xcode reached Apple
and got a real answer, not an auth error) — team `RMACS9VLS4`, certificate
`Apple Development: paul.nothaft@me.com (C9L892Z59P)`, valid until 2027-07-17. Apple issues a
development profile only for **named devices**, and this team has none registered. No iPhone is
connected (`xcrun devicectl list devices` → none) and no device was ever paired with this Mac (no
`~/Library/Developer/CoreDevice`, no iOS DeviceSupport). There is no route around this from a
machine with no phone attached:
- development / ad-hoc profiles both require registered UDIDs;
- an App-Store-method export needs no devices but produces an IPA that iOS refuses to sideload;
- a locally `codesign`-ed `.app` without an embedded profile will not install either.
**Correction, same day: this is a FREE account, not a paid membership.** Xcode's own cache says so
`defaults read com.apple.dt.Xcode``IDEProvisioningTeamByIdentifier`:
`teamName = "Paul Nothaft (Personal Team)"`, `teamType = "Personal Team"`,
**`isFreeProvisioningTeam = 1`**. The note further up this file claiming "Paul has an Apple
Developer Program" (section on the 2026-08-17 port) is therefore **wrong** and must not be relied
on. Consequences, all confirmed against Apple's membership comparison and the free-provisioning
limits:
- **There is no portal route to register a device.** Certificates, Identifiers & Profiles device
management is a paid-membership feature. A free team registers a device only by having it
**physically connected to this Mac and trusted**; Xcode then does it via
`-allowProvisioningUpdates`. So "add the UDID on the website" is not an option here.
- **Everything expires after 7 days** — provisioning profile, App ID and device registration alike.
The app stops launching and has to be rebuilt and reinstalled, forever, every week.
- Ceilings: 3 devices per platform, 10 App IDs per 7 days.
- Whether `-exportArchive` even yields a usable `.ipa` for a free team is **untested and doubtful**
— free provisioning is built around "Run straight onto the connected device" from Xcode, not
around exporting a redistributable archive. If the export step fails once a phone is attached,
install directly instead of debugging the export.
**What to do (owner):** connect the iPhone by cable, tap "Trust", then run the script below. That
is the only path with this account type. If the weekly re-install turns out to be intolerable, the
paid Apple Developer Program (99 €/year) is what buys the 1-year signature, portal-side UDID
registration without the phone present, and 100 devices — `UMSETZUNGSPLAN.md` Phase 10 already
flagged this as an owner decision, and it is now a decision with a known answer on one side.
**What was built instead of a hand-clicked Xcode signature:** `companion-app/scripts/ios-signieren.sh`
— build → `cap sync` → signed archive → `.ipa` export, one command. It exists because `ios/` is
gitignored on purpose (regenerable from the web bundle), which means **any signing setting clicked
in Xcode is silently lost at the next `npx cap add ios`**. A versioned script is the only place the
team ID can survive. `APPLE_TEAM_ID` overrides it; output lands in `ios/build/App.ipa` (already
covered by the `ios/` ignore, no build artifact enters git). Verified by running it end to end: it
passes build, sync and archive setup and stops exactly at Apple's device requirement, nowhere else.
Deliberately **not** done: committing an unsigned `.ipa` as a stand-in. It is not what was asked
for, it cannot be installed as-is, and a per-build ~6 MB binary would sit in the git history
forever. The OTA path already covers "new UI without Xcode" (section above) — Xcode is only needed
when native code or the signature itself changes.
Phase 10 step 7 therefore stays **unchecked** in `UMSETZUNGSPLAN.md`: the app is not on the phone
yet, and marking it done would be exactly the silent staleness this project keeps designing against.
---
## Working conventions (observed — keep them) ## Working conventions (observed — keep them)
- German is the project language: identifiers, comments, commits, UI texts. Exceptions: - German is the project language: identifiers, comments, commits, UI texts. Exceptions:
+20 -3
View File
@@ -423,6 +423,13 @@ nicht ein Riesencommit.
> echte Daten. `CapacitorHttp` umgeht die CORS-Beschränkung der WebView. > echte Daten. `CapacitorHttp` umgeht die CORS-Beschränkung der WebView.
> Offen bleibt allein das Signieren aufs eigene Gerät — das braucht das > Offen bleibt allein das Signieren aufs eigene Gerät — das braucht das
> angeschlossene iPhone und die Apple-ID des Besitzers. > angeschlossene iPhone und die Apple-ID des Besitzers.
>
> **2026-08-29:** Schritt 7 vorbereitet, aber nicht abschließbar. Der Gerätebau
> (arm64, Release) läuft fehlerfrei durch, das Signieren scheitert
> ausschließlich daran, dass dem Team `RMACS9VLS4` **kein Gerät** bekannt ist:
> Apple erzeugt ein Development-Profil nur für konkrete UDIDs. Der ganze
> Ablauf steckt jetzt in `companion-app/scripts/ios-signieren.sh` und läuft
> bis genau zu diesem Punkt. Details in `AGENTS.md` Abschnitt AI.
**Ziel:** Die App läuft auf dem iPhone. Zwei Stufen — erst PWA (sofort nutzbar), dann Capacitor **Ziel:** Die App läuft auf dem iPhone. Zwei Stufen — erst PWA (sofort nutzbar), dann Capacitor
(Keychain + QR-Scan). (Keychain + QR-Scan).
@@ -449,9 +456,19 @@ nicht ein Riesencommit.
(Offline-JS-QR-Bibliothek, keine Netzabfrage) als QR anzeigt. Inhalt des QR: JSON (Offline-JS-QR-Bibliothek, keine Netzabfrage) als QR anzeigt. Inhalt des QR: JSON
`{"url": "...", "token": "..."}`. Wenn das zusammen > 1 Tag Aufwand wird: weglassen — `{"url": "...", "token": "..."}`. Wenn das zusammen > 1 Tag Aufwand wird: weglassen —
manuelles Einfügen ist die beschlossene, ausreichende Lösung. manuelles Einfügen ist die beschlossene, ausreichende Lösung.
7. **iOS-Sideload:** `npx cap open ios`, in Xcode Signing mit eigener Apple-ID, aufs Gerät bauen. 7. **iOS-Sideload:** statt Xcode von Hand jetzt `bash companion-app/scripts/ios-signieren.sh`
⚠️ Entscheidungspunkt für den Besitzer: mit kostenlosem Apple-Konto läuft die Signatur nach (baut Webbündel, synchronisiert die Hülle, archiviert signiert, exportiert die `.ipa`).
**7 Tagen** ab (App neu aufspielen); ein bezahltes Entwicklerkonto (99 €/Jahr) macht 1 Jahr. Die Team-Kennung steht im Skript, weil `ios/` gitignored ist und jede in Xcode geklickte
Einstellung beim nächsten `npx cap add ios` verschwinden würde.
⚠️ **Voraussetzung, die kein Skript herstellen kann:** das iPhone muss **per Kabel an diesem
Mac hängen und vertraut sein**. Sonst: „Your team has no devices from which to generate a
provisioning profile". Die UDID stattdessen auf developer.apple.com einzutragen geht **nicht** —
das ist ein Recht der bezahlten Mitgliedschaft, und das Konto ist ein kostenloses Personal Team
(`isFreeProvisioningTeam = 1`, belegt 2026-08-29, siehe `AGENTS.md` Abschnitt AI).
⚠️ Entscheidungspunkt für den Besitzer, jetzt mit bekannter Faktenlage: das Konto **ist**
kostenlos, die Signatur läuft also alle **7 Tage** ab (Profil, App-ID und Geräteeintrag
gleichermaßen — App wöchentlich neu aufspielen). Ein bezahltes Entwicklerkonto (99 €/Jahr)
macht daraus 1 Jahr und erlaubt die Geräteregistrierung ohne angeschlossenes Telefon.
Bei 7-Tage-Schmerz ist die PWA-Stufe die Alltagslösung, Capacitor das Extra für Keychain/QR. Bei 7-Tage-Schmerz ist die PWA-Stufe die Alltagslösung, Capacitor das Extra für Keychain/QR.
8. ✅ Fertig wenn: App startet nativ auf dem iPhone, Token liegt im Keychain (Test: App löschen und 8. ✅ Fertig wenn: App startet nativ auf dem iPhone, Token liegt im Keychain (Test: App löschen und
neu installieren → Token weg; Backup/Restore-Verhalten notieren), QR-Einrichtung funktioniert neu installieren → Token weg; Backup/Restore-Verhalten notieren), QR-Einrichtung funktioniert
+6
View File
@@ -76,6 +76,12 @@ dort niemals Markendateien ablegen.
(Keychain/Keystore) ist dagegen bereits vollständig angebunden (Keychain/Keystore) ist dagegen bereits vollständig angebunden
(`src/api/ablageNativ.ts`, von `main.tsx` aktiviert) und wird automatisch (`src/api/ablageNativ.ts`, von `main.tsx` aktiviert) und wird automatisch
aktiv, sobald die Hülle existiert aktiv, sobald die Hülle existiert
- Signierte `.ipa`: `scripts/ios-signieren.sh` baut und signiert in einem
Durchlauf, **sobald das iPhone per Kabel am Mac hängt und vertraut ist**.
Vorher bricht Apple den Profilabruf ab - das ist die einzige verbleibende
Hürde, der Gerätebau selbst läuft fehlerfrei durch. Das Konto ist ein
kostenloses Personal Team: die UDID lässt sich nicht auf developer.apple.com
nachtragen, und die Signatur verfällt alle 7 Tage
- QR-Einrichtung als Alternative zum Einfügen des Tokens - QR-Einrichtung als Alternative zum Einfügen des Tokens
- Live-Ansicht der laufenden Fahrt: gebaut, aber über - Live-Ansicht der laufenden Fahrt: gebaut, aber über
`src/funktionen.ts` abgeschaltet, bis der FMM003 echte Werte liefert `src/funktionen.ts` abgeschaltet, bis der FMM003 echte Werte liefert
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# Baut die native iOS-Huelle und signiert sie zu einer installierbaren .ipa.
# Nur auf einem Mac mit Xcode lauffaehig. Siehe ../../UMSETZUNGSPLAN.md Phase 10.
#
# Warum es dieses Skript gibt: `ios/` ist absichtlich gitignored (aus dem
# Webbuendel jederzeit wiederherstellbar). Damit verschwindet aber auch jede
# Signatureinstellung, die man in Xcode von Hand setzt, beim naechsten
# `npx cap add ios` wieder. Die Team-Kennung gehoert deshalb hierher - in eine
# versionierte Datei - und wird dem Build von aussen mitgegeben.
#
# Voraussetzung, die dieses Skript nicht herstellen kann: das iPhone muss
# per Kabel an diesem Mac haengen und vertraut sein. Apple erzeugt ein
# Development-Profil nur fuer konkrete Geraete, und dieses Konto ist ein
# kostenloses Personal Team - da gibt es keine Geraeteverwaltung auf
# developer.apple.com, das Anmelden der Geraetekennung macht Xcode selbst ueber
# -allowProvisioningUpdates am angeschlossenen Telefon. Ohne Telefon bricht der
# Archivschritt mit "Your team has no devices" ab; das ist kein Fehler im
# Projekt.
#
# Ebenfalls Folge des kostenlosen Kontos: Profil, App-ID und Geraeteeintrag
# verfallen nach 7 Tagen, die App muss dann neu aufgespielt werden.
#
# Ungeprueft, weil bisher kein Geraet zur Verfuegung stand: ob der
# -exportArchive-Schritt mit einem Personal Team ueberhaupt eine brauchbare
# .ipa liefert. Kostenloses Signieren ist auf "direkt aufs angeschlossene
# Geraet starten" ausgelegt, nicht auf ein weitergebbares Archiv. Scheitert der
# Export, ist der direkte Weg der richtige, nicht die Fehlersuche am Export:
# xcodebuild -project ios/App/App.xcodeproj -scheme App \
# -destination 'id=<UDID>' -allowProvisioningUpdates \
# DEVELOPMENT_TEAM=$TEAM install
set -euo pipefail
HIER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP="$(dirname "$HIER")"
TEAM="${APPLE_TEAM_ID:-RMACS9VLS4}"
AUSGABE="$APP/ios/build"
ARCHIV="$AUSGABE/DataMetric360.xcarchive"
cd "$APP"
echo "==> Webbuendel bauen"
npm run build
echo "==> Native Huelle synchronisieren"
if [ ! -d ios ]; then
echo "==> ios/ fehlt, wird neu erzeugt"
npx cap add ios
fi
npx cap sync ios
echo "==> Archiv bauen und signieren (Team $TEAM)"
rm -rf "$AUSGABE"
mkdir -p "$AUSGABE"
xcodebuild \
-project ios/App/App.xcodeproj \
-scheme App \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath "$ARCHIV" \
-allowProvisioningUpdates \
DEVELOPMENT_TEAM="$TEAM" \
archive
# Die Exportart heisst seit Xcode 16 offiziell "debugging"; "development" ist
# weiterhin als Synonym gueltig und funktioniert auch mit aelteren Xcode-
# Versionen, deshalb bleibt es hier stehen.
cat > "$AUSGABE/ExportOptions.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key><string>development</string>
<key>teamID</key><string>$TEAM</string>
<key>signingStyle</key><string>automatic</string>
<key>stripSwiftSymbols</key><true/>
</dict>
</plist>
PLIST
echo "==> .ipa exportieren"
xcodebuild -exportArchive \
-archivePath "$ARCHIV" \
-exportOptionsPlist "$AUSGABE/ExportOptions.plist" \
-exportPath "$AUSGABE" \
-allowProvisioningUpdates
echo
echo "Fertig: $AUSGABE/App.ipa"
echo "Aufs Geraet: xcrun devicectl device install app --device <UDID> $AUSGABE/App.ipa"