Skip to content

archonity/codetools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CodeTools – Template-Driven CRUD Microservice Generator

A deterministic, template-driven code generation toolkit for building CRUD-style microservices β€” designed for environments where consistency, control, and scalability matter more than automation magic.


⚑ Stop writing the same microservice over and over again

If your backend looks like this:

  • dozen of models
  • hundreds of fields
  • dozens of nearly identical services, repositories, controllers
  • the same validation and business rules repeated again and again

…then you’re not writing code β€” you’re rewriting patterns.


πŸ’‘ This project takes a different approach

Instead of generating code directly with AI or scaffolding tools:

Build your own code generator β€” and reuse it.

Define:

  • your style (templates)
  • your domain (data)

Then generate everything else β€” deterministically.


🧠 Why this matters

Typical tools:

  • generate only the project skeleton
  • enforce their own architecture
  • or produce non-deterministic results (AI)

This tool:

  • generates entire vertical slices
  • keeps full control over architecture and style
  • works deterministically
  • scales to large codebases

πŸ€– AI is still useful β€” just in the right place

Use AI to:

  • extract data from requirements
  • help build templates
  • assist with mapping and enrichment

But let the generator produce the final code.


πŸš€ Result

Instead of writing:

(the same CRUD + patterns) Γ— N models

you define them once β€” and regenerate when needed.


⬇️ Scroll down for architecture, workflow, and examples.


πŸš€ Overview

This project is a code generation toolkit, not a ready-to-use generator.

It allows you to:

  • define your own code style using templates,
  • describe your domain using structured data,
  • generate large amounts of repeatable, consistent code,
  • keep full control over the output.

It was created to speed up development of enterprise microservices where a large part of the codebase follows repeatable CRUD-like patterns, often extended with recurring business rules.

The goal is not to eliminate engineering work. The goal is to reduce repetitive work and make the remaining manual work more focused.


πŸ’‘ Why this exists

In real enterprise systems, a large amount of code is repetitive.

For many domain models, developers end up creating the same overall structure again and again: a similar vertical slice, often consisting of many classes across API, application, domain, infrastructure, tests, and database-related code.

That kind of repetition is exactly what code generators are good at.

But repetition does not stop at the structural level. Even business logic often contains recurring patterns, such as:

  • uniqueness checks,
  • existence checks for referenced objects,
  • active/inactive checks,
  • flag-based constraints,
  • date-related rules,
  • status-dependent behavior.

So the goal is not only to generate CRUD-like structure, but also to capture and reuse repeated business-rule patterns where that is practical.

This project formalizes that workflow.

Instead of repeatedly copying and rewriting code, you can:

  1. create or reuse example code,
  2. turn it into templates,
  3. describe the domain as data,
  4. regenerate the repetitive parts as often as needed.

πŸ”₯ Core idea

The central idea is to separate:

  • Data (D) β€” the domain description and generation input,
  • Style (S) β€” templates, conventions, and code structure,
  • translation logic β€” mapping and enrichment,
  • reusable infrastructure β€” common low-volatility building blocks.

In practice, instead of manually producing code as:

D Γ— S where D = data and S = style,

you define:

D + S where D = data and S = style,

and let the generator produce the repetitive result.

This also makes the process cheaper and easier to support with AI, because data and style are handled separately instead of being mixed into one large prompt.


πŸͺΆ Lightweight by design

This tool is intentionally minimal:

  • implemented in Java
  • generates Java code
  • requires only a small set of dependencies (FreeMarker)

This makes it easy to adopt in constrained environments (e.g. corporate setups), where:

  • installing additional runtimes (like Node.js) is restricted,
  • developers are expected to work within a single technology stack,
  • tooling must remain transparent and controllable.

FreeMarker was chosen deliberately, as it integrates well with IntelliJ and is widely understood.


βœ… Deterministic by design

A major goal of this project is determinism.

The final code should be generated by the generator, not directly by AI.

Why:

  • the output is repeatable,
  • the author keeps architectural control,
  • the workflow scales better for large codebases,
  • token usage stays lower,
  • the result is easier to reason about than one-off AI output.

This matters especially in enterprise environments, where the generated code must fit an existing architecture and coding style rather than follow a generic framework opinion.


πŸ€– Role of AI

AI is meant to assist the process, not replace the generator.

