{"id":50864824,"url":"https://github.com/testero-app/testero-backend","last_synced_at":"2026-06-15T00:03:39.290Z","repository":{"id":359819744,"uuid":"1247440766","full_name":"testero-app/testero-backend","owner":"testero-app","description":"Testero backend","archived":false,"fork":false,"pushed_at":"2026-06-13T14:53:14.000Z","size":6544,"stargazers_count":0,"open_issues_count":15,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T16:24:44.771Z","etag":null,"topics":["agpl-3-0","assessment","edtech","education","java","open-source","rest-api","spring-boot"],"latest_commit_sha":null,"homepage":"https://testero.app","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/testero-app.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T10:16:56.000Z","updated_at":"2026-06-13T14:53:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/testero-app/testero-backend","commit_stats":null,"previous_names":["testero-app/testero-backend"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/testero-app/testero-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testero-app%2Ftestero-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testero-app%2Ftestero-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testero-app%2Ftestero-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testero-app%2Ftestero-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/testero-app","download_url":"https://codeload.github.com/testero-app/testero-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testero-app%2Ftestero-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34342089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agpl-3-0","assessment","edtech","education","java","open-source","rest-api","spring-boot"],"created_at":"2026-06-15T00:03:38.430Z","updated_at":"2026-06-15T00:03:39.277Z","avatar_url":"https://github.com/testero-app.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# testero-backend\n\n[![Version](https://img.shields.io/github/v/release/testero-app/testero-backend)](https://github.com/testero-app/testero-backend/releases)\n\nBackend for **Testero**, an open source system for administering tests\nand assessments, designed for educational settings: private schools,\ntraining organizations, teachers, and trainers.\n\nThis repository contains the **backend API**. The web frontend lives in\n[testero-web](https://github.com/testero-app/testero-web).\n\n## Stack\n\n- **Framework**: Spring Boot\n- **Language**: Java\n- **Database**: PostgreSQL (the hosted project uses [Supabase](https://supabase.com), but any PostgreSQL instance works)\n- **Migrations**: [Liquibase](https://www.liquibase.org/) (runs automatically on startup)\n- **Hosting**: [Render](https://render.com) via Docker (any container-compatible platform works)\n- **Build**: Maven (wrapper included)\n\n## Architecture\n\nSee [testero-docs](https://github.com/testero-app/testero-docs) for\narchitecture diagrams, data model, and functional documentation.\n\n## Getting Started\n\nPrerequisites:\n\n- JDK 21 or later\n- Docker (for local PostgreSQL)\n\n```bash\n# Clone the repository\ngit clone https://github.com/testero-app/testero-backend.git\ncd testero-backend\n\n# Start PostgreSQL\ndocker compose up -d\n\n# Copy the environment variables template and fill in the values\ncp .env.example .env\n\n# Run the application (starts with \"dev\" profile by default)\n./mvnw spring-boot:run\n```\n\nTo stop PostgreSQL: `docker compose down`.\n\nTo **reset the database** (wipe all data and let Liquibase recreate everything on next startup):\n\n```bash\ndocker compose down -v \u0026\u0026 docker compose up -d\n```\n\n### Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `SPRING_PROFILES_ACTIVE` | `dev` (local) or `prod` (Render) — defaults to `dev` |\n| `DATABASE_URL` | PostgreSQL JDBC connection string |\n| `JWT_SECRET` | HS256 signing key, min 256 bits — generate with `openssl rand -hex 32` |\n| `CORS_ORIGINS` | Allowed frontend origin (e.g. `http://localhost:3000`) |\n\nSee [`.env.example`](./.env.example) for the expected format.\n\n### Spring Profiles\n\n| Profile | Purpose | Datasource |\n|---------|---------|------------|\n| `dev` | Local development | Docker Compose PostgreSQL (hardcoded in profile) |\n| `prod` | Production (Render) | `DATABASE_URL` env var (Supabase) |\n\n### Database Migrations\n\nThe database schema is managed by **Liquibase**. Migrations run\nautomatically when the application starts — there is no manual step\nrequired.\n\nChangelog files live under `src/main/resources/db/changelog/` and are\norganized by version (e.g. `v1.0/`). The master file\n`db.changelog-master.yaml` includes all version directories in order.\n\n**First-time setup:** just start the application against an empty\ndatabase. Liquibase will create all tables, indexes, and constraints.\n\n**Adding a migration:** create a new changeset file in the current\nversion directory (or a new `vX.Y/` directory for a new release), then\nadd an `include` entry in `db.changelog-master.yaml`.\n\n\u003e **Note (Supabase):** if you connect through the Supabase connection\n\u003e pooler (port 6543 / PgBouncer), add `prepareThreshold=0` to the JDBC\n\u003e URL to avoid prepared-statement conflicts.\n\n## CI \u0026 Code Quality\n\nRun all checks locally (same as CI):\n\n```bash\n./mvnw compile checkstyle:check spotbugs:check test\n```\n\nThe CI pipeline runs four steps on every PR to `main`:\n\n| Step | What it does |\n|------|-------------|\n| **Compile** | Verifies the code compiles without errors |\n| **Checkstyle** | Enforces code style (indentation, imports, naming) |\n| **SpotBugs** | Static analysis for common bug patterns |\n| **Test** | Runs the full test suite (JUnit 5 + Mockito) |\n\nThe \"Build \u0026 Verify\" check is **required** — PRs cannot be merged if any\nstep fails. Tests also run during the **Docker build on Render**, blocking\ndeploys if they fail.\n\nTest coverage reports are generated by [JaCoCo](https://www.jacoco.org/)\nand available under `target/site/jacoco/` after running `./mvnw test`.\n\n\u003e **For contributors:** every change to backend logic must include tests.\n\u003e See [CONTRIBUTING.md](./CONTRIBUTING.md#testing) for details.\n\n## Releases\n\nThis project uses [Release Please](https://github.com/googleapis/release-please)\nfor automated versioning and changelog generation.\n\nVersioning follows [Semantic Versioning](https://semver.org/) and is driven\nby [Conventional Commits](https://www.conventionalcommits.org/) prefixes:\n\n| Prefix | Version bump |\n|--------|-------------|\n| `fix:` | Patch (1.0.0 → 1.0.1) |\n| `feat:` | Minor (1.0.0 → 1.1.0) |\n| `feat!:` / `BREAKING CHANGE:` | Major (1.0.0 → 2.0.0) |\n\nAfter each merge to `main`, Release Please opens (or updates) a Release\nPR that bumps the version in `pom.xml` and updates `CHANGELOG.md`. When\nthe Release PR is merged, a git tag and a GitHub Release are created\nautomatically.\n\n## Contributing\n\nContributions are welcome. Please read [CONTRIBUTING.md](./CONTRIBUTING.md)\nbefore opening a pull request. All contributions follow the\nDeveloper Certificate of Origin (DCO) model.\n\n## License\n\nReleased under the\n[GNU Affero General Public License v3.0](./LICENSE).\n\nThis means anyone can use, modify, and redistribute the software, as long\nas modified versions remain under the same license and the source code is\nmade available — including when the software is offered as a network service.\n\n## Website\n\n[testero.app](https://testero.app)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestero-app%2Ftestero-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftestero-app%2Ftestero-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftestero-app%2Ftestero-backend/lists"}