This repository contains the Feedback platform as a single monorepo: the web app, the backend services, and the root-level infrastructure used to run and deploy them together.
The root of the repo is for shared orchestration only. Product work should usually happen inside web/ or backend/.
web/contains the Next.js frontend.backend/contains the Kotlin services, shared backend libraries, and database tooling.docker-compose.ymlis the canonical stack for shared and production wiring using published images.docker-compose.override.ymladds only local development concerns: host ports, local backend startup wiring, and locally built images for the backend and web app..github/workflows/contains CI and release automation.
- Next.js 16
- React 19
- Node.js 20.19.0 for the
web/app in local development, CI, and Docker - TypeScript
- Tailwind CSS
- Radix UI / shadcn-style primitives
- Firebase client auth
- Playwright for end-to-end testing
- Kotlin
- Spring Boot
- Gradle
- PostgreSQL
- Liquibase
- OpenAPI / Swagger
- Firebase integration
- Dedicated scheduler service for background jobs
- Docker Compose
- GitHub Actions
- Coolify for production deployment
- Published Docker images for
feedback-api,feedback-scheduler, andfeedback-web
.
|-- web/ # Frontend app
|-- backend/ # API, scheduler, shared backend code, DB tooling
|-- docker-compose.yml # Base stack using published production images
|-- docker-compose.override.yml
|-- .github/workflows/ # CI/CD pipelines
|-- AGENTS.md # Root-level repo working rules
App-specific instructions live in:
web/README.mdbackend/README.mdweb/AGENTS.mdbackend/AGENTS.md
For frontend work, use Node 20.19.0 in web/ so local installs match
GitHub Actions (web/.nvmrc) and the pinned web Docker image.
The backend setup and day-to-day commands now live directly in backend/README.md instead of a separate getting-started document.
For full-stack local development from the repo root:
./scripts/run -dThe override starts a local db service (Postgres 16) inside Compose. The backend services connect to that container (POSTGRES_HOST=db, POSTGRES_PORT=5432) and still use your root .env for database name, user, password, and host port mapping.
Useful root-level commands:
docker compose down
docker compose logs -f
docker compose psGenerate the canonical API OpenAPI contract from the repo root:
cd backend && SPRING_PROFILES_ACTIVE=openapi ./gradlew syncOpenApiSpec --no-configuration-cacheGenerate all committed API artifacts from the repo root:
./scripts/generate-api-artifacts.shThe generated contract is committed at contracts/openapi/feedback-api.yaml.
Both generated clients read from that file:
web/src/lib/api/generated/openapi.tsios-app/Modules/Sources/OpenAPI/GeneratedSources/
How Compose is wired:
docker-compose.ymlcontains the shared service definitions, explicit runtime env contract, and published images.docker-compose.override.ymlconnects the backend services to a local Postgres instance outside Compose, publishes local ports, and uses locally built images forapi,scheduler, andweb.- Local Compose still expects the full env contract to exist in
.env, and.env.exampleincludes every variable needed for a local run with explicit values or intentionally blank placeholders. There are no Compose fallbacks. The developer is responsible for running a reachable local Postgres instance, and Compose useshost.docker.internalto reach it from containers. - For the API docs:
SPRING_DOC_API_DOCS_ENABLEDcontrols the raw OpenAPI document at/v3/api-docsand/v3/api-docs.yaml, whileSPRING_DOC_SWAGGER_UI_ENABLEDcontrols the interactive Swagger UI served at/.
For feature work inside a single app, switch into that app directory and use its local README and AGENTS instructions.
Compose reads variables from the root .env file when present.
Typical values stored there include:
- Compose/image settings
- Runtime image platform selection via
IMAGE_PLATFORM - Postgres connection settings
- JWT / auth configuration
- Firebase configuration
- Zoho mail settings
- public frontend variables prefixed with
NEXT_PUBLIC_
Rules:
- never commit real secrets
- keep secrets in
.env, GitHub secrets, or Coolify-managed environment variables - treat
NEXT_PUBLIC_*values as client-exposed
Production deployment is handled through Coolify using the root docker-compose.yml.
Important deployment assumptions:
- production should pull the mutable
prodimage tags IMAGE_PLATFORMmust match the CPU architecture of the Docker host that will run the published images: uselinux/amd64for x86_64 hosts andlinux/arm64for ARM64 hosts- root deployment changes should stay aligned with the current Coolify setup and runtime env contract
- infrastructure changes should call out any new env vars, ports, domains, or image changes
GitHub Actions in .github/workflows/ handle validation and releases.
ci.ymlruns backend build/tests plus web install, lint, and buildci.ymlalso verifies the committed OpenAPI contract, generated TypeScript client, and generated Swift client are up to daterelease.ymlruns web e2e tests, builds and publishes Docker images, creates a GitHub release with the committed OpenAPI contract, and triggers deployment
- Work in
web/for frontend routes, components, and UI behavior. - Work in
backend/for API logic, scheduler jobs, database changes, and backend integrations. - Keep root changes focused on documentation, Docker Compose, CI/CD, and deployment wiring.