This repository is the full-stack Bub application: a private digital home for couples, built with a Next.js frontend, Spring Boot backend, Flutter mobile app, direct Google/GitHub OAuth login, Postgres persistence, generated OpenAPI TypeScript types, and GitHub Actions image publishing.
- Node.js 20
- pnpm 10.12.1, via Corepack or a local install matching
packageManager - Java 21
- Docker with Docker Compose
make dev
# Postgres :5432, backend :8080, frontend :3000Open http://localhost:3000. Protected app routes redirect to Google/GitHub login when you are not signed in.
flowchart LR
Browser -->|HTTP| Next[Next.js frontend :3000]
Next -->|API requests| Spring[Spring Boot backend :8080]
Next -->|Auth.js OAuth| Google[Google OAuth]
Next -->|Auth.js OAuth| GitHub[GitHub OAuth]
Spring -->|Bearer token userinfo lookup| Google
Spring -->|Bearer token userinfo lookup| GitHub
Spring -->|JPA/Flyway| Postgres[(Postgres :5432)]
apps/
backend/ Spring Boot API, Flyway migrations, tests
frontend/ Next.js app, Auth.js, TanStack Query, shadcn/ui
mobile/ Flutter app, Riverpod, Dio, generated OpenAPI client
packages/
api-types/ TypeScript types generated from OpenAPI
infra/
docker-compose.yml
postgres/ Local database initialization
docs/
adr/ Architecture decision records
product/ Bub product vision, user stories, MVP scope, and epics
tickets/ Implementation tickets and completion history
| State type | Owner |
|---|---|
| Server state | TanStack Query |
| Session/auth | Auth.js |
| Ephemeral UI state | Zustand |
Keep these layers separate. Do not copy API entities into Zustand, and do not use TanStack Query for local UI controls.
- Create a vertical slice for the feature under
apps/backend/src/main/java/com/vencentdev/backend/<name>/, following the existing package style:controller,service,repository,entity,dto, andmapper. - Use Lombok for JPA entities, Java records for DTOs, and MapStruct for mapper boundaries.
- Add a Flyway migration such as
apps/backend/src/main/resources/db/migration/V<n>__<name>.sql. - Add repository tests with
@DataJpaTestwhen persistence behavior matters. - Add API integration tests by extending
IntegrationTestBase. - Keep security behavior explicit in controller integration tests.
- Add the page under
apps/frontend/src/app/app/<feature>/page.tsxfor authenticated app routes. - Add a hook such as
apps/frontend/src/hooks/use<Feature>.ts. - Type API inputs and responses through
@app/api-types. - Use TanStack Query for server data and mutations.
- Add a Zustand store only for ephemeral UI state such as filters, selected tabs, or drawer state.
- Keep shared UI primitives in
apps/frontend/src/components/ui.
See docs/google-github-oauth-setup.md for the required Google/GitHub OAuth apps, callback URLs, and local environment variables.
make backend-test
pnpm --filter @app/frontend lint
pnpm --filter @app/frontend typecheck
pnpm --filter @app/frontend test --if-present
make mobile-test # flutter analyze && flutter test (see apps/mobile/README.md)The backend tests use Testcontainers for Postgres. The frontend test script is currently a placeholder until a Jest, Vitest, or Playwright suite is added.
GitHub Actions is defined in .github/workflows/ci.yml.
- Pull requests run backend, frontend, and mobile (Flutter analyze + test) jobs.
- Pushes to
mainrun tests and publish images to GHCR:ghcr.io/<owner>/<repo>/backend:latestghcr.io/<owner>/<repo>/backend:<sha>ghcr.io/<owner>/<repo>/frontend:latestghcr.io/<owner>/<repo>/frontend:<sha>
Repository settings must allow GitHub Actions read/write package permissions for GHCR publishing.
Architecture decisions live in docs/adr/. ADR files are append-only: do not renumber them, and supersede old decisions with a new ADR instead of editing history.