Recommended use cases:

  • extracting CSV input data from requirements or analysis documents,
  • helping refine templates after automated conversion,
  • generating mapping code from CSV input into the template data model,
  • generating data enrichment logic,
  • optionally helping with non-standard business rules as a post-generation step.

The final source code should still be produced by the deterministic generator.

This documentation was vibe coded β€” the tool itself was not.


🧠 Why not just use AI?

Because AI and deterministic generation solve different problems.

AI is useful for:

  • drafting,
  • transformation,
  • filling gaps,
  • reducing manual work during generator development.

But direct AI code generation has trade-offs:

  • non-deterministic results,
  • inconsistent output between runs,
  • expensive context requirements for large codebases,
  • weaker control over style and architecture.

This project takes a different path:

  • AI can help create the generator inputs and style,
  • the final repetitive code is generated by a controlled tool.

πŸ†š Why not Spring Initializr or JHipster?

Because this project solves a different problem.

Spring Initializr

Spring Initializr helps bootstrap a project, but it does not generate the repetitive CRUD and business-pattern code inside the microservice.

JHipster

JHipster is powerful, but in many enterprise environments it is a poor fit:

  • it is opinionated,
  • it assumes its own ecosystem and conventions,
  • it adds tooling overhead,
  • it may not fit restricted corporate environments,
  • it does not give the same level of fine-grained control over internal style.

CodeTools is intended for cases where:

  • the architecture already exists,
  • the coding style is already defined,
  • the team wants full control,
  • the repetitive work is inside the service implementation, not just in project bootstrap.

βš™οΈ Generation model (simplified)

The generation process is intentionally straightforward:

  1. Load input data (CSV)
  2. Map it to a template data model
  3. Enrich it using processors
  4. Pass the same data to all templates
  5. Iterate over template definitions (templates.csv)
  6. For each template:
  • decide when it should be executed (e.g. per model, per context),
  • generate file content using FreeMarker,
  • write the output file

There is no complex orchestration layer β€” just structured data and repeatable rules.


βš™οΈ How it works

This is a toolkit-style workflow, not a one-click pipeline.

1. Prepare example code

Create or reuse example code that represents the style you want to reproduce.

This may be:

  • a vertical slice,
  • a set of classes,
  • or even a larger microservice fragment.

2. Convert to templates

Use StyleGenerator to extract templates:

  • based on a manually prepared templates.csv,
  • inline markers in code,
  • configuration defined in the generator code, which typically requires manual refinement.

This means the conversion step is not just automatic extraction. You also need to define the template list and adjust the generated configuration and templates manually.

3. Refine templates

Manually improve the generated templates.

The expectation is not full automation. The expectation is that a substantial part of the repetitive work has already been done for you.

4. Define domain data

Prepare structured input data, typically in CSV files such as:

  • microservice.csv
  • models.csv
  • fields.csv
  • groups.csv
  • contexts.csv
  • rules.csv

AI can help with that.

5. Map data to the template model

Implement code that maps the input CSV model into the data model used by templates.

AI can help with that.

6. Enrich the data

Add processors that compute extra structure, relations, derived values, or other generation-ready information.

AI can help with that.

7. Generate code

Run the code generator to produce the output files.

8. Iterate

Adjust templates, mapping, processors, or input data and generate again.

The goal is speed and leverage, not necessarily perfect generation on the first attempt.


Examples

Enterprise CRUD Classic

Style example: https://github.com/archonity/enterprise-crud-classic-example

Generated output: https://github.com/archonity/enterprise-crud-classic-generated


πŸ“¦ Example input

Example data for the CRM style is stored in:

  • data/crm/microservice.csv
  • data/crm/models.csv
  • data/crm/fields.csv
  • data/crm/groups.csv
  • data/crm/contexts.csv
  • data/crm/rules.csv

These files describe the domain input used by the example style-specific generator.


πŸ“„ Example output

A single generation run may produce many files, for example:

  • domain classes,
  • repositories,
  • services,
  • mappers,
  • REST resources,
  • DTOs,
  • Liquibase changelogs,
  • fixtures,
  • integration tests,
  • supporting infrastructure classes.

In practice, the output is intentionally large β€” that is the point of the tool.


πŸ—οΈ Project structure

Simplified overview:

  • reusable/

    • reusable low-volatility building blocks shared across tools and styles
  • styles/*/

    • style-specific implementations
    • new styles should be created here, each in its own package
    • styles can be copied, adapted, and evolved independently
    • the repository currently contains one example style: crm

Within each styles/*/ style:

  • codegen/

    • the style-specific code generator
  • stylegen/

    • the style-specific code-to-template conversion tool

