Read-only PRD for a coding agent
Keine einfache, allein nutzbare Web-App, um bereiste Länder auf einer 3D-Erdkugel zu…
1. Problem, goal & success metric
Problem: Keine einfache, allein nutzbare Web-App, um bereiste Länder auf einer 3D-Erdkugel zu verfolgen. Goal: Eine eigenständige Reise-Tracker-Web-App im Browser (Handy und Computer) mit drehbarer 3D-Erdkugel, allen 204 Ländern mit echter Hauptstadt und Einwohnerzahl (aus einer statischen JSON-Datei, keine erfundenen Fakten), Markierung besuchter Länder als grüne Fläche oder Stecknadel, Detail-Kachel mit Notiz/Bewertung/Datum/Favorit, Suche, gespeicherte Orte, Fortschrittsbalken als Prozent der besuchten Länder von 204. Success metric: Nutzer öffnet die App, sieht alle 204 Länder auf der Kugel, klickt ein Land an, speichert Notiz/Bewertung/Datum, sucht einen Ort, sieht den Fortschrittsbalken als Prozentsatz der besuchten Länder von 204 – alles ohne Konto und Server.
2. Users & roles
Ein einzelner Nutzer (Besitzer). Keine Rollen, keine Registrierung, keine Multi-User-Funktionen. Alle Daten gehören diesem einen Nutzer und werden nur auf seinem Gerät gespeichert (LocalStorage oder IndexedDB).
3. Core workflows
- App öffnen → drehbare 3D-Erdkugel mit allen 204 Ländern laden.
- Land/Ort/Spot anklicken → Detail-Kachel mit Fakten (Hauptstadt, Einwohnerzahl, historische/kulturelle Infos), Notiz-Feld, Sternebewertung 1–5, Besuchsdatum-Felder, Favoriten-Schalter.
- Änderungen speichern → lokal auf dem Gerät speichern, Kachel schließt sich oder bleibt offen.
- Ort suchen → Suchleiste oben, Trefferliste, Klick öffnet Detail-Kachel.
- Gespeicherte Orte aufrufen → Liste aller Orte mit Notizen/Bewertungen, Klick öffnet Detail-Kachel.
- Fortschritt prüfen → Fortschrittsbalken oben zeigt Prozentsatz der besuchten Länder von 204.
4. Features & requirements
Features & requirements (must-haves):
- Globe view: 3D-Erdkugel mit Globe.gl, drehbar per Drag/Maus und Touch, alle 204 Länder sichtbar und klickbar, besuchte Länder als grüne Fläche passend zur Landfläche oder als Stecknadel kenntlich gemacht.
- Detail tile: Beim Anklicken öffnet sich eine Kachel über dem Globus mit echten Fakten (Hauptstadt, Einwohnerzahl, historische/kulturelle Infos), freiem Text für Notizen, Sternebewertung 1–5, einem oder mehreren Besuchsdaten und einem Favoriten-Schalter. Speichern- und Schließen-Button.
- Save locally: Alle Änderungen (Notiz, Bewertung, Datum, Favorit, besucht/nicht besucht) nur im Browser des Nutzers gespeichert (LocalStorage oder IndexedDB), kein Server, kein Konto.
- Search: Suchleiste oben, durchsucht alle 204 Länder und gespeicherte Orte, klickbare Trefferliste, Klick öffnet Detail-Kachel.
- Saved places: Liste aller gespeicherten Orte, sortierbar nach Name oder Datum, Klick öffnet Detail-Kachel.
- Progress bar: Oben angezeigt, berechnet als (besuchte Länder ÷ 204) × 100, visueller Balken plus Prozentzahl, aktualisiert sich sofort nach Speichern.
- Country facts: Echte Hauptstadt und Einwohnerzahl für alle 204 Länder aus einer mitgelieferten statischen JSON-Datei, keine erfundenen Daten.
5. Scope: must / later / never
- Scope:
- Must: oben genannte sieben Features, lokaler Speicher, responsive Bedienung auf Handy und Computer, kostenloses Hosting auf Vercel/Netlify.
- Later: Export/Import von Daten als JSON, mehrere Reisen/Tagebücher, Fotos zu Orten, Offline-Nutzung (PWA), Länder ohne feste Hauptstadt.
- Never: Multi-User, Konto/Registrierung, Synchronisation zwischen Geräten, Backend-Server, Bezahlfunktionen, Werbung, Social Sharing.
6. Screens & UI
- Main globe view: drehbare 3D-Erdkugel im Vollbild, Fortschrittsbalken oben, Suchleiste oben, Favoriten-/Liste-Button, alle 204 Länder als klickbare Flächen, besuchte Länder als grüne Fläche oder Stecknadel (siehe images/screenshot-1.jpg).
- Detail tile (overlay): öffnet sich über dem Globus bei Klick auf Land/Ort/Spot; zeigt Fakten, Notiz-Feld, Sternebewertung, Besuchsdatum, Favoriten-Schalter, Speichern- und Schließen-Button (siehe images/screenshot-2.jpg).
- Saved places list: zeigt alle gespeicherten Orte mit kurzer Info und Bewertung, Klick öffnet Detail-Kachel.
7. Design system & visual style
Component library: keine externen UI-Komponenten; reines Vanilla JS mit DOM-Elementen und CSS.
- Colors: Hintergrund #0a0a0a, Text #e5e5e5, Sekundärtext #94a3b8, Akzent/besucht/grün #22c55e, Suchleiste-Hintergrund #1a1a1a, Suchleiste-Text #e5e5e5, Buttons #e5e5e5 auf #0a0a0a, Border #334155.
- Font: System-Schrift (Inter oder system-ui, sans-serif).
- Corner radius: 12 px für Kacheln, 8 px für Buttons und Suchleiste.
- Spacing: 16 px Grundraster, 24 px bei Kacheln und Listen.
- Light/dark mode: nur Dark Mode.
- Look & feel: dunkle Web-App wie die beigefügten Screens (images/screenshot-1.jpg zeigt den Globus mit Suchleiste oben, images/screenshot-2.jpg zeigt die Detail-Kachel mit Notizen, Datum, Bewertung und Tags).
Default: UI-Komponenten, Schriftart, Corner-Radius, Spacing, Look & feel. The user already gave colors and dark mode.
8. Data model
- Add a markdown table per entity: a header line "| field | type | required |", then one line per field
- 7158 characters is too long for small coding models: cut it under 2500, in short bullets without repeats
Entity: countries (statische JSON-Datei, mitgeliefert)
- iso_code (string, required)
- name (string, required)
- capital (string, required)
- population (integer, required)
- lat (number, required)
- lng (number, required)
- region (string, optional)
- geo_json (string, optional, für Länderkonturen/grüne Fläche)
Entity: visits (lokal im Browser, LocalStorage/IndexedDB, Schlüssel 'traveltracker_visits')
- iso_code (string, required, verweist auf countries.iso_code)
- visited (boolean, required, default false)
- notes (string, optional, default '')
- rating (integer, optional, 1–5, default null)
- visit_dates (array of ISO-date strings, optional, default [])
- favorite (boolean, required, default false)
- updated_at (ISO-date string, required)
- Default: LocalStorage als Speicherort, Schlüsselname, Feldnamen, Feldtypen.
- Default: Länder-JSON-Quelle (der Coding Agent nutzt eine öffentlich verfügbare REST-Countries-Exportdatei mit 204 Ländern, Hauptstadt und Einwohnerzahl und legt sie als public/countries.json ins Projekt).
Screens & UI:
- Detail tile (overlay): öffnet sich über dem Globus bei Klick auf Land/Ort/Spot; zeigt oben den Namen und Kürzel (z. B. Liechtenstein · LI), darunter Notiz-Feld, Besuchsdatum (Von / Bis optional), Sternebewertung 1–5, Tags-Feld, einen Button '+ Lieblingsspot hinzufügen', unten links einen 'Abbrechen'-Button und unten rechts einen 'Speichern'-Button sowie einen roten 'Markierung entfernen'-Button (siehe images/screenshot-3.jpg).
- stack: Framework: Vanilla JavaScript mit Vite (Build-Tool, dev-Server, Production-Build).
- 3D-Globus: globe.gl (basiert auf Three.js), für drehbaren Globus, Länderflächen und Marker.
- Länder-Daten: statische JSON-Datei im Projektverzeichnis (public/countries.json), mitgeliefert mit der App, keine externe API.
- Lokaler Speicher: LocalStorage (Schlüssel 'traveltracker_visits'), Fallback IndexedDB nur wenn LocalStorage nicht verfügbar.
- Hosting: statische Seite auf Vercel oder Netlify (kostenloser Tier, kein Server, keine Build-Schritte außer Vite).
- Keine separaten Dienste: keine API-Server, keine Datenbank, keine Queues, keine Caches, keine Kubernetes, keine Mikroservices.
Default: Stack, Build-Tool, Hosting-Anbieter, Speicherlösung.
existing_code: Not needed: Greenfield-Projekt, es gibt keinen bestehenden Code, den der Coding Agent beachten oder nicht ändern darf.
Default: Kein vorhandener code.
- build_order: Slice 1 – Projekt-Gerüst und Globus: Vite-Projekt anlegen, globe.gl einbinden, statische Länder-JSON laden, 3D-Erdkugel mit allen 204 Ländern rendern, per Drag/Maus und Touch drehbar machen, Ladefehler der JSON abfangen ('Länderdaten konnten nicht geladen werden'). Ergebnis: lauffähige leere Kugel.
- Slice 2 – Interaktion und Detail-Kachel: Länder klickbar machen (Fläche und Name auf der Fläche), Overlay-Detail-Kachel öffnen mit Fakten (Name, Kürzel, Hauptstadt, Einwohnerzahl), Notiz-Feld, Besuchsdatum (Von/Bis), Sternebewertung 1–5, Tags, Button '+ Lieblingsspot hinzufügen', unten links 'Abbrechen', unten rechts 'Speichern' und roten 'Markierung entfernen'-Button. Ergebnis: Klick auf Land öffnet Kachel.
- Slice 3 – Lokaler Speicher und Fortschritt: Kachel-Daten im LocalStorage speichern/laden, besuchte Länder als grüne Fläche oder Stecknadel markieren, Fortschrittsbalken (besuchte ÷ 204 × 100) oben anzeigen und sofort aktualisieren. Ergebnis: Daten überleben Seiten-Refresh.
- Slice 4 – Suche und gespeicherte Orte: Suchleiste oben (durchsucht alle 204 Länder und gespeicherte Orte, Trefferliste, Klick öffnet Kachel), Liste aller gespeicherten Orte (sortierbar nach Name oder Datum). Ergebnis: Suche und Liste funktionieren.
- Slice 5 – Qualität und Deployment: Tastaturbedienung und Fokus-Ränder, WCAG-AA-Kontraste, Performance (Kugel lädt unter 3 Sekunden), Fehlerbehandlung bei vollem LocalStorage ('Speicher nicht verfügbar'), Build auf Vercel/Netlify deployen und auf Handy + Computer testen. Ergebnis: fertige, gehostete Web-App.
Default: Fünf Slices in dieser Reihenfolge, jeder lauffähig allein.
acceptance: 1. App öffnet im Browser auf Handy und Computer, die 3D-Erdkugel mit allen 204 Ländern ist sichtbar und drehbar.
- Klick auf eine Landesfläche oder den darauf stehenden Namen öffnet die Detail-Kachel mit echter Hauptstadt und Einwohnerzahl aus der JSON-Datei.
- Notiz, Sternebewertung (1–5), Besuchsdatum (Von/Bis), Tags und Lieblingsspot können eingetragen und gespeichert werden; nach Refresh sind die Daten noch da.
- Unten links in der Kachel ist ein 'Abbrechen'-Button, unten rechts ein 'Speichern'-Button und ein roter 'Markierung entfernen'-Button.
- Besuchte Länder werden als grüne Fläche oder Stecknadel auf der Kugel markiert.
- Fortschrittsbalken zeigt (besuchte Länder ÷ 204) × 100 als Balken plus Prozentzahl und aktualisiert sich sofort nach Speichern.
- Suchleiste findet Länder und gespeicherte Orte; Trefferliste ist klickbar und öffnet die Detail-Kachel.
- Liste der gespeicherten Orte ist sortierbar nach Name oder Datum.
- Keine Daten verlassen das Gerät; alles bleibt in LocalStorage.
- Bei vollem LocalStorage zeigt die App 'Speicher nicht verfügbar' und erlaubt weiterhin Betrachten (Speichern deaktiviert).
- Bei nicht-ladbarer JSON zeigt die App 'Länderdaten konnten nicht geladen werden'.
Default: Diese elf Tests als Abnahmekriterien.
- deployment: Hosting: statische Seite auf Vercel oder Netlify (kostenloser Tier).
- Build:
vite builderzeugt statische Dateien (dist/), die über den Host bereitgestellt werden. - Environments: nur Production (keine separate Staging-Umgebung nötig für Einzelnutzer-Tool).
- Secrets: keine (keine API-Keys, keine Datenbank-Zugangsdaten, kein Backend).
- Domain: kostenlose Subdomain des Hosts (z. B. name.vercel.app oder name.netlify.app).
- CI/CD: automatischer Build und Deploy bei Push ins Git-Repository (Vercel/Netlify integriert).
Default: Vercel als Host, kostenlose Subdomain, keine Staging-Umgebung, keine Secrets.
- open_questions: Default: UI-Komponenten, Schriftart, Corner-Radius, Spacing, Look & feel (dunkles Design, Hintergrund #0a0a0a, Text #e5e5e5, Akzent #22c55e, Suchleiste #1a1a1a, System-Schrift, 12px Kacheln, 8px Buttons, 16px Raster).
- Default: LocalStorage als Speicherort, Schlüsselname 'traveltracker_visits', Feldnamen, Feldtypen.
- Default: Keine Integrationen.
- Default: Kein Auth.
- Default: Kein PWA, normale Web-App im Browser.
- Default: Fünf Build-Slices in der beschriebenen Reihenfolge.
- Default: Die elf Abnahmetests oben.
- Default: Vercel als Host, kostenlose Subdomain, keine Staging-Umgebung, keine Secrets.
- Default: Länder-JSON-Quelle (der Coding Agent nutzt eine öffentlich verfügbare REST-Countries-Exportdatei mit 204 Ländern, Hauptstadt und Einwohnerzahl und legt sie als public/countries.json ins Projekt).
- Default: Der '+ Lieblingsspot hinzufügen'-Button fügt den Ort zu den gespeicherten Orten hinzu; 'Markierung entfernen' setzt visited=false und löscht die Markierung auf der Kugel.
- Default: Detail-Kachel zeigt '--' statt Hauptstadt, wenn ein Land keine feste Hauptstadt hat.
- Default: Datumsfelder akzeptieren ISO-Format; 'Von' ist erforderlich, 'Bis' optional.
- Default: Tags sind ein freies Textfeld, kommagetrennt.
9. APIs & integrations
Not needed: keine externen APIs, kein Backend, keine Drittdienste. Alle 204 Länder kommen aus einer statischen JSON-Datei, die mit der App ausgeliefert wird.
Default: Keine Integrationen.
10. Auth, permissions & security
Not needed: keine Registrierung, kein Login, kein Multi-User. Es gibt einen einzigen Besitzer (den Nutzer am Gerät) und keine Berechtigungen.
Default: Kein Auth.
11. Performance, privacy & accessibility
- Performance: die 3D-Erdkugel mit allen 204 Ländern lädt in unter 3 Sekunden auf einem mittleren Smartphone; der Fortschrittsbalken aktualisiert sich sofort nach dem Speichern.
- Privacy: alle Daten (Notizen, Bewertungen, Daten, Favoriten, besucht/nicht besucht) bleiben im LocalStorage/IndexedDB des Browsers; nichts verlässt das Gerät.
- Accessibility: Suchleiste und Buttons sind per Tastatur bedienbar; alle interaktiven Elemente haben sichtbare Fokus-Ränder; Kontraste mindestens WCAG AA (weißer Text #e5e5e5 auf #0a0a0a, grün #22c55e auf #0a0a0a).
12. Edge cases & errors
- Leerer LocalStorage beim ersten Besuch: Fortschritt 0 %, keine gespeicherten Orte, Kachel zeigt nur Länderfakten.
- Land ohne feste Hauptstadt: Detail-Kachel zeigt '--' statt Hauptstadt.
- Ungültige Suchbegriffe: Trefferliste leer, Hinweis 'Keine Treffer'.
- LocalStorage voll/verweigert: App zeigt Fehlermeldung 'Speicher nicht verfügbar' und lässt dennoch das Anklicken und Betrachten zu (Speichern deaktiviert).
- JSON-Datei nicht ladbar: App zeigt 'Länderdaten konnten nicht geladen werden' statt einer leeren Kugel.
- Touch-Geräte: Drag zum Drehen der Kugel und Tippen zum Auswählen funktionieren wie Maus-Klick.
13. Stack & constraints
- Framework: Vanilla JavaScript mit Vite (Build-Tool, dev-Server, Production-Build).
- 3D-Globus: globe.gl (basiert auf Three.js), für drehbaren Globus, Länderflächen und Marker.
- Länder-Daten: statische JSON-Datei im Projektverzeichnis (public/countries.json), mitgeliefert mit der App, keine externe API.
- Lokaler Speicher: LocalStorage (Schlüssel 'traveltracker_visits'), Fallback IndexedDB nur wenn LocalStorage nicht verfügbar.
- Hosting: statische Seite auf Vercel oder Netlify (kostenloser Tier, kein Server, keine Build-Schritte außer Vite).
- Keine separaten Dienste: keine API-Server, keine Datenbank, keine Queues, keine Caches, keine Kubernetes, keine Mikroservices.
Default: Stack, Build-Tool, Hosting-Anbieter, Speicherlösung.
14. Existing code & do-not-change
Not needed: Greenfield-Projekt, es gibt keinen bestehenden Code, den der Coding Agent beachten oder nicht ändern darf.
Default: Kein vorhandener Code.
15. Build order
- Slice 1 – Projekt-Gerüst und Globus: Vite-Projekt anlegen, globe.gl einbinden, statische Länder-JSON laden, 3D-Erdkugel mit allen 204 Ländern rendern, per Drag/Maus und Touch drehbar machen, Ladefehler der JSON abfangen ('Länderdaten konnten nicht geladen werden'). Ergebnis: lauffähige leere Kugel.
- Slice 2 – Interaktion und Detail-Kachel: Länder klickbar machen, Overlay-Detail-Kachel öffnen (Fakten: Hauptstadt, Einwohnerzahl; Notiz-Feld, Sternebewertung 1–5, Besuchsdatum, Favoriten-Schalter, Speichern-/Schließen-Button). Ergebnis: Klick auf Land öffnet Kachel.
- Slice 3 – Lokaler Speicher und Fortschritt: Kachel-Daten im LocalStorage speichern/laden, besuchte Länder als grüne Fläche oder Stecknadel markieren, Fortschrittsbalken (besuchte ÷ 204 × 100) oben anzeigen und sofort aktualisieren. Ergebnis: Daten überleben Seiten-Refresh.
- Slice 4 – Suche und gespeicherte Orte: Suchleiste oben (durchsucht alle 204 Länder und gespeicherte Orte, Trefferliste, Klick öffnet Kachel), Liste aller gespeicherten Orte (sortierbar nach Name oder Datum). Ergebnis: Suche und Liste funktionieren.
- Slice 5 – Qualität und Deployment: Tastaturbedienung und Fokus-Ränder, WCAG-AA-Kontraste, Performance (Kugel lädt unter 3 Sekunden), Fehlerbehandlung bei vollem LocalStorage ('Speicher nicht verfügbar'), Build auf Vercel/Netlify deployen und auf Handy + Computer testen. Ergebnis: fertige, gehostete Web-App.
Default: Fünf Slices in dieser Reihenfolge, jeder lauffähig allein.
16. Acceptance criteria & tests
- App öffnet im Browser auf Handy und Computer, die 3D-Erdkugel mit allen 204 Ländern ist sichtbar und drehbar.
- Klick auf ein Land öffnet die Detail-Kachel mit echter Hauptstadt und Einwohnerzahl aus der JSON-Datei.
- Notiz, Sternebewertung (1–5), Besuchsdatum und Favorit können eingetragen und gespeichert werden; nach Refresh sind die Daten noch da.
- Besuchte Länder werden als grüne Fläche oder Stecknadel auf der Kugel markiert.
- Fortschrittsbalken zeigt (besuchte Länder ÷ 204) × 100 als Balken plus Prozentzahl und aktualisiert sich sofort nach Speichern.
- Suchleiste findet Länder und gespeicherte Orte; Trefferliste ist klickbar und öffnet die Detail-Kachel.
- Liste der gespeicherten Orte ist sortierbar nach Name oder Datum.
- Keine Daten verlassen das Gerät; alles bleibt in LocalStorage.
- Bei vollem LocalStorage zeigt die App 'Speicher nicht verfügbar' und erlaubt weiterhin Betrachten (Speichern deaktiviert).
- Bei nicht-ladbarer JSON zeigt die App 'Länderdaten konnten nicht geladen werden'.
Default: Diese zehn Tests als Abnahmekriterien.
17. Deployment, environments & secrets
- Hosting: statische Seite auf Vercel oder Netlify (kostenloser Tier).
- Build:
vite builderzeugt statische Dateien (dist/), die über den Host bereitgestellt werden. - Environments: nur Production (keine separate Staging-Umgebung nötig für Einzelnutzer-Tool).
- Secrets: keine (keine API-Keys, keine Datenbank-Zugangsdaten, kein Backend).
- Domain: kostenlose Subdomain des Hosts (z. B. name.vercel.app oder name.netlify.app).
- CI/CD: automatischer Build und Deploy bei Push ins Git-Repository (Vercel/Netlify integriert).
Default: Vercel als Host, kostenlose Subdomain, keine Staging-Umgebung, keine Secrets.
18. Open questions & assumptions
- Default: Länder-JSON-Quelle (der Coding Agent nutzt eine öffentlich verfügbare REST-Countries-Exportdatei mit 204 Ländern, Hauptstadt und Einwohnerzahl und legt sie als public/countries.json ins Projekt).
- Default: UI-Komponenten, Schriftart, Corner-Radius, Spacing, Look & feel (dunkles Design, Hintergrund #0a0a0a, Text #e5e5e5, Akzent #22c55e, Suchleiste #1a1a1a, System-Schrift, 12px Kacheln, 8px Buttons, 16px Raster).
- Default: LocalStorage als Speicherort, Schlüsselname 'traveltracker_visits', Feldnamen, Feldtypen.
- Default: Keine Integrationen.
- Default: Kein Auth.
- Default: Kein PWA, normale Web-App im Browser.
- Default: Fünf Build-Slices in der beschriebenen Reihenfolge.
- Default: Die zehn Abnahmetests oben.
- Default: Vercel als Host, kostenlose Subdomain, keine Staging-Umgebung, keine Secrets.