Repository navigation
arch tech stack
Decision:
React Native with TypeScript
Rationale:
React Native allows the team to develop one mobile application for both iOS and Android using a shared TypeScript codebase.
Decision: Java 21, Spring Boot 3.x, Spring Web
Use in the solution: The backend will expose REST endpoints, validate requests, enforce authorization rules, manage OAuth sessions, and read and write application data.
Rationale: Spring Boot provides mature support for REST APIs, OAuth authentication, validation, database persistence, and integration testing. Java 21 is a current long-term-support Java release.
Decision: Spring Data JPA, Flyway migrations, hibernate-spatial
Rationale: Flyway keeps migrations versioned and in the repository, applied on startup. hibernate-spatial maps PostGIS geometry to JTS types on the entity.
Decision: PostgreSQL with the PostGIS extension, on Railway or Supabase
Rationale: Supabase has a permanent free tier with no card and ships PostGIS enabled. Railway's current free allowance needs confirming in week 1. Not Render's free Postgres, which expires mid-semester.
Decision: spring-boot-starter-oauth2-client against Google or Microsoft, with a server-side email domain allowlist
Rationale: See Authentication and Identity. No passwords to store, reset, or get wrong.
Decision:
Mapbox Maps SDK for React Native using @rnmapbox/maps
Rationale:
@rnmapbox/maps provides React Native components that use the native Mapbox SDKs for iOS and Android. It supports interactive maps, event markers, camera movement, user location, and clustering.
Backend hosting:
The Spring Boot API will be deployed as a managed web service on Render.
Database hosting:
PostgreSQL with PostGIS will be hosted using Supabase or another managed PostgreSQL provider.
Mobile distribution:
The React Native application will be distributed as an installable Android and iOS development or preview build.
Rationale:
The React Native client is installed on a mobile device and is not hosted as a static website. The backend remains available through a public HTTPS API.
Decision: GitHub Actions
Rationale: Already where the repository lives.
Decision: JUnit 5, Testcontainers with a PostGIS image, Spring Boot test slices
Rationale: Testcontainers runs a real PostGIS-enabled Postgres, which both the visibility matrix and the spatial queries need.
Render's free tier sleeps after 15 idle minutes, with 30 to 50 second cold starts plus JVM startup, so warm the API before demoing. Set the JVM max heap explicitly to stay under 512 MB.
Keep Spring shallow: controller, service, repository. No single-implementation interfaces, DTO mapper frameworks, or abstract base services.