|
| 1 | += Requirements |
| 2 | +:toc: left |
| 3 | +:toc-title: Contents |
| 4 | +:toclevels: 2 |
| 5 | + |
| 6 | +Create a Maven archetype named `java-service-archetype` that generates a |
| 7 | +structured multi-module Java service project. In addition to the standard Maven |
| 8 | +coordinates (`groupId`, `artifactId`, `version`), prompt the user for the |
| 9 | +properties below, then produce the module structure described in this document. |
| 10 | + |
| 11 | +== Prompts |
| 12 | + |
| 13 | +=== `package` — base package |
| 14 | + |
| 15 | +Prompt for the base Java package for the application (e.g. `com.example.myapp`). |
| 16 | +All module sub-packages are derived from this value as described in |
| 17 | +<<source-structure>>. |
| 18 | + |
| 19 | +=== `integrations` |
| 20 | + |
| 21 | +Prompt for a comma-separated list of `type:name` pairs, one per external data |
| 22 | +source or system (e.g. `database:users,rest:orders,graphql:catalog`). |
| 23 | + |
| 24 | +* Abbreviate the `database` type to `db` in all generated module and package |
| 25 | + names; use all other types as-is. |
| 26 | +* Normalize all type and name values to lowercase. |
| 27 | +* Silently skip malformed entries (missing colon, blank type or name). |
| 28 | +* No default — leave blank to generate a project with no integration modules. |
| 29 | + |
| 30 | +=== `singleService` (default: `y`) |
| 31 | + |
| 32 | +Ask whether the application has a single unnamed service area. |
| 33 | + |
| 34 | +* `y` — generate one module named `service`; ignore `serviceAreas`. |
| 35 | +* `n` — use `serviceAreas` to name the service modules. |
| 36 | + |
| 37 | +=== `serviceAreas` (default: empty) |
| 38 | + |
| 39 | +Used when `singleService=n`. Prompt for a comma-separated list of service area |
| 40 | +names (e.g. `orders,inventory,notifications`). Generate a `service-{name}` |
| 41 | +module for each non-blank name. If no non-blank names are provided, fall back |
| 42 | +to a single module named `service`. |
| 43 | + |
| 44 | +=== `presentationTypes` (default: `rest`) |
| 45 | + |
| 46 | +Prompt for a comma-separated list of presentation-tier types |
| 47 | +(e.g. `rest,graphql`). |
| 48 | + |
| 49 | +* Normalize all type values to lowercase. |
| 50 | +* Leave blank (or provide only blank entries) to generate a project with no |
| 51 | + presentation modules. |
| 52 | + |
| 53 | +== Module Structure |
| 54 | + |
| 55 | +Generate all modules as siblings of a `parent/` directory. |
| 56 | +Do not create a `pom.xml` at the project root. |
| 57 | + |
| 58 | +=== `parent/` |
| 59 | + |
| 60 | +* `<packaging>pom</packaging>` |
| 61 | +* List every sibling module in `<modules>` using `../module` relative paths, |
| 62 | + sorted alphabetically. |
| 63 | +* List every sibling module in `<dependencyManagement>` pinned to |
| 64 | + `${project.version}`, sorted alphabetically by `artifactId`. |
| 65 | +* Properties: Java 21 via `maven.compiler.release`; UTF-8 source encoding via |
| 66 | + `project.build.sourceEncoding`. |
| 67 | +* `<pluginManagement>` — declare pinned versions for `maven-compiler-plugin`, |
| 68 | + `maven-failsafe-plugin`, `maven-jar-plugin` (configured with `skipIfEmpty=true`), |
| 69 | + and `maven-surefire-plugin`. |
| 70 | + |
| 71 | +=== Child module POMs |
| 72 | + |
| 73 | +Every module except `parent/` must declare `parent/pom.xml` as its parent |
| 74 | +using `<relativePath>../parent/pom.xml</relativePath>`. |
| 75 | + |
| 76 | +=== `common-domain` |
| 77 | + |
| 78 | +Shared domain classes. No dependencies on other generated modules. |
| 79 | + |
| 80 | +=== `common-testing` |
| 81 | + |
| 82 | +Shared test utilities. |
| 83 | + |
| 84 | +* Dependency: `common-domain` |
| 85 | +* No test-scope Java packages (the `src/test/java` directory is created but contains no source files). |
| 86 | + |
| 87 | +=== Per integration: `domain-{type}-{name}` and `integration-{type}-{name}` |
| 88 | + |
| 89 | +For each `type:name` integration entry, generate two modules |
| 90 | +(e.g. `domain-db-users` and `integration-db-users`): |
| 91 | + |
| 92 | +* `domain-{type}-{name}` — domain classes for this data source. |
| 93 | + Dependency: `common-domain`. |
| 94 | +* `integration-{type}-{name}` — implementation classes (DAOs, repositories, |
| 95 | + clients, etc.). |
| 96 | + Dependencies: `common-domain`, `domain-{type}-{name}`. |
| 97 | + Configure `maven-failsafe-plugin` with the `integration-test` and `verify` goals. |
| 98 | + |
| 99 | +=== Per service area: `service` or `service-{name}` |
| 100 | + |
| 101 | +Business logic for a service area. |
| 102 | +Dependency: `common-domain`. |
| 103 | + |
| 104 | +=== Per presentation tier: `domain-{type}` and `presentation-{type}` |
| 105 | + |
| 106 | +For each presentation type, generate two modules |
| 107 | +(e.g. `domain-rest` and `presentation-rest`): |
| 108 | + |
| 109 | +* `domain-{type}` — domain classes for this presentation tier. |
| 110 | + Dependency: `common-domain`. |
| 111 | +* `presentation-{type}` — request-handling classes (controllers, etc.). |
| 112 | + Dependencies: `common-domain`, `domain-{type}`. |
| 113 | + |
| 114 | +=== `app` |
| 115 | + |
| 116 | +Assembles the runnable artifact (e.g. Spring Boot uber jar). |
| 117 | +Depend on all generated modules except `acceptance-tests`, `common-testing`, |
| 118 | +and `app` itself. |
| 119 | + |
| 120 | +=== `acceptance-tests` |
| 121 | + |
| 122 | +Functional tests that exercise the application end-to-end. |
| 123 | +No main-scope Java packages (the `src/main/java` directory is created but contains no source files). |
| 124 | + |
| 125 | +* Dependencies: `app`, `common-domain`, all `domain-{type}-{name}` modules, |
| 126 | + all `domain-{type}` (presentation) modules. |
| 127 | +* Do not depend on service modules or integration implementation modules. |
| 128 | +* Configure `maven-failsafe-plugin` with the `integration-test` and `verify` goals. |
| 129 | + |
| 130 | +[[source-structure]] |
| 131 | +== Source Structure |
| 132 | + |
| 133 | +Each module's source root is the package derived from the base package prompt. |
| 134 | +Place a `package-info.java` in each leaf package directory with a Javadoc comment |
| 135 | +describing the package's purpose. |
| 136 | +The package for each module is: |
| 137 | + |
| 138 | +[cols="1,1"] |
| 139 | +|=== |
| 140 | +|Module |Package |
| 141 | + |
| 142 | +|`common-domain` |`${base.package}.common.domain` |
| 143 | +|`common-testing` |`${base.package}.common.testing` |
| 144 | +|`domain-{type}-{name}` |`${base.package}.domain.{type}.{name}` |
| 145 | +|`integration-{type}-{name}` |`${base.package}.integration.{type}.{name}` |
| 146 | +|`service` |`${base.package}.service` |
| 147 | +|`service-{name}` |`${base.package}.service.{name}` |
| 148 | +|`domain-{type}` |`${base.package}.domain.{type}` |
| 149 | +|`presentation-{type}` |`${base.package}.presentation.{type}` |
| 150 | +|`app` |`${base.package}.app` |
| 151 | +|`acceptance-tests` |`${base.package}.at` |
| 152 | +|=== |
0 commit comments