Skip to content

Bootstrap ObservationTracker: full project structure, web SPA, and docs - #1

Draft
abbysko with Copilot wants to merge 2 commits into
mainfrom
copilot/observation-tracker-ios
Draft

Bootstrap ObservationTracker: full project structure, web SPA, and docs#1
abbysko with Copilot wants to merge 2 commits into
mainfrom
copilot/observation-tracker-ios

Conversation

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown

Implements the complete repository layout described in the project spec — previously only README.md existed.

Documentation (docs/)

11 spec files: Vision, Requirements, Architecture, UX, DesignSystem, DataModel, Repository, CodingStandards, Milestones, DecisionLog, AIInstructions.

Web SPA (web/)

Offline-first nature-observation tracker in vanilla JS ES2020+ — no build step, opens directly as file://.

Layer Key files
Models Observation.js (factory + update), Category.js (lazy JSON loader)
Repository ObservationRepository.js — localStorage CRUD
Services ObservationService.js (list/filter/stats), LocationService.js (GPS + Nominatim reverse-geocode), ExportService.js (JSON export/import)
Screens Home, LogObservation, MyObservations, Map (Leaflet CDN), Stats (Chart.js CDN)
Components NavBar, ObservationCard, ObservationModal, FilterBar, Toast, ConfirmDialog
Utils date.js, validation.js, format.js (pure helpers)
Data categories.json (8 categories), species.json (~150 species for autocomplete)

Hash-based router in app.js maps #/home, #/log, #/observations, #/map, #/stats to screen modules.

iOS placeholder (ios/)

README.md stub documenting the planned Swift/SwiftUI stack for Milestone 4.

Security

CodeQL flagged 5 XSS paths in the initial pass; all resolved:

  • ConfirmDialog — replaced innerHTML interpolation of caller-supplied title/message with textContent assignment after DOM construction (prevents obs.species from localStorage reaching innerHTML unescaped)
  • ObservationCard / ObservationModal / LogObservationScreenobs.count was interpolated as-is; now coerced via escapeHtml(String(obs.count))
  • ObservationModalphotoDataUrl moved out of the HTML template string; set via element.src = obs.photoDataUrl after render to prevent attribute-injection
Original prompt

ObservationTracker/

├── README.md
├── LICENSE
├── .gitignore

├── docs/
│ ├── Vision.md
│ ├── Requirements.md
│ ├── Architecture.md
│ ├── UX.md
│ ├── DesignSystem.md
│ ├── DataModel.md
│ ├── Repository.md
│ ├── CodingStandards.md
│ ├── Milestones.md
│ ├── DecisionLog.md
│ └── AIInstructions.md

├── web/
│ ├── index.html
│ ├── styles.css
│ ├── app.js
│ ├── components/
│ ├── screens/
│ ├── services/
│ ├── repository/
│ ├── models/
│ ├── utils/
│ ├── assets/
│ └── data/

└── ios/
└── (added later)

- Add .gitignore and MIT LICENSE
- Create docs/ with all 11 documentation files (Vision, Requirements,
  Architecture, UX, DesignSystem, DataModel, Repository, CodingStandards,
  Milestones, DecisionLog, AIInstructions)
- Build complete vanilla-JS SPA under web/:
  - models/: Observation factory, Category loader
  - repository/: ObservationRepository (localStorage CRUD)
  - services/: ObservationService, LocationService, ExportService
  - components/: NavBar, ObservationCard, ObservationModal, FilterBar,
    Toast, ConfirmDialog (XSS-safe via textContent/escapeHtml)
  - screens/: Home, LogObservation, MyObservations, Map, Stats
  - utils/: date, validation, format helpers
  - data/: categories.json, species.json reference data
  - assets/icons/ placeholder
  - index.html app shell and styles.css design system
- Add ios/README.md placeholder for Milestone 4
- Update README.md with project overview and quickstart
Copilot AI changed the title [WIP] Add iOS support to ObservationTracker Bootstrap ObservationTracker: full project structure, web SPA, and docs Jul 15, 2026
Copilot AI requested a review from abbysko July 15, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants