@rashidee/co2 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25449 -0
- package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
- package/drizzle/0001_wise_wolf_cub.sql +13 -0
- package/drizzle/0002_secret_spyke.sql +16 -0
- package/drizzle/0003_workspace_config_singleton.sql +16 -0
- package/drizzle/0004_terminal_claim_v120.sql +11 -0
- package/drizzle/0005_brainstorm_v124.sql +10 -0
- package/drizzle/0006_project_v140.sql +6 -0
- package/drizzle/0007_prd_wizard_v124.sql +14 -0
- package/drizzle/0008_workflow_artifact_v126.sql +24 -0
- package/drizzle/0009_project_import_v150.sql +7 -0
- package/drizzle/0010_quality_v151.sql +3 -0
- package/drizzle/meta/0000_snapshot.json +1335 -0
- package/drizzle/meta/0001_snapshot.json +1416 -0
- package/drizzle/meta/0002_snapshot.json +1510 -0
- package/drizzle/meta/_journal.json +83 -0
- package/package.json +41 -0
- package/plugin/.claude-plugin/marketplace.json +36 -0
- package/plugin/.claude-plugin/plugin.json +22 -0
- package/plugin/README.md +625 -0
- package/plugin/SKILLS.md +350 -0
- package/plugin/co2.svg +5 -0
- package/plugin/commands/brainstorm-loop.md +129 -0
- package/plugin/skills/conductor-defect/SKILL.md +898 -0
- package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
- package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
- package/plugin/skills/depgen-k8s/SKILL.md +468 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
- package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
- package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
- package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
- package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
- package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
- package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
- package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
- package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
- package/plugin/skills/modelgen-relational/SKILL.md +707 -0
- package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
- package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
- package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
- package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
- package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
- package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
- package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
- package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
- package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
- package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
- package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
- package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
- package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
- package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
- package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
- package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
- package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
- package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
- package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
- package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
- package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
- package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
- package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
- package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
- package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
- package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
- package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
- package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
- package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
- package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
- package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
- package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
- package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
- package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
- package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
- package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
- package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
- package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
- package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
- package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
- package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
- package/plugin/skills/testgen-functional/SKILL.md +1381 -0
- package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
- package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
- package/plugin/skills/util-projectinit/SKILL.md +307 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
- package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
- package/plugin/skills/util-projectsync/SKILL.md +501 -0
- package/plugin/skills/util-updprd/SKILL.md +324 -0
- package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
- package/plugin/skills/util-ustagger/SKILL.md +154 -0
- package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
- package/static/assets/arc-DRKw7sjs.js +1 -0
- package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
- package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
- package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
- package/static/assets/channel-C2nVbuwv.js +1 -0
- package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
- package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
- package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
- package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
- package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
- package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
- package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
- package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
- package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
- package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
- package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
- package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
- package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
- package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
- package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
- package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
- package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
- package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
- package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
- package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
- package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
- package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
- package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
- package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
- package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
- package/static/assets/graph-C9eacEi8.js +1 -0
- package/static/assets/index-LZSQkLE2.css +41 -0
- package/static/assets/index-y7XDSgMG.js +495 -0
- package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
- package/static/assets/init-Gi6I4Gst.js +1 -0
- package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
- package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
- package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
- package/static/assets/katex-C5jXJg4s.js +257 -0
- package/static/assets/layout-DEXfKzaS.js +1 -0
- package/static/assets/linear-CLO--ryk.js +1 -0
- package/static/assets/map-Czzmt4hB.js +1 -0
- package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
- package/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
- package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
- package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
- package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
- package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
- package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
- package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
- package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
- package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
- package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
- package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
- package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
- package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
- package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
- package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
- package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
- package/static/index.html +24 -0
|
@@ -0,0 +1,1284 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specgen-spring-jpa-jtehtmx
|
|
3
|
+
model: claude-opus-4-8
|
|
4
|
+
effort: high
|
|
5
|
+
description: >
|
|
6
|
+
Generate a detailed specification document for building a monolith Spring Boot 3 web
|
|
7
|
+
application with server-rendered views (JTE), Tailwind CSS, Alpine.js, htmx, and
|
|
8
|
+
Spring Modulith packaging. Database (MongoDB, PostgreSQL, MySQL, or none), authentication
|
|
9
|
+
(Keycloak OAuth2 Client, Spring Security form login, or none), scheduling (Quartz +
|
|
10
|
+
Spring Batch or none), messaging (RabbitMQ pub/sub or none), and internationalisation
|
|
11
|
+
(multi-locale via Spring's native MessageSource, or none) are configurable
|
|
12
|
+
based on user input.
|
|
13
|
+
Standardized input: application name (mandatory), version (mandatory), module (optional).
|
|
14
|
+
Use this skill whenever the user asks to create a spec, specification, blueprint, or
|
|
15
|
+
technical design document for a new Spring Boot web application with server-side rendering.
|
|
16
|
+
Also trigger when the user says things like "spec out a new web project",
|
|
17
|
+
"design a Spring Boot web skeleton", "write a technical spec for my new web app",
|
|
18
|
+
"scaffold spec for a monolith web app", or any request for a specification document
|
|
19
|
+
describing a Spring Boot + JTE + Tailwind application. Even if the user only mentions
|
|
20
|
+
a subset of the stack (e.g., "Spring Boot web app" or "Spring web with Mongo" or
|
|
21
|
+
"Spring Boot with Keycloak"), this skill likely applies — ask and confirm.
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Spring Boot Web Application Specification Generator
|
|
25
|
+
|
|
26
|
+
This skill generates a comprehensive specification document (Markdown) that serves as a
|
|
27
|
+
blueprint for building a monolith Spring Boot 3 web application with server-rendered
|
|
28
|
+
views. The spec is intended to be followed by a developer or a coding agent to produce
|
|
29
|
+
a fully functional project scaffold.
|
|
30
|
+
|
|
31
|
+
The specification does NOT generate code. It produces a detailed, opinionated technical
|
|
32
|
+
document describing every layer of the application — from Maven configuration to JTE
|
|
33
|
+
layouts to security filter chains — so that implementation becomes a mechanical exercise.
|
|
34
|
+
|
|
35
|
+
## Technology Stack
|
|
36
|
+
|
|
37
|
+
### Core Stack (Always Included)
|
|
38
|
+
|
|
39
|
+
These are the fixed versions the spec targets. Do not deviate unless the user explicitly
|
|
40
|
+
requests different versions.
|
|
41
|
+
|
|
42
|
+
| Component | Version |
|
|
43
|
+
|--------------------|-----------|
|
|
44
|
+
| Java JDK | 21 |
|
|
45
|
+
| Spring Boot | 3.5.7 |
|
|
46
|
+
| Maven | 4.0.0 |
|
|
47
|
+
| JTE | 3.2.1 |
|
|
48
|
+
| Tailwind CSS | 4.x |
|
|
49
|
+
| Alpine.js | 3.x |
|
|
50
|
+
| htmx | 2.x |
|
|
51
|
+
| Vite | 6.x |
|
|
52
|
+
|
|
53
|
+
### Optional Integration Versions
|
|
54
|
+
|
|
55
|
+
Include in the version table only when the corresponding integration is selected.
|
|
56
|
+
|
|
57
|
+
| Component | Version | When Selected |
|
|
58
|
+
|--------------------|-----------|----------------------|
|
|
59
|
+
| MongoDB | 8.0.19 | Database = MongoDB |
|
|
60
|
+
| PostgreSQL | 17.x | Database = PostgreSQL|
|
|
61
|
+
| MySQL | 8.4.x | Database = MySQL |
|
|
62
|
+
| Keycloak | 26.5.3 | Auth = Keycloak |
|
|
63
|
+
| RabbitMQ | 4.x | Messaging = yes OR Remote Partitioning = yes |
|
|
64
|
+
|
|
65
|
+
## Core Dependencies
|
|
66
|
+
|
|
67
|
+
The spec must include these in the Maven configuration section (always):
|
|
68
|
+
|
|
69
|
+
- Spring Web (starter-web)
|
|
70
|
+
- Spring Modulith (core, events-api)
|
|
71
|
+
- JTE Spring Boot Starter (`gg.jte:jte-spring-boot-starter-3`)
|
|
72
|
+
- JTE precompiler (`gg.jte:jte-maven-plugin` with `precompile` goal at `process-classes` phase, output to `target/classes` so precompiled templates are included in the Spring Boot fat JAR)
|
|
73
|
+
- Lombok
|
|
74
|
+
- Spring Boot DevTools
|
|
75
|
+
- MapStruct (with annotation processor)
|
|
76
|
+
- frontend-maven-plugin (for Node/Vite build)
|
|
77
|
+
|
|
78
|
+
### Conditional Dependencies
|
|
79
|
+
|
|
80
|
+
**If Database = MongoDB:**
|
|
81
|
+
- Spring Data MongoDB (`spring-boot-starter-data-mongodb`)
|
|
82
|
+
- MongoDB Driver
|
|
83
|
+
- Spring Modulith starter-mongodb (`spring-modulith-starter-mongodb`)
|
|
84
|
+
|
|
85
|
+
**If Database = PostgreSQL or MySQL:**
|
|
86
|
+
- Spring Data JPA (`spring-boot-starter-data-jpa`)
|
|
87
|
+
- PostgreSQL driver (`org.postgresql:postgresql`) or MySQL driver (`com.mysql:mysql-connector-j`)
|
|
88
|
+
- Flyway (`org.flywaydb:flyway-core`) for schema migration
|
|
89
|
+
- Spring Modulith starter-jpa (`spring-modulith-starter-jpa`)
|
|
90
|
+
|
|
91
|
+
**If Auth = Keycloak:**
|
|
92
|
+
- Spring Security (`spring-boot-starter-security`)
|
|
93
|
+
- Spring Security OAuth2 Client (`spring-boot-starter-oauth2-client`)
|
|
94
|
+
|
|
95
|
+
**If Auth = Spring Security (form login):**
|
|
96
|
+
- Spring Security (`spring-boot-starter-security`)
|
|
97
|
+
|
|
98
|
+
**If Scheduling = yes:**
|
|
99
|
+
- Spring Quartz (`spring-boot-starter-quartz`)
|
|
100
|
+
- If Database = MongoDB: `io.fluidsonic.mirror:fluidsonic-mirror-quartz` (MongoDB job store for Quartz)
|
|
101
|
+
- If Database = PostgreSQL/MySQL: Quartz JDBC job store (built-in)
|
|
102
|
+
|
|
103
|
+
**If Scheduling = yes AND Spring Batch = yes:**
|
|
104
|
+
- Spring Batch (`spring-boot-starter-batch`)
|
|
105
|
+
|
|
106
|
+
**If Scheduling = yes AND Spring Batch = yes AND Remote Partitioning = yes:**
|
|
107
|
+
- Spring Batch Integration (`spring-batch-integration`)
|
|
108
|
+
- Spring Integration AMQP (`spring-integration-amqp`)
|
|
109
|
+
- Spring Boot AMQP Starter (`spring-boot-starter-amqp`)
|
|
110
|
+
|
|
111
|
+
**If Messaging = yes:**
|
|
112
|
+
- Spring Boot AMQP Starter (`spring-boot-starter-amqp`)
|
|
113
|
+
*(shared with Remote Partitioning — if both are selected, include the dependency once)*
|
|
114
|
+
|
|
115
|
+
**If i18n = yes:**
|
|
116
|
+
- No extra dependency — uses Spring's **built-in `MessageSource`** (part of `spring-context`,
|
|
117
|
+
already on the classpath via `starter-web`). Resource bundles under
|
|
118
|
+
`src/main/resources/i18n/`, a `CookieLocaleResolver`, and a `LocaleChangeInterceptor`
|
|
119
|
+
provide locale resolution and switching; a small `Localizer` helper exposes messages to
|
|
120
|
+
JTE templates.
|
|
121
|
+
|
|
122
|
+
**If Reporting = yes:**
|
|
123
|
+
- JasperReports (`net.sf.jasperreports:jasperreports:7.0.3`) — report engine with JRDesign API for programmatic layout
|
|
124
|
+
- JasperReports Fonts (`net.sf.jasperreports:jasperreports-fonts:7.0.3`)
|
|
125
|
+
- OpenPDF (`com.github.librepdf:openpdf:2.0.4`) — PDF export engine for JasperReports 7.x
|
|
126
|
+
- Apache POI OOXML (`org.apache.poi:poi-ooxml:5.4.1`) — XLSX export support
|
|
127
|
+
|
|
128
|
+
## When the Skill Triggers
|
|
129
|
+
|
|
130
|
+
Generate the spec when the user provides an **application name** and **version** that
|
|
131
|
+
corresponds to one of the custom applications defined in `CLAUDE.md`. The skill
|
|
132
|
+
reads all required inputs from the project's context files — no interactive Q&A is needed
|
|
133
|
+
for the core inputs.
|
|
134
|
+
|
|
135
|
+
The user invokes this skill by specifying the target application and version, for example:
|
|
136
|
+
- `/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3`
|
|
137
|
+
- `/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3 module:Location Information`
|
|
138
|
+
- `/specgen-spring-jpa-jtehtmx "Hub Middleware" v1.0.3`
|
|
139
|
+
|
|
140
|
+
The skill then locates the matching context folder and reads all input files automatically.
|
|
141
|
+
|
|
142
|
+
## Version Gate
|
|
143
|
+
|
|
144
|
+
Before starting any work, resolve the application folder first (see Input Resolution below), then check `CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
|
|
145
|
+
|
|
146
|
+
1. If `<app_folder>/CHANGELOG.md` does not exist, skip this check (first-ever execution for this application).
|
|
147
|
+
2. If `<app_folder>/CHANGELOG.md` exists, scan all `## vX.Y.Z` headings and determine the **highest version** using semantic versioning comparison.
|
|
148
|
+
3. Compare the requested version against the highest version:
|
|
149
|
+
- If requested version **>=** highest version: proceed normally.
|
|
150
|
+
- If requested version **<** highest version: **STOP immediately**. Print: `"Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected."` Do NOT proceed with any work.
|
|
151
|
+
|
|
152
|
+
## Input Resolution
|
|
153
|
+
|
|
154
|
+
This skill uses standardized input resolution. Provide:
|
|
155
|
+
|
|
156
|
+
| Argument | Required | Example | Description |
|
|
157
|
+
|----------|----------|---------|-------------|
|
|
158
|
+
| `<application>` | Yes | `hub_middleware` | Application name to locate the context folder |
|
|
159
|
+
| `<version>` | Yes | `v1.0.3` | Version to scope processing |
|
|
160
|
+
| `module:<name>` | No | `module:Location Information` | Limit generation to a single module |
|
|
161
|
+
|
|
162
|
+
### Application Folder Resolution
|
|
163
|
+
|
|
164
|
+
The application name is matched against root-level application folders:
|
|
165
|
+
1. Strip any leading `<number>_` prefix from folder names (e.g., `1_hub_middleware` → `hub_middleware`)
|
|
166
|
+
2. Match case-insensitively against the provided application name
|
|
167
|
+
3. Accept snake_case, kebab-case, or title-case input (all match the same folder)
|
|
168
|
+
4. If no match found, list available applications and stop
|
|
169
|
+
|
|
170
|
+
### Auto-Resolved Paths
|
|
171
|
+
|
|
172
|
+
| File | Resolved Path |
|
|
173
|
+
|------|---------------|
|
|
174
|
+
| PRD.md | `<app_folder>/context/PRD.md` |
|
|
175
|
+
| Module Models | `<app_folder>/context/model/` |
|
|
176
|
+
| HTML Mockups | `<app_folder>/context/mockup/` |
|
|
177
|
+
| Output (specification) | `<app_folder>/context/specification/` |
|
|
178
|
+
|
|
179
|
+
### Example Invocations
|
|
180
|
+
|
|
181
|
+
- `/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3` (all modules)
|
|
182
|
+
- `/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3 module:Location Information` (one module)
|
|
183
|
+
- `/specgen-spring-jpa-jtehtmx "Hub Middleware" v1.0.3`
|
|
184
|
+
|
|
185
|
+
### Version Filtering
|
|
186
|
+
|
|
187
|
+
When a version is provided, only include user stories, NFRs, and constraints from versions
|
|
188
|
+
<= the provided version. For example, if `v1.0.3` is specified:
|
|
189
|
+
- Include items tagged `[v1.0.0]`, `[v1.0.1]`, `[v1.0.2]`, `[v1.0.3]`
|
|
190
|
+
- Exclude items tagged `[v1.0.4]` or later
|
|
191
|
+
- Version comparison uses semantic versioning order
|
|
192
|
+
|
|
193
|
+
### Module Filtering
|
|
194
|
+
|
|
195
|
+
When `module:<name>` is provided:
|
|
196
|
+
- Only generate the `SPEC.md` for that specific module
|
|
197
|
+
- Other existing module spec files remain untouched
|
|
198
|
+
- `SPECIFICATION.md` (root) gets a partial update — only that module's entry in the TOC
|
|
199
|
+
is added or updated; all other TOC entries are preserved as-is
|
|
200
|
+
|
|
201
|
+
## Gathering Input
|
|
202
|
+
|
|
203
|
+
The specification is driven by **six input sources** that are read from the project's
|
|
204
|
+
context files. The skill does NOT ask the user for database, authentication, scheduling,
|
|
205
|
+
or messaging choices — it **determines** these automatically from the context.
|
|
206
|
+
|
|
207
|
+
### Input 1: Application Name (from CLAUDE.md)
|
|
208
|
+
|
|
209
|
+
From CLAUDE.md (already loaded in context), locate the target application under the **Custom Applications**
|
|
210
|
+
section. Extract:
|
|
211
|
+
|
|
212
|
+
- **Application name**: The section heading (e.g., "Hub Middleware", "HC Adapter")
|
|
213
|
+
- **Application description**: The description paragraph below the heading
|
|
214
|
+
- **Dependencies**: The "Depends on" list — this is the primary source for determining
|
|
215
|
+
optional components (see [Determining Optional Components](#determining-optional-components))
|
|
216
|
+
|
|
217
|
+
The application name is used to derive:
|
|
218
|
+
- **Artifact ID**: Kebab-case of the application name (e.g., `hub-middleware`)
|
|
219
|
+
- **Group ID**: `com.bestinet.urp` (project-level constant)
|
|
220
|
+
- **Base package**: `com.bestinet.urp.<artifactid_no_hyphens>` (e.g., `com.bestinet.urp.hubmiddleware`)
|
|
221
|
+
|
|
222
|
+
### Input 2: User Stories (from PRD.md)
|
|
223
|
+
|
|
224
|
+
Read `<app_folder>/context/PRD.md`. This file contains all user stories
|
|
225
|
+
organized by module. Extract:
|
|
226
|
+
|
|
227
|
+
- **System modules**: Modules under the `# System Module` heading (e.g., User, Notification,
|
|
228
|
+
Activities, Audit Trail). These become system-level modules in the spec.
|
|
229
|
+
- **Business modules**: Modules under the `# Business Module` heading (e.g., Location
|
|
230
|
+
Information, Corridor, Employer). These become business-level modules.
|
|
231
|
+
- **User stories per module**: Each `### User Story` section contains tagged items like
|
|
232
|
+
`[USHM00108] As a user, I want to...`. These define the functional requirements for
|
|
233
|
+
each module's service interface and page controllers.
|
|
234
|
+
|
|
235
|
+
The user stories directly inform:
|
|
236
|
+
- Which CRUD operations each module's service must expose
|
|
237
|
+
- Which page controllers and JTE views are needed
|
|
238
|
+
- Which form fields and validation rules apply
|
|
239
|
+
|
|
240
|
+
**Important:** Items with strikethrough (`~~text~~`) are deprecated — do NOT include them
|
|
241
|
+
as active requirements. Instead, list them in the "Removed / Replaced" subsection of the
|
|
242
|
+
traceability table (see spec-template.md) so that developers can see what was removed and
|
|
243
|
+
which version removed it. If a deprecated item has a replacement (e.g., `USHM00015` replaced
|
|
244
|
+
by `USHM00222`), note the replacement ID.
|
|
245
|
+
|
|
246
|
+
- **Version tags per item**: Each `### User Story`, `### Non Functional Requirement`,
|
|
247
|
+
and `### Constraint` section contains one or more version blocks formatted as `[v1.0.x]`.
|
|
248
|
+
Items listed under each version tag belong to that version. The skill must track the
|
|
249
|
+
version tag for each item (user story, NFR, constraint) and carry it through to the
|
|
250
|
+
generated specification's traceability section. When a version block explicitly lists
|
|
251
|
+
"Removed ... from previous version", record those removals in a "Removed / Replaced"
|
|
252
|
+
subsection with the version that removed them and the replacement ID (if any).
|
|
253
|
+
|
|
254
|
+
### Input 3: Non-Functional Requirements (from PRD.md)
|
|
255
|
+
|
|
256
|
+
Within the same `PRD.md`, each module has a `### Non Functional Requirement` section
|
|
257
|
+
with tagged items like `[NFRHM0120]`. These inform:
|
|
258
|
+
|
|
259
|
+
- Data storage strategies (e.g., "stored in JWT token", "stored in the database")
|
|
260
|
+
- Integration patterns (e.g., "API call to SSO service", "sent asynchronously")
|
|
261
|
+
- Performance constraints (e.g., "automatically deleted after 30 days")
|
|
262
|
+
- Security requirements (e.g., "require user to relogin")
|
|
263
|
+
|
|
264
|
+
NFRs should be mapped to specific technical decisions in the spec — for example, an NFR
|
|
265
|
+
stating "stored in JWT token" confirms stateless auth, while "sent asynchronously" confirms
|
|
266
|
+
event-driven processing.
|
|
267
|
+
|
|
268
|
+
### Input 4: Constraints (from PRD.md)
|
|
269
|
+
|
|
270
|
+
Within the same `PRD.md`, each module has a `### Constraint` section with tagged
|
|
271
|
+
items like `[CONSHM042]`. These define hard boundaries that the spec must enforce:
|
|
272
|
+
|
|
273
|
+
- Field-level restrictions (e.g., "can only change name and phone number")
|
|
274
|
+
- Feature boundaries (e.g., "only 2 delivery channels supported")
|
|
275
|
+
- Scope limitations (e.g., "does not manage any user, permissions and roles")
|
|
276
|
+
|
|
277
|
+
Constraints are embedded directly into the relevant module blueprint — they inform
|
|
278
|
+
service interface contracts, validation rules, and UI form configurations.
|
|
279
|
+
|
|
280
|
+
### Input 5: Module Model (from model/ folder)
|
|
281
|
+
|
|
282
|
+
Read `<app_folder>/context/model/MODEL.md` first as the index, then read the
|
|
283
|
+
individual module model files in each module subfolder.
|
|
284
|
+
|
|
285
|
+
**MODEL.md** provides:
|
|
286
|
+
- Summary table of all modules with collection counts and design decisions
|
|
287
|
+
- Links to each module's detailed model files
|
|
288
|
+
|
|
289
|
+
**Per-module files** (e.g., `model/location-information/model.md`):
|
|
290
|
+
- Complete document/entity field definitions with types and constraints
|
|
291
|
+
- Embedded vs. referenced relationships
|
|
292
|
+
- Collection/table names
|
|
293
|
+
- Index specifications
|
|
294
|
+
- Audit field patterns
|
|
295
|
+
|
|
296
|
+
**Per-module schema** (e.g., `model/location-information/schemas.json`):
|
|
297
|
+
- JSON schemas defining exact field types, required fields, and validation rules
|
|
298
|
+
|
|
299
|
+
**Per-module diagram** (e.g., `model/location-information/document-model.mermaid`):
|
|
300
|
+
- Visual representation of document structure and relationships
|
|
301
|
+
|
|
302
|
+
The module model directly maps to:
|
|
303
|
+
- MongoDB documents or JPA entities (field-for-field, not placeholder)
|
|
304
|
+
- Repository methods and query patterns
|
|
305
|
+
- MapStruct mapper definitions
|
|
306
|
+
- DTO structures matching the actual module fields
|
|
307
|
+
- Service interface method signatures
|
|
308
|
+
|
|
309
|
+
- **Version tracking**: The MODEL.md summary table includes a "Versions" column listing
|
|
310
|
+
which versions each module participates in (e.g., "1.0.0, 1.0.1, 1.0.3"). Per-module
|
|
311
|
+
model.md files may also include version annotations on fields and indexes. The skill
|
|
312
|
+
must carry these version tags into the generated specification.
|
|
313
|
+
|
|
314
|
+
### Input 6: HTML Mockup Screens (from mockup/ folder)
|
|
315
|
+
|
|
316
|
+
Read `<app_folder>/context/mockup/MOCKUP.html` first as the index page, then
|
|
317
|
+
read the HTML files organized by role in subfolders.
|
|
318
|
+
|
|
319
|
+
**MOCKUP.html** provides:
|
|
320
|
+
- Application identity (name, version, short name)
|
|
321
|
+
- Design tokens: fonts, colors, spacing from Tailwind config
|
|
322
|
+
- List of user roles and their screen sets
|
|
323
|
+
- Setup instructions for the shared Mockup Hub (`<root>/mockup`)
|
|
324
|
+
|
|
325
|
+
**Role-specific subfolders** (e.g., `mockup/hub_administrator/content/`):
|
|
326
|
+
- Individual HTML screens for each page in the application
|
|
327
|
+
- Screen layout: which components are used (tables, forms, cards, tabs, modals)
|
|
328
|
+
- Navigation structure from sidebar HTML files
|
|
329
|
+
- Data display patterns (list pages, detail pages, create/edit forms)
|
|
330
|
+
|
|
331
|
+
**IMPORTANT — Role folders inform access control, NOT URL paths.** The role-specific
|
|
332
|
+
folder structure (e.g., `mockup/hub_administrator/content/corridor.html`) determines:
|
|
333
|
+
1. Which role can access the page → `@PreAuthorize("hasRole('HUB_ADMINISTRATOR')")`
|
|
334
|
+
2. Which sidebar navigation items appear for each role
|
|
335
|
+
It does NOT determine the URL path. The URL path is always module-based:
|
|
336
|
+
- `@RequestMapping("/corridor")` — NOT `@RequestMapping("/hub_administrator/corridor")`
|
|
337
|
+
- Fragment URL: `@RequestMapping("/corridor/fragments")` — NOT `@RequestMapping("/api/content/hub_administrator/corridor")`
|
|
338
|
+
|
|
339
|
+
**Shared partials** (e.g., `mockup/partials/`):
|
|
340
|
+
- `header.html` — Header bar layout and elements
|
|
341
|
+
- `footer.html` — Footer layout
|
|
342
|
+
- `sidebar-<role>.html` — Per-role navigation menus
|
|
343
|
+
- `shell.html` — Page shell/wrapper structure
|
|
344
|
+
|
|
345
|
+
The mockup screens directly map to:
|
|
346
|
+
- JTE page templates (one per HTML screen)
|
|
347
|
+
- JTE fragment templates (for htmx partial updates)
|
|
348
|
+
- Page controller endpoints (one per screen)
|
|
349
|
+
- View model classes (with fields matching the data shown in each screen)
|
|
350
|
+
- Sidebar navigation items per role
|
|
351
|
+
- Form field layouts and validation display
|
|
352
|
+
- Design tokens for Tailwind configuration (colors, fonts from MOCKUP.html)
|
|
353
|
+
|
|
354
|
+
- **Version tracking**: The MOCKUP.html index page shows a version tag on each screen
|
|
355
|
+
card (e.g., `v1.0.0`, `v1.0.3`). Individual mockup screens may include version
|
|
356
|
+
annotations. The skill must associate each mockup screen with its version and carry
|
|
357
|
+
this through to the generated specification.
|
|
358
|
+
|
|
359
|
+
## PRD.md Extended Sections
|
|
360
|
+
|
|
361
|
+
Before determining optional components, check PRD.md for the following extended sections and extract their content for use throughout specification generation:
|
|
362
|
+
|
|
363
|
+
### Architecture Principle Extraction
|
|
364
|
+
|
|
365
|
+
If PRD.md contains an `# Architecture Principle` section, read it and extract architectural patterns as a structured context object. These patterns serve as **primary signals** for optional component determination and specification content:
|
|
366
|
+
|
|
367
|
+
| Pattern to Extract | How It Influences the Specification |
|
|
368
|
+
|---|---|
|
|
369
|
+
| Framework mention (e.g., "Spring Boot") | Validates technology stack choice; confirms Spring Modulith approach |
|
|
370
|
+
| "Monolithic" / "modular architecture" | Validates Spring Modulith module structure; cross-module communication via application events |
|
|
371
|
+
| "Stateless" | Confirms no HTTP session — JWT/OAuth2 token-based auth; include in Security Configuration section |
|
|
372
|
+
| "Event-driven" | Enhances Event-Driven Architecture section (Section 14) with event catalog, event payload DTOs, and explicit listener registration patterns per module |
|
|
373
|
+
| "Message driven" / "message queue" | Validates RabbitMQ integration sections; include message flow documentation per module |
|
|
374
|
+
| "Document based database" / "MongoDB" | Primary signal for Database = MongoDB (overrides CLAUDE.md if conflicting) |
|
|
375
|
+
| "Container based deployment" | Confirms environment-variable-based configuration (`${ENV_VAR}` syntax) |
|
|
376
|
+
| "Scale out" / "horizontally scalable" | Include HPA-related notes in deployment considerations |
|
|
377
|
+
| View engine mention (e.g., "JTE") | Validates JTE template engine choice |
|
|
378
|
+
| Build tool mention (e.g., "Vite") | Include Vite build configuration in the specification |
|
|
379
|
+
|
|
380
|
+
If the section is absent, proceed with existing CLAUDE.md-only detection.
|
|
381
|
+
|
|
382
|
+
### Design System Extraction
|
|
383
|
+
|
|
384
|
+
If PRD.md contains a `# Design System` section with a file reference (e.g., `[DESIGN_SYSTEM.md](reference/DESIGN_SYSTEM.md)`):
|
|
385
|
+
1. Resolve the path relative to PRD.md and read the referenced file
|
|
386
|
+
2. Extract design tokens: color palettes, typography, component patterns
|
|
387
|
+
3. Include a "Design System Integration" subsection in SPECIFICATION.md under "Application Configuration" specifying:
|
|
388
|
+
- Tailwind CSS custom theme configuration (colors, fonts from design system)
|
|
389
|
+
- JTE layout template design token variables
|
|
390
|
+
- CSS variable definitions for dynamic theming
|
|
391
|
+
4. In per-module SPEC.md, reference which design tokens apply to specific components (e.g., status badges use `accent-success` color for Active)
|
|
392
|
+
|
|
393
|
+
If the section is absent, use design tokens from MOCKUP.html Tailwind config (existing behavior).
|
|
394
|
+
|
|
395
|
+
### High Level Process Flow Extraction
|
|
396
|
+
|
|
397
|
+
If PRD.md contains a `# High Level Process Flow` section:
|
|
398
|
+
1. Parse all named process flows and their ordered steps
|
|
399
|
+
2. Each process flow becomes an **authoritative source** for the messaging pipeline sections in per-module SPEC.md:
|
|
400
|
+
- Each step maps to a specific service method, event listener, or message handler
|
|
401
|
+
- Error paths generate corresponding exception handlers and dead-letter queue configurations
|
|
402
|
+
- ACK/NACK patterns become outbound message publisher specifications with defined message schemas
|
|
403
|
+
3. Include a "Process Flow Implementation" subsection in each affected module's SPEC.md that maps flow steps to service methods
|
|
404
|
+
4. Generate an event catalog in SPECIFICATION.md listing all domain events derived from process flows
|
|
405
|
+
|
|
406
|
+
If the section is absent, derive messaging patterns from NFRs only (existing behavior).
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Determining Optional Components
|
|
411
|
+
|
|
412
|
+
Instead of asking the user, the skill determines optional components by analyzing the
|
|
413
|
+
dependencies listed in `CLAUDE.md`, the `# Architecture Principle` section in PRD.md (if present),
|
|
414
|
+
and cross-referencing with PRD.md NFRs and constraints.
|
|
415
|
+
|
|
416
|
+
### Database Detection
|
|
417
|
+
|
|
418
|
+
**First check PRD.md `# Architecture Principle`**: If it explicitly mentions a database type (e.g., "document based database", "MongoDB", "relational database", "MySQL"), use that as the primary signal.
|
|
419
|
+
|
|
420
|
+
**Fallback to CLAUDE.md**: Examine the "Depends on" list in CLAUDE.md for the target application:
|
|
421
|
+
|
|
422
|
+
| Dependency Pattern | Database Selection |
|
|
423
|
+
|---|---|
|
|
424
|
+
| References "Hub Database" (MongoDB) | Database = MongoDB |
|
|
425
|
+
| References "HC Database" or "SC Database" (MySQL) | Database = MySQL |
|
|
426
|
+
| No database dependency listed | Database = none |
|
|
427
|
+
|
|
428
|
+
Also check `CLAUDE.md`'s database section for the exact database name, and read
|
|
429
|
+
`ENVIRONMENT.md` (in the project root) for host, port, and credentials to use in the
|
|
430
|
+
spec's application configuration.
|
|
431
|
+
|
|
432
|
+
### Authentication Detection
|
|
433
|
+
|
|
434
|
+
| Dependency Pattern | Auth Selection |
|
|
435
|
+
|---|---|
|
|
436
|
+
| References "Hub Single Sign On" (Keycloak) | Auth = Keycloak |
|
|
437
|
+
| PRD.md constraint says "does not manage any user, permissions and roles" | Auth = none |
|
|
438
|
+
| PRD.md NFRs reference "SSO service" or "JWT token" | Auth = Keycloak |
|
|
439
|
+
| No SSO/Keycloak dependency but has user management stories | Auth = form |
|
|
440
|
+
|
|
441
|
+
If Auth = Keycloak, also extract from CLAUDE.md:
|
|
442
|
+
- Keycloak version from "Hub Single Sign On" section
|
|
443
|
+
- Keycloak realm: Default derived from project name
|
|
444
|
+
- Keycloak client ID: Default `<artifact-id>-web`
|
|
445
|
+
- Keycloak issuer URI: Default `http://localhost:8180/realms/<realm>`
|
|
446
|
+
- Keycloak roles: Infer from mockup sidebar roles (e.g., `hub_administrator` → `HUB_ADMINISTRATOR`)
|
|
447
|
+
|
|
448
|
+
### Messaging Detection
|
|
449
|
+
|
|
450
|
+
| Dependency Pattern | Messaging Selection |
|
|
451
|
+
|---|---|
|
|
452
|
+
| References "Hub to HC Adapter Message Queue" or "Hub to SC Adapter Message Queue" (RabbitMQ) | Messaging = yes |
|
|
453
|
+
| No message queue dependency listed | Messaging = no |
|
|
454
|
+
|
|
455
|
+
If Messaging = yes, also extract the RabbitMQ version from the corresponding message
|
|
456
|
+
queue section in CLAUDE.md.
|
|
457
|
+
|
|
458
|
+
### Scheduling Detection
|
|
459
|
+
|
|
460
|
+
Scheduling is determined from PRD.md content:
|
|
461
|
+
|
|
462
|
+
| Content Pattern | Scheduling Selection |
|
|
463
|
+
|---|---|
|
|
464
|
+
| NFRs mention "automatically deleted after X days", "scheduled", "periodic", "batch processing" | Scheduling = yes |
|
|
465
|
+
| User stories describe recurring jobs, cleanup tasks, or time-triggered operations | Scheduling = yes |
|
|
466
|
+
| No scheduling-related requirements found | Scheduling = no |
|
|
467
|
+
|
|
468
|
+
**If Scheduling = yes**, further determine:
|
|
469
|
+
- **Spring Batch = yes** if NFRs mention "batch processing", "ETL", "bulk import/export",
|
|
470
|
+
or processing large volumes of data with reader/processor/writer patterns
|
|
471
|
+
- **Remote Partitioning = yes** if NFRs mention "distributed processing", "horizontal
|
|
472
|
+
scaling", or "partitioned batch jobs"
|
|
473
|
+
|
|
474
|
+
### Reporting Detection
|
|
475
|
+
|
|
476
|
+
Reporting is determined from PRD.md content:
|
|
477
|
+
|
|
478
|
+
| Content Pattern | Reporting Selection |
|
|
479
|
+
|---|---|
|
|
480
|
+
| NFRs mention "report", "Report interface", "generate report", "report generation" | Reporting = yes |
|
|
481
|
+
| User stories describe generating/downloading PDF, Excel, or CSV reports | Reporting = yes |
|
|
482
|
+
| A "Report" module exists in PRD.md with NFRs defining a Report interface | Reporting = yes |
|
|
483
|
+
| No reporting-related requirements found | Reporting = no |
|
|
484
|
+
|
|
485
|
+
**If Reporting = yes**, the spec includes:
|
|
486
|
+
- JasperReports with JRDesign API for fully programmatic report layout (no .jrxml templates)
|
|
487
|
+
- `ReportDefinition` interface with `buildDesign()` method for modules to implement
|
|
488
|
+
- `ReportDesignHelper` utility class with static builders for common layout patterns
|
|
489
|
+
- `ReportService` orchestrating compile → fill → export via `JRBeanCollectionDataSource`
|
|
490
|
+
- Report registry persisted in the database
|
|
491
|
+
- Report page controller with parameter form and download endpoint
|
|
492
|
+
- JTE templates for report list and parameter form pages
|
|
493
|
+
- Multi-format export: PDF (OpenPDF), XLSX (Apache POI), CSV
|
|
494
|
+
|
|
495
|
+
### Internationalisation Detection
|
|
496
|
+
|
|
497
|
+
Internationalisation is determined from PRD.md content:
|
|
498
|
+
|
|
499
|
+
| Content Pattern | i18n Selection |
|
|
500
|
+
|---|---|
|
|
501
|
+
| PRD.md mentions multiple languages or localization (e.g., "English and Bahasa Malaysia", "multilingual", "support multiple locales") | i18n = yes |
|
|
502
|
+
| NFRs require translatable UI, locale-specific date/number formatting, or a language switcher | i18n = yes |
|
|
503
|
+
| User stories describe choosing/switching the interface language | i18n = yes |
|
|
504
|
+
| No language/localization requirements found | i18n = no |
|
|
505
|
+
|
|
506
|
+
**If i18n = yes**, the spec includes:
|
|
507
|
+
- An `I18nConfig` providing a `MessageSource`, a `CookieLocaleResolver`, and a `LocaleChangeInterceptor`
|
|
508
|
+
- Resource bundles under `src/main/resources/i18n/` (`messages.properties` + `messages_<locale>.properties`)
|
|
509
|
+
- An `app.i18n` config block (`default-locale`, `supported-locales`) under the `app:` namespace
|
|
510
|
+
- A `Localizer` helper exposed as a global `@ModelAttribute` so JTE templates resolve message keys
|
|
511
|
+
- A language switcher fragment (htmx-driven, hitting `?lang=<locale>`)
|
|
512
|
+
- Bean-validation message localization wired to the same `MessageSource`
|
|
513
|
+
|
|
514
|
+
**If i18n = no**, do NOT generate a locale/language switcher or any message-bundle scaffolding —
|
|
515
|
+
JTE templates use literal copy. This is the existing "do NOT generate UI without backend
|
|
516
|
+
support" constraint (see Constraints below).
|
|
517
|
+
|
|
518
|
+
### Summary of Determination
|
|
519
|
+
|
|
520
|
+
After analyzing all inputs, produce a determination summary before generating the spec.
|
|
521
|
+
Present it to the user for confirmation:
|
|
522
|
+
|
|
523
|
+
```
|
|
524
|
+
Optional Component Determination:
|
|
525
|
+
- Database: MongoDB (from CLAUDE.md → depends on Hub Database)
|
|
526
|
+
- Authentication: Keycloak (from CLAUDE.md → depends on Hub Single Sign On)
|
|
527
|
+
- Scheduling: yes (from PRD.md → NFR mentions automatic deletion)
|
|
528
|
+
- Spring Batch: no
|
|
529
|
+
- Remote Partitioning: no
|
|
530
|
+
- Messaging: yes (from CLAUDE.md → depends on Hub to HC/SC Adapter Message Queue)
|
|
531
|
+
- Reporting: yes (from PRD.md → Report module with Report interface NFR)
|
|
532
|
+
- Internationalisation: yes (en, ms) (from PRD.md → English + Bahasa Malaysia required)
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
If the user disagrees with any determination, allow them to override before proceeding.
|
|
536
|
+
|
|
537
|
+
## Required Inputs
|
|
538
|
+
|
|
539
|
+
After determination, these values are needed. Most are derived automatically:
|
|
540
|
+
|
|
541
|
+
**Auto-derived from context files:**
|
|
542
|
+
- **Application name**: From CLAUDE.md section heading
|
|
543
|
+
- **Artifact ID**: Kebab-case of application name
|
|
544
|
+
- **Group ID**: `com.bestinet.urp`
|
|
545
|
+
- **Base package**: `com.bestinet.urp.<artifactid>`
|
|
546
|
+
- **Application description**: From CLAUDE.md description
|
|
547
|
+
- **Modules**: From PRD.md module headings + model/MODEL.md
|
|
548
|
+
- **Database**: Auto-determined (see above)
|
|
549
|
+
- **Authentication**: Auto-determined (see above)
|
|
550
|
+
- **Scheduling**: Auto-determined (see above)
|
|
551
|
+
- **Messaging**: Auto-determined (see above)
|
|
552
|
+
- **Database name/credentials**: From ENVIRONMENT.md (root-level file with local environment credentials)
|
|
553
|
+
- **User roles**: From mockup sidebar files
|
|
554
|
+
- **Design tokens**: From MOCKUP.html Tailwind config
|
|
555
|
+
|
|
556
|
+
**Auto-derived from CLAUDE.md (Port Allocation table):**
|
|
557
|
+
- **Server port**: Look up the application's port from the `Port Allocation` table in the `Custom Applications` section of `CLAUDE.md`. Do NOT hardcode a default — the port MUST match the allocated port for this application.
|
|
558
|
+
|
|
559
|
+
**Optional (use sensible defaults if not found in context):**
|
|
560
|
+
- **Default theme**: Default `light` (supports `light`/`dark`)
|
|
561
|
+
- **Log level**: Default `INFO` for application, `WARN` for frameworks
|
|
562
|
+
- **Default locale**: Default `en` (only relevant if i18n = yes)
|
|
563
|
+
- **Supported locales**: Derived from PRD.md language requirements (e.g., `en`, `ms`); default `[en]`
|
|
564
|
+
|
|
565
|
+
## Generating the Specification
|
|
566
|
+
|
|
567
|
+
Once inputs are gathered from context files and optional components are determined,
|
|
568
|
+
generate the specification as a **multi-file output split by module**. Read the spec
|
|
569
|
+
template at `references/spec-template.md` for the exact structure and content of each
|
|
570
|
+
section. The template is the authoritative guide — follow it closely.
|
|
571
|
+
|
|
572
|
+
The specification is split into two categories:
|
|
573
|
+
|
|
574
|
+
1. **Root `SPECIFICATION.md`** — Contains the Table of Contents, shared infrastructure,
|
|
575
|
+
and application-level sections that apply across all modules.
|
|
576
|
+
2. **Per-module `<module-name>/SPEC.md`** — Each module gets its own folder with
|
|
577
|
+
a self-contained specification file covering that module's complete blueprint.
|
|
578
|
+
|
|
579
|
+
This split enables a coding agent to:
|
|
580
|
+
- First, scaffold the shared infrastructure from `SPECIFICATION.md`
|
|
581
|
+
- Then, implement each module independently by picking up its `<module>/SPEC.md`
|
|
582
|
+
|
|
583
|
+
**Important:** The generated spec must use **real module data** from the context files,
|
|
584
|
+
not generic placeholders. Specifically:
|
|
585
|
+
|
|
586
|
+
- **Modules** must use the actual module names from PRD.md and MODEL.md
|
|
587
|
+
(e.g., `locationInformation`, `corridor`, `employer` — not `module1`, `module2`)
|
|
588
|
+
- **Document/Entity fields** must match the actual fields defined in the module model
|
|
589
|
+
files (e.g., `model/location-information/model.md`), not placeholder `fieldOne`/`fieldTwo`
|
|
590
|
+
- **Service interfaces** must expose methods matching the actual user stories (e.g., if
|
|
591
|
+
a story says "view provinces by country", the service needs `listProvincesByCountry()`)
|
|
592
|
+
- **Page controllers** must map to the actual mockup screens (e.g., if
|
|
593
|
+
`hub_administrator/content/location_information.html` exists, there must be a matching
|
|
594
|
+
controller endpoint and JTE page). The controller URL is module-based (e.g.,
|
|
595
|
+
`/location-information`), NOT role-prefixed (e.g., NOT `/hub_administrator/location-information`).
|
|
596
|
+
The mockup's role folder determines `@PreAuthorize` annotations, not URL structure.
|
|
597
|
+
- **Sidebar navigation** must match the mockup sidebar files per role. Sidebar hrefs use
|
|
598
|
+
module-based paths (e.g., `/corridor`, `/quota`) — the role determines which items
|
|
599
|
+
appear in the sidebar, not the URL prefix
|
|
600
|
+
- **Form fields** must match what the mockup screens display
|
|
601
|
+
- **Design tokens** (colors, fonts) must match the MOCKUP.html Tailwind configuration
|
|
602
|
+
- **Version tags**: Every user story ID, NFR ID, constraint ID, and mockup screen in
|
|
603
|
+
the traceability section must include its version tag (e.g., `USHM00228 [v1.0.3]`).
|
|
604
|
+
This enables incremental implementation by version. **ALL traceability sub-tables
|
|
605
|
+
(User Stories, NFRs, AND Constraints) MUST include the `| Version |` column.** Do not
|
|
606
|
+
omit the Version column from any table — even if a module only has v1.0.0 items.
|
|
607
|
+
- **Removed / Replaced items**: The traceability section must include a "Removed / Replaced"
|
|
608
|
+
subsection listing any deprecated items from previous versions — showing the removed ID,
|
|
609
|
+
the version that removed it, the replacement ID (if any), and a brief reason. This
|
|
610
|
+
ensures developers can see what was removed and understand the evolution of requirements.
|
|
611
|
+
If a module has no removed items, include the subsection with `_None._` to make it
|
|
612
|
+
explicit that nothing was removed.
|
|
613
|
+
|
|
614
|
+
### Output Structure
|
|
615
|
+
|
|
616
|
+
```
|
|
617
|
+
<app_folder>/context/specification/
|
|
618
|
+
├── SPECIFICATION.md ↠TOC + shared/application-level specs
|
|
619
|
+
├── location-information/
|
|
620
|
+
│ └── SPEC.md ↠Module blueprint for Location Information
|
|
621
|
+
├── corridor/
|
|
622
|
+
│ └── SPEC.md ↠Module blueprint for Corridor
|
|
623
|
+
├── employer/
|
|
624
|
+
│ └── SPEC.md ↠Module blueprint for Employer
|
|
625
|
+
├── ... ↠One folder per module from PRD.md
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### What Goes in `SPECIFICATION.md` (Root)
|
|
629
|
+
|
|
630
|
+
The root file contains the TOC and all shared/application-level sections. These are the
|
|
631
|
+
sections that a coding agent implements **first** before any module work:
|
|
632
|
+
|
|
633
|
+
#### 1. Project Overview
|
|
634
|
+
Project metadata, application description, technology stack summary, the complete
|
|
635
|
+
list of user roles extracted from mockup sidebar files, and the **Module Index** —
|
|
636
|
+
a table listing every module with a link to its `<module>/SPEC.md` file.
|
|
637
|
+
|
|
638
|
+
#### 2. Maven Configuration
|
|
639
|
+
Complete `pom.xml` structure with all dependencies (core + selected conditional),
|
|
640
|
+
plugin configurations (MapStruct annotation processor, Spring Boot Maven plugin,
|
|
641
|
+
frontend-maven-plugin for Vite build, `maven-clean-plugin` to delete on-demand
|
|
642
|
+
`jte-classes/` folder, `jte-maven-plugin` with `precompile` goal at `process-classes`
|
|
643
|
+
phase outputting to `${project.build.directory}/classes`), and property management.
|
|
644
|
+
|
|
645
|
+
#### 3. Application Configuration *(conditional content varies)*
|
|
646
|
+
A single `application.yml` (no profile-specific files like `application-dev.yml` or
|
|
647
|
+
`application-prod.yml`) covering database connection (MongoDB URI or JDBC datasource
|
|
648
|
+
depending on selection), auth settings (Keycloak/OAuth2 if selected, or form login if
|
|
649
|
+
selected), JTE configuration (with `JTE_DEV_MODE` and `JTE_PRECOMPILED` env vars),
|
|
650
|
+
scheduling config (if selected), theme defaults, and logging configuration. **All environment-sensitive values (ports, hostnames, credentials,
|
|
651
|
+
URIs) MUST use Spring's `${ENV_VAR:default}` syntax** to allow externalization via
|
|
652
|
+
environment variables while keeping sensible defaults for local development. Do NOT use
|
|
653
|
+
Spring profiles or profile-specific YAML files — environment differences are handled
|
|
654
|
+
entirely through environment variables (e.g., via `.env` file locally or system
|
|
655
|
+
environment variables in deployment).
|
|
656
|
+
|
|
657
|
+
#### 3a. Application-Specific Configuration (`app:` namespace)
|
|
658
|
+
|
|
659
|
+
All application-owned configuration — any config specific to THIS application, as
|
|
660
|
+
opposed to the Spring/Java ecosystem — MUST live under the top-level `app:` key in
|
|
661
|
+
`application.yml`. NEVER place application-specific keys under Spring framework
|
|
662
|
+
namespaces (`spring.*`, `server.*`, `management.*`, `logging.*`) — those are
|
|
663
|
+
reserved for framework configuration.
|
|
664
|
+
|
|
665
|
+
**Grouping rule.** Organise the `app:` tree by module:
|
|
666
|
+
- **Cross-cutting values** (version, shared feature flags, shared timeouts, CORS,
|
|
667
|
+
shared security settings, shared messaging infrastructure, shared object-storage
|
|
668
|
+
settings) sit directly under `app.*` with no module prefix.
|
|
669
|
+
- **Per-module values** are grouped under `app.<module-kebab-case>.*`, one block
|
|
670
|
+
per module that needs runtime config. A module with a single config value still
|
|
671
|
+
gets its own block — do not flatten.
|
|
672
|
+
- **NEVER place module-specific keys at the YAML root** (e.g., top-level
|
|
673
|
+
`notification:`, `batch-job:`, `audit-trail:`). They MUST be nested under `app:`.
|
|
674
|
+
|
|
675
|
+
**Naming rule.** YAML keys use **kebab-case** (`from-address`, `retry-limit`,
|
|
676
|
+
`max-retry`). Spring Boot's relaxed binding maps them to camelCase Java fields
|
|
677
|
+
automatically. Do NOT use camelCase or snake_case in YAML.
|
|
678
|
+
|
|
679
|
+
**Binding rule.** For every `app.*` subtree (cross-cutting OR per-module), bind once
|
|
680
|
+
via `@ConfigurationProperties` on a **record** in the corresponding module's `config`
|
|
681
|
+
subpackage — or, for cross-cutting values, in the application-level `config`
|
|
682
|
+
subpackage. **Do NOT** inject individual values via `@Value("${app....}")` scattered
|
|
683
|
+
across beans or templates. Bind once at the module boundary and inject the typed record.
|
|
684
|
+
|
|
685
|
+
**Environment-override rule.** Every `app.*` leaf value MUST use Spring's
|
|
686
|
+
`${ENV_VAR:default}` syntax so it can be overridden per environment without editing
|
|
687
|
+
YAML. Every referenced `${ENV_VAR}` MUST appear in the `.env` file generated in
|
|
688
|
+
section 3b.
|
|
689
|
+
|
|
690
|
+
**Example structure:**
|
|
691
|
+
|
|
692
|
+
```yaml
|
|
693
|
+
app:
|
|
694
|
+
# Cross-cutting (no module prefix)
|
|
695
|
+
version: ${APP_VERSION:1.0.0}
|
|
696
|
+
cors:
|
|
697
|
+
allowed-origins: ${APP_CORS_ALLOWED_ORIGINS:http://localhost:3000}
|
|
698
|
+
security:
|
|
699
|
+
public-paths:
|
|
700
|
+
- /actuator/health
|
|
701
|
+
- /login
|
|
702
|
+
- /error
|
|
703
|
+
|
|
704
|
+
# Per-module blocks — one per module with runtime config
|
|
705
|
+
notification:
|
|
706
|
+
email:
|
|
707
|
+
from-address: ${NOTIFICATION_FROM_ADDRESS:noreply@example.com}
|
|
708
|
+
retry-limit: ${NOTIFICATION_RETRY_LIMIT:3}
|
|
709
|
+
cleanup:
|
|
710
|
+
retention-days: ${NOTIFICATION_RETENTION_DAYS:30}
|
|
711
|
+
batch-job:
|
|
712
|
+
cleanup:
|
|
713
|
+
retention-days: ${BATCH_JOB_RETENTION_DAYS:90}
|
|
714
|
+
audit-trail:
|
|
715
|
+
cleanup:
|
|
716
|
+
retention-days: ${AUDIT_TRAIL_RETENTION_DAYS:365}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Example cross-cutting record (`app.*`):**
|
|
720
|
+
|
|
721
|
+
```java
|
|
722
|
+
@ConfigurationProperties(prefix = "app")
|
|
723
|
+
public record AppProperties(String version, Cors cors, Security security) {
|
|
724
|
+
public record Cors(List<String> allowedOrigins) {}
|
|
725
|
+
public record Security(List<String> publicPaths) {}
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
**Example per-module record (`app.<module>.*`):**
|
|
730
|
+
|
|
731
|
+
```java
|
|
732
|
+
@ConfigurationProperties(prefix = "app.notification")
|
|
733
|
+
public record NotificationProperties(
|
|
734
|
+
Email email,
|
|
735
|
+
Cleanup cleanup
|
|
736
|
+
) {
|
|
737
|
+
public record Email(String fromAddress, int retryLimit) {}
|
|
738
|
+
public record Cleanup(int retentionDays) {}
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Enable binding at the application root with `@ConfigurationPropertiesScan` on the
|
|
743
|
+
main application class, or register each record individually via
|
|
744
|
+
`@EnableConfigurationProperties` on a `@Configuration` class in the owning module.
|
|
745
|
+
|
|
746
|
+
**Mandatory cross-cutting values:**
|
|
747
|
+
|
|
748
|
+
| Key | Purpose | Binding |
|
|
749
|
+
|-----|---------|---------|
|
|
750
|
+
| `app.version` | Current application version; must match `pom.xml` `<version>` | `AppProperties.version()` |
|
|
751
|
+
|
|
752
|
+
Additional cross-cutting keys may be added as the application grows, but
|
|
753
|
+
`app.version` is always present.
|
|
754
|
+
|
|
755
|
+
**`app.version` specifics.** The `.env` file must include `APP_VERSION={version}`
|
|
756
|
+
with the actual version value. The `pom.xml` `<version>` element MUST also be set to
|
|
757
|
+
the same version value (e.g., `1.0.3`). When multiple versions were provided during
|
|
758
|
+
skill invocation, use the highest one. The application MUST expose this version in
|
|
759
|
+
the **footer** of every page. Expose it by injecting `AppProperties` into a
|
|
760
|
+
`@ControllerAdvice`-annotated class that registers `appVersion` as a global
|
|
761
|
+
`@ModelAttribute`, then read it from the shared footer layout (`footer.jte` or
|
|
762
|
+
`footer.html`) as `${appVersion}` and render it as `v{version}` (e.g., `v1.0.3`).
|
|
763
|
+
Do NOT use `@Value("${app.version}")` in controllers or templates.
|
|
764
|
+
|
|
765
|
+
#### 3b. `.env` File Generation from ENVIRONMENT.md
|
|
766
|
+
Generate a `.env` file at the project root by reading `ENVIRONMENT.md` from the project root.
|
|
767
|
+
The `.env` file maps ENVIRONMENT.md credential and platform values to the environment variable
|
|
768
|
+
names referenced in `application.yml`. The spec must define the complete `.env` content
|
|
769
|
+
with actual values from ENVIRONMENT.md.
|
|
770
|
+
|
|
771
|
+
**Process:**
|
|
772
|
+
1. Read `ENVIRONMENT.md` from the project root
|
|
773
|
+
2. Extract credential values from `ENVIRONMENT.md` (`# Supporting 3rd Party Applications`
|
|
774
|
+
for database hosts, ports, usernames, passwords, plus Keycloak/RabbitMQ); read toolchain
|
|
775
|
+
paths (JDK, Maven, Node.js) from `DEVTOOL.md`
|
|
776
|
+
3. Map each value to the corresponding `${ENV_VAR}` name used in `application.yml`
|
|
777
|
+
4. Generate the `.env` file with `KEY=value` pairs
|
|
778
|
+
|
|
779
|
+
**Example `.env` output (derived from ENVIRONMENT.md):**
|
|
780
|
+
```properties
|
|
781
|
+
# Database
|
|
782
|
+
DB_HOST=localhost
|
|
783
|
+
DB_PORT=3306
|
|
784
|
+
DB_NAME=hub_supp
|
|
785
|
+
DB_USERNAME=root
|
|
786
|
+
DB_PASSWORD=B3st1n3t@2025
|
|
787
|
+
|
|
788
|
+
# Authentication (Keycloak)
|
|
789
|
+
KEYCLOAK_HOST=http://localhost:8180
|
|
790
|
+
KEYCLOAK_REALM=urp
|
|
791
|
+
KEYCLOAK_CLIENT_ID=hub-middleware-web
|
|
792
|
+
|
|
793
|
+
# Messaging (RabbitMQ)
|
|
794
|
+
RABBITMQ_HOST=localhost
|
|
795
|
+
RABBITMQ_PORT=5672
|
|
796
|
+
RABBITMQ_USERNAME=guest
|
|
797
|
+
RABBITMQ_PASSWORD=guest
|
|
798
|
+
|
|
799
|
+
# Server
|
|
800
|
+
SERVER_PORT=<port from CLAUDE.md Port Allocation table>
|
|
801
|
+
|
|
802
|
+
# Platform
|
|
803
|
+
JAVA_HOME=C:\Users\rashidee.rashid.BESTINET\.jdks\azul-21.0.9
|
|
804
|
+
MAVEN_HOME=C:\Users\rashidee.rashid.BESTINET\apache-maven-3.9.12
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
**Rules:**
|
|
808
|
+
- Only include variables that are actually referenced in `application.yml`
|
|
809
|
+
- Use actual values from ENVIRONMENT.md — never use placeholders or `TODO`
|
|
810
|
+
- If ENVIRONMENT.md does not exist or a value is not found, use sensible defaults for local
|
|
811
|
+
development (e.g., `localhost`, default ports)
|
|
812
|
+
- The `.env` file is gitignored (already covered in `.gitignore`)
|
|
813
|
+
|
|
814
|
+
#### 4. Build & Tooling
|
|
815
|
+
Vite configuration, Tailwind CSS setup (using design tokens from MOCKUP.html), PostCSS
|
|
816
|
+
config, frontend directory structure, and Maven integration for building JS/CSS assets.
|
|
817
|
+
|
|
818
|
+
#### 4b. `.gitignore`
|
|
819
|
+
Generate a `.gitignore` file at the project root that excludes all generated, downloaded,
|
|
820
|
+
and environment-specific files from version control. The spec must include the complete
|
|
821
|
+
`.gitignore` content. At minimum, include:
|
|
822
|
+
|
|
823
|
+
```
|
|
824
|
+
# Build output
|
|
825
|
+
target/
|
|
826
|
+
|
|
827
|
+
# IDE
|
|
828
|
+
.idea/
|
|
829
|
+
*.iml
|
|
830
|
+
.vscode/
|
|
831
|
+
.settings/
|
|
832
|
+
.project
|
|
833
|
+
.classpath
|
|
834
|
+
*.swp
|
|
835
|
+
*~
|
|
836
|
+
|
|
837
|
+
# OS
|
|
838
|
+
.DS_Store
|
|
839
|
+
Thumbs.db
|
|
840
|
+
|
|
841
|
+
# Frontend
|
|
842
|
+
frontend/node_modules/
|
|
843
|
+
frontend/.vite/
|
|
844
|
+
src/main/resources/static/dist/
|
|
845
|
+
|
|
846
|
+
# JTE generated
|
|
847
|
+
jte-classes/
|
|
848
|
+
|
|
849
|
+
# E2E
|
|
850
|
+
e2e/node_modules/
|
|
851
|
+
e2e/test-results/
|
|
852
|
+
e2e/playwright-report/
|
|
853
|
+
e2e/visual-baselines/
|
|
854
|
+
|
|
855
|
+
# Logs
|
|
856
|
+
*.log
|
|
857
|
+
logs/
|
|
858
|
+
|
|
859
|
+
# Environment
|
|
860
|
+
.env
|
|
861
|
+
.env.*
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
**Conditional additions:**
|
|
865
|
+
- **If Database = PostgreSQL/MySQL:** No additional entries needed (Flyway migrations are committed)
|
|
866
|
+
- **If Scheduling = yes AND Spring Batch = yes:** Add `*.tmp` for batch temp files
|
|
867
|
+
- **If Reporting = yes:** No additional .gitignore entries needed (report layouts are programmatic Java code, not external template files)
|
|
868
|
+
|
|
869
|
+
#### 5. Package Structure
|
|
870
|
+
The complete directory tree rooted at the base package. The structure follows
|
|
871
|
+
Domain-Driven Design with Spring Modulith conventions, adapted for server-rendered web
|
|
872
|
+
with `page` and `fragment` subpackages. Use actual module names from the context.
|
|
873
|
+
Read `references/modulith-patterns.md` for the detailed module layout and inter-module
|
|
874
|
+
communication rules.
|
|
875
|
+
|
|
876
|
+
#### 6. Security Configuration *(conditional — include only if Auth != none)*
|
|
877
|
+
**If Auth = Keycloak:** OAuth2 Client setup with Keycloak OIDC, SecurityFilterChain
|
|
878
|
+
with `oauth2Login()`, `KeycloakGrantedAuthoritiesMapper` to extract roles from ID token
|
|
879
|
+
claims, CSP nonce filter, automatic redirect to Keycloak login, and public endpoint
|
|
880
|
+
configuration. Session-based (Spring default). Read `references/security-patterns.md`
|
|
881
|
+
for the full security architecture.
|
|
882
|
+
|
|
883
|
+
**If Auth = form:** Spring Security form login configuration, `SecurityFilterChain` with
|
|
884
|
+
`formLogin()`, `UserDetailsService` implementation backed by the selected database, password
|
|
885
|
+
encoding with BCrypt, role-based access control, CSP nonce filter, and remember-me support.
|
|
886
|
+
|
|
887
|
+
#### 7. Layouts (JTE)
|
|
888
|
+
Three layouts: MainLayout (header/sidebar/footer for authenticated pages), AuthLayout
|
|
889
|
+
(split-screen for login), ErrorLayout (centered error display). Each with Java view
|
|
890
|
+
model class and JTE template. Layout structure should match the mockup shell/partials.
|
|
891
|
+
*Note: If Auth = none, AuthLayout may be omitted or simplified.*
|
|
892
|
+
|
|
893
|
+
#### 8. Fragments
|
|
894
|
+
Reusable JTE fragments: HeaderFragment, SidebarFragment, FooterFragment,
|
|
895
|
+
ThemeSwitcherFragment. Each with view model and template. Sidebar must include the actual
|
|
896
|
+
navigation items from the mockup sidebar files, organized per role.
|
|
897
|
+
|
|
898
|
+
#### 9. UI Components (Tailwind-based)
|
|
899
|
+
Pure Tailwind CSS components (no DaisyUI): Alert, Avatar, Badge, Breadcrumb, Button,
|
|
900
|
+
Card, Drawer, Dropdown, FormControl/Input/Select/Textarea/Checkbox/Radio/Toggle,
|
|
901
|
+
Loading, Menu, Modal, Navbar, Pagination, Progress, Stats, Steps, Table, Tabs,
|
|
902
|
+
Toast, Tooltip. Each with Java view model and JTE template using Tailwind utility classes.
|
|
903
|
+
|
|
904
|
+
#### 10. Frontend JS Structure
|
|
905
|
+
Alpine.js stores (toast, modal, drawer, theme), htmx extensions (loading states, toast
|
|
906
|
+
errors), ES module organization, and CSP nonce integration.
|
|
907
|
+
|
|
908
|
+
#### 11. Styles
|
|
909
|
+
Tailwind CSS organization: base (reset, typography), components (buttons, forms, cards,
|
|
910
|
+
tables, modals, navigation), layouts (sidebar, navbar, footer responsive), themes
|
|
911
|
+
(light/dark CSS custom properties). Use the actual design tokens (colors, fonts) from
|
|
912
|
+
MOCKUP.html.
|
|
913
|
+
|
|
914
|
+
#### 12. Authentication Pages *(conditional — include only if Auth != none)*
|
|
915
|
+
**If Auth = Keycloak:** No custom login page needed. Spring Security automatically
|
|
916
|
+
redirects unauthenticated users to Keycloak login. Keycloak handles the login form,
|
|
917
|
+
social login providers, and credential management. After successful authentication,
|
|
918
|
+
Keycloak redirects back with an authorization code which Spring exchanges for tokens.
|
|
919
|
+
|
|
920
|
+
**If Auth = form:** Login page with email/password form, CSRF token, remember-me checkbox.
|
|
921
|
+
Logout endpoint. Optionally a registration page if user self-registration is desired.
|
|
922
|
+
|
|
923
|
+
#### 13. Data Access *(conditional content varies)*
|
|
924
|
+
**If Database = MongoDB:** MongoDB repositories per module with Spring Data MongoRepository.
|
|
925
|
+
DTO mapping via MapStruct. Pagination helpers with `PaginationAware` mixin. All list
|
|
926
|
+
endpoints paginated. Use actual collection names from the module model.
|
|
927
|
+
|
|
928
|
+
**If Database = PostgreSQL/MySQL:** JPA repositories per module with Spring Data
|
|
929
|
+
JpaRepository. JPA entities with `@Entity`/`@Table` annotations extending `BaseEntity`.
|
|
930
|
+
`BaseEntity` uses `@UuidGenerator(style = UuidGenerator.Style.TIME)` with
|
|
931
|
+
`@Column(columnDefinition = "CHAR(36)")` and `private String id`. Flyway migration scripts.
|
|
932
|
+
DTO mapping via MapStruct. Pagination helpers. All list endpoints paginated. Use actual
|
|
933
|
+
table names from the module model.
|
|
934
|
+
**MySQL UUID rule:** All UUID primary keys and foreign keys use `CHAR(36)` in DDL.
|
|
935
|
+
In JPA entities, map with `columnDefinition = "CHAR(36)"` (not `length = 36`) to
|
|
936
|
+
pass Hibernate `ddl-auto: validate`.
|
|
937
|
+
|
|
938
|
+
**If Database = none:** In-memory data structures or stubs. The spec should note that a
|
|
939
|
+
database integration can be added later.
|
|
940
|
+
|
|
941
|
+
#### 14. Error Handling & Exceptions
|
|
942
|
+
Base `WebApplicationException` with status/code/userMessage. `GlobalExceptionHandler`
|
|
943
|
+
returning error pages for full requests and toast fragments for htmx requests.
|
|
944
|
+
|
|
945
|
+
#### 15. Theming
|
|
946
|
+
Light/dark theme switching via cookie. Server reads cookie and passes theme to layout
|
|
947
|
+
view model. Alpine store syncs toggle with cookie and `data-theme` attribute.
|
|
948
|
+
|
|
949
|
+
#### 16. Pagination Support
|
|
950
|
+
PaginationRequest, PaginatedResult, and the shared pagination JTE component.
|
|
951
|
+
|
|
952
|
+
#### 17. Logging Strategy
|
|
953
|
+
SLF4J with Logback configuration, correlation ID (from JWT if auth is enabled, or
|
|
954
|
+
request-scoped UUID otherwise), MDC context filter, per-module log levels.
|
|
955
|
+
|
|
956
|
+
#### 18. Scheduling and Batch Processing *(conditional — include only if Scheduling = yes)*
|
|
957
|
+
Quartz scheduler configuration with job store matching the selected database (MongoDB
|
|
958
|
+
job store via fluidsonic-mirror if MongoDB, JDBC job store if relational, in-memory if
|
|
959
|
+
no database). If Spring Batch = no, Quartz runs standalone with direct service-call jobs.
|
|
960
|
+
If Spring Batch = yes, Quartz triggers Spring Batch jobs with chunk-oriented
|
|
961
|
+
reader/processor/writer processing. If Remote Partitioning = yes (requires Spring Batch),
|
|
962
|
+
also includes Spring Batch remote partitioning with RabbitMQ for horizontal scaling of
|
|
963
|
+
batch jobs across multiple worker nodes. Read `references/batch-patterns.md` for the full
|
|
964
|
+
scaffolding spec (Quartz-only, Quartz+Batch, and remote partitioning patterns).
|
|
965
|
+
|
|
966
|
+
#### 19. Event-Driven Architecture
|
|
967
|
+
Spring Modulith application events for inter-module communication. Read
|
|
968
|
+
`references/modulith-patterns.md` for details.
|
|
969
|
+
|
|
970
|
+
#### 20. Messaging (RabbitMQ Pub/Sub) *(conditional — include only if Messaging = yes)*
|
|
971
|
+
Standalone RabbitMQ publisher/consumer services for inter-system communication.
|
|
972
|
+
Topic exchange for event broadcasting, direct exchange for point-to-point commands.
|
|
973
|
+
Read `references/messaging-patterns.md` for the full messaging architecture.
|
|
974
|
+
|
|
975
|
+
#### 21. MapStruct Usage
|
|
976
|
+
Per-module MapStruct mapper conventions and mapping flow patterns.
|
|
977
|
+
|
|
978
|
+
#### 22. Testing Strategy
|
|
979
|
+
Overview of testing approach — unit tests, module tests, security test utilities
|
|
980
|
+
(JWT mocking if Keycloak, or `@WithMockUser` if form login), view model tests.
|
|
981
|
+
|
|
982
|
+
#### 23. Reporting (JasperReports JRDesign API) *(conditional — include only if Reporting = yes)*
|
|
983
|
+
JasperReports infrastructure with fully programmatic report layout via JRDesign API — no
|
|
984
|
+
`.jrxml` XML templates. Report layouts are built entirely in Java code using `JasperDesign`,
|
|
985
|
+
`JRDesignBand`, `JRDesignStaticText`, `JRDesignTextField`, and `JRDesignField` classes.
|
|
986
|
+
Includes `ReportDefinition` interface with `buildDesign()` method for modules to implement,
|
|
987
|
+
`ReportDesignHelper` utility with static builders for common patterns (A4 portrait/landscape,
|
|
988
|
+
column headers, detail bands, page footers), `ReportService` orchestrating compile → fill →
|
|
989
|
+
export via `JRBeanCollectionDataSource`, `ReportRegistry` for auto-discovering and persisting
|
|
990
|
+
report definitions at startup, report page controller with parameter form and download
|
|
991
|
+
endpoint, JTE templates for report list and parameter form, multi-format export (PDF via
|
|
992
|
+
OpenPDF, XLSX via Apache POI, CSV). Modules register reports by creating `@Component`
|
|
993
|
+
classes implementing `ReportDefinition` — each report builds its layout programmatically
|
|
994
|
+
and calls module services to produce DTOs (never repositories directly), preserving Spring
|
|
995
|
+
Modulith module boundaries. Read `references/jasper-patterns.md` for the full reporting
|
|
996
|
+
architecture.
|
|
997
|
+
|
|
998
|
+
#### 24. Internationalisation (i18n) *(conditional — include only if i18n = yes)*
|
|
999
|
+
Spring's built-in `MessageSource` localization. Covers: an `I18nConfig` declaring a
|
|
1000
|
+
`ResourceBundleMessageSource` (basename `i18n/messages`, UTF-8, fallback disabled), a
|
|
1001
|
+
`CookieLocaleResolver` (cookie `LOCALE`, default from `app.i18n.default-locale`), and a
|
|
1002
|
+
`LocaleChangeInterceptor` (param `lang`) registered through a `WebMvcConfigurer`; resource
|
|
1003
|
+
bundles under `src/main/resources/i18n/` (`messages.properties` as default/en plus
|
|
1004
|
+
`messages_<locale>.properties` per supported locale, with module keys namespaced by module
|
|
1005
|
+
slug, e.g. `location-information.title`); an `app.i18n` block under the `app:` namespace
|
|
1006
|
+
(`default-locale`, `supported-locales`) bound to an `I18nProperties` record; a `Localizer`
|
|
1007
|
+
helper registered as a global `@ModelAttribute("t")` via `@ControllerAdvice` (mirroring how
|
|
1008
|
+
`appVersion` is exposed) so JTE templates resolve keys with `${t.msg("location-information.title")}`
|
|
1009
|
+
against `LocaleContextHolder.getLocale()`; a language switcher JTE fragment (htmx `hx-get`
|
|
1010
|
+
to `?lang=<locale>` with `hx-refresh`); and bean-validation localization by pointing a
|
|
1011
|
+
`LocalValidatorFactoryBean` at the same `MessageSource`. The language switcher is the ONLY
|
|
1012
|
+
locale UI element and MUST NOT be rendered when i18n = no.
|
|
1013
|
+
|
|
1014
|
+
### What Goes in Each `<module>/SPEC.md` (Per-Module)
|
|
1015
|
+
|
|
1016
|
+
For EACH module from PRD.md and MODEL.md, create a folder named after the
|
|
1017
|
+
module (kebab-case, e.g., `location-information/`) and generate a `SPEC.md` inside it.
|
|
1018
|
+
|
|
1019
|
+
Each module `SPEC.md` is a **self-contained** blueprint that a coding agent can pick up
|
|
1020
|
+
and implement independently (after the shared infrastructure is in place). It must include:
|
|
1021
|
+
|
|
1022
|
+
- **Header** with module name and a back-reference to the root `SPECIFICATION.md`
|
|
1023
|
+
- **Traceability**: User story IDs, NFR IDs, constraint IDs, collection/table names,
|
|
1024
|
+
mockup screen filenames
|
|
1025
|
+
- **Service interface** with methods derived from user stories
|
|
1026
|
+
- **DTOs** with fields matching the module model's document/entity fields
|
|
1027
|
+
- **Exception class** for module-specific errors
|
|
1028
|
+
- **Document/Entity class** with fields from `model/<module>/model.md` and
|
|
1029
|
+
`model/<module>/schemas.json`
|
|
1030
|
+
- **Repository** with query methods matching user stories' data access patterns
|
|
1031
|
+
- **MapStruct mapper** with mappings matching actual field names
|
|
1032
|
+
- **Service implementation** with full CRUD logic
|
|
1033
|
+
- **Page controllers** with endpoints matching mockup screens for that module
|
|
1034
|
+
- **Fragment controllers** for htmx partial updates
|
|
1035
|
+
- **View models** with fields matching what mockup screens display
|
|
1036
|
+
- **JTE templates** (list, detail, create, edit, row fragments)
|
|
1037
|
+
- **Message keys** *(only if i18n = yes)* — the module's display strings added to each
|
|
1038
|
+
`i18n/messages_<locale>.properties` bundle under a module-slug key namespace
|
|
1039
|
+
(e.g., `location-information.title`, `location-information.create`), referenced from this
|
|
1040
|
+
module's JTE templates via `${t.msg("location-information.title")}` instead of literal copy
|
|
1041
|
+
- **Complete code samples** for every component — continuous and copy-pasteable
|
|
1042
|
+
|
|
1043
|
+
**Separating UI Layer from Messaging/Async Pipeline:**
|
|
1044
|
+
|
|
1045
|
+
When a module has BOTH user-facing screens (user stories) AND async processing NFRs
|
|
1046
|
+
(e.g., RabbitMQ message consumption, message validation, ACK publishing, forwarding),
|
|
1047
|
+
the SPEC.md MUST clearly separate these into distinct sections:
|
|
1048
|
+
|
|
1049
|
+
1. **UI Layer sections** — service methods for read-only queries (search, getById,
|
|
1050
|
+
getHistory), page controllers, fragment controllers, JTE templates. These are driven
|
|
1051
|
+
by user stories (USHMxxxxx).
|
|
1052
|
+
2. **Messaging Pipeline sections** — message consumer (`@RabbitListener`), message
|
|
1053
|
+
validator, ACK publisher, forward publisher, queue configuration, domain events,
|
|
1054
|
+
`processIncomingMessage()` service method. These are driven by NFRs (NFRHMxxxx).
|
|
1055
|
+
|
|
1056
|
+
> **MQ listener placement (mandatory).** Every `@RabbitListener` class generated for a
|
|
1057
|
+
> module MUST be placed inside that module's `internal/` package
|
|
1058
|
+
> (`{{base}}.{{module}}.internal`), package-private, alongside the page/fragment
|
|
1059
|
+
> controllers. Shared messaging infrastructure (`RabbitMQMessagingConfig`,
|
|
1060
|
+
> `RabbitMQPublisher`, `MessageConverterConfig`, cross-module event/command DTOs)
|
|
1061
|
+
> lives in `shared/messaging/`, but that package must contain **no** `@RabbitListener`
|
|
1062
|
+
> classes. See `references/messaging-patterns.md` § "Consumer Service (module-internal)"
|
|
1063
|
+
> for the canonical pattern.
|
|
1064
|
+
|
|
1065
|
+
This separation enables the implementation orchestrator to track and implement each
|
|
1066
|
+
concern independently. A module may have its UI layer fully implemented while its
|
|
1067
|
+
messaging pipeline remains pending (e.g., waiting for an upstream adapter). The
|
|
1068
|
+
IMPLEMENTATION_MODULE.md checklist tracks each user story and NFR individually, so
|
|
1069
|
+
the status accurately reflects what is done vs. what remains.
|
|
1070
|
+
|
|
1071
|
+
See `references/spec-template.md` Section "Module SPEC.md Template" for the
|
|
1072
|
+
exact template structure.
|
|
1073
|
+
|
|
1074
|
+
## Changelog Append
|
|
1075
|
+
|
|
1076
|
+
After all specification files are successfully generated, append an entry to `CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
|
|
1077
|
+
|
|
1078
|
+
1. Read `<app_folder>/CHANGELOG.md`. If it does not exist, create it with:
|
|
1079
|
+
```markdown
|
|
1080
|
+
# Changelog
|
|
1081
|
+
|
|
1082
|
+
- This file tracks all skill executions by version for this application.
|
|
1083
|
+
- The highest version recorded here is the current application version.
|
|
1084
|
+
- Skills MUST NOT execute for a version lower than the highest version in this file.
|
|
1085
|
+
|
|
1086
|
+
---
|
|
1087
|
+
```
|
|
1088
|
+
2. Search for a `## {version}` heading matching the current version.
|
|
1089
|
+
3. If the section **exists**: append a new row to its table.
|
|
1090
|
+
4. If the section **does not exist**: insert a new section after the `---` below the context header and before any existing `## vX.Y.Z` section (newest-first ordering), with a new table header and the first row.
|
|
1091
|
+
5. Row format: `| {YYYY-MM-DD} | {application_name} | specgen-spring-jpa-jtehtmx | {module or "All"} | Generated Spring Boot web application technical specification |`
|
|
1092
|
+
6. **Never modify or delete existing rows.**
|
|
1093
|
+
|
|
1094
|
+
## Output Format
|
|
1095
|
+
|
|
1096
|
+
The generated specification is a **folder of files**, not a single document:
|
|
1097
|
+
|
|
1098
|
+
```
|
|
1099
|
+
<app_folder>/context/specification/
|
|
1100
|
+
├── SPECIFICATION.md ↠Root: TOC + shared/application-level specs
|
|
1101
|
+
├── <module-1>/
|
|
1102
|
+
│ └── SPEC.md ↠Module blueprint (self-contained)
|
|
1103
|
+
├── <module-2>/
|
|
1104
|
+
│ └── SPEC.md
|
|
1105
|
+
├── <module-N>/
|
|
1106
|
+
│ └── SPEC.md
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
- **Root folder**: `<app_folder>/context/specification/`
|
|
1110
|
+
- **Root file**: `SPECIFICATION.md` — contains the Table of Contents (with links to
|
|
1111
|
+
each module's `SPEC.md`), all shared infrastructure sections (1–9), and all
|
|
1112
|
+
application-level cross-cutting sections (10–24, excluding module blueprints)
|
|
1113
|
+
- **Module folders**: One folder per module from PRD.md, named in kebab-case
|
|
1114
|
+
(e.g., `location-information/`, `corridor/`, `employer/`)
|
|
1115
|
+
- **Module files**: Each `SPEC.md` is self-contained with full code samples for that
|
|
1116
|
+
module's module — service, DTOs, document/entity, repository, mapper, controllers,
|
|
1117
|
+
views, and JTE templates
|
|
1118
|
+
|
|
1119
|
+
**Design goal:** A coding agent can implement the application module-by-module:
|
|
1120
|
+
1. First pass: implement shared infrastructure from `SPECIFICATION.md`
|
|
1121
|
+
2. Subsequent passes: pick up each `<module>/SPEC.md` independently and implement it
|
|
1122
|
+
|
|
1123
|
+
**Sample code is mandatory.** Every component described in any spec file must include a
|
|
1124
|
+
complete, self-explanatory code sample inside a fenced code block (Java, JTE, JavaScript,
|
|
1125
|
+
YAML, or HTML as appropriate). The sample code must be continuous (not fragments stitched
|
|
1126
|
+
with "// ..." gaps) and usable as a direct reference by a coding agent or developer. A
|
|
1127
|
+
section that only has bullet-point descriptions without accompanying code is incomplete.
|
|
1128
|
+
The code samples in `references/spec-template.md` and the other reference files show the
|
|
1129
|
+
expected level of detail — reproduce that level in the generated spec, substituting the
|
|
1130
|
+
actual project values from the context files.
|
|
1131
|
+
|
|
1132
|
+
## Constraints
|
|
1133
|
+
|
|
1134
|
+
These constraints are non-negotiable. Every code sample in the generated spec must
|
|
1135
|
+
follow them. If any constraint is violated, the spec is incorrect.
|
|
1136
|
+
|
|
1137
|
+
### Universal Constraints (Always Apply)
|
|
1138
|
+
|
|
1139
|
+
**Do NOT use Lombok's `@Data` annotation — anywhere.** Use `@Getter` and `@Setter`
|
|
1140
|
+
explicitly on every class that needs accessors. `@Data` generates `equals()`, `hashCode()`,
|
|
1141
|
+
and `toString()` which cause problems with persistent documents/entities, lazy-loaded
|
|
1142
|
+
collections, and circular references. The spec must use `@Getter @Setter` consistently.
|
|
1143
|
+
|
|
1144
|
+
**Do NOT use field injection.** Every Spring-managed bean must use constructor injection.
|
|
1145
|
+
Use Lombok's `@RequiredArgsConstructor` with `private final` fields. Never use `@Autowired`
|
|
1146
|
+
on fields. This applies to services, controllers, configurations, filters, and any other
|
|
1147
|
+
Spring component.
|
|
1148
|
+
|
|
1149
|
+
**Do NOT use DaisyUI.** All UI components must be built with pure Tailwind CSS utility
|
|
1150
|
+
classes. No DaisyUI plugin, no DaisyUI class names (no `btn`, `card`, `navbar`, `alert`,
|
|
1151
|
+
`badge`, `modal`, `drawer`, `menu`, `dropdown`, `tabs`, `toast`, `tooltip`, `table`,
|
|
1152
|
+
`stats`, `steps`, `progress`, `avatar`, `breadcrumbs`, `swap`, `join`, `indicator`,
|
|
1153
|
+
`input`, `select`, `textarea`, `checkbox`, `radio`, `toggle`, `range`, `file-input`,
|
|
1154
|
+
`form-control`, etc.). Build equivalent components using Tailwind utility classes only.
|
|
1155
|
+
|
|
1156
|
+
**Use MapStruct for all object mapping.** Define MapStruct mappers per module with
|
|
1157
|
+
`@Mapper(componentModel = "spring")`. Avoid handwritten mapping beyond simple passthroughs.
|
|
1158
|
+
|
|
1159
|
+
**URL routing must be module-based, NOT role-prefixed.** Controller `@RequestMapping`
|
|
1160
|
+
paths use only the module name (e.g., `/corridor`, `/quota`). Never embed role names
|
|
1161
|
+
in URL paths (e.g., NOT `/hub_administrator/corridor`). Role-based access control is
|
|
1162
|
+
enforced via `@PreAuthorize` annotations on controllers, derived from the mockup's
|
|
1163
|
+
role folder structure. Fragment controllers use `/{module}/fragments` (e.g.,
|
|
1164
|
+
`/corridor/fragments`), NOT `/api/content/{role}/{module}`.
|
|
1165
|
+
|
|
1166
|
+
**All data listings must be paginated.** Every page and fragment that renders a list
|
|
1167
|
+
must use the shared pagination component. Never render unbounded lists.
|
|
1168
|
+
|
|
1169
|
+
**Use real module data from context files.** The spec must use actual field names,
|
|
1170
|
+
collection names, module names, and user stories from the context files. Generic
|
|
1171
|
+
placeholder names (`fieldOne`, `module1`, etc.) are only acceptable in the shared
|
|
1172
|
+
infrastructure sections (layouts, components, error handling) — never in modules.
|
|
1173
|
+
|
|
1174
|
+
**Alpine.js v3 requires `'unsafe-eval'` in CSP `script-src`.** Alpine.js v3 uses
|
|
1175
|
+
`new Function()` for expression evaluation. The CspNonceFilter MUST include
|
|
1176
|
+
`'unsafe-eval'` in the `script-src` directive alongside the nonce. Without this,
|
|
1177
|
+
Alpine.js expressions will be silently blocked and all `x-data`, `x-show`, `@click`
|
|
1178
|
+
etc. will fail. The CSP `font-src` must also include `data:` for bundled font data
|
|
1179
|
+
URIs.
|
|
1180
|
+
|
|
1181
|
+
**Tailwind CSS v4 requires an explicit `@source` directive to scan JTE templates.**
|
|
1182
|
+
In `app.css`, add `@source "../../../jte";` after the `@import "tailwindcss";` line.
|
|
1183
|
+
Without this, Tailwind v4's automatic content detection only scans the frontend
|
|
1184
|
+
`src/` directory and misses all utility classes used in JTE template files, resulting
|
|
1185
|
+
in a minimal CSS output missing most styling.
|
|
1186
|
+
|
|
1187
|
+
**Do NOT generate UI elements without backend support.** Every interactive UI element
|
|
1188
|
+
in the spec (buttons, dropdowns, toggles) must be backed by a requirement in PRD.md
|
|
1189
|
+
or a functional backend endpoint. Specifically: do NOT include a locale/language
|
|
1190
|
+
switcher unless i18n = yes (i.e., PRD.md has internationalisation requirements). When
|
|
1191
|
+
i18n = yes, the language switcher and its backing `MessageSource`/`LocaleResolver`
|
|
1192
|
+
infrastructure are specified in Section 24 (Internationalisation); when i18n = no, omit
|
|
1193
|
+
all of it. Do NOT include features "for future use" — they will be non-functional and
|
|
1194
|
+
confuse users.
|
|
1195
|
+
|
|
1196
|
+
**HTMX navigation in sidebar and header fragments MUST use direct module URLs**, NOT
|
|
1197
|
+
`/api/content/...` prefixed paths. The pattern is: `hx-get="${item.getHref()}"` with
|
|
1198
|
+
`hx-select="#content-area"` and `hx-target="#content-area"` to extract the content area
|
|
1199
|
+
from the full page response. Never use `/api/content/` as a URL prefix — this pattern
|
|
1200
|
+
creates a dependency on a non-existent content API and causes navigation failures.
|
|
1201
|
+
|
|
1202
|
+
**Sidebar navigation must be filtered by the current user's roles.** The LayoutService
|
|
1203
|
+
(or equivalent) that builds `NavItem` lists MUST check the authenticated user's roles
|
|
1204
|
+
and only include menu items that the user is authorized to access. The role-to-menu
|
|
1205
|
+
mapping is derived from the mockup sidebar files (each role folder defines which menu
|
|
1206
|
+
items that role sees). Never show all menu items to all users — this exposes
|
|
1207
|
+
unauthorized functionality in the UI.
|
|
1208
|
+
|
|
1209
|
+
### Conditional Constraints
|
|
1210
|
+
|
|
1211
|
+
**If Auth = Keycloak:**
|
|
1212
|
+
- **Use OAuth2 Client (not Resource Server).** The application uses `oauth2Login()` with
|
|
1213
|
+
Authorization Code flow. After successful login, the `OidcUser` principal is stored in
|
|
1214
|
+
the HTTP session (Spring Security default session management).
|
|
1215
|
+
- **Do NOT manage users and roles in the application.** The application does not create,
|
|
1216
|
+
update, or delete users or roles. Keycloak (the external identity provider) owns all
|
|
1217
|
+
user and role management. The application only reads roles from the OIDC ID token to
|
|
1218
|
+
enforce access control. There are no user registration endpoints, no role assignment
|
|
1219
|
+
endpoints, and no user entity/document in the database.
|
|
1220
|
+
|
|
1221
|
+
**If Auth = form:**
|
|
1222
|
+
- The application manages its own user authentication. A `UserDetailsService` backed by
|
|
1223
|
+
the selected database provides user lookup. Passwords must be encoded with BCrypt.
|
|
1224
|
+
Session management uses Spring Security defaults (not stateless).
|
|
1225
|
+
|
|
1226
|
+
**If Scheduling = yes and Database = MongoDB:**
|
|
1227
|
+
- **Use `io.fluidsonic.mirror` for Quartz MongoDB job store.** Instead of the default
|
|
1228
|
+
in-memory or JDBC job store, Quartz is configured to persist job metadata in MongoDB
|
|
1229
|
+
using the `fluidsonic-mirror-quartz` library.
|
|
1230
|
+
|
|
1231
|
+
**If Scheduling = yes and Database = PostgreSQL/MySQL:**
|
|
1232
|
+
- Use the built-in Quartz JDBC job store with the selected relational database.
|
|
1233
|
+
|
|
1234
|
+
**If Messaging = yes:**
|
|
1235
|
+
- Queue and exchange names for pub/sub messaging (`app.*`) must not collide with batch
|
|
1236
|
+
partition queues (`batch.partition.*`). Use distinct prefixes for each concern.
|
|
1237
|
+
|
|
1238
|
+
**If Reporting = yes:**
|
|
1239
|
+
- Report definitions must call **module services** to produce DTOs, never repositories
|
|
1240
|
+
directly. This preserves Spring Modulith module boundaries.
|
|
1241
|
+
- Report layouts are built programmatically using JRDesign API — no `.jrxml` XML templates.
|
|
1242
|
+
Each `ReportDefinition` implements `buildDesign()` to construct the `JasperDesign` in Java.
|
|
1243
|
+
- Report DTO field names must match `JRDesignField` names declared in `buildDesign()`
|
|
1244
|
+
exactly (JavaBean getter convention).
|
|
1245
|
+
- Use `ReportDesignHelper` utility methods for common layout patterns (title bands, column
|
|
1246
|
+
headers, detail bands, page footers) to keep report implementations concise.
|
|
1247
|
+
- Report implementations must be `@Component` beans implementing `ReportDefinition` so
|
|
1248
|
+
that `ReportRegistry` auto-discovers them at startup.
|
|
1249
|
+
|
|
1250
|
+
**If Scheduling = yes and Remote Partitioning = yes:**
|
|
1251
|
+
- Manager and worker nodes must share the **same `JobRepository` database**. The manager
|
|
1252
|
+
writes partition metadata (`StepExecution` entries) and workers update them on completion.
|
|
1253
|
+
- **If Database = none and Remote Partitioning = yes**: This is an **invalid combination**.
|
|
1254
|
+
The spec must warn that remote partitioning requires a shared database. Either select a
|
|
1255
|
+
database (MongoDB, PostgreSQL, or MySQL) or disable remote partitioning.
|
|
1256
|
+
|
|
1257
|
+
## Principles Embedded in the Spec
|
|
1258
|
+
|
|
1259
|
+
These principles should be woven into every section of the spec rather than listed
|
|
1260
|
+
separately.
|
|
1261
|
+
|
|
1262
|
+
### Always-Applicable Principles
|
|
1263
|
+
- Server-rendered views with JTE templating and view-model-first design
|
|
1264
|
+
- Tailwind CSS utility-first styling (no component framework)
|
|
1265
|
+
- Alpine.js for client-side interactivity, htmx for partial page updates
|
|
1266
|
+
- Vite build pipeline with manifest-based asset resolution
|
|
1267
|
+
- Event-driven inter-module communication via Spring Modulith events
|
|
1268
|
+
- Domain-driven package structure (one module per bounded context)
|
|
1269
|
+
- Separation of concerns (controller -> service -> repository, view model -> template)
|
|
1270
|
+
- Constructor injection everywhere (`@RequiredArgsConstructor` + `private final`)
|
|
1271
|
+
- `@Getter @Setter` instead of `@Data` on all classes
|
|
1272
|
+
- Single `application.yml` with environment variables for all environment-specific values (no profile-specific YAML files)
|
|
1273
|
+
- Custom exception hierarchy with global error handling
|
|
1274
|
+
- CSP nonce support for inline scripts
|
|
1275
|
+
- Light/dark theme switching persisted in cookies
|
|
1276
|
+
- Structured logging of important events and errors
|
|
1277
|
+
|
|
1278
|
+
### Conditional Principles
|
|
1279
|
+
- **If Auth = Keycloak:** OAuth2 Client with Keycloak OIDC for all authentication and
|
|
1280
|
+
authorization (session-based). No user/role management — external IdP only.
|
|
1281
|
+
- **If Auth = form:** Spring Security form-based login with database-backed user store.
|
|
1282
|
+
Session-based authentication.
|
|
1283
|
+
- **If Auth = none:** No security filter chain. All endpoints are publicly accessible.
|
|
1284
|
+
Auth can be layered on later.
|