{"id":51024007,"url":"https://github.com/abasheger/terubase","last_synced_at":"2026-06-21T18:01:05.372Z","repository":{"id":361595862,"uuid":"1254824971","full_name":"AbaSheger/TeruBase","owner":"AbaSheger","description":" Maven plugin for Spring Boot/JPA projects that scans entity metadata, creates seed-data plans, validates INSERT-only SQL, and exports data.sql or Flyway-ready files.","archived":false,"fork":false,"pushed_at":"2026-06-07T17:54:01.000Z","size":277,"stargazers_count":1,"open_issues_count":5,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T19:22:22.595Z","etag":null,"topics":["developer-tools","hibernate","java","jpa","seed-data","spring-boot","test-data"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AbaSheger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-31T03:36:32.000Z","updated_at":"2026-06-07T17:58:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/AbaSheger/TeruBase","commit_stats":null,"previous_names":["abasheger/terubase"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AbaSheger/TeruBase","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2FTeruBase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2FTeruBase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2FTeruBase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2FTeruBase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AbaSheger","download_url":"https://codeload.github.com/AbaSheger/TeruBase/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2FTeruBase/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34620358,"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-21T02:00:05.568Z","response_time":54,"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":["developer-tools","hibernate","java","jpa","seed-data","spring-boot","test-data"],"created_at":"2026-06-21T18:01:04.125Z","updated_at":"2026-06-21T18:01:05.345Z","avatar_url":"https://github.com/AbaSheger.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eTeruBase\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/TeruBase.png\" alt=\"TeruBase logo\" width=\"220\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Build-time JPA metadata planning and reviewed SQL export for Maven projects.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Java 21\" src=\"https://img.shields.io/badge/Java-21-blue\"\u003e\n  \u003cimg alt=\"Spring Boot 3.4.6\" src=\"https://img.shields.io/badge/Spring%20Boot-3.4.6-brightgreen\"\u003e\n  \u003cimg alt=\"Maven\" src=\"https://img.shields.io/badge/Maven-build-orange\"\u003e\n  \u003cimg alt=\"MIT License\" src=\"https://img.shields.io/badge/License-MIT-green\"\u003e\n  \u003ca href=\"https://central.sonatype.com/artifact/io.github.abasheger/terubase-maven-plugin/0.1.2\"\u003e\n    \u003cimg alt=\"Maven Central\" src=\"https://img.shields.io/badge/Maven%20Central-0.1.2-blue\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/AbaSheger/TeruBase/actions/workflows/maven.yml\"\u003e\n    \u003cimg alt=\"Build status\" src=\"https://github.com/AbaSheger/TeruBase/actions/workflows/maven.yml/badge.svg\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nTeruBase is a Maven plugin that inspects compiled, field-annotated JPA entities,\nwrites schema-context and seed-plan files, checks that reviewed SQL contains\nonly `INSERT` statements, and copies it to Spring Boot `data.sql` or a Flyway\nmigration path.\n\nThe preferred path is the Maven plugin. It discovers JPA entities at build time\nand writes reviewable artifacts without requiring an AI account:\n\n```xml\n\u003cplugin\u003e\n  \u003cgroupId\u003eio.github.abasheger\u003c/groupId\u003e\n  \u003cartifactId\u003eterubase-maven-plugin\u003c/artifactId\u003e\n  \u003cversion\u003e0.1.2\u003c/version\u003e\n\u003c/plugin\u003e\n```\n\n```bash\nmvn -B -ntp compile terubase:plan\n```\n\n```text\ntarget/terubase/schema-context.json\ntarget/terubase/seed-plan.md\n```\n\nThe command also prints an AI handoff: the files an AI tool must be able to\nread, a short instruction, the expected SQL save path, and the export commands.\n\nThe plugin does not generate row values or call an AI provider. Create\n`target/terubase/generated-seed.sql` yourself or with an AI assistant, review\nit, then export it as Spring Boot's familiar `data.sql`:\n\n```bash\nmvn -B -ntp terubase:export-data-sql\n```\n\n```text\nsrc/main/resources/data.sql\n```\n\nIf Hibernate creates your schema with `spring.jpa.hibernate.ddl-auto`, also set\n`spring.jpa.defer-datasource-initialization=true` so Spring runs `data.sql`\nafter the tables exist.\n\nProjects using Flyway can instead run `mvn -B -ntp terubase:export-flyway`.\n\nTeruBase is local-first tooling. It is not a generic fake-data generator, an H2\nconsole clone, a production database API, or an enterprise test-data-management\nplatform.\n\nThe runtime starter remains available as an optional local playground. The\nMaven plugin can copy reviewed SQL to a Flyway migration path, but it does not\nrun Flyway or replace a migration tool.\n\n## Why TeruBase?\n\n- Write deterministic JSON and Markdown artifacts from compiled JPA classes.\n- Record IDs, generated values, Java enums, explicit `@Column` metadata, and\n  common relationship annotation types.\n- Print a clear handoff for creating SQL with a developer's chosen AI tool.\n- Reject blank exports and statements that are not `INSERT` statements.\n- Copy reviewed SQL to Spring Boot `data.sql` or a fixed Flyway migration path.\n\n## Working With AI Coding Assistants\n\nCodex, Copilot, Cursor, Claude, ChatGPT, and other coding assistants can draft\nseed SQL. TeruBase complements them by providing a deterministic workflow around\nthe generated output.\n\nThe Maven plugin:\n\n- scans your compiled Spring Boot/JPA model\n- records explicit `@Table` and `@Column` names, Java enums, IDs, generated\n  values, and common relationship annotation types\n- creates reusable schema-context and seed-plan artifacts\n- checks reviewed SQL as `INSERT`-only\n- copies reviewed SQL into `data.sql` or a Flyway migration path\n- keeps AI optional and export-first\n\nThe assistant remains responsible for drafting row values. TeruBase supplies\nproject metadata and planning artifacts, checks the reviewed result as\n`INSERT`-only, and copies it to the selected Spring Boot or Flyway path.\n\nSee [AI coding assistants and TeruBase](docs/AI_ASSISTANTS_AND_TERUBASE.md) for the\ndivision of responsibilities.\n\n## Try It in 5 Minutes\n\nTeruBase requires Java 21. The runtime starter is built and tested with Spring\nBoot 3.4.6; compatibility with later Spring Boot releases is not yet claimed.\n\nAdd the Maven plugin to a Spring Boot/JPA project's `pom.xml`:\n\n```xml\n\u003cbuild\u003e\n  \u003cplugins\u003e\n    \u003cplugin\u003e\n      \u003cgroupId\u003eio.github.abasheger\u003c/groupId\u003e\n      \u003cartifactId\u003eterubase-maven-plugin\u003c/artifactId\u003e\n      \u003cversion\u003e0.1.2\u003c/version\u003e\n      \u003cconfiguration\u003e\n        \u003centityBasePackage\u003ecom.example.yourapp\u003c/entityBasePackage\u003e\n      \u003c/configuration\u003e\n    \u003c/plugin\u003e\n  \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\nRun the goal from the Maven module whose compiled output contains the entity\nclasses. The current goal does not aggregate entity classes from child modules.\n\nGenerate non-AI planning artifacts from compiled project classes:\n\n```bash\nmvn -B -ntp compile terubase:plan\n```\n\nThis writes:\n\n```text\ntarget/terubase/schema-context.json\ntarget/terubase/seed-plan.md\n```\n\nThe terminal prints this instruction with absolute paths to the two generated\nfiles:\n\n```text\nGenerate INSERT-only seed SQL using \u003cschema-context.json\u003e and \u003cseed-plan.md\u003e. Follow the relationships, constraints, row count, and SQL dialect in those files. Return SQL only.\n```\n\nA terminal AI agent may be able to read those paths. For a browser chat, upload\nboth files first; pasting local paths alone does not give the chat access.\n\nTo copy a reviewed `target/terubase/generated-seed.sql` file into Spring Boot's\n`data.sql`:\n\n```bash\nmvn -B -ntp terubase:export-data-sql\n```\n\nThis writes:\n\n```text\nsrc/main/resources/data.sql\n```\n\nFor applications where Hibernate creates the schema, configure:\n\n```yaml\nspring:\n  jpa:\n    defer-datasource-initialization: true\n```\n\nFor a Flyway migration instead:\n\n```bash\nmvn -B -ntp terubase:export-flyway\n```\n\nAI generation is not built into the Maven plugin. You can use any AI assistant\nto draft SQL from the generated artifacts, or use the optional runtime starter's\nOpenAI-compatible endpoint.\n\n### Maven Plugin Limits\n\n- Entity inspection recognizes Jakarta Persistence (`jakarta.persistence`)\n  annotations. It does not recognize legacy `javax.persistence` annotations.\n- The goal scans only the current Maven project's compiled output directory. In\n  a multi-module build, run it in the module containing the entities.\n- When `entityBasePackage` is omitted, the package filter defaults to the\n  current project's `groupId`, or `com` when no group ID is available.\n- Entity inspection supports field annotations, not JPA property access. It\n  currently records every non-static field and does not exclude fields marked\n  `@Transient`.\n- An explicit `@Table` name is recorded; otherwise `tableName` falls back to the\n  Java class name. Fields always include their Java names, while column metadata\n  is present only for explicit `@Column` annotations. The plugin does not apply\n  a Hibernate physical naming strategy.\n- The plugin records common relationship annotation types, but not `@JoinColumn`\n  or `@JoinTable` details.\n- The plan always includes generic insert-order text, including a join-table\n  hint. Those lines are instructions, not proof that matching metadata was\n  discovered, and they are not a foreign-key dependency graph.\n- The configured row count and dialect are written into the plan for the SQL\n  author or AI tool; the plugin does not enforce either one.\n- SQL checking is syntactic and `INSERT`-only. It does not connect to the host\n  database or verify tables, columns, constraints, values, or dialect syntax.\n- Export goals overwrite their configured output file.\n- `terubase:plan` fails when it discovers no entities. Compile the module that\n  contains the entities and verify `entityBasePackage` when this happens.\n\n### Example Output\n\nA compact `schema-context.json` looks like this:\n\n```json\n{\n  \"entities\": [\n    {\n      \"className\": \"com.example.invoice.Customer\",\n      \"simpleName\": \"Customer\",\n      \"tableName\": \"customers\",\n      \"fields\": [\n        {\n          \"name\": \"id\",\n          \"type\": \"java.lang.Long\",\n          \"id\": true,\n          \"generatedValue\": true\n        },\n        {\n          \"name\": \"email\",\n          \"type\": \"java.lang.String\",\n          \"column\": {\n            \"name\": \"email\",\n            \"nullable\": false,\n            \"unique\": true\n          }\n        }\n      ],\n      \"insertOrderHint\": \"Parent or reference entity; insert before dependent child entities.\"\n    }\n  ]\n}\n```\n\nThe matching `seed-plan.md` records the configured scenario, count, dialect,\ndiscovered entities, and basic hints:\n\n```markdown\n# TeruBase Seed Plan\n\n- Scenario: Generate realistic relationship-aware local development seed data.\n- Target row count: 20\n- SQL dialect: h2-postgresql-mode\n- Discovered entities: 3\n\n## Insert Order Hints\n\n- Insert parent and reference tables first.\n- Insert child tables with foreign keys second.\n- Insert join tables last.\n- Populate every nullable=false field.\n```\n\nAfter review, `terubase:export-data-sql` checks the file as `INSERT`-only and\ncopies it into `data.sql`:\n\n```sql\n-- TeruBase seed data\nINSERT INTO customers (id, name, email) VALUES (1, 'Northstar Studio', 'billing@northstar.example');\nINSERT INTO invoices (id, customer_id, invoice_number, total_amount) VALUES (10, 1, 'INV-2026-0001', 1200.00);\n```\n\n### Optional Starter Playground\n\nAdd the starter to a Spring Boot application when you want the local runtime\nplayground endpoints:\n\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.abasheger\u003c/groupId\u003e\n    \u003cartifactId\u003eterubase-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nAdd local-only configuration to `application-local.yml`:\n\n```yaml\nterubase:\n  enabled: true\n  entity-base-package: com.example.store.domain\n  sql-execution-enabled: false\n```\n\nThe runtime starter is disabled unless `terubase.enabled=true` is set.\n\nStart the application with the `local` profile, then inspect the built-in\nscenarios:\n\n```bash\ncurl http://localhost:8080/terubase/api/scenarios\n```\n\nGenerate a seed plan from your discovered JPA entities:\n\n```bash\ncurl \"http://localhost:8080/terubase/api/seed-plan?scenarioId=saas-billing-demo\u0026count=30\"\n```\n\nThe seed-plan response is metadata-only. It does not call AI or execute SQL.\nCopy its `recommendedMockRequest` into `POST /terubase/api/mock` when you want\nAI-generated SQL. The generated request keeps `execute=false`.\n\n## Try the Invoice Demo\n\nGenerate Maven plugin artifacts from the invoice demo:\n\n```bash\ncd examples/invoice-demo\nmvn -B -ntp compile terubase:plan\n```\n\nThis writes:\n\n```text\nexamples/invoice-demo/target/terubase/schema-context.json\nexamples/invoice-demo/target/terubase/seed-plan.md\n```\n\nTo export reviewed SQL to `data.sql`, place reviewed `INSERT` statements in\n`examples/invoice-demo/target/terubase/generated-seed.sql`, then run:\n\n```bash\nmvn -B -ntp terubase:export-data-sql\n```\n\nThis writes:\n\n```text\nexamples/invoice-demo/src/main/resources/data.sql\n```\n\nUse `mvn -B -ntp terubase:export-flyway` instead when the project uses Flyway.\n\nYou can also run the example Spring Boot app and use the local runtime\nplayground endpoints:\n\n```bash\nmvn -B -ntp spring-boot:run\n```\n\nSee [`examples/invoice-demo/README.md`](examples/invoice-demo/README.md) for\nplugin output, curl examples, and details.\n\n## Architecture\n\n### Maven Plugin\n\n```mermaid\nflowchart LR\n    A[JPA classes] --\u003e B[Plan files]\n    B --\u003e C[Draft and review SQL]\n    C --\u003e D{Export}\n    D --\u003e E[data.sql]\n    D --\u003e F[Flyway file]\n```\n\n`terubase:plan` creates `schema-context.json` and `seed-plan.md`. A developer or\nAI assistant drafts `generated-seed.sql`; TeruBase checks it as `INSERT`-only\nbefore copying it to the selected output.\n\n### Optional Runtime Starter\n\n```mermaid\nflowchart LR\n    A[JPA classes] --\u003e B[Metadata and seed plan]\n    B --\u003e C[AI provider]\n    C --\u003e D[Review or export]\n    C --\u003e E[Optional isolated H2]\n```\n\nThe runtime starter is a separate, explicitly enabled local playground. The\nMaven plugin does not start it or call an AI provider.\n\n## Endpoints\n\n| Method | Endpoint | Purpose |\n| --- | --- | --- |\n| `GET` | `/terubase/api/entities` | Discover JPA entity metadata. |\n| `GET` | `/terubase/api/scenarios` | List built-in scenario templates. |\n| `GET` | `/terubase/api/scenarios/{id}` | Get one built-in scenario template. |\n| `GET` | `/terubase/api/seed-plan` | Build an AI-ready seed plan. |\n| `POST` | `/terubase/api/mock` | Generate export-first AI seed SQL. |\n| `POST` | `/terubase/api/export/sql` | Export reviewed `INSERT` statements as SQL. |\n| `POST` | `/terubase/api/export/json` | Export reviewed `INSERT` statements as JSON. |\n| `GET` | `/terubase/api/status` | Check isolated SQL service status. |\n| `POST` | `/terubase/api/execute` | Execute SQL when explicitly enabled. |\n\n## Safety Defaults\n\n\u003e Keep TeruBase local, export-first, and separate from production data.\n\n- Use TeruBase only with `local`, `dev`, or `test` profiles.\n- Never expose `/terubase/api/**` publicly.\n- Never use real production records in prompts or examples.\n- Keep AI generation export-first with `\"execute\": false`.\n- Review generated SQL before optional isolated execution.\n- Keep `sql-execution-enabled` disabled unless direct local SQL access is needed.\n- Keep `force-enable-in-production` disabled.\n\n## Configuration\n\nThe complete example is\n[`application-terubase-example.yml`](terubase-spring-boot-starter/src/main/resources/application-terubase-example.yml).\nAll settings are flat `terubase.*` properties:\n\n```yaml\nterubase:\n  enabled: true\n  jdbc-url: jdbc:h2:mem:terubase_isolated_db;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH\n  username: sa\n  password: \"\"\n  entity-base-package: com.example.store.domain\n  open-ai-chat-completions-url: https://api.openai.com/v1/chat/completions\n  open-ai-model: gpt-4o\n  max-mock-rows: 100\n  sql-execution-enabled: false\n  force-enable-in-production: false\n```\n\nTeruBase auto-configuration is blocked when the `prod` or `production` Spring\nprofile is active. It is also disabled by default in every profile. Enable it\nexplicitly for local use with `terubase.enabled=true`. An intentional\nproduction override requires both:\n\n```yaml\nterubase:\n  enabled: true\n  force-enable-in-production: true\n```\n\n## Main Workflow\n\n### Discover Entities\n\n```http\nGET /terubase/api/entities\n```\n\nWhen `terubase.entity-base-package` is set, TeruBase scans that package. When it\nis omitted, the runtime starter derives candidate packages from application\nbean definitions and falls back to `com` if none are found. It returns JPA\nmetadata for columns, IDs, generated values, enums, relationships, join\ncolumns, join tables, and deterministic insert-order hints. The hints guide\nseed generation; they are not a full database dependency planner.\n\nRuntime metadata inspection is also field-based. It does not inspect\nproperty/getter mappings, apply Hibernate physical naming strategies, or\nexclude fields marked `@Transient`.\n\n### Choose a Scenario\n\n```http\nGET /terubase/api/scenarios\nGET /terubase/api/scenarios/{id}\n```\n\nBuilt-in IDs:\n\n- `ecommerce-demo`\n- `saas-billing-demo`\n- `crm-demo`\n- `banking-lite-demo`\n- `task-management-demo`\n- `inventory-management-demo`\n- `learning-management-demo`\n- `event-registration-demo`\n- `qa-edge-cases`\n- `frontend-dashboard-demo`\n\n### Build an AI-Ready Seed Plan\n\n```http\nGET /terubase/api/seed-plan?scenarioId=saas-billing-demo\u0026count=30\n```\n\nThe response combines scenario intent with discovered metadata and returns a\n`schemaPrompt` plus a `recommendedMockRequest`. This endpoint does not require\nan API key and does not call AI. Its `count` cannot exceed\n`terubase.max-mock-rows`, so the recommended request is accepted by `/mock`.\n\n### Generate Export-First Seed SQL\n\n```http\nPOST /terubase/api/mock\nContent-Type: application/json\n\n{\n  \"count\": 20,\n  \"apiKey\": \"your-local-api-key\",\n  \"schema\": \"\u003cschemaPrompt from /terubase/api/seed-plan\u003e\",\n  \"scenario\": \"Generate a fictional SaaS billing demo with overdue invoices\",\n  \"dialect\": \"h2-postgresql-mode\",\n  \"execute\": false\n}\n```\n\n`execute=false` returns SQL for review without running it. TeruBase accepts only\n`INSERT` statements from AI output. It blocks unsupported or destructive SQL.\nAPI keys are request-only: never commit, store, or log them.\n\n### Export Generated Data\n\nExport reviewed statements as SQL:\n\n```http\nPOST /terubase/api/export/sql\nContent-Type: application/json\n\n{\n  \"statements\": [\n    \"insert into customer (id, name) values (1, 'Sara')\"\n  ],\n  \"filename\": \"demo-seed.sql\"\n}\n```\n\nOr as JSON:\n\n```http\nPOST /terubase/api/export/json\nContent-Type: application/json\n\n{\n  \"scenario\": \"Fictional SaaS billing demo\",\n  \"statements\": [\n    \"insert into customer (id, name) values (1, 'Sara')\"\n  ]\n}\n```\n\nExport endpoints do not execute SQL or write files to disk. They accept only\n`INSERT` statements and return content for review, local seed files, CI\nfixtures, and demos.\n\n### Optional Local Execution\n\nAI-generated SQL can run against TeruBase's isolated H2 database by setting\n`\"execute\": true` in `POST /terubase/api/mock`. Batch execution is transactional\nand rolls back on failure.\n\nFor direct local SQL access, explicitly enable:\n\n```yaml\nterubase:\n  sql-execution-enabled: true\n```\n\nThen use:\n\n```http\nGET /terubase/api/status\n\nPOST /terubase/api/execute\nContent-Type: application/json\n\n{\n  \"sql\": \"select 1 as value\"\n}\n```\n\n## Build\n\n```bash\nmvn -B -ntp clean verify\n```\n\n## License\n\nMIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabasheger%2Fterubase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabasheger%2Fterubase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabasheger%2Fterubase/lists"}