Within each styles/*/codegen/ package, the most important areas are:

  • data/

    • the style-specific input model and template data model
    • includes mapping from source data into the model used by templates
  • dataprocessor/

    • style-specific enrichment and transformation logic
    • this is one of the main places where generation behavior is customized
  • template/

    • template root definitions used by the generator
    • corresponds to the FreeMarker templates stored in src/main/resources/...

Also important:

  • src/main/resources/com/codetools/styles/*/codegen/

    • style-specific FreeMarker templates and related template resources

In practice, the main extension point of the repository is the styles/*/ area:

  • create a new style,
  • define its generator,
  • define its template conversion process,
  • define its data model and processors,
  • add or modify the corresponding FreeMarker templates.

🎯 Current style layout

The repository is organized around the idea that:

  • some parts are highly reusable,
  • some parts are style-specific,
  • styles can evolve independently while still using shared infrastructure.

At the moment, the repository contains a CRM style example with:

  • a style-specific generator,
  • a style-specific code-to-template conversion tool,
  • a style-specific CSV model,
  • a style-specific template data model,
  • style-specific templates and processors.

This structure is intended to support multiple styles over time.


πŸ§ͺ Status

  • prototype,
  • experimentally evolved through real use,
  • already used to generate production code,
  • used with multiple independent code styles, including at least four in practice.

This repository currently contains one example style as a reference implementation.


🎯 Who is this for?

This project may be useful for:

  • backend developers working on repetitive CRUD-heavy systems,
  • architects who need strong control over generated code,
  • teams maintaining internal architectural conventions,
  • engineers who want AI assistance without giving up determinism.

It is probably not useful for someone looking for a plug-and-play generator with zero setup.


🧭 Design philosophy

This project intentionally avoids over-engineering.

In practice, attempts to over-design code generators often lead to:

  • unnecessary abstractions,
  • premature generalization,
  • increased complexity without real benefit.

Instead, this approach favors:

  • simple data flow (load β†’ map β†’ enrich β†’ generate),
  • minimal assumptions,
  • incremental evolution,
  • extracting reusability only when it naturally appears (bottom-up).

The generator is designed to stay understandable and adaptable, rather than β€œperfectly abstract”.


The generator itself is intentionally pragmatic. It may contain shortcuts or style-specific logic, as its primary goal is to enable fast iteration and effective code generation, not to serve as a general-purpose framework.

This code does not aim to be "perfect" or highly reusable in the traditional sense. In practice, the generator is adapted per use case (per code style), so reusability is not the primary goal.

Some parts may be fragile or implemented as quick solutions β€” this is a conscious trade-off. The generator is typically used intensively for a period of time, and then left unchanged once the target code is generated.

This is not a statement against clean code principles. In general, reusable, non-fragile, and flexible code is preferable. However, in this specific context, prioritizing speed and effectiveness often leads to more pragmatic solutions.

As long as the generated code is correct and maintainable, this trade-off is acceptable. The generator itself can always be improved later β€” or rewritten differently for another use case.


⚠️ Important

This is not:

  • a universal code generator,
  • a low-code platform,
  • a one-click framework bootstrapper,
  • a promise of perfectly compiling output in every workflow.

You are expected to:

  • shape the style to your own needs,
  • adapt the generator,
  • refine templates,
  • treat generation as a productivity tool rather than a magic final step.

Depending on the workflow, the generated application may still require manual setup or post-generation fixes.


πŸ“Š Real-world experience

This approach has been used in real-world projects over an extended period.

Example observations:

  • Generating a large microservice (dozens of models, tens of thousands of lines of code) can be reduced from months of manual work to weeks of combined template + generation work.
  • In one case, a complex service was effectively rebuilt using the generator faster than extending the existing codebase.

These results depend heavily on the use case, but the approach consistently reduces repetitive work significantly.

Rough estimates suggest that this approach can reduce repetitive coding effort by more than half in CRUD-heavy systems.


πŸ“„ License

MIT License


✨ Philosophy

The goal is not perfect code generation.

The goal is to save time.

If the generator removes most of the repetitive work and leaves only the valuable, case-specific work to humans, then it is doing its job.

About

No description or website provided.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors