$38
This skill generates a comprehensive specification document (Markdown) that serves as a blueprint for building a monolith Spring Boot 3 web application with server-rendered views. The spec is intended to be followed by a developer or a coding agent to produce a fully functional project scaffold.
The specification does NOT generate code. It produces a detailed, opinionated technical document describing every layer of the application — from Maven configuration to JTE layouts to security filter chains — so that implementation becomes a mechanical exercise.
These are the fixed versions the spec targets. Do not deviate unless the user explicitly requests different versions.
| Component | Version |
|---|---|
| Java JDK | 21 |
| Spring Boot | 3.5.7 |
| Maven | 4.0.0 |
| JTE | 3.2.1 |
| Tailwind CSS | 4.x |
| Alpine.js | 3.x |
| htmx | 2.x |
| Vite | 6.x |
Include in the version table only when the corresponding integration is selected.
| Component | Version | When Selected |
|---|---|---|
| MongoDB | 8.0.19 | Database = MongoDB |
| PostgreSQL | 17.x | Database = PostgreSQL |
| MySQL | 8.4.x | Database = MySQL |
| Keycloak | 26.5.3 | Auth = Keycloak |
| RabbitMQ | 4.x | Messaging = yes OR Remote Partitioning = yes |
The spec must include these in the Maven configuration section (always):
gg.jte:jte-spring-boot-starter-3)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)If Database = MongoDB:
spring-boot-starter-data-mongodb)spring-modulith-starter-mongodb)If Database = PostgreSQL or MySQL:
spring-boot-starter-data-jpa)org.postgresql:postgresql) or MySQL driver (com.mysql:mysql-connector-j)org.flywaydb:flyway-core) for schema migrationspring-modulith-starter-jpa)If Auth = Keycloak:
spring-boot-starter-security)spring-boot-starter-oauth2-client)If Auth = Spring Security (form login):
spring-boot-starter-security)If Scheduling = yes:
spring-boot-starter-quartz)io.fluidsonic.mirror:fluidsonic-mirror-quartz (MongoDB job store for Quartz)If Scheduling = yes AND Spring Batch = yes:
spring-boot-starter-batch)If Scheduling = yes AND Spring Batch = yes AND Remote Partitioning = yes:
spring-batch-integration)spring-integration-amqp)spring-boot-starter-amqp)If Messaging = yes:
spring-boot-starter-amqp)
(shared with Remote Partitioning — if both are selected, include the dependency once)If Reporting = yes:
net.sf.jasperreports:jasperreports:7.0.3) — report engine with JRDesign API for programmatic layoutnet.sf.jasperreports:jasperreports-fonts:7.0.3)com.github.librepdf:openpdf:2.0.4) — PDF export engine for JasperReports 7.xorg.apache.poi:poi-ooxml:5.4.1) — XLSX export supportGenerate the spec when the user provides an application name and version that
corresponds to one of the custom applications defined in CLAUDE.md. The skill
reads all required inputs from the project's context files — no interactive Q&A is needed
for the core inputs.
The user invokes this skill by specifying the target application and version, for example:
/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3 module:Location Information/specgen-spring-jpa-jtehtmx "Hub Middleware" v1.0.3The skill then locates the matching context folder and reads all input files automatically.
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):
<app_folder>/CHANGELOG.md does not exist, skip this check (first-ever execution for this application).<app_folder>/CHANGELOG.md exists, scan all ## vX.Y.Z headings and determine the highest version using semantic versioning comparison."Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected." Do NOT proceed with any work.This skill uses standardized input resolution. Provide:
| Argument | Required | Example | Description |
|---|---|---|---|
<application> | Yes | hub_middleware | Application name to locate the context folder |
<version> | Yes | v1.0.3 | Version to scope processing |
module:<name> | No | module:Location Information | Limit generation to a single module |
The application name is matched against root-level application folders:
<number>_ prefix from folder names (e.g., 1_hub_middleware → hub_middleware)| File | Resolved Path |
|---|---|
| PRD.md | <app_folder>/context/PRD.md |
| Module Models | <app_folder>/context/model/ |
| HTML Mockups | <app_folder>/context/mockup/ |
| Output (specification) | <app_folder>/context/specification/ |
/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3 (all modules)/specgen-spring-jpa-jtehtmx hub_middleware v1.0.3 module:Location Information (one module)/specgen-spring-jpa-jtehtmx "Hub Middleware" v1.0.3When a version is provided, only include user stories, NFRs, and constraints from versions
<= the provided version. For example, if v1.0.3 is specified:
[v1.0.0], [v1.0.1], [v1.0.2], [v1.0.3][v1.0.4] or laterWhen module:<name> is provided:
SPEC.md for that specific moduleSPECIFICATION.md (root) gets a partial update — only that module's entry in the TOC
is added or updated; all other TOC entries are preserved as-isThe specification is driven by six input sources that are read from the project's context files. The skill does NOT ask the user for database, authentication, scheduling, or messaging choices — it determines these automatically from the context.
From CLAUDE.md (already loaded in context), locate the target application under the Custom Applications section. Extract:
The application name is used to derive:
hub-middleware)com.bestinet.urp (project-level constant)com.bestinet.urp.<artifactid_no_hyphens> (e.g., com.bestinet.urp.hubmiddleware)Read <app_folder>/context/PRD.md. This file contains all user stories
organized by module. Extract:
# System Module heading (e.g., User, Notification,
Activities, Audit Trail). These become system-level modules in the spec.# Business Module heading (e.g., Location
Information, Corridor, Employer). These become business-level modules.### User Story section contains tagged items like
[USHM00108] As a user, I want to.... These define the functional requirements for
each module's service interface and page controllers.The user stories directly inform:
Important: Items with strikethrough (~~text~~) are deprecated — do NOT include them
as active requirements. Instead, list them in the "Removed / Replaced" subsection of the
traceability table (see spec-template.md) so that developers can see what was removed and
which version removed it. If a deprecated item has a replacement (e.g., USHM00015 replaced
by USHM00222), note the replacement ID.
### User Story, ### Non Functional Requirement,
and ### Constraint section contains one or more version blocks formatted as [v1.0.x].
Items listed under each version tag belong to that version. The skill must track the
version tag for each item (user story, NFR, constraint) and carry it through to the
generated specification's traceability section. When a version block explicitly lists
"Removed ... from previous version", record those removals in a "Removed / Replaced"
subsection with the version that removed them and the replacement ID (if any).Within the same PRD.md, each module has a ### Non Functional Requirement section
with tagged items like [NFRHM0120]. These inform:
NFRs should be mapped to specific technical decisions in the spec — for example, an NFR stating "stored in JWT token" confirms stateless auth, while "sent asynchronously" confirms event-driven processing.
Within the same PRD.md, each module has a ### Constraint section with tagged
items like [CONSHM042]. These define hard boundaries that the spec must enforce:
Constraints are embedded directly into the relevant module blueprint — they inform service interface contracts, validation rules, and UI form configurations.
Read <app_folder>/context/model/MODEL.md first as the index, then read the
individual module model files in each module subfolder.
MODEL.md provides:
Per-module files (e.g., model/location-information/model.md):
Per-module schema (e.g., model/location-information/schemas.json):
Per-module diagram (e.g., model/location-information/document-model.mermaid):
The module model directly maps to:
MongoDB documents or JPA entities (field-for-field, not placeholder)
Repository methods and query patterns
MapStruct mapper definitions
DTO structures matching the actual module fields
Service interface method signatures
Version tracking: The MODEL.md summary table includes a "Versions" column listing which versions each module participates in (e.g., "1.0.0, 1.0.1, 1.0.3"). Per-module model.md files may also include version annotations on fields and indexes. The skill must carry these version tags into the generated specification.
Read <app_folder>/context/mockup/MOCKUP.html first as the index page, then
read the HTML files organized by role in subfolders.
MOCKUP.html provides:
Role-specific subfolders (e.g., mockup/hub_administrator/content/):
IMPORTANT — Role folders inform access control, NOT URL paths. The role-specific
folder structure (e.g., mockup/hub_administrator/content/corridor.html) determines:
@PreAuthorize("hasRole('HUB_ADMINISTRATOR')")@RequestMapping("/corridor") — NOT @RequestMapping("/hub_administrator/corridor")@RequestMapping("/corridor/fragments") — NOT @RequestMapping("/api/content/hub_administrator/corridor")Shared partials (e.g., mockup/partials/):
header.html — Header bar layout and elementsfooter.html — Footer layoutsidebar-<role>.html — Per-role navigation menusshell.html — Page shell/wrapper structureThe mockup screens directly map to:
JTE page templates (one per HTML screen)
JTE fragment templates (for htmx partial updates)
Page controller endpoints (one per screen)
View model classes (with fields matching the data shown in each screen)
Sidebar navigation items per role
Form field layouts and validation display
Design tokens for Tailwind configuration (colors, fonts from MOCKUP.html)
Version tracking: The MOCKUP.html index page shows a version tag on each screen
card (e.g., v1.0.0, v1.0.3). Individual mockup screens may include version
annotations. The skill must associate each mockup screen with its version and carry
this through to the generated specification.
Before determining optional components, check PRD.md for the following extended sections and extract their content for use throughout specification generation:
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:
| Pattern to Extract | How It Influences the Specification |
|---|---|
| Framework mention (e.g., "Spring Boot") | Validates technology stack choice; confirms Spring Modulith approach |
| "Monolithic" / "modular architecture" | Validates Spring Modulith module structure; cross-module communication via application events |
| "Stateless" | Confirms no HTTP session — JWT/OAuth2 token-based auth; include in Security Configuration section |
| "Event-driven" | Enhances Event-Driven Architecture section (Section 14) with event catalog, event payload DTOs, and explicit listener registration patterns per module |
| "Message driven" / "message queue" | Validates RabbitMQ integration sections; include message flow documentation per module |
| "Document based database" / "MongoDB" | Primary signal for Database = MongoDB (overrides CLAUDE.md if conflicting) |
| "Container based deployment" | Confirms environment-variable-based configuration (${ENV_VAR} syntax) |
| "Scale out" / "horizontally scalable" | Include HPA-related notes in deployment considerations |
| View engine mention (e.g., "JTE") | Validates JTE template engine choice |
| Build tool mention (e.g., "Vite") | Include Vite build configuration in the specification |
If the section is absent, proceed with existing CLAUDE.md-only detection.
If PRD.md contains a # Design System section with a file reference (e.g., [DESIGN_SYSTEM.md](reference/DESIGN_SYSTEM.md)):
accent-success color for Active)If the section is absent, use design tokens from MOCKUP.html Tailwind config (existing behavior).
If PRD.md contains a # High Level Process Flow section:
If the section is absent, derive messaging patterns from NFRs only (existing behavior).
Instead of asking the user, the skill determines optional components by analyzing the
dependencies listed in CLAUDE.md, the # Architecture Principle section in PRD.md (if present),
and cross-referencing with PRD.md NFRs and constraints.
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.
Fallback to CLAUDE.md: Examine the "Depends on" list in CLAUDE.md for the target application:
| Dependency Pattern | Database Selection |
|---|---|
| References "Hub Database" (MongoDB) | Database = MongoDB |
| References "HC Database" or "SC Database" (MySQL) | Database = MySQL |
| No database dependency listed | Database = none |
Also check CLAUDE.md's database section for the exact database name, and read
SECRET.md (in the project root) for host, port, and credentials to use in the
spec's application configuration.
| Dependency Pattern | Auth Selection |
|---|---|
| References "Hub Single Sign On" (Keycloak) | Auth = Keycloak |
| PRD.md constraint says "does not manage any user, permissions and roles" | Auth = none |
| PRD.md NFRs reference "SSO service" or "JWT token" | Auth = Keycloak |
| No SSO/Keycloak dependency but has user management stories | Auth = form |
If Auth = Keycloak, also extract from CLAUDE.md:
<artifact-id>-webhttp://localhost:8180/realms/<realm>hub_administrator → HUB_ADMINISTRATOR)| Dependency Pattern | Messaging Selection |
|---|---|
| References "Hub to HC Adapter Message Queue" or "Hub to SC Adapter Message Queue" (RabbitMQ) | Messaging = yes |
| No message queue dependency listed | Messaging = no |
If Messaging = yes, also extract the RabbitMQ version from the corresponding message queue section in CLAUDE.md.
Scheduling is determined from PRD.md content:
| Content Pattern | Scheduling Selection |
|---|---|
| NFRs mention "automatically deleted after X days", "scheduled", "periodic", "batch processing" | Scheduling = yes |
| User stories describe recurring jobs, cleanup tasks, or time-triggered operations | Scheduling = yes |
| No scheduling-related requirements found | Scheduling = no |
If Scheduling = yes, further determine:
Reporting is determined from PRD.md content:
| Content Pattern | Reporting Selection |
|---|---|
| NFRs mention "report", "Report interface", "generate report", "report generation" | Reporting = yes |
| User stories describe generating/downloading PDF, Excel, or CSV reports | Reporting = yes |
| A "Report" module exists in PRD.md with NFRs defining a Report interface | Reporting = yes |
| No reporting-related requirements found | Reporting = no |
If Reporting = yes, the spec includes:
ReportDefinition interface with buildDesign() method for modules to implementReportDesignHelper utility class with static builders for common layout patternsReportService orchestrating compile → fill → export via JRBeanCollectionDataSourceAfter analyzing all inputs, produce a determination summary before generating the spec. Present it to the user for confirmation:
Optional Component Determination:
- Database: MongoDB (from CLAUDE.md → depends on Hub Database)
- Authentication: Keycloak (from CLAUDE.md → depends on Hub Single Sign On)
- Scheduling: yes (from PRD.md → NFR mentions automatic deletion)
- Spring Batch: no
- Remote Partitioning: no
- Messaging: yes (from CLAUDE.md → depends on Hub to HC/SC Adapter Message Queue)
- Reporting: yes (from PRD.md → Report module with Report interface NFR)
If the user disagrees with any determination, allow them to override before proceeding.
After determination, these values are needed. Most are derived automatically:
Auto-derived from context files:
com.bestinet.urpcom.bestinet.urp.<artifactid>Auto-derived from CLAUDE.md (Port Allocation table):
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.Optional (use sensible defaults if not found in context):
light (supports light/dark)INFO for application, WARN for frameworksOnce inputs are gathered from context files and optional components are determined,
generate the specification as a multi-file output split by module. Read the spec
template at references/spec-template.md for the exact structure and content of each
section. The template is the authoritative guide — follow it closely.
The specification is split into two categories:
SPECIFICATION.md — Contains the Table of Contents, shared infrastructure,
and application-level sections that apply across all modules.<module-name>/SPEC.md — Each module gets its own folder with
a self-contained specification file covering that module's complete blueprint.This split enables a coding agent to:
SPECIFICATION.md<module>/SPEC.mdImportant: The generated spec must use real module data from the context files, not generic placeholders. Specifically:
locationInformation, corridor, employer — not module1, module2)model/location-information/model.md), not placeholder fieldOne/fieldTwolistProvincesByCountry())hub_administrator/content/location_information.html exists, there must be a matching
controller endpoint and JTE page). The controller URL is module-based (e.g.,
/location-information), NOT role-prefixed (e.g., NOT /hub_administrator/location-information).
The mockup's role folder determines @PreAuthorize annotations, not URL structure./corridor, /quota) — the role determines which items
appear in the sidebar, not the URL prefixUSHM00228 [v1.0.3]).
This enables incremental implementation by version. ALL traceability sub-tables
(User Stories, NFRs, AND Constraints) MUST include the | Version | column. Do not
omit the Version column from any table — even if a module only has v1.0.0 items._None._ to make it
explicit that nothing was removed.<app_folder>/context/specification/
├── SPECIFICATION.md ← TOC + shared/application-level specs
├── location-information/
│ └── SPEC.md ← Module blueprint for Location Information
├── corridor/
│ └── SPEC.md ← Module blueprint for Corridor
├── employer/
│ └── SPEC.md ← Module blueprint for Employer
├── ... ← One folder per module from PRD.md
SPECIFICATION.md (Root)The root file contains the TOC and all shared/application-level sections. These are the sections that a coding agent implements first before any module work:
Project metadata, application description, technology stack summary, the complete
list of user roles extracted from mockup sidebar files, and the Module Index —
a table listing every module with a link to its <module>/SPEC.md file.
Complete pom.xml structure with all dependencies (core + selected conditional),
plugin configurations (MapStruct annotation processor, Spring Boot Maven plugin,
frontend-maven-plugin for Vite build, maven-clean-plugin to delete on-demand
jte-classes/ folder, jte-maven-plugin with precompile goal at process-classes
phase outputting to ${project.build.directory}/classes), and property management.
A single application.yml (no profile-specific files like application-dev.yml or
application-prod.yml) covering database connection (MongoDB URI or JDBC datasource
depending on selection), auth settings (Keycloak/OAuth2 if selected, or form login if
selected), JTE configuration (with JTE_DEV_MODE and JTE_PRECOMPILED env vars),
scheduling config (if selected), theme defaults, and logging configuration. All environment-sensitive values (ports, hostnames, credentials,
URIs) MUST use Spring's ${ENV_VAR:default} syntax to allow externalization via
environment variables while keeping sensible defaults for local development. Do NOT use
Spring profiles or profile-specific YAML files — environment differences are handled
entirely through environment variables (e.g., via .env file locally or system
environment variables in deployment).
app: namespace)All application-owned configuration — any config specific to THIS application, as
opposed to the Spring/Java ecosystem — MUST live under the top-level app: key in
application.yml. NEVER place application-specific keys under Spring framework
namespaces (spring.*, server.*, management.*, logging.*) — those are
reserved for framework configuration.
Grouping rule. Organise the app: tree by module:
app.* with no module prefix.app.<module-kebab-case>.*, one block
per module that needs runtime config. A module with a single config value still
gets its own block — do not flatten.notification:, batch-job:, audit-trail:). They MUST be nested under app:.Naming rule. YAML keys use kebab-case (from-address, retry-limit,
max-retry). Spring Boot's relaxed binding maps them to camelCase Java fields
automatically. Do NOT use camelCase or snake_case in YAML.
Binding rule. For every app.* subtree (cross-cutting OR per-module), bind once
via @ConfigurationProperties on a record in the corresponding module's config
subpackage — or, for cross-cutting values, in the application-level config
subpackage. Do NOT inject individual values via @Value("${app....}") scattered
across beans or templates. Bind once at the module boundary and inject the typed record.
Environment-override rule. Every app.* leaf value MUST use Spring's
${ENV_VAR:default} syntax so it can be overridden per environment without editing
YAML. Every referenced ${ENV_VAR} MUST appear in the .env file generated in
section 3b.
Example structure: