Skip to content

Generated output, ownership and regeneration

JoinedWorkz projects contain several kinds of files that have different owners. The file path alone is not sufficient to identify that owner: outlets can route generated files to different directories or even to sibling Maven modules.

Before changing a file, determine:

  1. which model, configuration, generator or developer owns it;
  2. whether generation may overwrite it;
  3. whether a clean build may delete it;
  4. whether it is part of persistent project history.

This distinction applies to the public Base, Java and SpringBoot facilities. It also applies to the experimental Quasar facility, whose generated frontend tree remains replaceable output.

1. Ownership matrix

ClassTypical examplesHow to change itRegeneration behaviorVersion-control policy
Authoritative inputmodel/**/*.cmn, joinedworkz.properties, pom.xml; custom .profile files and generator sources in facility projectsEdit the owning input and review it as sourceDrives subsequent generationCommit
Manual project sourceApplication shell, business services, runtime configuration and manually written tests outside replaceable output treesEdit directlyMust not be deleted or overwritten by generationCommit
Replaceable generated outputBase OpenAPI and diagrams; Java/Spring generated Java, resources and tests; Quasar src/generated outputChange the model, configuration or generator, then regenerateSame-named files may be overwritten; clean regeneration may delete the complete dedicated output treeEither ignore and regenerate in the build, or commit as reviewed generated output; never edit it manually
First-cut outputFiles written through SpringBoot firstCutJavaSource or firstCutHandlerSource, normally below src/main/javaAfter the first creation, the project owns the file and edits it manuallyAn existing file is retained; JoinedWorkz does not merge later model changes into itCommit
Versioned generated historyFlyway versioned SQL migrations and their schema snapshotsAdvance the persistence model and generate the next version; preserve accepted historyExisting versioned files are not overwritten and must not be removed by normal cleanupCommit SQL and matching snapshots together
Temporary or diagnostic outputFlyway development migration/snapshot, transformed-model diagnostics, build output below targetRegenerate; do not use as a manual sourceMay be replaced or removed according to its specific workflowNormally ignore; follow the feature-specific page if a temporary artifact is shared

The model is the source of truth for artifacts that remain generator-owned. A generated OpenAPI document may be the published API contract consumed by other tools, but it is still derived output: change its CMN source and regenerate it.

Flyway history is deliberately different. The current persistence model describes the desired schema, while the committed migration files and snapshots record how an existing database reached that schema. See Flyway schema migrations before changing or cleaning those directories.

2. Public facility outputs

Default paths can be changed with outlet overrides. Use the outlet and the project's explicit ownership policy, not just the directory name, when classifying a file.

The following list is intentionally limited to the outlets provided or used by the public JoinedWorkz facilities documented here. It is not a closed, JoinedWorkz-wide outlet registry. Other facilities can declare additional outlets in their profiles and must define the defaults and ownership rules for those outlets.

2.1 Base

Outlet and default locationOwnership
generatedOpenApi
Default: src/generated/resources/openapi
Replaceable
generatedDiagram
Default: diagram
Replaceable
generatedOpenApiHtml
Default: diagram/api
Replaceable

2.2 Java

Outlet and default locationOwnership
generatedJavaSource
Default: src/generated/java
Replaceable

2.3 SpringBoot

Outlet and default locationOwnership
generatedConfiguration
Default: src/generated/resources
Replaceable only when it does not contain a nested stateful migration target
generatedHandlerSource
Default: src/generated/java
Replaceable
generatedMappingSource
Default: src/generated/java
Replaceable
generatedIntegrationTestSource
Default: src/generated/test
Replaceable
firstCutJavaSource
Default: src/main/java
First-cut, then manual
firstCutHandlerSource
Default: src/main/java
First-cut, then manual
generatedSchemaMigration
Default: src/generated/resources/db/migration
Stateful; classify by STRICT or DEVELOPMENT mode
generatedSchemaSnapshot
Default: src/generated/resources/db/schema
Stateful; classify by STRICT or DEVELOPMENT mode

generatedIntegrationTestSource is a real configurable outlet and remains replaceable. The SpringBoot IntegrationTestCartridge is disabled by default; opt in with:

properties
cartridge.IntegrationTestCartridge.enabled=true

The generator emits tests only for eligible flat Create-to-Read flows. Unsupported intents, parent-resource paths and create bodies with required entity references produce a warning and no @Test method. The stable warning codes are JW_SPRING_BOOT_IT_UNSUPPORTED_FLOW and JW_SPRING_BOOT_IT_UNSUPPORTED_INTENT.

Whether generated test source compiles and runs still depends on a compatible test shell, test dependencies and registration of the outlet as a Maven test source. Keep update, delete, query and every skipped case in manually maintained tests. See the Spring Boot facility for the complete eligibility contract.

2.4 Quasar (experimental)

Outlet and default locationOwnership
generatedFrontendSource
Default: src/main/frontend/src/generated
Replaceable

The Base transformed-model output is a diagnostic for facility and cartridge developers. It is replaceable diagnostic output, not an application schema and not a stable application artifact.

3. Replaceable output

Replaceable output is owned by the model, generation configuration and generator version together. The safe change cycle is:

  1. edit the CMN model, joinedworkz.properties, facility version or generator;
  2. remove only the project's declared replaceable output directories;
  3. run generation;
  4. compile and test all consumers of the generated artifacts;
  5. review the model/configuration diff and the generated result.

There is no general protected-region or merge contract for replaceable JoinedWorkz output. If a generator writes the same file again, manual edits are not preserved merely because they are inside that file. Put project-specific logic behind generated interfaces or in separately owned manual classes.

