Record that downloads fill the Cache and ship the built app.

A failed open can repair the shell, and the installed PWA matches Ziele, Einstellungen, and the view download.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-09 08:55:43 +02:00
co-authored by Cursor
parent 2f1fab202e
commit 3a49d52681
36 changed files with 1801 additions and 24 deletions
@@ -0,0 +1,26 @@
# 01: Mehrere Ziele behalten
**What to build:** The person types Koordinaten as Gitter, Rechtswert, and Hochwert. Each valid Koordinate adds a Ziel instead of replacing the previous one. The Ziele are red points, listed newest first, and each row shows that Koordinate. When a Standort is known, the Entfernung to that Ziel follows the Koordinate, in metres below 1000 m and in kilometres from 1000 m, and it updates as the Standort moves. Adding a Ziel, or tapping its row, centers it at 1:25,000. Auf Ziel is gone. Auf Standort stays. Löschen on a row removes that Ziel and does not move the view. The list remains on the device until each Ziel is deleted. Deleting the whole Cache leaves the Ziele in place.
**Blocked by:** None (can start immediately).
**Status:** ready-for-agent
The session contract in the spec is the seam. This ticket owns `enterKoordinate`, `deleteZiel`, `centerOnZiel`, `ziele` on the snapshot, Entfernung per Ziel, and remembered `ziele`. `deleteCache` already exists and must leave those Ziele in place. A repeated Koordinate uses the notice `Diese Koordinate ist schon ein Ziel.`
- [x] The Ziele section offers Gitter, Rechtswert, and Hochwert, and Gitter starts as `32U MA`.
- [x] A valid Koordinate adds a red Ziel. A second Koordinate adds another. The newest stands at the top of the list.
- [x] Each row shows that Ziel's Koordinate. When a Standort is known, the Entfernung follows it, in metres below 1000 m and in kilometres from 1000 m, and it updates as the Standort moves. With no Standort, the row shows only the Koordinate.
- [x] Adding a Ziel centers the view on it at 1:25,000, even while its Kacheln are blank. Tapping the row centers that Ziel the same way.
- [x] Auf Standort remains. There is no Auf Ziel control.
- [x] Löschen on a row removes that Ziel without asking and does not move the view.
- [x] The same Koordinate cannot be added twice. A repeat is explained in German and leaves the list and the view unchanged.
- [x] An invalid Koordinate, or one that no Blatt covers, is explained in German and leaves the list and the view unchanged.
- [x] The typed Gitter, Rechtswert, and Hochwert stay visible after a successful entry.
- [x] Leaving or reloading the page keeps the Ziele. The Standort is not stored.
- [x] A late first Standort, after a pan or an added Ziel, moves only the blue mark.
- [x] Deleting the whole Cache leaves the Ziele in place.
## Comments
The screen offers the Koordinate fields in Ziele, lists every Ziel newest first, and centers the one just added or the row that was tapped. A rejected Koordinate changes nothing. A new session keeps the Ziele and drops the Standort.
@@ -0,0 +1,20 @@
# 02: Ein Ziel auf der Karte setzen oder löschen
**What to build:** A tap on the Karte deletes the nearest Ziel when one lies within 44 px, and otherwise adds a Ziel at that point. The new Ziel is written as a Koordinate to the metre, appears at the top of the list, and the view stays where it is. A tap on the Standort adds a Ziel there when no Ziel is within 44 px. A tap that no Blatt covers changes nothing. Dragging still pans the Karte. This works without a separate mode.
**Blocked by:** 01: Mehrere Ziele behalten
**Status:** ready-for-agent
The session contract in the spec is the seam. This ticket owns `tap(point)`. Near means within 44 screen pixels at the current scale, inclusive. A repeated Koordinate uses the same notice as a typed repeat. A point no Blatt covers does not set a notice.
- [x] A tap within 44 px of a Ziel deletes the nearest one, at every scale. When two Ziele are equally near, the newer one is deleted.
- [x] A tap farther than 44 px from every Ziel adds a Ziel at that point, as a Koordinate to the metre, at the top of the list, and does not move the view.
- [x] A tap on the Standort adds a Ziel there when no Ziel is within 44 px.
- [x] A tap on a point that no Blatt covers leaves the list and the view unchanged.
- [x] A repeated Koordinate from a tap is treated like a repeated typed Koordinate: the list and the view stay unchanged.
- [x] Dragging pans the Karte. There is no separate mode for setting or deleting a Ziel.
## Comments
The person taps the Karte to add a red Ziel or to remove the one under the finger. The list from 01 gains or loses that row, and the view stays put.
@@ -0,0 +1,24 @@
# 03: Downloads füllen den Cache
**What to build:** Einstellungen replace the Cache section and start collapsed. Inside, Hessen herunterladen stays those words. It is red while any Kachel of Hessen is missing from the Cache, and disabled once every one of them is stored. Starting it fetches only the missing Kacheln, at every prepared scale, the current scale first. A second press while that fill is running adds nothing. Closing the app stops the fill. Opening the app does not continue it. Pressing again fetches what is still missing. While the app stays open, losing the network pauses the fill and regaining it continues it. Looking around still fetches only the current view at the current scale. Ganzen Cache löschen asks first, then removes every Kachel and does not start a fetch. There is no Hessen entfernen.
**Blocked by:** None (can start immediately).
**Status:** ready-for-agent
The session contract in the spec is the seam. This ticket owns `startHessen`, `hessen` and `visit` on the snapshot, the shared queue, pause on offline, and stop on close. `deleteCache` drops Kacheln and the visit fills, does not itself start a fetch, and leaves Ziele and the checkbox. There is no `removeGebiet` and no heruntergeladen mark. The screen copy for a running fill is `Kacheln: ${arrived} von ${total}`.
- [x] Einstellungen replace the Cache section and start collapsed. Hessen herunterladen and Ganzen Cache löschen are inside it.
- [x] Hessen herunterladen keeps that label. It is red while any Kachel of Hessen is missing, and disabled, and shown as disabled, once every Kachel of Hessen is in the Cache.
- [x] Starting Hessen fetches only missing Kacheln of Hessen, at every prepared scale from 1.25 m per pixel up to the 36 km span. Kacheln of the current scale arrive first.
- [x] A second press of Hessen herunterladen, while that fill is running, adds nothing further.
- [x] While the fill runs, Einstellungen show how many of the Kacheln requested in this visit have arrived. Kacheln already in the Cache stay usable.
- [x] Losing the network while the app stays open pauses the fill. Regaining the network continues it. No fetch runs while the device is offline.
- [x] Leaving the app stops the fill. Opening the app does not continue it, and shows no leftover progress. Pressing Hessen herunterladen again fetches only the Kacheln still missing.
- [x] Looking around, while online and the app is open, fetches only the missing Kacheln of the current view at the current scale.
- [x] The app does not mark a Gebiet heruntergeladen, and it offers no Hessen entfernen.
- [x] Ganzen Cache löschen asks "Den ganzen Cache löschen?" first. Declining leaves the Cache unchanged. Accepting removes every Kachel, does not start a fetch, and makes Hessen herunterladen red and active again.
## Comments
The person starts Hessen from Einstellungen. Finished Kacheln stay in the Cache. The fill does not resume on its own, and the only way to drop Kacheln is to delete the whole Cache after confirming.
@@ -0,0 +1,22 @@
# 04: Die aktuelle Ansicht herunterladen
**What to build:** The first control in Einstellungen is a checkbox labelled Download-Knopf. It starts off, and the device remembers it. While it is on, a download control sits at the bottom right of the Karte, including when Einstellungen are collapsed. Pressing it fetches every missing Kachel that intersects the view at that moment, at every prepared scale. The set stays fixed if the person then pans. Hessen and this fill share one queue, and Kacheln of the current scale go first. A second press of the same control, while that fill is running, adds nothing. Deleting the whole Cache leaves the checkbox as it was.
**Blocked by:** 03: Downloads füllen den Cache
**Status:** ready-for-agent
The session contract in the spec is the seam. This ticket owns `setDownloadKnopf`, `downloadView`, and remembered `downloadKnopf`. The control on the Karte is labelled Diese Ansicht herunterladen. It shares the queue and the `visit` counts with Hessen.
- [x] The first control in Einstellungen is a checkbox labelled Download-Knopf. The first time, it is off. After that, the device remembers it across leaving and reopening.
- [x] While the checkbox is on, a download control sits at the bottom right of the Karte. It stays there when Einstellungen are collapsed, and it is hidden when the checkbox is off.
- [x] Pressing it fetches every missing Kachel that intersects the view at the moment of the press, at every prepared scale. A view zoomed out to the 36 km span includes the finer Kacheln inside it.
- [x] Panning or zooming after the press does not add Kacheln to that request. Kacheln already in the Cache are skipped. A press that finds nothing missing fetches nothing.
- [x] A second press of that same control, while its fill is running, adds nothing further. Pressing Hessen herunterladen while the view fill runs adds Hessen's missing Kacheln on the same queue.
- [x] The two fills share one queue. Kacheln of the current scale of the current view are fetched before the rest. Einstellungen show how many of the Kacheln requested in this visit have arrived.
- [x] Closing the app stops the view fill. Opening the app does not continue it. Pressing the control again fetches what is still missing.
- [x] Deleting the whole Cache leaves the Download-Knopf checkbox as it was.
## Comments
The person turns on Download-Knopf, presses the control on the Karte, and the visible view is fetched at every prepared scale. The fill follows the same pause, stop, and Cache rules as Hessen.