arch tech stack - Andre-asn/Quack-Campus-Event-Coordinator GitHub Wiki

Client

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.

Server

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.

Persistence

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.

Database

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.

Auth

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.

Map SDK

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.

App Hosting and Distribution

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.

CI

Decision: GitHub Actions

Rationale: Already where the repository lives.

Testing

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.