3.1 Commit or ignore?

Both repository policies can be valid:

  • Regenerate during every build. Ignore replaceable output and make generation a required build step. This keeps the repository small and makes the authoritative inputs unambiguous.
  • Commit reviewed generated output. This can be useful for visible diffs, consumers that do not run JoinedWorkz, or published artifacts. CI should delete the declared replaceable trees, regenerate them and require a clean Git diff.

Choose one policy per output tree and record it in the project README or AI Context. A committed generated file is still generator-owned; committing it does not make manual edits safe.

Do not mix manual files, first-cut files, Flyway history and replaceable files in a directory that is cleaned as one unit.

4. First-cut output

SpringBoot first-cut outlets use overwriteExistingFiles=false and firstCutHandlerSource for generated handler implementation skeletons. The outlet creates a missing file but retains an existing file on later generation runs. This is a bootstrap mechanism, not a merge mechanism.

After the first successful generation:

  • review and commit the file;
  • treat it as manual project source;
  • maintain later model-driven changes yourself;
  • do not place its directory in a replaceable-output clean fileset.

If a model rename causes a new first-cut file to be generated, the previous manual file is not automatically renamed or deleted. Decide explicitly whether to migrate, retain or remove it.

5. Flyway output

The SpringBoot schema-migration outlets inherit the non-overwriting first-cut write behavior, but their ownership is defined by the migration mode:

  • STRICT: versioned SQL and matching schema snapshots form persistent migration history. Commit them together and never include their directories in generic generated-output cleanup.
  • DEVELOPMENT: R__DEV_work.sql and DEV_main_schema.json are temporary, replaceable working artifacts. The generator deletes and recreates them for the current model state. Remove them before generating the next STRICT migration.

Do not infer the policy from the path src/generated/resources: outlet routing can place migration history there even though most neighboring generated resources are replaceable.

Route migration history outside replaceable parent outlets

The SpringBoot defaults place the two stateful Flyway outlets below src/generated/resources, while the parent generatedConfiguration outlet is eligible for whole-directory cleanup in a Studio full generation. Route versioned migrations and snapshots to dedicated persistent directories such as src/main/resources/db/migration and src/main/resources/db/schema before using full-directory cleanup.

6. Clean regeneration and stale files

Generating a new file does not provide a project-wide manifest of every file created by previous runs. After a model element, package, resource or outlet route is renamed, the new output can therefore coexist with an obsolete old file.

If you have not yet established whether the problem is routing, generation or a later consumer build, begin with Troubleshooting.

The JoinedWorkz Maven goal generates artifacts; it does not configure Maven Clean for directories outside target. A normal mvn clean removes target by default, but not automatically src/generated or diagram.

For a single-module project, configure the Maven Clean Plugin with an explicit allowlist of dedicated replaceable directories:

xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-clean-plugin</artifactId>
    <version>3.5.0</version>
    <configuration>
        <filesets>
            <fileset>
                <directory>${project.basedir}/src/generated</directory>
                <followSymlinks>false</followSymlinks>
            </fileset>
            <fileset>
                <directory>${project.basedir}/diagram</directory>
                <followSymlinks>false</followSymlinks>
            </fileset>
        </filesets>
    </configuration>
</plugin>

Then use the lifecycle that your project verifies, for example:

sh
mvn clean verify

Safety rules:

  • clean only exact, dedicated replaceable directories;
  • never clean src/main, a repository root, a shared mixed-ownership directory or Flyway history;
  • when outputs are routed into sibling modules, include every mapped replaceable directory and make sure cleanup runs before generation;
  • after routing, package or namespace changes, search the previous locations for stale files;
  • after a JoinedWorkz upgrade, fully regenerate viewer directories so bundled HTML/JavaScript resources are refreshed as well;
  • run the complete consumer build, not generation alone.

Studio uses outlet metadata for its workspace build and full-generation cleanup. This does not replace an explicit Maven cleanup contract, especially for outputs routed to sibling projects. Use a clean Maven build as the release/CI check.

7. What outlet flags do and do not mean

Facility profiles define flags such as:

  • overwriteExistingFiles;
  • markAsDerived;
  • deleteFilesOnCleanBuild;
  • cleanWholdDirectoryOnCleanBuild;
  • keepLocalHistory.

These flags configure filesystem-access and Studio build behavior. They are not a repository commit policy, and they do not add Maven Clean Plugin filesets. They are profile declarations rather than public joinedworkz.properties overrides.

For exact profile syntax, see the Profile reference. For directory and layer-specific routing, see Multi-module setup with outlet overrides.

8. Taking generated code over manually

Readable generated code can be taken over if a project deliberately stops regenerating that artifact. Make the ownership transition explicit:

  1. disable or remove the responsible generation path;
  2. move the file out of any replaceable, automatically cleaned tree;
  3. document that the file is now manual and that the model no longer updates it;
  4. compile and test the project before refactoring it.

Do not refactor a file in place while the same cartridge still owns and regenerates it.

9. Guidance for AI tools

Before proposing a code change:

  1. trace the file back to its model, outlet and cartridge;
  2. classify it with the ownership matrix;
  3. modify authoritative inputs or manual sources only;
  4. regenerate replaceable output instead of patching it;
  5. preserve first-cut/manual files and Flyway history during cleanup;
  6. report stale or ambiguous ownership instead of guessing.

Reproducibility means the same complete inputs, generator versions and required starting state produce the same result after the declared cleanup. It does not mean that stale output, manually changed generated files or migration history can be ignored.