@rashidee/co2 1.3.7 → 1.3.8

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.
Files changed (77) hide show
  1. package/dist/.co2-dat/app.db +0 -0
  2. package/dist/.co2-dat/app.db-shm +0 -0
  3. package/dist/.co2-dat/app.db-wal +0 -0
  4. package/dist/index.js +167 -68
  5. package/package.json +41 -41
  6. package/plugin/skills/conductor-feature-develop/SKILL.md +1384 -1383
  7. package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +225 -224
  8. package/plugin/skills/mockgen-shadcn/SKILL.md +1073 -1067
  9. package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +5 -3
  10. package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +631 -498
  11. package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +2 -2
  12. package/plugin/skills/mockgen-tailwind/SKILL.md +913 -904
  13. package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +722 -720
  14. package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +631 -498
  15. package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -190
  16. package/static/assets/{abnfDiagram-VRR7QNED-CsyqZblo.js → abnfDiagram-VRR7QNED-DP7zbvBZ.js} +1 -1
  17. package/static/assets/{arc-it3yvCvj.js → arc-Ckh0cqx_.js} +1 -1
  18. package/static/assets/{architectureDiagram-ZJ3FMSHR-sjNv2MOQ.js → architectureDiagram-ZJ3FMSHR-EpVuCwzS.js} +1 -1
  19. package/static/assets/{blockDiagram-677ZJIJ3-DW9ZjtwO.js → blockDiagram-677ZJIJ3-DsgBkX_g.js} +1 -1
  20. package/static/assets/{c4Diagram-LMCZKHZV-DP3gJkhN.js → c4Diagram-LMCZKHZV-CR04rrP-.js} +1 -1
  21. package/static/assets/channel-DfxyTZ0M.js +1 -0
  22. package/static/assets/{chunk-2Q5K7J3B-ByxTr7KB.js → chunk-2Q5K7J3B-DeQC-sio.js} +1 -1
  23. package/static/assets/{chunk-32BRIVSS-vNETwpX4.js → chunk-32BRIVSS-Qbam-XOV.js} +1 -1
  24. package/static/assets/{chunk-5VM5RSS4-DbdsRtpE.js → chunk-5VM5RSS4-CH-IX0uh.js} +1 -1
  25. package/static/assets/{chunk-EX3LRPZG-DPkDGikN.js → chunk-EX3LRPZG-6gUCPZ6x.js} +1 -1
  26. package/static/assets/{chunk-JWPE2WC7-Ccpx-Rog.js → chunk-JWPE2WC7-DSNEXnbo.js} +1 -1
  27. package/static/assets/{chunk-MOJQB5TN-CnRPtHb3.js → chunk-MOJQB5TN-BVmlLOXk.js} +1 -1
  28. package/static/assets/{chunk-RYQCIY6F-C--_KRGR.js → chunk-RYQCIY6F-2pIZN6PI.js} +1 -1
  29. package/static/assets/{chunk-V7JOEXUC-BJQ5fwNa.js → chunk-V7JOEXUC-Dj8a39S7.js} +1 -1
  30. package/static/assets/{chunk-VR4S4FIN-BPcVRYqJ.js → chunk-VR4S4FIN-D2kLoVlo.js} +1 -1
  31. package/static/assets/{chunk-XXDRQBXY-BoC3DCKQ.js → chunk-XXDRQBXY-x3SQWIAg.js} +1 -1
  32. package/static/assets/classDiagram-OUVF2IWQ-DPLLyb_P.js +1 -0
  33. package/static/assets/classDiagram-v2-EOCWNBFH-DPLLyb_P.js +1 -0
  34. package/static/assets/{cose-bilkent-JH36ORCC-DlKrOw_E.js → cose-bilkent-JH36ORCC-ltgQwU4R.js} +1 -1
  35. package/static/assets/{cynefin-VYW2F7L2-CZQhaPM1.js → cynefin-VYW2F7L2-BwJnOy5O.js} +1 -1
  36. package/static/assets/{cynefinDiagram-TSTJHNR4-cZP74_0I.js → cynefinDiagram-TSTJHNR4-Bi47Fvnv.js} +1 -1
  37. package/static/assets/{dagre-VKFMJZFB-tB2cBd_e.js → dagre-VKFMJZFB-5_l7QdUh.js} +1 -1
  38. package/static/assets/{diagram-FQU43EPY-QwoADT9c.js → diagram-FQU43EPY-HKDyXOzo.js} +1 -1
  39. package/static/assets/{diagram-G47NLZAW-Bjz2rwUz.js → diagram-G47NLZAW-xHHInyx1.js} +1 -1
  40. package/static/assets/{diagram-NH7WQ7WH-DS9j6K7F.js → diagram-NH7WQ7WH-nftmRdjw.js} +1 -1
  41. package/static/assets/{diagram-OA4YK3LP-CUPwlGEi.js → diagram-OA4YK3LP-CX8gIXu7.js} +1 -1
  42. package/static/assets/{diagram-WEI45ONY-iejOZOdV.js → diagram-WEI45ONY-BaT3ur6a.js} +1 -1
  43. package/static/assets/{ebnfDiagram-CCIWWBDH-Bg3puNXE.js → ebnfDiagram-CCIWWBDH-CM9hwJSh.js} +1 -1
  44. package/static/assets/{erDiagram-Q63AITRT-DTxdGEtK.js → erDiagram-Q63AITRT-C9cK36a5.js} +1 -1
  45. package/static/assets/{flowDiagram-23GEKE2U-CRl-AJlj.js → flowDiagram-23GEKE2U-BQw_JFaW.js} +1 -1
  46. package/static/assets/{ganttDiagram-NO4QXBWP-wCOJ8cfC.js → ganttDiagram-NO4QXBWP-Cgg9ZbM9.js} +1 -1
  47. package/static/assets/{gitGraphDiagram-IHSO6WYX-CnVtKot-.js → gitGraphDiagram-IHSO6WYX-SciNAnN3.js} +1 -1
  48. package/static/assets/{index-xLqMMC0F.css → index-CM4GfOLV.css} +1 -1
  49. package/static/assets/{index-DAL1vVaa.js → index-HUEMwsDE.js} +194 -194
  50. package/static/assets/{infoDiagram-FWYZ7A6U-DmvEl4fi.js → infoDiagram-FWYZ7A6U-BPCKxKmJ.js} +1 -1
  51. package/static/assets/{ishikawaDiagram-FXEZZL3T-CjKerAXn.js → ishikawaDiagram-FXEZZL3T-C0eQKvpo.js} +1 -1
  52. package/static/assets/{journeyDiagram-5HDEW3XC-Bmc4ARKl.js → journeyDiagram-5HDEW3XC-DgrJ90BU.js} +1 -1
  53. package/static/assets/{kanban-definition-HUTT4EX6-BZ9I3imN.js → kanban-definition-HUTT4EX6-ISgFrxBl.js} +1 -1
  54. package/static/assets/{linear-CrHKLpp_.js → linear-CaPqviiq.js} +1 -1
  55. package/static/assets/{mindmap-definition-LN4V7U3C-SUk59XXF.js → mindmap-definition-LN4V7U3C-DTpJ3Okf.js} +1 -1
  56. package/static/assets/{pegDiagram-2B236MQR-CknFYdh_.js → pegDiagram-2B236MQR-D0EbYB8X.js} +1 -1
  57. package/static/assets/{pieDiagram-ENE6RG2P-B3VlLXXT.js → pieDiagram-ENE6RG2P-lAwviOjS.js} +1 -1
  58. package/static/assets/{quadrantDiagram-ABIIQ3AL-BUkZjvW_.js → quadrantDiagram-ABIIQ3AL-Dn8yVCWJ.js} +1 -1
  59. package/static/assets/{railroadDiagram-RFXS5EU6-LklmPimD.js → railroadDiagram-RFXS5EU6-BVLcNBsS.js} +1 -1
  60. package/static/assets/{requirementDiagram-TGXJPOKE-DnRFaZbz.js → requirementDiagram-TGXJPOKE-Bmjsh1uy.js} +1 -1
  61. package/static/assets/{sankeyDiagram-HTMAVEWB-D242DUlQ.js → sankeyDiagram-HTMAVEWB-tdNqcgyd.js} +1 -1
  62. package/static/assets/{sequenceDiagram-DBY2YBRQ-DmiiStqo.js → sequenceDiagram-DBY2YBRQ-ChtQkNW9.js} +1 -1
  63. package/static/assets/{sizeCapture-X5ZJPWSS-cbMvR047.js → sizeCapture-X5ZJPWSS-BAnRJGV8.js} +1 -1
  64. package/static/assets/{stateDiagram-2N3HPSRC-YIIylI9N.js → stateDiagram-2N3HPSRC-CI7wmYAe.js} +1 -1
  65. package/static/assets/stateDiagram-v2-6OUMAXLB-BJrR07NX.js +1 -0
  66. package/static/assets/{swimlanes-5IMT3BWC-Ba309Ysu.js → swimlanes-5IMT3BWC-k6NGsb3p.js} +2 -2
  67. package/static/assets/swimlanesDiagram-G3AALYLV-B0-5v6_-.js +8 -0
  68. package/static/assets/{timeline-definition-FHXFAJF6-BdpW3kGY.js → timeline-definition-FHXFAJF6-CweEa8iU.js} +1 -1
  69. package/static/assets/{vennDiagram-L72KCM5P-BiSgQ9Lf.js → vennDiagram-L72KCM5P-DDPbV_sp.js} +1 -1
  70. package/static/assets/{wardleyDiagram-EHGQE667-Clr8YWGW.js → wardleyDiagram-EHGQE667-IP4J8kqe.js} +1 -1
  71. package/static/assets/{xychartDiagram-FW5EYKEG-LsC066MO.js → xychartDiagram-FW5EYKEG-CMfWLoM8.js} +1 -1
  72. package/static/index.html +2 -2
  73. package/static/assets/channel-C_J_aLZ7.js +0 -1
  74. package/static/assets/classDiagram-OUVF2IWQ-yUfBrCjx.js +0 -1
  75. package/static/assets/classDiagram-v2-EOCWNBFH-yUfBrCjx.js +0 -1
  76. package/static/assets/stateDiagram-v2-6OUMAXLB-m0MSGh0v.js +0 -1
  77. package/static/assets/swimlanesDiagram-G3AALYLV-DY_J_ih_.js +0 -8
@@ -1,904 +1,913 @@
1
- ---
2
- name: mockgen-tailwind
3
- model: claude-opus-4-8
4
- effort: high
5
- description: >
6
- Generate HTML mockup screens from PRD.md files for UI/UX human designer review.
7
- Creates Alpine.js + HTMX mockup assets with admin dashboard layout
8
- (left sidebar navigation, header with logo/notifications/locale/user menu, footer
9
- with copyright/version) served as partials, organized by user role in a mockup/ folder.
10
- All mockups are served by the SINGLE shared Mockup Hub at <root>/mockup — a
11
- zero-dependency Node.js server with a landing page listing every application and role
12
- (unclickable when not ready) and a configurable port (PORT env / mockup.config.json).
13
- Input: application name (mandatory), version (mandatory), module (optional).
14
- Output: mockup/ folder in the application's context folder
15
- containing MOCKUP.html index page, mockup-manifest.json, partials/, and role-specific
16
- content subfolders (assets only — no per-app server); plus the shared hub at
17
- <root>/mockup if not already present. Trigger on keywords: "generate mockup", "generate mockups",
18
- "create mockup screens", "HTML mockup", "UI mockup from user stories",
19
- "mockup from PRD.md", "generate screens", "create UI screens".
20
- Accepts application name and version as input
21
- (e.g., `/mockgen-tailwind hub_middleware v1.0.3`).
22
- Optionally accepts a module name to limit generation to screens for that module only
23
- (e.g., `/mockgen-tailwind hub_middleware v1.0.3 module:Location Information`).
24
- When module is specified, only content files for that module are generated/updated
25
- (plus the manifest); partials, sidebars, the shared hub, and other module screens are
26
- left untouched.
27
- Automatically excludes strikethrough (deprecated/removed) items.
28
- ---
29
-
30
- # Mockgen HTML
31
-
32
- Generate HTMX + Alpine.js mockup assets from PRD.md for UI/UX designer review.
33
- Header, footer, and sidebar are served as partials. Content pages are HTMX fragments
34
- swapped into a shell layout. All image/PDF links open in new tabs.
35
-
36
- The application's mockup folder contains **assets only** — no server. All applications'
37
- mockups are served by the **shared Mockup Hub**, a single zero-dependency Node.js server
38
- at `<root>/mockup/` (see [references/mockup-hub-template.md](references/mockup-hub-template.md)).
39
- The hub assembles pages at `/{app_slug}/{role}/{page}`, renders a landing page listing
40
- every application and role (roles are unclickable until their mockups are ready), and
41
- listens on a configurable port (`PORT` env var → `mockup.config.json` → 3000).
42
-
43
- ## Stack
44
-
45
- | Layer | Technology |
46
- |-------|------------|
47
- | Server | Shared Mockup Hub — `<root>/mockup/server.js` (zero-dependency Node.js) |
48
- | Partial loading / navigation | HTMX 2.x |
49
- | Interactive UI (dropdowns, dark mode) | Alpine.js 3.x |
50
- | Styling | Tailwind CSS (CDN) |
51
- | Icons | Inline Heroicons SVG |
52
-
53
- ## Input
54
-
55
- This skill uses standardized input resolution. Provide:
56
-
57
- | Argument | Required | Example | Description |
58
- |----------|----------|---------|-------------|
59
- | `<application>` | Yes | `hub_middleware` | Application name to locate the context folder |
60
- | `<version>` | Yes | `v1.0.3` | Version to scope processing (filter user stories <= this version) |
61
- | `module:<name>` | No | `module:Location Information` | Limit generation to a single module |
62
-
63
- ### Application Folder Resolution
64
-
65
- The application name is matched against root-level application folders:
66
- 1. Strip any leading `<number>_` prefix from folder names (e.g., `1_hub_middleware` → `hub_middleware`)
67
- 2. Match case-insensitively against the provided application name
68
- 3. Accept snake_case, kebab-case, or title-case input (all match the same folder)
69
- 4. If no match found, list available applications and stop
70
-
71
- ### Auto-Resolved Paths
72
-
73
- | File | Resolved Path |
74
- |------|---------------|
75
- | PRD.md | `<app_folder>/context/PRD.md` |
76
- | Module Models | `<app_folder>/context/model/` |
77
- | Output (mockup) | `<app_folder>/context/mockup/` |
78
- | Mockup Hub (shared) | `<root>/mockup/` |
79
-
80
- **App slug** (used in all generated routes): the application folder name with the leading
81
- `<number>_` prefix stripped (e.g., `1_hub_middleware` → `hub_middleware`). Record it during
82
- input resolution every generated link is prefixed with `/{app_slug}`.
83
-
84
- ### Example Invocations
85
-
86
- - `/mockgen-tailwind hub_middleware v1.0.3` (all modules, up to v1.0.3)
87
- - `/mockgen-tailwind hub_middleware v1.0.3 module:Location Information` (one module, specific version)
88
- - `/mockgen-tailwind "Hub Middleware" v1.0.3 module:Employer` (title-case app name)
89
-
90
- ### Version and Module Filtering
91
-
92
- - Only include user stories, NFRs, constraints,
93
- and references from sections whose version tag is **less than or equal to** the target version
94
- - If a module is provided (e.g., `module:Location Information`), only generate/update screens
95
- for that specific module. All other modules are skipped. Common screens (home, profile,
96
- account, notifications) and partials (shell, header, footer, sidebars) are
97
- NOT regenerated when a module filter is active — only the module's own content fragments
98
- are written (plus MOCKUP.html updated for only that module's cards and
99
- mockup-manifest.json refreshed).
100
- - If no module is provided, process all modules (default behavior)
101
-
102
- **Argument parsing**: The `module:` prefix is the canonical form. Also accept:
103
- - `module:"Location Information"` (quoted, with space)
104
- - `module:location_information` (snake_case — convert to title-case for matching)
105
- - Natural language: `for Location Information module`, `only Location Information`
106
-
107
- ## Version Gate
108
-
109
- 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`):
110
-
111
- 1. If `<app_folder>/CHANGELOG.md` does not exist, skip this check (first-ever execution for this application).
112
- 2. If `<app_folder>/CHANGELOG.md` exists, scan all `## vX.Y.Z` headings and determine the **highest version** using semantic versioning comparison.
113
- 3. Compare the requested version against the highest version:
114
- - If requested version **>=** highest version: proceed normally.
115
- - 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.
116
-
117
- ## Workflow
118
-
119
- ### Step 1: Parse PRD.md
120
-
121
- Read the auto-resolved PRD.md file and extract:
122
-
123
- 1. **Application name**: Derive from the parent folder name containing PRD.md.
124
- Strip leading number and underscore prefix, then title-case.
125
- Example: `1_hub_middleware` -> "Hub Middleware"
126
-
127
- 2. **Application initials**: First letter of each word, uppercase.
128
- Example: `1_hub_middleware` -> "HM"
129
-
130
- 3. **Modules**: Each `## Module Name` section under a `# Module Category` heading.
131
- Record the module name and its description (the line after the heading).
132
-
133
- 4. **User stories per module**: Lines matching `- [USxx#####] As a {Role} user, I want to...`
134
- Extract: tag, role, action summary.
135
-
136
- 5. **Unique roles**: Collect all distinct roles from user stories.
137
- Example: "Hub Administrator", "Hub Operation Support"
138
-
139
- 6. **Target version** (from input argument): If a version was provided, record it for
140
- filtering in the next sub-step.
141
-
142
- #### 1a: Version Filtering and Strikethrough Exclusion (MANDATORY)
143
-
144
- PRD.md is a version-controlled document. Each section (User Story, Non Functional
145
- Requirement, Constraint, Reference) has a version tag in square brackets, e.g., `[v1.0.1]`.
146
- Items may also be marked with strikethrough (`~~`) to indicate they are deprecated/removed.
147
-
148
- **Strikethrough exclusion** (always applied, regardless of version parameter):
149
- - Any line wrapped in `~~strikethrough~~` markup MUST be excluded from processing
150
- - This includes user stories, NFRs, constraints, and references
151
- - Example: `~~[USHM00006] As a Hub Administrator user, I want to...~~` → **SKIP**
152
- - Partially strikethrough lines (where only part is struck) should still be excluded
153
- if the tag identifier is within the strikethrough
154
-
155
- **Version filtering** (applied only when a target version is provided):
156
- - Each section under a module has one or more version tags like `[v1.0.0]` or `[v1.0.1]`
157
- - Items listed under a version tag belong to that version
158
- - When a target version is specified (e.g., `v1.0.1`):
159
- - **Include** items from sections whose version tag is **<= target version**
160
- - **Exclude** items from sections whose version tag is **> target version**
161
- - Version comparison uses semantic versioning: compare major, then minor, then patch
162
- - When no target version is specified, include all items from all versions (but still
163
- exclude strikethrough items)
164
-
165
- **Version tracking per section**: Record which version tag each item belongs to, as this
166
- will be used for traceability in the generated screens.
167
-
168
- Example parsing of a section with multiple versions:
169
- ```markdown
170
- ### User Story
171
- [v1.0.0]
172
- - ~~[USHM00006] As a Hub Administrator user, I want to manage...~~
173
- - [USHM00009] As a Hub Administrator user, I want to map...
174
- [v1.0.1]
175
- - [USHM00012] As a Hub Administrator user, I want to manage the list...
176
- ```
177
-
178
- With target version `v1.0.0`:
179
- - USHM00006 → EXCLUDED (strikethrough)
180
- - USHM00009 → INCLUDED (v1.0.0 <= v1.0.0, not strikethrough)
181
- - USHM00012 → EXCLUDED (v1.0.1 > v1.0.0)
182
-
183
- With target version `v1.0.1` (or no version specified):
184
- - USHM00006 → EXCLUDED (strikethrough)
185
- - USHM00009 → INCLUDED
186
- - USHM00012 → INCLUDED
187
-
188
- #### 1c: Module Filtering (applied only when a module argument is provided)
189
-
190
- When a `module` argument is present, apply module filtering after version filtering:
191
-
192
- 1. **Match the specified module** against the list of parsed modules (case-insensitive, ignoring
193
- leading/trailing whitespace). Also accept snake_case input by converting it to title-case
194
- for comparison (e.g., `location_information` → match "Location Information").
195
- 2. **Record the matched module name** for use in Step 3 and beyond.
196
- 3. If no module matches, stop and report the available module names to the user before proceeding.
197
- 4. **Module filter scope**: the filter only affects **content fragment generation** (Step 6e).
198
- All other steps complete normally (parsing, design system, planning) but output is restricted
199
- to the filtered module's screens.
200
-
201
- **Module-filtered generation mode** differs from full generation in these ways:
202
-
203
- | Aspect | Full Generation | Module-Filtered |
204
- |--------|----------------|-----------------|
205
- | Common screens (home, profile, account, notifications) | Generate for every role | **SKIP** — already exist |
206
- | Partials (shell, header, footer) | Generate | **SKIP** — already exist |
207
- | Sidebar per role | Generate | **SKIP** — already exist |
208
- | mockup-manifest.json | Generate | **Update** (version, generatedAt, screen counts) |
209
- | Mockup Hub (`<root>/mockup/`) | Ensure (create/upgrade) | **Ensure** (create/upgrade) |
210
- | Module content files (target module) | Generate | **Generate / overwrite** |
211
- | Module content files (other modules) | Generate | **SKIP** — leave untouched |
212
- | MOCKUP.html | Generate full file | **Update only the target module's cards** |
213
- | footer.html version string | Update | **Update** (version may have changed) |
214
-
215
- **MOCKUP.html partial update** (module-filtered mode):
216
- - Read the existing MOCKUP.html
217
- - Locate the screen cards section for the target module (search by module name heading or
218
- existing card tags)
219
- - Replace only those cards with freshly generated ones reflecting the new screens
220
- - Update the total screen count per role (add net new screens)
221
- - Update the version badge if it changed
222
- - Update the "N new screens added in vX.Y.Z" banner text
223
- - Leave all other role sections and cards unchanged
224
-
225
- ### Step 1b: Discover and Load Module Models
226
-
227
- After parsing PRD.md, look for module models at the auto-resolved model path:
228
- `<app_folder>/context/model/`
229
-
230
- For each module extracted in Step 1:
231
-
232
- 1. Convert the module name to **kebab-case** to derive the model folder name:
233
- - Lowercase the module name and replace spaces with hyphens
234
- - Examples: "Location Information" → `location-information`, "Industrial Classification" → `industrial-classification`, "Employer" → `employer`
235
-
236
- 2. Check for `{model_dir}/{kebab-module}/model.md`
237
-
238
- 3. If the file exists, parse it and extract the following sections:
239
-
240
- - **Section 2 – Collection Catalog**: collection names and types (Root Collection, Audit Collection, etc.)
241
- - **Section 5 – Field Detail per Collection**: for each collection — field name, type, required, nullable, constraints/notes
242
- - **Section 6 – Embedded Document Definitions**: embedded type name and its sub-fields
243
- - **Section 7 – Enum Definitions**: enum name and all allowed values with descriptions
244
- - **Section 9 – Index Recommendations**: indexed fields (used to identify search/filter parameters)
245
-
246
- 4. Store this as the **module model** for the module, keyed by module name
247
-
248
- **Field classification** (used during content generation in Step 6e):
249
-
250
- | Category | Definition | Usage |
251
- |----------|-----------|-------|
252
- | System fields | `_id`, `_audit`, `_version`, `deleted`, `deletedAt`, `deletedBy` | Exclude from user-facing forms |
253
- | Audit-only fields | Fields whose Source is `CONVENTION` and type is `Audit` | Show in detail views only |
254
- | Required form fields | `Required: Yes` AND not a system field | Mandatory inputs in create/edit forms |
255
- | Optional form fields | `Required: No` AND not a system field | Optional inputs in create/edit forms |
256
- | Read-only after creation | Fields marked as unique identity keys (e.g., `companyRegistrationNumber`) | Show in edit forms as readonly |
257
- | Search/filter fields | Fields referenced in Index Recommendations | Render as filter controls in list screens |
258
- | Enum fields | Type matches an entry in Section 7 Enum Definitions | Render as `<select>` dropdowns |
259
- | Embedded object fields | Type is a custom embedded document type (not a primitive) | Render as `<fieldset>` sub-group |
260
- | Embedded array fields | Type ends in `[]` (e.g., `PersonInCharge[]`) | Render as repeatable row with Add/Remove |
261
-
262
- **Fallback**: If no `model.md` exists for a module, infer fields from user story text (original behavior).
263
-
264
- ---
265
-
266
- ### Step 2: Load Design System
267
-
268
- Load the design system using a two-tier resolution strategy:
269
-
270
- #### 2a: PRD.md Design System Reference (Primary Source)
271
-
272
- Check if PRD.md contains a `# Design System` section. If it does:
273
- 1. Extract the referenced file path (e.g., from `[DESIGN_SYSTEM.md](reference/DESIGN_SYSTEM.md)`)
274
- 2. Resolve the path relative to PRD.md's location
275
- 3. If the referenced file exists, read it and extract:
276
- - Color palettes (primary, secondary, accent, neutral — hex values)
277
- - Typography (font families, font sizes, weight scale)
278
- - Spacing scale (if overriding Tailwind defaults)
279
- - Component patterns (button styles, card styles, form input styles, table styles, badge/chip styles, modal patterns)
280
- - Layout grid rules
281
- 4. Apply extracted tokens to the Tailwind CDN `<script>` config block in `shell.html` (custom colors, fonts), all generated partials (consistent color classes), and component rendering
282
-
283
- #### 2b: Context Design Folder (Fallback)
284
-
285
- If PRD.md does not have a `# Design System` section, or the referenced file does not exist, fall back to the application's `<app_folder>/context/design/` folder. This folder contains pre-defined design tokens and Tailwind component guidelines maintained externally by the UI/UX team.
286
-
287
- Read all files in `{app_name}/context/design/` (where `{app_name}` is the resolved application folder name from Step 1). Apply the design tokens and guidelines found there to all generated mockup screens.
288
-
289
- **Expected files** (any or all may be present):
290
- - `design-system.md` — Colors, typography, spacing, and visual style definitions
291
- - `components.md` — Reusable component patterns and Tailwind class conventions
292
- - `guidelines.md` — Layout rules, accessibility standards, and stack-specific guidelines
293
-
294
- #### 2c: Default Fallback
295
-
296
- If neither the PRD reference nor the `{app_name}/context/design/` folder provides design tokens, use sensible defaults: a neutral color palette, Inter/system font stack, and standard Tailwind utility classes for spacing and layout.
297
-
298
- #### 2d: Process Flow Status States
299
-
300
- If PRD.md contains a `# High Level Process Flow` section, scan it for entity status lifecycle descriptions (e.g., "Received → Validated → Enriched → Active"). For each status lifecycle found:
301
- - Ensure list screens for the corresponding module include a status column with colored badges for each state
302
- - Use design system color tokens for badge colors (e.g., success color for active/completed states, warning for pending, danger for failed/rejected)
303
-
304
- ### Step 3: Plan Screen Files
305
-
306
- For each role, determine ALL screens to generate. **Every clickable link, tab, or action
307
- in any generated screen MUST have a corresponding content fragment file. No link may point
308
- to `#` or be a dead end.**
309
-
310
- **Module filter applied here**: If a module argument was provided (Step 1c), plan only the
311
- screens for that module across all roles. Skip common screens (home, profile, account,
312
- notifications) and skip all other modules entirely. The screen plan table should list only
313
- the filtered module's screens.
314
-
315
- #### 3a: Core Screens (content fragments)
316
-
317
- 1. **home.html**: Default home/dashboard page with welcome message and summary widgets
318
- 2. **profile.html**: User profile page (linked from header user dropdown)
319
- 3. **account.html**: Account settings page (linked from header user dropdown)
320
- 4. **notifications.html**: Notifications page (linked from header notification bell)
321
- 5. **One screen per module that has user stories for this role**
322
-
323
- #### 3b: Sub-Screens (Detail / Edit / Create)
324
-
325
- For each module screen, analyze the user stories and identify sub-screens needed:
326
-
327
- | User Story Pattern | Sub-Screen Required |
328
- |-------------------|---------------------|
329
- | "view details of X" | `{module}_detail.html` - Detail view for a single record |
330
- | "add/create/register X" | `{module}_create.html` - Create/add form |
331
- | "edit/update/modify X" | `{module}_edit.html` - Edit form (pre-filled) |
332
- | "view history/audit of X" | `{module}_history.html` - History/audit log view |
333
- | "view associated X of Y" | `{module}_{sub}_list.html` - Associated records list |
334
-
335
- #### 3f: Report Layout Screens (conditional — if PRD.md contains report-related content)
336
-
337
- Scan PRD.md for report-related content:
338
- - NFRs mentioning "report", "Report interface", "generate report", "report generation"
339
- - User stories describing generating/downloading PDF, Excel, or CSV reports
340
- - A "Report" module or report-related NFRs defining specific report types
341
-
342
- **If report requirements are found**, generate HTML report layout mockups for each
343
- identified report. These layouts serve as draft previews for human designers/stakeholders
344
- to verify the report structure before the AI coding agent implements the actual report
345
- generation code (JasperReports JRDesign API for Java, Puppeteer for Laravel/React).
346
-
347
- For each identified report, create a standalone HTML file in a `reports/` subfolder:
348
-
349
- | Report Source | File Generated |
350
- |--------------|----------------|
351
- | NFR describes "Staff Allocation Summary report" | `reports/staff_allocation_summary.html` |
352
- | User story: "generate Job Demand report by country" | `reports/job_demand_by_country.html` |
353
- | Report module NFR: "Monthly Activity Report" | `reports/monthly_activity_report.html` |
354
-
355
- **Report layout file conventions:**
356
- - Each report layout is a **standalone self-contained HTML document** (not a content fragment)
357
- with its own `<html>`, `<head>`, `<body>` tags and Tailwind CDN `<script>` in the head
358
- - Layout simulates a **print-ready A4 page** with appropriate margins and sizing:
359
- ```html
360
- <body class="bg-gray-100">
361
- <div class="mx-auto bg-white shadow" style="width: 210mm; min-height: 297mm; padding: 15mm;">
362
- <!-- Report content -->
363
- </div>
364
- </body>
365
- ```
366
- - **Report header**: Report title (centered, bold), generation date, filter parameters used
367
- - **Report body**: Data table or summary layout using actual fields from the module model
368
- (if `model/{module}/model.md` exists, use its field definitions for column headers)
369
- - **Report footer**: Page indicator text ("Page 1 of 1"), generation timestamp
370
- - Use **sample data rows** (5-10 rows) with realistic placeholder values matching model constraints
371
- - Apply the design system colors from Step 2 for header background, borders, and accents
372
- - For landscape reports (wide tables with many columns), use `style="width: 297mm; min-height: 210mm;"`
373
-
374
- **Report parameter section**: Above the report data, include a gray-shaded "Parameters" box
375
- showing the filter criteria used to generate the report (e.g., Date Range: 2025-01-01 to
376
- 2025-12-31, Department: All, Status: Active).
377
-
378
- **Add to MOCKUP.html**: Include a "Reports" section at the bottom of each role's screen cards
379
- (after all module cards) listing the report layout links. Report links open in new tabs
380
- pointing to the hub's static route `/{app_slug}/reports/{report_file}.html`. Also list the
381
- report file names in the manifest's `reports` array.
382
-
383
- **Add to sidebar**: If reports are present, add a "Reports" navigation group in each role's
384
- sidebar with links opening report layouts in new tabs.
385
-
386
- #### 3c: Tabbed Screens
387
-
388
- If a module screen contains tabs (e.g., a detail page with Overview, Documents, History tabs),
389
- **each tab MUST be a separate content fragment file** unless the tab content is trivially small.
390
- Use the naming convention: `{module}_tab_{tab_name}.html`
391
-
392
- Example: `employer_tab_overview.html`, `employer_tab_documents.html`, `employer_tab_history.html`
393
-
394
- #### 3d: Screen File Naming Convention
395
-
396
- Convert names to snake_case, no `.html` extension in HTMX route references.
397
- Example: "Location Information" -> `location_information`
398
-
399
- #### 3e: Build Screen Plan
400
-
401
- Build a **complete** screen plan. Every entry must map to a generated file:
402
-
403
- | Role | Folder Name | Screen File | Source | Description |
404
- |------|-------------|-------------|--------|-------------|
405
- | Hub Administrator | hub_administrator | home | Common | Dashboard home |
406
- | Hub Administrator | hub_administrator | profile | Common | User profile |
407
- | Hub Administrator | hub_administrator | account | Common | Account settings |
408
- | Hub Administrator | hub_administrator | notifications | Common | Notifications list |
409
- | Hub Administrator | hub_administrator | location_information | Module | USHM00006, USHM00009 |
410
- | Hub Administrator | hub_administrator | location_information_detail | Sub-screen | View location details |
411
- | Hub Administrator | hub_administrator | location_information_create | Sub-screen | Add new location |
412
- | Hub Operation Support | hub_operation_support | home | Common | Dashboard home |
413
- | Hub Operation Support | hub_operation_support | profile | Common | User profile |
414
- | Hub Operation Support | hub_operation_support | account | Common | Account settings |
415
- | Hub Operation Support | hub_operation_support | notifications | Common | Notifications list |
416
- | Hub Operation Support | hub_operation_support | employer | Module | USHM00021-USHM00033 |
417
- | Hub Operation Support | hub_operation_support | employer_detail | Sub-screen | View employer details |
418
- | Hub Operation Support | hub_operation_support | employer_create | Sub-screen | Register new employer |
419
-
420
- ### Step 4: Create Output Folder Structure
421
-
422
- **Module filter**: When a module argument is active, skip this step entirely — the folder
423
- structure already exists from a previous full generation. Only content files for the target
424
- module will be written in Step 6e.
425
-
426
- Create the mockup folder at the auto-resolved mockup output path (full generation only).
427
- The folder contains **assets only** — no server files (the shared hub at `<root>/mockup/`
428
- serves them):
429
-
430
- ```
431
- <app_folder>/context/
432
- mockup/
433
- mockup-manifest.json # Hub discovery manifest (app, stack, roles, version)
434
- MOCKUP.html # Per-app screen index (served by hub at /{app_slug})
435
- partials/
436
- shell.html # Page shell (assembled server-side)
437
- header.html # Top header with Alpine.js dropdowns
438
- footer.html # Footer partial
439
- sidebar-{role_snake_case}.html # One sidebar per role with HTMX nav
440
- {role_snake_case}/
441
- content/
442
- home.html # Content fragment (no layout wrapper)
443
- profile.html
444
- account.html
445
- notifications.html
446
- {module_snake_case}.html
447
- {module_snake_case}_detail.html
448
- {module_snake_case}_create.html
449
- {module_snake_case}_edit.html
450
- ...
451
- ```
452
-
453
- ### Step 4b: Write mockup-manifest.json
454
-
455
- **Module filter**: When a module argument is active, UPDATE the existing manifest
456
- (version, generatedAt, per-role screen counts) instead of regenerating it.
457
-
458
- Write `<app_folder>/context/mockup/mockup-manifest.json` following the schema in
459
- [references/mockup-hub-template.md](references/mockup-hub-template.md):
460
-
461
- ```json
462
- {
463
- "app": "{app_slug}",
464
- "appName": "{App Name}",
465
- "description": "{short description from PRD.md}",
466
- "stack": "tailwind",
467
- "version": "{target version}",
468
- "generatedAt": "{YYYY-MM-DD}",
469
- "roles": [
470
- { "name": "{Role Name}", "slug": "{role_snake_case}", "screens": {count} }
471
- ],
472
- "reports": ["{report_file}.html"]
473
- }
474
- ```
475
-
476
- (`reports` only when report layouts were generated.) The hub reads this manifest to route
477
- the app and to render its landing-page card; without it the app shows as "Not generated
478
- yet" and its roles are unclickable.
479
-
480
- ### Step 4c: Ensure the Mockup Hub
481
-
482
- **Always runs** (full AND module-filtered generation).
483
-
484
- Ensure the shared hub exists at `<root>/mockup/` per the Ensure-Hub rules in
485
- [references/mockup-hub-template.md](references/mockup-hub-template.md):
486
-
487
- 1. `<root>/mockup/server.js` missing → create `server.js`, `package.json`,
488
- `mockup.config.json`, and `.gitignore` from the templates.
489
- 2. Exists → compare the `HUB_VERSION` marker; overwrite `server.js` + `package.json` only
490
- when the existing version is lower. Never overwrite an existing `mockup.config.json`
491
- or `.gitignore`.
492
- 3. All hub artifacts (config, logs, any `node_modules/`) live inside `<root>/mockup/` and
493
- are covered by its `.gitignore`.
494
-
495
- Key behaviours of the hub (for reference):
496
- - `GET /` → landing page listing ALL applications and roles (unclickable when not ready)
497
- - `GET /{app_slug}` → serves this app's `MOCKUP.html`
498
- - `GET /{app_slug}/{role}` → redirects to `/{app_slug}/{role}/home`
499
- - `GET /{app_slug}/{role}/{page}` → assembles shell + header + sidebar + content + footer
500
- - `GET /api/content/{app_slug}/{role}/{page}` → content fragment only (HTMX swaps)
501
- - `GET /{app_slug}/static/*` and `GET /{app_slug}/reports/*` → static assets
502
- - Injects `{{ROLE}}` into the header partial before responding
503
- - Port: `PORT` env var → `mockup.config.json` → 3000
504
-
505
- ### Step 5: Generate MOCKUP.html Index
506
-
507
- **Module filter**: When a module argument is active, do NOT regenerate the full MOCKUP.html.
508
- Instead, apply a **partial update** as described in Step 1c: update only the target module's
509
- screen cards, the version badge, and the per-role screen count. Leave all other content
510
- unchanged.
511
-
512
- Create the index page using the template in [references/mockup-index-template.md](references/mockup-index-template.md).
513
-
514
- MOCKUP.html is this app's screen index, served by the hub at `/{app_slug}`. It shows:
515
- - Hub startup banner with instructions (`cd <root>/mockup && npm start` — no install
516
- needed; port configurable via `PORT` env var or `mockup.config.json`)
517
- - Application name and description
518
- - **Target version** used for generation
519
- - Number of excluded items for transparency
520
- - For each role: role name, list of screen cards with links
521
- - **ALL screen links use `target="_blank" rel="noopener noreferrer"`** with
522
- **root-relative** URLs `/{app_slug}/{role}/{page}` (never hardcode `http://localhost:<port>`
523
- — the port is user-configurable) so they open in new tabs via the running hub
524
- - A "Open Role Dashboard" quick-launch link per role section
525
-
526
- ### Step 6: Generate Partials and Content Fragments
527
-
528
- Use templates from [references/admin-layout-template.md](references/admin-layout-template.md).
529
-
530
- **Apply the design system** from Step 2 (colors, typography, spacing) to all templates.
531
-
532
- **Module filter**: When a module argument is active, skip steps 6a–6d (shell, header,
533
- footer, sidebars). Proceed directly to **6e** for the target module's content fragments only.
534
- Also update `partials/footer.html` if the version string changed (the footer version badge
535
- must always reflect the current target version).
536
-
537
- #### 6a: Generate partials/shell.html
538
-
539
- Single shared shell file. The server replaces `{{HEADER}}`, `{{SIDEBAR}}`, `{{CONTENT}}`,
540
- and `{{FOOTER}}` at request time. Includes HTMX, Alpine.js, and Tailwind CDN.
541
-
542
- #### 6b: Generate partials/header.html
543
-
544
- One header partial (or one per role if HTMX links differ per role). Contains:
545
- - Logo + App Name (left)
546
- - Notification bell with Alpine.js dropdown (`x-data`, `@click`, `@click.outside`)
547
- - Globe/locale selector with Alpine.js dropdown
548
- - Dark mode toggle button (dispatches to parent `appShell()` Alpine context)
549
- - User avatar with Alpine.js dropdown (Profile, Account, Logout)
550
- - All notification/profile/account navigation links use HTMX (`hx-get`, `hx-target="#content-area"`)
551
-
552
- #### 6c: Generate partials/footer.html
553
-
554
- Simple footer with copyright year and version string.
555
-
556
- #### 6d: Generate partials/sidebar-{role}.html (one per role)
557
-
558
- Each sidebar contains HTMX-powered navigation links. `{{APP_SLUG}}` is replaced with the
559
- app slug **at generation time** (it is constant for the whole mockup folder):
560
- ```html
561
- <a href="/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
562
- hx-get="/api/content/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
563
- hx-target="#content-area"
564
- hx-swap="innerHTML"
565
- hx-push-url="/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
566
- ...>
567
- ```
568
- Alpine.js `:class` binding highlights the active menu item based on `window.location.pathname`.
569
-
570
- #### 6e: Generate content fragments ({role}/content/{page}.html)
571
-
572
- Each content fragment contains **only** the page content — no `<html>`, `<head>`, `<body>`,
573
- no Tailwind config, no CDN scripts. Structure:
574
-
575
- ```
576
- [breadcrumb bar div]
577
- [main content div with padding]
578
- ```
579
-
580
- **All navigation links within content fragments use HTMX** (same pattern as sidebar).
581
-
582
- **Breadcrumbs**: Home link uses HTMX; module link uses HTMX; current page is plain text.
583
-
584
- #### Admin Layout: Screen Content Generation
585
-
586
- For each module screen, analyze the user stories and generate appropriate UI mockup elements:
587
-
588
- | User Story Pattern | UI Element |
589
- |-------------------|------------|
590
- | "search for X based on parameters" | Search form with filter fields + results table |
591
- | "view details of X" | Detail view with labeled fields in card/panel layout |
592
- | "manage X" / "configure X" | CRUD table with Add/Edit/Delete actions |
593
- | "view history/changes" | Timeline or audit log table with timestamps |
594
- | "map X to Y" | Two-panel mapping interface or matrix table |
595
- | "activate/deactivate X" | Alpine.js toggle switches in table rows or config panel |
596
- | "view associated X" | Related records table or linked cards section |
597
-
598
- #### Model-Driven Field Usage (MANDATORY when model file exists)
599
-
600
- When a module model was loaded in Step 1b, use its actual field definitions — not generic placeholders — to populate every screen. Generic field names like "Field 1" or "Description" are not acceptable when a model is available.
601
-
602
- **Field type → HTML input mapping:**
603
-
604
- | Model Type | Form Input | Notes |
605
- |------------|-----------|-------|
606
- | `String` | `<input type="text">` | Use `maxlength` if constraints specify length |
607
- | `Number` | `<input type="number">` | |
608
- | `Boolean` | Alpine.js toggle (`x-data`, `@click`) | |
609
- | `ISODate` | `<input type="date">` or `<input type="datetime-local">` | |
610
- | `ObjectId` (reference) | `<input type="text" readonly>` or lookup widget | Display as read-only ID reference |
611
- | Enum (Section 7 match) | `<select>` with all enum values as `<option>` | Show enum value descriptions as option text |
612
- | Embedded Object | `<fieldset>` grouping sub-fields | Label the fieldset with the embedded type name |
613
- | Embedded Array (`[]`) | Repeatable section with "+ Add" / "Remove" buttons | Show one pre-filled example row |
614
-
615
- **List / Search screens** (`{module}.html`):
616
- - **Filter form**: render filter inputs only for fields that appear in Index Recommendations (Section 9). Use the correct input type per the mapping above. Enum-indexed fields use `<select>`. Date-indexed fields use date range pickers.
617
- - **Results table**: choose 5–7 of the most identifying non-system fields as columns. For embedded objects, show them as a single column (e.g., "Company Name" rather than expanding all sub-fields). Null/optional fields can be shown with a dash (`—`) in sample data.
618
- - **Table row actions**: View → `{module}_detail`, Edit → `{module}_edit`, Delete → Alpine.js confirm
619
- - **Pagination** (MANDATORY): Every results table MUST include a pagination bar directly below the table. Requirements:
620
- - Default page size: **10 items per page**
621
- - Show "Showing X–Y of Z results" summary text on the left
622
- - Show page size selector (`<select>`) with options 10, 25, 50 on the right (default 10)
623
- - Show Previous / Next buttons and page number buttons in the centre
624
- - Page number buttons: show first page, last page, current page ± 1, with `...` ellipsis for gaps
625
- - Use Alpine.js `x-data="{ currentPage: 1, pageSize: 10, totalItems: 47 }"` (sample total) to drive display state
626
- - Page buttons use HTMX `hx-get` linking to the same route (self-referential) — acceptable per Link Integrity Rule 6
627
- - Previous/Next buttons are disabled (visual only with `opacity-50 cursor-not-allowed`) when at first/last page
628
- - Use sample data: populate exactly 10 visible rows in the table (matching the default page size)
629
-
630
- **Detail screens** (`{module}_detail.html`):
631
- - Show ALL non-system fields, grouped logically:
632
- - Basic fields: flat primitive fields in a 2-column grid card
633
- - Embedded objects (e.g., `address`, `contact`): each in its own labelled sub-card
634
- - Embedded arrays (e.g., `personsInCharge`): rendered as a sub-table with a row per item
635
- - Enum fields: display value wrapped in a colored badge/chip
636
- - ISODate fields: formatted as `DD MMM YYYY HH:mm` in sample data
637
- - Boolean fields: show as a green/red badge ("Active" / "Inactive")
638
- - Include Edit, Delete (Alpine.js confirm), and Back to List action buttons
639
-
640
- **Create screens** (`{module}_create.html`):
641
- - Include ALL `Required: Yes` non-system fields as mandatory inputs (mark with `*`)
642
- - Include `Required: No` fields as optional inputs where they make sense for initial creation
643
- - Group embedded objects as `<fieldset>` sections with a legend
644
- - For embedded arrays: show one empty repeatable row with an "+ Add" button
645
- - Submit and Cancel buttons; Cancel navigates back to `{module}` list screen
646
-
647
- **Edit screens** (`{module}_edit.html`):
648
- - Same structure as create screen but with sample data pre-filled in all inputs
649
- - Fields that serve as unique identity keys (e.g., `companyRegistrationNumber`) must be rendered as `<input readonly>` with a tooltip explaining they cannot be changed
650
- - Save and Cancel buttons
651
-
652
- **History / Audit screens** (`{module}_history.html`):
653
- - Use fields from the **audit/history collection** (the non-root collection in the Collection Catalog):
654
- - `changeType` → colored badge using enum values from Section 7
655
- - `fieldChanged` → code-styled text (`<code>`)
656
- - `previousValue` / `newValue` → inline diff or truncated JSON display
657
- - `changedAt` → formatted timestamp
658
- - `changedBy` → plain text (e.g., "SYSTEM" or username)
659
- - Render as a chronological table, newest first
660
- - **Pagination** (MANDATORY): Include pagination bar below the history table. Default 10 items per page. Same Alpine.js + HTMX pattern as list screens (see above).
661
-
662
- **Sample data alignment**: Placeholder values in screens must be consistent with field constraints:
663
- - `countryCode` → use actual allowed values (e.g., "MYS", "BHR", "MDV") per CONSHM constraints if present in model notes
664
- - Enum fields → use one of the defined enum values (not arbitrary strings)
665
- - `companyRegistrationNumber` → e.g., "201901012345 (1234567-X)"
666
- - `ISODate` fields → use realistic ISO dates (e.g., "2025-08-15T10:30:00Z")
667
-
668
- ---
669
-
670
- #### Link Integrity Rules (CRITICAL)
671
-
672
- **Every clickable element MUST navigate to a real route. No `href="#"` allowed anywhere.**
673
-
674
- 1. **Table row actions** (View, Edit, Delete):
675
- - "View" / "Details" → HTMX link to `/{app_slug}/{role}/{module}_detail`
676
- - "Edit" → HTMX link to `/{app_slug}/{role}/{module}_edit`
677
- - "Delete" → Alpine.js inline confirm dialog (`href="javascript:void(0)"`)
678
- - "Add New" / "Create" → HTMX link to `/{app_slug}/{role}/{module}_create`
679
-
680
- 2. **Tabs within a screen**:
681
- - Each tab MUST HTMX-link to its corresponding content file
682
- - The current tab is visually active; other tabs link to their respective content pages
683
-
684
- 3. **Header links**:
685
- - Notification bell icon → HTMX nav to `notifications`
686
- - Notification dropdown "View all notifications" → HTMX nav to `notifications`
687
- - Locale dropdown options → `javascript:void(0)` (static language switcher mockup)
688
- - Night mode toggle → Alpine.js `@click="toggleDark()"` (no href)
689
- - Profile dropdown → HTMX nav to `profile`
690
- - Account dropdown → HTMX nav to `account`
691
- - Logout → `href="/"` (returns to the hub landing page)
692
-
693
- 4. **Sidebar links**: HTMX links to correct module screen routes (already enforced)
694
-
695
- 5. **Breadcrumb links**: HTMX links
696
- - Home → `/{app_slug}/{role}/home`
697
- - Module → `/{app_slug}/{role}/{module}`
698
- - Detail / current → plain text, no link
699
-
700
- 6. **Pagination links**: HTMX `hx-get` links to the same route (self-referential) are acceptable. Pagination is MANDATORY on every list — page buttons must use `hx-get` with the same route, not `href="#"`
701
-
702
- 7. **Back / Cancel buttons**: HTMX link to the parent screen
703
-
704
- 8. **Images** (inline previews, thumbnails, etc.):
705
- - Must open the full image in a **new tab** via `<a href="..." target="_blank" rel="noopener noreferrer">`
706
- - Use placeholder image URLs like `https://placehold.co/800x600`
707
-
708
- 9. **PDFs and documents** (download/view links):
709
- - Must open in a **new tab** via `<a href="..." target="_blank" rel="noopener noreferrer">`
710
- - Never render PDFs inline within the mockup
711
-
712
- **Content guidelines:**
713
- - Use placeholder/sample data that reflects the module context
714
- - Include appropriate form fields based on NFRs and constraints
715
- - Show the user story tags with their version as HTML comments for traceability
716
- (e.g., `<!-- USHM00012 [v1.0.1] -->`)
717
- - All interactive elements use Alpine.js (`x-data`, `x-show`, `@click`, `:class`)
718
- - Use Tailwind utility classes for all styling
719
- - Use inline Heroicons SVG (no external icon dependencies)
720
-
721
- #### Common Screens Content
722
-
723
- **profile.html**: User profile page showing:
724
- - User avatar, full name, email, role badge
725
- - Personal information form (read-only display): Name, Email, Phone, Department
726
- - "Edit Profile" button (HTMX links to self since it's a mockup)
727
-
728
- **account.html**: Account settings page showing:
729
- - Change Password section (current password, new password, confirm password fields)
730
- - Notification Preferences (Alpine.js email/SMS toggles)
731
- - Language/Locale selector (Alpine.js)
732
- - Session Management (active sessions table)
733
-
734
- **notifications.html**: Notifications list page showing:
735
- - Alpine.js filter tabs: All, Unread, Read
736
- - List of notification cards with: icon, title, message preview, timestamp, read/unread dot
737
- - Mark all as read button
738
- - **Pagination** (MANDATORY): Pagination bar below the notification list, default 10 items per page. Same Alpine.js + HTMX pattern as list screens.
739
-
740
- #### Sub-Screen Content
741
-
742
- **{module}_detail.html**: Record detail page showing:
743
- - Page title with record identifier
744
- - Back button (HTMX link to `{module}`)
745
- - Detail cards/panels with all relevant fields from user stories
746
- - Action buttons: Edit (HTMX to `{module}_edit`), Delete (Alpine.js confirm), Back to List
747
- - Related data sections if applicable
748
- - If the entity has sub-entities, show them in HTMX-linked tabs or sections
749
-
750
- **{module}_create.html**: Create/add form page showing:
751
- - Page title: "Add New {Entity}"
752
- - Breadcrumb: Home > {Module} > Add New
753
- - Form with all required fields derived from user stories
754
- - Submit and Cancel buttons (Cancel: HTMX link to `{module}`)
755
-
756
- **{module}_edit.html**: Edit form page showing:
757
- - Page title: "Edit {Entity}"
758
- - Breadcrumb: Home > {Module} > Edit
759
- - Pre-filled form with sample data
760
- - Save and Cancel buttons (Cancel: HTMX link to `{module}_detail` or `{module}`)
761
-
762
- ### Step 7: Output Summary
763
-
764
- After generation, print a summary:
765
-
766
- ```
767
- Mockup Generation Complete
768
- ===========================
769
- Application: {App Name} ({Initials})
770
- Target Version: {version or "latest (all versions)"}
771
- Module Filter: {module name or "all modules"}
772
- Output: {path}/mockup/
773
-
774
- Filtering Summary:
775
- - User stories included: {count}
776
- - User stories excluded (strikethrough): {count}
777
- - User stories excluded (version filter): {count}
778
- - User stories excluded (module filter): {count}
779
- - NFRs/Constraints included: {count}
780
- - NFRs/Constraints excluded: {count}
781
-
782
- | Role | Screens | Content Folder |
783
- |-----------------------|---------|-----------------------------------|
784
- | Hub Administrator | 8 | hub_administrator/content/ |
785
- | Hub Operation Support | 6 | hub_operation_support/content/ |
786
-
787
- Files generated:
788
- - mockup-manifest.json
789
- - MOCKUP.html
790
- - partials/shell.html, header.html, footer.html
791
- - partials/sidebar-hub_administrator.html
792
- - partials/sidebar-hub_operation_support.html
793
- - {N} content fragment files
794
- - Mockup Hub: {created at <root>/mockup | upgraded to v{N} | already present}
795
-
796
- Total: {N} files
797
-
798
- Quick Start
799
- ===========
800
- 1. cd <root>/mockup
801
- 2. npm start (zero dependencies — no npm install required)
802
- 3. Open http://localhost:3000 in your browser
803
- - Landing page lists ALL applications and roles
804
- - This app's screen index: http://localhost:3000/{app_slug}
805
- 4. Change port: PORT=4000 npm start, or edit <root>/mockup/mockup.config.json
806
- ```
807
-
808
- ### Step 7b: Link Integrity Validation (MANDATORY)
809
-
810
- Before finalizing output, perform a link integrity check across ALL generated files:
811
-
812
- 1. **Scan every generated file** for all `href`, `hx-get`, and `hx-push-url` attribute values
813
- 2. **Build a link registry**: map every route reference to the file that should exist
814
- 3. **Verify each HTMX route** resolves to an existing content fragment:
815
- - `hx-get="/api/content/{app_slug}/{role}/{page}"` → verify `{role}/content/{page}.html` exists
816
- - Every internal route MUST start with `/{app_slug}/` (or `/api/content/{app_slug}/`)
817
- — un-prefixed routes like `/{role}/{page}` are dead links under the hub
818
- - `href="javascript:void(0)"` → acceptable for delete confirm, locale switcher
819
- - `href="/"` → acceptable for logout
820
- - `target="_blank"` links → acceptable for images, PDFs, external resources
821
- - `href="#"` → **NOT ALLOWED** — dead link, must be fixed
822
- 4. **For any missing target file**, either:
823
- - Generate the missing content fragment, OR
824
- - Update the link to point to an existing route
825
- 5. **Report any fixes** made during validation in the output summary
826
-
827
- If any `href="#"` is found in the final output (excluding anchor-only usage), the generation
828
- is **incomplete**.
829
-
830
- ## Changelog Append
831
-
832
- After all mockup files are successfully generated, append an entry to `CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
833
-
834
- 1. Read `<app_folder>/CHANGELOG.md`. If it does not exist, create it with:
835
- ```markdown
836
- # Changelog
837
-
838
- - This file tracks all skill executions by version for this application.
839
- - The highest version recorded here is the current application version.
840
- - Skills MUST NOT execute for a version lower than the highest version in this file.
841
-
842
- ---
843
- ```
844
- 2. Search for a `## {version}` heading matching the current version.
845
- 3. If the section **exists**: append a new row to its table.
846
- 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.
847
- 5. Row format: `| {YYYY-MM-DD} | {application_name} | mockgen-tailwind | {module or "All"} | Generated HTML mockup screens |`
848
- 6. **Never modify or delete existing rows.**
849
-
850
- ## Important Rules
851
-
852
- - **Module filter is additive, not destructive**: When `module:` is specified, only the named
853
- module's content files are written/overwritten (plus manifest/MOCKUP.html updates). All
854
- other files (partials, other module content) remain untouched. If the target module does
855
- not exist in PRD.md, stop and report available module names before doing any file writes.
856
- - **No per-app server**: NEVER generate `server.js`/`package.json` inside the application's
857
- mockup folder. All serving is done by the shared hub at `<root>/mockup/` (ensure it per
858
- Step 4c). All npm/machine artifacts stay inside `<root>/mockup/` and are gitignored there.
859
- - **Manifest is mandatory**: every run writes/updates `mockup-manifest.json` — without it
860
- the hub cannot route the app and the landing page shows it as not ready.
861
- - **Root-relative links only**: never hardcode `http://localhost:<port>` in any generated
862
- file — the hub port is user-configurable.
863
- - **Version + module are independent axes**: Both may be combined freely. `module:Employer
864
- v1.0.2` means "generate Employer module screens as they exist at v1.0.2". Version filtering
865
- and module filtering each apply independently; a story must satisfy BOTH to be included.
866
- - **ZERO dead links**: Every `href` and `hx-get` in every file must resolve. No `href="#"`
867
- - **Pagination on every list** (MANDATORY): Every screen that renders a table or card list of records MUST include a pagination bar below it. Default page size is **10 items per page**. Applies to: module list screens, history/audit screens, notifications screen, and any embedded sub-tables within detail screens that may grow unbounded. Use Alpine.js `x-data` for page state and HTMX `hx-get` (self-referential) for page navigation. Omitting pagination from any list is a generation error.
868
- - **Partials for layout**: Header, footer, and sidebar are partial files, NOT duplicated inline
869
- - **Content fragments only**: Role screen files contain only page content — no `<html>/<head>/<body>`
870
- - **HTMX navigation**: All in-app navigation uses HTMX (`hx-get`, `hx-target`, `hx-push-url`)
871
- - **Alpine.js for interactivity**: Dropdowns, toggles, confirm dialogs use Alpine.js
872
- - **Images open in new tab**: Any `<img>` link or image view action uses `target="_blank"`
873
- - **PDFs open in new tab**: Any PDF/document view link uses `target="_blank" rel="noopener noreferrer"`
874
- - **MOCKUP.html links open in new tab**: All screen card links in the index use `target="_blank"`
875
- - No external image dependencies; use `https://placehold.co/` for placeholder images
876
- - Use inline SVG Heroicons only; no icon CDN dependencies
877
- - Sidebar navigation must link between screens within the same role using HTMX
878
- - Header navigation (notification, profile, account) links use HTMX
879
- - Table action buttons (View, Edit, Add) use HTMX navigation
880
- - Tabs within screens each link to a corresponding content fragment via HTMX
881
- - Back/Cancel buttons use HTMX to navigate to the parent list or detail screen
882
- - Preserve traceability: include user story tags with version as HTML comments in each screen
883
- (e.g., `<!-- USHM00012 [v1.0.1] -->`)
884
- - Do not generate screens for modules that have no user stories for a given role
885
- - Common screens (home, profile, account, notifications) are generated for EVERY role
886
- - Use consistent color scheme from the design system across all partials and content fragments
887
- - The version displayed in footer should be the target version if specified, or the latest version
888
- found in PRD.md
889
- - **Strikethrough items MUST always be excluded** — lines wrapped in `~~` are deprecated/removed
890
- - **Version filtering**: When a target version is provided, only include items from sections
891
- with version tags <= target version
892
- - **Model-driven screens**: When a module model file exists at `model/{kebab-module}/model.md`,
893
- use the actual field definitions (field names, types, required/nullable, enums) for all
894
- form inputs, table columns, and detail panels. Generic placeholder field names are NOT
895
- acceptable when a model is available. See Step 1b and the "Model-Driven Field Usage" section.
896
- - **Enum accuracy**: Enum select options must use the exact values from the model's Enum
897
- Definitions (Section 7), not inferred strings
898
- - **Constraint-aware sample data**: Sample values must respect field constraints noted in the
899
- model (e.g., use `MYS`, `BHR`, `MDV` for countryCode fields constrained by CONSHM018)
900
- - **Report layouts**: When PRD.md contains report-related NFRs or user stories, generate
901
- standalone HTML report layout files in `reports/` subfolder. These are self-contained A4
902
- mockups (not content fragments) for stakeholder review of report structure before coding.
903
- Use actual module model fields for column headers and realistic sample data rows. See
904
- Step 3f for full report layout generation rules.
1
+ ---
2
+ name: mockgen-tailwind
3
+ model: claude-opus-4-8
4
+ effort: high
5
+ description: >
6
+ Generate HTML mockup screens from PRD.md files for UI/UX human designer review.
7
+ Creates Alpine.js + HTMX mockup assets with admin dashboard layout
8
+ (left sidebar navigation, header with logo/notifications/locale/user menu, footer
9
+ with copyright/version) served as partials, organized by user role in a mockup/ folder.
10
+ All mockups are served by the SINGLE shared Mockup Hub at <root>/mockup — a
11
+ zero-dependency Node.js server with a landing page listing every application and role
12
+ (unclickable when not ready) and a configurable port (PORT env / mockup.config.json).
13
+ Input: application name (mandatory), version (mandatory), module (optional).
14
+ Output: mockup/ folder in the application's context folder
15
+ containing MOCKUP.html index page, mockup-manifest.json, partials/, and role-specific
16
+ content subfolders (assets only — no per-app server); plus the shared hub at
17
+ <root>/mockup if not already present. Trigger on keywords: "generate mockup", "generate mockups",
18
+ "create mockup screens", "HTML mockup", "UI mockup from user stories",
19
+ "mockup from PRD.md", "generate screens", "create UI screens".
20
+ Accepts application name and version as input
21
+ (e.g., `/mockgen-tailwind hub_middleware v1.0.3`).
22
+ Optionally accepts a module name to limit generation to screens for that module only
23
+ (e.g., `/mockgen-tailwind hub_middleware v1.0.3 module:Location Information`).
24
+ When module is specified, only content files for that module are generated/updated
25
+ (plus the manifest); partials, sidebars, the shared hub, and other module screens are
26
+ left untouched.
27
+ Automatically excludes strikethrough (deprecated/removed) items.
28
+ ---
29
+
30
+ # Mockgen HTML
31
+
32
+ Generate HTMX + Alpine.js mockup assets from PRD.md for UI/UX designer review.
33
+ Header, footer, and sidebar are served as partials. Content pages are HTMX fragments
34
+ swapped into a shell layout. All image/PDF links open in new tabs.
35
+
36
+ The application's mockup folder contains **assets only** — no server. All applications'
37
+ mockups are served by the **shared Mockup Hub**, a single zero-dependency Node.js server
38
+ at `<root>/mockup/` (see [references/mockup-hub-template.md](references/mockup-hub-template.md)).
39
+ The hub assembles pages at `/{app_slug}/{role}/{page}`, renders a landing page listing
40
+ every application and role (roles are unclickable until their mockups are ready), and
41
+ listens on a configurable port (`PORT` env var → `mockup.config.json` → first unused
42
+ port starting from 4000). The landing page includes a port input text (defaulting to the
43
+ current port) that persists a new port via `POST /api/port` and re-listens on it;
44
+ Compound Context Studio's Mockup page passes its own topbar port input via `PORT` when
45
+ its Start Hub button spawns the hub.
46
+
47
+ ## Stack
48
+
49
+ | Layer | Technology |
50
+ |-------|------------|
51
+ | Server | Shared Mockup Hub — `<root>/mockup/server.js` (zero-dependency Node.js) |
52
+ | Partial loading / navigation | HTMX 2.x |
53
+ | Interactive UI (dropdowns, dark mode) | Alpine.js 3.x |
54
+ | Styling | Tailwind CSS (CDN) |
55
+ | Icons | Inline Heroicons SVG |
56
+
57
+ ## Input
58
+
59
+ This skill uses standardized input resolution. Provide:
60
+
61
+ | Argument | Required | Example | Description |
62
+ |----------|----------|---------|-------------|
63
+ | `<application>` | Yes | `hub_middleware` | Application name to locate the context folder |
64
+ | `<version>` | Yes | `v1.0.3` | Version to scope processing (filter user stories <= this version) |
65
+ | `module:<name>` | No | `module:Location Information` | Limit generation to a single module |
66
+
67
+ ### Application Folder Resolution
68
+
69
+ The application name is matched against root-level application folders:
70
+ 1. Strip any leading `<number>_` prefix from folder names (e.g., `1_hub_middleware` → `hub_middleware`)
71
+ 2. Match case-insensitively against the provided application name
72
+ 3. Accept snake_case, kebab-case, or title-case input (all match the same folder)
73
+ 4. If no match found, list available applications and stop
74
+
75
+ ### Auto-Resolved Paths
76
+
77
+ | File | Resolved Path |
78
+ |------|---------------|
79
+ | PRD.md | `<app_folder>/context/PRD.md` |
80
+ | Module Models | `<app_folder>/context/model/` |
81
+ | Output (mockup) | `<app_folder>/context/mockup/` |
82
+ | Mockup Hub (shared) | `<root>/mockup/` |
83
+
84
+ **App slug** (used in all generated routes): the application folder name with the leading
85
+ `<number>_` prefix stripped (e.g., `1_hub_middleware` → `hub_middleware`). Record it during
86
+ input resolution every generated link is prefixed with `/{app_slug}`.
87
+
88
+ ### Example Invocations
89
+
90
+ - `/mockgen-tailwind hub_middleware v1.0.3` (all modules, up to v1.0.3)
91
+ - `/mockgen-tailwind hub_middleware v1.0.3 module:Location Information` (one module, specific version)
92
+ - `/mockgen-tailwind "Hub Middleware" v1.0.3 module:Employer` (title-case app name)
93
+
94
+ ### Version and Module Filtering
95
+
96
+ - Only include user stories, NFRs, constraints,
97
+ and references from sections whose version tag is **less than or equal to** the target version
98
+ - If a module is provided (e.g., `module:Location Information`), only generate/update screens
99
+ for that specific module. All other modules are skipped. Common screens (home, profile,
100
+ account, notifications) and partials (shell, header, footer, sidebars) are
101
+ NOT regenerated when a module filter is active — only the module's own content fragments
102
+ are written (plus MOCKUP.html updated for only that module's cards and
103
+ mockup-manifest.json refreshed).
104
+ - If no module is provided, process all modules (default behavior)
105
+
106
+ **Argument parsing**: The `module:` prefix is the canonical form. Also accept:
107
+ - `module:"Location Information"` (quoted, with space)
108
+ - `module:location_information` (snake_case — convert to title-case for matching)
109
+ - Natural language: `for Location Information module`, `only Location Information`
110
+
111
+ ## Version Gate
112
+
113
+ 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`):
114
+
115
+ 1. If `<app_folder>/CHANGELOG.md` does not exist, skip this check (first-ever execution for this application).
116
+ 2. If `<app_folder>/CHANGELOG.md` exists, scan all `## vX.Y.Z` headings and determine the **highest version** using semantic versioning comparison.
117
+ 3. Compare the requested version against the highest version:
118
+ - If requested version **>=** highest version: proceed normally.
119
+ - 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.
120
+
121
+ ## Workflow
122
+
123
+ ### Step 1: Parse PRD.md
124
+
125
+ Read the auto-resolved PRD.md file and extract:
126
+
127
+ 1. **Application name**: Derive from the parent folder name containing PRD.md.
128
+ Strip leading number and underscore prefix, then title-case.
129
+ Example: `1_hub_middleware` -> "Hub Middleware"
130
+
131
+ 2. **Application initials**: First letter of each word, uppercase.
132
+ Example: `1_hub_middleware` -> "HM"
133
+
134
+ 3. **Modules**: Each `## Module Name` section under a `# Module Category` heading.
135
+ Record the module name and its description (the line after the heading).
136
+
137
+ 4. **User stories per module**: Lines matching `- [USxx#####] As a {Role} user, I want to...`
138
+ Extract: tag, role, action summary.
139
+
140
+ 5. **Unique roles**: Collect all distinct roles from user stories.
141
+ Example: "Hub Administrator", "Hub Operation Support"
142
+
143
+ 6. **Target version** (from input argument): If a version was provided, record it for
144
+ filtering in the next sub-step.
145
+
146
+ #### 1a: Version Filtering and Strikethrough Exclusion (MANDATORY)
147
+
148
+ PRD.md is a version-controlled document. Each section (User Story, Non Functional
149
+ Requirement, Constraint, Reference) has a version tag in square brackets, e.g., `[v1.0.1]`.
150
+ Items may also be marked with strikethrough (`~~`) to indicate they are deprecated/removed.
151
+
152
+ **Strikethrough exclusion** (always applied, regardless of version parameter):
153
+ - Any line wrapped in `~~strikethrough~~` markup MUST be excluded from processing
154
+ - This includes user stories, NFRs, constraints, and references
155
+ - Example: `~~[USHM00006] As a Hub Administrator user, I want to...~~` → **SKIP**
156
+ - Partially strikethrough lines (where only part is struck) should still be excluded
157
+ if the tag identifier is within the strikethrough
158
+
159
+ **Version filtering** (applied only when a target version is provided):
160
+ - Each section under a module has one or more version tags like `[v1.0.0]` or `[v1.0.1]`
161
+ - Items listed under a version tag belong to that version
162
+ - When a target version is specified (e.g., `v1.0.1`):
163
+ - **Include** items from sections whose version tag is **<= target version**
164
+ - **Exclude** items from sections whose version tag is **> target version**
165
+ - Version comparison uses semantic versioning: compare major, then minor, then patch
166
+ - When no target version is specified, include all items from all versions (but still
167
+ exclude strikethrough items)
168
+
169
+ **Version tracking per section**: Record which version tag each item belongs to, as this
170
+ will be used for traceability in the generated screens.
171
+
172
+ Example parsing of a section with multiple versions:
173
+ ```markdown
174
+ ### User Story
175
+ [v1.0.0]
176
+ - ~~[USHM00006] As a Hub Administrator user, I want to manage...~~
177
+ - [USHM00009] As a Hub Administrator user, I want to map...
178
+ [v1.0.1]
179
+ - [USHM00012] As a Hub Administrator user, I want to manage the list...
180
+ ```
181
+
182
+ With target version `v1.0.0`:
183
+ - USHM00006 → EXCLUDED (strikethrough)
184
+ - USHM00009 → INCLUDED (v1.0.0 <= v1.0.0, not strikethrough)
185
+ - USHM00012 → EXCLUDED (v1.0.1 > v1.0.0)
186
+
187
+ With target version `v1.0.1` (or no version specified):
188
+ - USHM00006 → EXCLUDED (strikethrough)
189
+ - USHM00009 → INCLUDED
190
+ - USHM00012 → INCLUDED
191
+
192
+ #### 1c: Module Filtering (applied only when a module argument is provided)
193
+
194
+ When a `module` argument is present, apply module filtering after version filtering:
195
+
196
+ 1. **Match the specified module** against the list of parsed modules (case-insensitive, ignoring
197
+ leading/trailing whitespace). Also accept snake_case input by converting it to title-case
198
+ for comparison (e.g., `location_information` → match "Location Information").
199
+ 2. **Record the matched module name** for use in Step 3 and beyond.
200
+ 3. If no module matches, stop and report the available module names to the user before proceeding.
201
+ 4. **Module filter scope**: the filter only affects **content fragment generation** (Step 6e).
202
+ All other steps complete normally (parsing, design system, planning) but output is restricted
203
+ to the filtered module's screens.
204
+
205
+ **Module-filtered generation mode** differs from full generation in these ways:
206
+
207
+ | Aspect | Full Generation | Module-Filtered |
208
+ |--------|----------------|-----------------|
209
+ | Common screens (home, profile, account, notifications) | Generate for every role | **SKIP** — already exist |
210
+ | Partials (shell, header, footer) | Generate | **SKIP** — already exist |
211
+ | Sidebar per role | Generate | **SKIP** — already exist |
212
+ | mockup-manifest.json | Generate | **Update** (version, generatedAt, screen counts) |
213
+ | Mockup Hub (`<root>/mockup/`) | Ensure (create/upgrade) | **Ensure** (create/upgrade) |
214
+ | Module content files (target module) | Generate | **Generate / overwrite** |
215
+ | Module content files (other modules) | Generate | **SKIP** — leave untouched |
216
+ | MOCKUP.html | Generate full file | **Update only the target module's cards** |
217
+ | footer.html version string | Update | **Update** (version may have changed) |
218
+
219
+ **MOCKUP.html partial update** (module-filtered mode):
220
+ - Read the existing MOCKUP.html
221
+ - Locate the screen cards section for the target module (search by module name heading or
222
+ existing card tags)
223
+ - Replace only those cards with freshly generated ones reflecting the new screens
224
+ - Update the total screen count per role (add net new screens)
225
+ - Update the version badge if it changed
226
+ - Update the "N new screens added in vX.Y.Z" banner text
227
+ - Leave all other role sections and cards unchanged
228
+
229
+ ### Step 1b: Discover and Load Module Models
230
+
231
+ After parsing PRD.md, look for module models at the auto-resolved model path:
232
+ `<app_folder>/context/model/`
233
+
234
+ For each module extracted in Step 1:
235
+
236
+ 1. Convert the module name to **kebab-case** to derive the model folder name:
237
+ - Lowercase the module name and replace spaces with hyphens
238
+ - Examples: "Location Information" → `location-information`, "Industrial Classification" → `industrial-classification`, "Employer" → `employer`
239
+
240
+ 2. Check for `{model_dir}/{kebab-module}/model.md`
241
+
242
+ 3. If the file exists, parse it and extract the following sections:
243
+
244
+ - **Section 2 – Collection Catalog**: collection names and types (Root Collection, Audit Collection, etc.)
245
+ - **Section 5 – Field Detail per Collection**: for each collection — field name, type, required, nullable, constraints/notes
246
+ - **Section 6 – Embedded Document Definitions**: embedded type name and its sub-fields
247
+ - **Section 7 – Enum Definitions**: enum name and all allowed values with descriptions
248
+ - **Section 9 – Index Recommendations**: indexed fields (used to identify search/filter parameters)
249
+
250
+ 4. Store this as the **module model** for the module, keyed by module name
251
+
252
+ **Field classification** (used during content generation in Step 6e):
253
+
254
+ | Category | Definition | Usage |
255
+ |----------|-----------|-------|
256
+ | System fields | `_id`, `_audit`, `_version`, `deleted`, `deletedAt`, `deletedBy` | Exclude from user-facing forms |
257
+ | Audit-only fields | Fields whose Source is `CONVENTION` and type is `Audit` | Show in detail views only |
258
+ | Required form fields | `Required: Yes` AND not a system field | Mandatory inputs in create/edit forms |
259
+ | Optional form fields | `Required: No` AND not a system field | Optional inputs in create/edit forms |
260
+ | Read-only after creation | Fields marked as unique identity keys (e.g., `companyRegistrationNumber`) | Show in edit forms as readonly |
261
+ | Search/filter fields | Fields referenced in Index Recommendations | Render as filter controls in list screens |
262
+ | Enum fields | Type matches an entry in Section 7 Enum Definitions | Render as `<select>` dropdowns |
263
+ | Embedded object fields | Type is a custom embedded document type (not a primitive) | Render as `<fieldset>` sub-group |
264
+ | Embedded array fields | Type ends in `[]` (e.g., `PersonInCharge[]`) | Render as repeatable row with Add/Remove |
265
+
266
+ **Fallback**: If no `model.md` exists for a module, infer fields from user story text (original behavior).
267
+
268
+ ---
269
+
270
+ ### Step 2: Load Design System
271
+
272
+ Load the design system using a two-tier resolution strategy:
273
+
274
+ #### 2a: PRD.md Design System Reference (Primary Source)
275
+
276
+ Check if PRD.md contains a `# Design System` section. If it does:
277
+ 1. Extract the referenced file path (e.g., from `[DESIGN_SYSTEM.md](reference/DESIGN_SYSTEM.md)`)
278
+ 2. Resolve the path relative to PRD.md's location
279
+ 3. If the referenced file exists, read it and extract:
280
+ - Color palettes (primary, secondary, accent, neutral — hex values)
281
+ - Typography (font families, font sizes, weight scale)
282
+ - Spacing scale (if overriding Tailwind defaults)
283
+ - Component patterns (button styles, card styles, form input styles, table styles, badge/chip styles, modal patterns)
284
+ - Layout grid rules
285
+ 4. Apply extracted tokens to the Tailwind CDN `<script>` config block in `shell.html` (custom colors, fonts), all generated partials (consistent color classes), and component rendering
286
+
287
+ #### 2b: Context Design Folder (Fallback)
288
+
289
+ If PRD.md does not have a `# Design System` section, or the referenced file does not exist, fall back to the application's `<app_folder>/context/design/` folder. This folder contains pre-defined design tokens and Tailwind component guidelines maintained externally by the UI/UX team.
290
+
291
+ Read all files in `{app_name}/context/design/` (where `{app_name}` is the resolved application folder name from Step 1). Apply the design tokens and guidelines found there to all generated mockup screens.
292
+
293
+ **Expected files** (any or all may be present):
294
+ - `design-system.md` — Colors, typography, spacing, and visual style definitions
295
+ - `components.md` — Reusable component patterns and Tailwind class conventions
296
+ - `guidelines.md` — Layout rules, accessibility standards, and stack-specific guidelines
297
+
298
+ #### 2c: Default Fallback
299
+
300
+ If neither the PRD reference nor the `{app_name}/context/design/` folder provides design tokens, use sensible defaults: a neutral color palette, Inter/system font stack, and standard Tailwind utility classes for spacing and layout.
301
+
302
+ #### 2d: Process Flow Status States
303
+
304
+ If PRD.md contains a `# High Level Process Flow` section, scan it for entity status lifecycle descriptions (e.g., "Received → Validated → Enriched → Active"). For each status lifecycle found:
305
+ - Ensure list screens for the corresponding module include a status column with colored badges for each state
306
+ - Use design system color tokens for badge colors (e.g., success color for active/completed states, warning for pending, danger for failed/rejected)
307
+
308
+ ### Step 3: Plan Screen Files
309
+
310
+ For each role, determine ALL screens to generate. **Every clickable link, tab, or action
311
+ in any generated screen MUST have a corresponding content fragment file. No link may point
312
+ to `#` or be a dead end.**
313
+
314
+ **Module filter applied here**: If a module argument was provided (Step 1c), plan only the
315
+ screens for that module across all roles. Skip common screens (home, profile, account,
316
+ notifications) and skip all other modules entirely. The screen plan table should list only
317
+ the filtered module's screens.
318
+
319
+ #### 3a: Core Screens (content fragments)
320
+
321
+ 1. **home.html**: Default home/dashboard page with welcome message and summary widgets
322
+ 2. **profile.html**: User profile page (linked from header user dropdown)
323
+ 3. **account.html**: Account settings page (linked from header user dropdown)
324
+ 4. **notifications.html**: Notifications page (linked from header notification bell)
325
+ 5. **One screen per module that has user stories for this role**
326
+
327
+ #### 3b: Sub-Screens (Detail / Edit / Create)
328
+
329
+ For each module screen, analyze the user stories and identify sub-screens needed:
330
+
331
+ | User Story Pattern | Sub-Screen Required |
332
+ |-------------------|---------------------|
333
+ | "view details of X" | `{module}_detail.html` - Detail view for a single record |
334
+ | "add/create/register X" | `{module}_create.html` - Create/add form |
335
+ | "edit/update/modify X" | `{module}_edit.html` - Edit form (pre-filled) |
336
+ | "view history/audit of X" | `{module}_history.html` - History/audit log view |
337
+ | "view associated X of Y" | `{module}_{sub}_list.html` - Associated records list |
338
+
339
+ #### 3f: Report Layout Screens (conditional — if PRD.md contains report-related content)
340
+
341
+ Scan PRD.md for report-related content:
342
+ - NFRs mentioning "report", "Report interface", "generate report", "report generation"
343
+ - User stories describing generating/downloading PDF, Excel, or CSV reports
344
+ - A "Report" module or report-related NFRs defining specific report types
345
+
346
+ **If report requirements are found**, generate HTML report layout mockups for each
347
+ identified report. These layouts serve as draft previews for human designers/stakeholders
348
+ to verify the report structure before the AI coding agent implements the actual report
349
+ generation code (JasperReports JRDesign API for Java, Puppeteer for Laravel/React).
350
+
351
+ For each identified report, create a standalone HTML file in a `reports/` subfolder:
352
+
353
+ | Report Source | File Generated |
354
+ |--------------|----------------|
355
+ | NFR describes "Staff Allocation Summary report" | `reports/staff_allocation_summary.html` |
356
+ | User story: "generate Job Demand report by country" | `reports/job_demand_by_country.html` |
357
+ | Report module NFR: "Monthly Activity Report" | `reports/monthly_activity_report.html` |
358
+
359
+ **Report layout file conventions:**
360
+ - Each report layout is a **standalone self-contained HTML document** (not a content fragment)
361
+ with its own `<html>`, `<head>`, `<body>` tags and Tailwind CDN `<script>` in the head
362
+ - Layout simulates a **print-ready A4 page** with appropriate margins and sizing:
363
+ ```html
364
+ <body class="bg-gray-100">
365
+ <div class="mx-auto bg-white shadow" style="width: 210mm; min-height: 297mm; padding: 15mm;">
366
+ <!-- Report content -->
367
+ </div>
368
+ </body>
369
+ ```
370
+ - **Report header**: Report title (centered, bold), generation date, filter parameters used
371
+ - **Report body**: Data table or summary layout using actual fields from the module model
372
+ (if `model/{module}/model.md` exists, use its field definitions for column headers)
373
+ - **Report footer**: Page indicator text ("Page 1 of 1"), generation timestamp
374
+ - Use **sample data rows** (5-10 rows) with realistic placeholder values matching model constraints
375
+ - Apply the design system colors from Step 2 for header background, borders, and accents
376
+ - For landscape reports (wide tables with many columns), use `style="width: 297mm; min-height: 210mm;"`
377
+
378
+ **Report parameter section**: Above the report data, include a gray-shaded "Parameters" box
379
+ showing the filter criteria used to generate the report (e.g., Date Range: 2025-01-01 to
380
+ 2025-12-31, Department: All, Status: Active).
381
+
382
+ **Add to MOCKUP.html**: Include a "Reports" section at the bottom of each role's screen cards
383
+ (after all module cards) listing the report layout links. Report links open in new tabs
384
+ pointing to the hub's static route `/{app_slug}/reports/{report_file}.html`. Also list the
385
+ report file names in the manifest's `reports` array.
386
+
387
+ **Add to sidebar**: If reports are present, add a "Reports" navigation group in each role's
388
+ sidebar with links opening report layouts in new tabs.
389
+
390
+ #### 3c: Tabbed Screens
391
+
392
+ If a module screen contains tabs (e.g., a detail page with Overview, Documents, History tabs),
393
+ **each tab MUST be a separate content fragment file** unless the tab content is trivially small.
394
+ Use the naming convention: `{module}_tab_{tab_name}.html`
395
+
396
+ Example: `employer_tab_overview.html`, `employer_tab_documents.html`, `employer_tab_history.html`
397
+
398
+ #### 3d: Screen File Naming Convention
399
+
400
+ Convert names to snake_case, no `.html` extension in HTMX route references.
401
+ Example: "Location Information" -> `location_information`
402
+
403
+ #### 3e: Build Screen Plan
404
+
405
+ Build a **complete** screen plan. Every entry must map to a generated file:
406
+
407
+ | Role | Folder Name | Screen File | Source | Description |
408
+ |------|-------------|-------------|--------|-------------|
409
+ | Hub Administrator | hub_administrator | home | Common | Dashboard home |
410
+ | Hub Administrator | hub_administrator | profile | Common | User profile |
411
+ | Hub Administrator | hub_administrator | account | Common | Account settings |
412
+ | Hub Administrator | hub_administrator | notifications | Common | Notifications list |
413
+ | Hub Administrator | hub_administrator | location_information | Module | USHM00006, USHM00009 |
414
+ | Hub Administrator | hub_administrator | location_information_detail | Sub-screen | View location details |
415
+ | Hub Administrator | hub_administrator | location_information_create | Sub-screen | Add new location |
416
+ | Hub Operation Support | hub_operation_support | home | Common | Dashboard home |
417
+ | Hub Operation Support | hub_operation_support | profile | Common | User profile |
418
+ | Hub Operation Support | hub_operation_support | account | Common | Account settings |
419
+ | Hub Operation Support | hub_operation_support | notifications | Common | Notifications list |
420
+ | Hub Operation Support | hub_operation_support | employer | Module | USHM00021-USHM00033 |
421
+ | Hub Operation Support | hub_operation_support | employer_detail | Sub-screen | View employer details |
422
+ | Hub Operation Support | hub_operation_support | employer_create | Sub-screen | Register new employer |
423
+
424
+ ### Step 4: Create Output Folder Structure
425
+
426
+ **Module filter**: When a module argument is active, skip this step entirely — the folder
427
+ structure already exists from a previous full generation. Only content files for the target
428
+ module will be written in Step 6e.
429
+
430
+ Create the mockup folder at the auto-resolved mockup output path (full generation only).
431
+ The folder contains **assets only** — no server files (the shared hub at `<root>/mockup/`
432
+ serves them):
433
+
434
+ ```
435
+ <app_folder>/context/
436
+ mockup/
437
+ mockup-manifest.json # Hub discovery manifest (app, stack, roles, version)
438
+ MOCKUP.html # Per-app screen index (served by hub at /{app_slug})
439
+ partials/
440
+ shell.html # Page shell (assembled server-side)
441
+ header.html # Top header with Alpine.js dropdowns
442
+ footer.html # Footer partial
443
+ sidebar-{role_snake_case}.html # One sidebar per role with HTMX nav
444
+ {role_snake_case}/
445
+ content/
446
+ home.html # Content fragment (no layout wrapper)
447
+ profile.html
448
+ account.html
449
+ notifications.html
450
+ {module_snake_case}.html
451
+ {module_snake_case}_detail.html
452
+ {module_snake_case}_create.html
453
+ {module_snake_case}_edit.html
454
+ ...
455
+ ```
456
+
457
+ ### Step 4b: Write mockup-manifest.json
458
+
459
+ **Module filter**: When a module argument is active, UPDATE the existing manifest
460
+ (version, generatedAt, per-role screen counts) instead of regenerating it.
461
+
462
+ Write `<app_folder>/context/mockup/mockup-manifest.json` following the schema in
463
+ [references/mockup-hub-template.md](references/mockup-hub-template.md):
464
+
465
+ ```json
466
+ {
467
+ "app": "{app_slug}",
468
+ "appName": "{App Name}",
469
+ "description": "{short description from PRD.md}",
470
+ "stack": "tailwind",
471
+ "version": "{target version}",
472
+ "generatedAt": "{YYYY-MM-DD}",
473
+ "roles": [
474
+ { "name": "{Role Name}", "slug": "{role_snake_case}", "screens": {count} }
475
+ ],
476
+ "reports": ["{report_file}.html"]
477
+ }
478
+ ```
479
+
480
+ (`reports` only when report layouts were generated.) The hub reads this manifest to route
481
+ the app and to render its landing-page card; without it the app shows as "Not generated
482
+ yet" and its roles are unclickable.
483
+
484
+ ### Step 4c: Ensure the Mockup Hub
485
+
486
+ **Always runs** (full AND module-filtered generation).
487
+
488
+ Ensure the shared hub exists at `<root>/mockup/` per the Ensure-Hub rules in
489
+ [references/mockup-hub-template.md](references/mockup-hub-template.md):
490
+
491
+ 1. `<root>/mockup/server.js` missing → create `server.js`, `package.json`,
492
+ `mockup.config.json`, and `.gitignore` from the templates.
493
+ 2. Exists → compare the `HUB_VERSION` marker; overwrite `server.js` + `package.json` only
494
+ when the existing version is lower. Never overwrite an existing `mockup.config.json`
495
+ or `.gitignore`.
496
+ 3. All hub artifacts (config, logs, any `node_modules/`) live inside `<root>/mockup/` and
497
+ are covered by its `.gitignore`.
498
+
499
+ Key behaviours of the hub (for reference):
500
+ - `GET /` → landing page listing ALL applications and roles (unclickable when not ready)
501
+ - `GET /{app_slug}` → serves this app's `MOCKUP.html`
502
+ - `GET /{app_slug}/{role}` → redirects to `/{app_slug}/{role}/home`
503
+ - `GET /{app_slug}/{role}/{page}` → assembles shell + header + sidebar + content + footer
504
+ - `GET /api/content/{app_slug}/{role}/{page}` → content fragment only (HTMX swaps)
505
+ - `GET /{app_slug}/static/*` and `GET /{app_slug}/reports/*` → static assets
506
+ - Injects `{{ROLE}}` into the header partial before responding
507
+ - `POST /api/port` → persists a new port (from the landing page's port input) to
508
+ `mockup.config.json` and re-listens on it
509
+ - Port: `PORT` env var (exact) → `mockup.config.json` → first unused port from 4000
510
+
511
+ ### Step 5: Generate MOCKUP.html Index
512
+
513
+ **Module filter**: When a module argument is active, do NOT regenerate the full MOCKUP.html.
514
+ Instead, apply a **partial update** as described in Step 1c: update only the target module's
515
+ screen cards, the version badge, and the per-role screen count. Leave all other content
516
+ unchanged.
517
+
518
+ Create the index page using the template in [references/mockup-index-template.md](references/mockup-index-template.md).
519
+
520
+ MOCKUP.html is this app's screen index, served by the hub at `/{app_slug}`. It shows:
521
+ - Hub startup banner with instructions (`cd <root>/mockup && npm start` — no install
522
+ needed; port configurable via `PORT` env var or `mockup.config.json`)
523
+ - Application name and description
524
+ - **Target version** used for generation
525
+ - Number of excluded items for transparency
526
+ - For each role: role name, list of screen cards with links
527
+ - **ALL screen links use `target="_blank" rel="noopener noreferrer"`** with
528
+ **root-relative** URLs `/{app_slug}/{role}/{page}` (never hardcode `http://localhost:<port>`
529
+ — the port is user-configurable) so they open in new tabs via the running hub
530
+ - A "Open Role Dashboard" quick-launch link per role section
531
+
532
+ ### Step 6: Generate Partials and Content Fragments
533
+
534
+ Use templates from [references/admin-layout-template.md](references/admin-layout-template.md).
535
+
536
+ **Apply the design system** from Step 2 (colors, typography, spacing) to all templates.
537
+
538
+ **Module filter**: When a module argument is active, skip steps 6a–6d (shell, header,
539
+ footer, sidebars). Proceed directly to **6e** for the target module's content fragments only.
540
+ Also update `partials/footer.html` if the version string changed (the footer version badge
541
+ must always reflect the current target version).
542
+
543
+ #### 6a: Generate partials/shell.html
544
+
545
+ Single shared shell file. The server replaces `{{HEADER}}`, `{{SIDEBAR}}`, `{{CONTENT}}`,
546
+ and `{{FOOTER}}` at request time. Includes HTMX, Alpine.js, and Tailwind CDN.
547
+
548
+ #### 6b: Generate partials/header.html
549
+
550
+ One header partial (or one per role if HTMX links differ per role). Contains:
551
+ - Logo + App Name (left)
552
+ - Notification bell with Alpine.js dropdown (`x-data`, `@click`, `@click.outside`)
553
+ - Globe/locale selector with Alpine.js dropdown
554
+ - Dark mode toggle button (dispatches to parent `appShell()` Alpine context)
555
+ - User avatar with Alpine.js dropdown (Profile, Account, Logout)
556
+ - All notification/profile/account navigation links use HTMX (`hx-get`, `hx-target="#content-area"`)
557
+
558
+ #### 6c: Generate partials/footer.html
559
+
560
+ Simple footer with copyright year and version string.
561
+
562
+ #### 6d: Generate partials/sidebar-{role}.html (one per role)
563
+
564
+ Each sidebar contains HTMX-powered navigation links. `{{APP_SLUG}}` is replaced with the
565
+ app slug **at generation time** (it is constant for the whole mockup folder):
566
+ ```html
567
+ <a href="/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
568
+ hx-get="/api/content/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
569
+ hx-target="#content-area"
570
+ hx-swap="innerHTML"
571
+ hx-push-url="/{{APP_SLUG}}/{{ROLE}}/{{PAGE}}"
572
+ ...>
573
+ ```
574
+ Alpine.js `:class` binding highlights the active menu item based on `window.location.pathname`.
575
+
576
+ #### 6e: Generate content fragments ({role}/content/{page}.html)
577
+
578
+ Each content fragment contains **only** the page content — no `<html>`, `<head>`, `<body>`,
579
+ no Tailwind config, no CDN scripts. Structure:
580
+
581
+ ```
582
+ [breadcrumb bar div]
583
+ [main content div with padding]
584
+ ```
585
+
586
+ **All navigation links within content fragments use HTMX** (same pattern as sidebar).
587
+
588
+ **Breadcrumbs**: Home link uses HTMX; module link uses HTMX; current page is plain text.
589
+
590
+ #### Admin Layout: Screen Content Generation
591
+
592
+ For each module screen, analyze the user stories and generate appropriate UI mockup elements:
593
+
594
+ | User Story Pattern | UI Element |
595
+ |-------------------|------------|
596
+ | "search for X based on parameters" | Search form with filter fields + results table |
597
+ | "view details of X" | Detail view with labeled fields in card/panel layout |
598
+ | "manage X" / "configure X" | CRUD table with Add/Edit/Delete actions |
599
+ | "view history/changes" | Timeline or audit log table with timestamps |
600
+ | "map X to Y" | Two-panel mapping interface or matrix table |
601
+ | "activate/deactivate X" | Alpine.js toggle switches in table rows or config panel |
602
+ | "view associated X" | Related records table or linked cards section |
603
+
604
+ #### Model-Driven Field Usage (MANDATORY when model file exists)
605
+
606
+ When a module model was loaded in Step 1b, use its actual field definitions — not generic placeholders — to populate every screen. Generic field names like "Field 1" or "Description" are not acceptable when a model is available.
607
+
608
+ **Field type → HTML input mapping:**
609
+
610
+ | Model Type | Form Input | Notes |
611
+ |------------|-----------|-------|
612
+ | `String` | `<input type="text">` | Use `maxlength` if constraints specify length |
613
+ | `Number` | `<input type="number">` | |
614
+ | `Boolean` | Alpine.js toggle (`x-data`, `@click`) | |
615
+ | `ISODate` | `<input type="date">` or `<input type="datetime-local">` | |
616
+ | `ObjectId` (reference) | `<input type="text" readonly>` or lookup widget | Display as read-only ID reference |
617
+ | Enum (Section 7 match) | `<select>` with all enum values as `<option>` | Show enum value descriptions as option text |
618
+ | Embedded Object | `<fieldset>` grouping sub-fields | Label the fieldset with the embedded type name |
619
+ | Embedded Array (`[]`) | Repeatable section with "+ Add" / "Remove" buttons | Show one pre-filled example row |
620
+
621
+ **List / Search screens** (`{module}.html`):
622
+ - **Filter form**: render filter inputs only for fields that appear in Index Recommendations (Section 9). Use the correct input type per the mapping above. Enum-indexed fields use `<select>`. Date-indexed fields use date range pickers.
623
+ - **Results table**: choose 5–7 of the most identifying non-system fields as columns. For embedded objects, show them as a single column (e.g., "Company Name" rather than expanding all sub-fields). Null/optional fields can be shown with a dash (`—`) in sample data.
624
+ - **Table row actions**: View → `{module}_detail`, Edit → `{module}_edit`, Delete → Alpine.js confirm
625
+ - **Pagination** (MANDATORY): Every results table MUST include a pagination bar directly below the table. Requirements:
626
+ - Default page size: **10 items per page**
627
+ - Show "Showing X–Y of Z results" summary text on the left
628
+ - Show page size selector (`<select>`) with options 10, 25, 50 on the right (default 10)
629
+ - Show Previous / Next buttons and page number buttons in the centre
630
+ - Page number buttons: show first page, last page, current page ± 1, with `...` ellipsis for gaps
631
+ - Use Alpine.js `x-data="{ currentPage: 1, pageSize: 10, totalItems: 47 }"` (sample total) to drive display state
632
+ - Page buttons use HTMX `hx-get` linking to the same route (self-referential) — acceptable per Link Integrity Rule 6
633
+ - Previous/Next buttons are disabled (visual only with `opacity-50 cursor-not-allowed`) when at first/last page
634
+ - Use sample data: populate exactly 10 visible rows in the table (matching the default page size)
635
+
636
+ **Detail screens** (`{module}_detail.html`):
637
+ - Show ALL non-system fields, grouped logically:
638
+ - Basic fields: flat primitive fields in a 2-column grid card
639
+ - Embedded objects (e.g., `address`, `contact`): each in its own labelled sub-card
640
+ - Embedded arrays (e.g., `personsInCharge`): rendered as a sub-table with a row per item
641
+ - Enum fields: display value wrapped in a colored badge/chip
642
+ - ISODate fields: formatted as `DD MMM YYYY HH:mm` in sample data
643
+ - Boolean fields: show as a green/red badge ("Active" / "Inactive")
644
+ - Include Edit, Delete (Alpine.js confirm), and Back to List action buttons
645
+
646
+ **Create screens** (`{module}_create.html`):
647
+ - Include ALL `Required: Yes` non-system fields as mandatory inputs (mark with `*`)
648
+ - Include `Required: No` fields as optional inputs where they make sense for initial creation
649
+ - Group embedded objects as `<fieldset>` sections with a legend
650
+ - For embedded arrays: show one empty repeatable row with an "+ Add" button
651
+ - Submit and Cancel buttons; Cancel navigates back to `{module}` list screen
652
+
653
+ **Edit screens** (`{module}_edit.html`):
654
+ - Same structure as create screen but with sample data pre-filled in all inputs
655
+ - Fields that serve as unique identity keys (e.g., `companyRegistrationNumber`) must be rendered as `<input readonly>` with a tooltip explaining they cannot be changed
656
+ - Save and Cancel buttons
657
+
658
+ **History / Audit screens** (`{module}_history.html`):
659
+ - Use fields from the **audit/history collection** (the non-root collection in the Collection Catalog):
660
+ - `changeType` → colored badge using enum values from Section 7
661
+ - `fieldChanged` → code-styled text (`<code>`)
662
+ - `previousValue` / `newValue` → inline diff or truncated JSON display
663
+ - `changedAt` → formatted timestamp
664
+ - `changedBy` → plain text (e.g., "SYSTEM" or username)
665
+ - Render as a chronological table, newest first
666
+ - **Pagination** (MANDATORY): Include pagination bar below the history table. Default 10 items per page. Same Alpine.js + HTMX pattern as list screens (see above).
667
+
668
+ **Sample data alignment**: Placeholder values in screens must be consistent with field constraints:
669
+ - `countryCode` → use actual allowed values (e.g., "MYS", "BHR", "MDV") per CONSHM constraints if present in model notes
670
+ - Enum fields → use one of the defined enum values (not arbitrary strings)
671
+ - `companyRegistrationNumber` → e.g., "201901012345 (1234567-X)"
672
+ - `ISODate` fields → use realistic ISO dates (e.g., "2025-08-15T10:30:00Z")
673
+
674
+ ---
675
+
676
+ #### Link Integrity Rules (CRITICAL)
677
+
678
+ **Every clickable element MUST navigate to a real route. No `href="#"` allowed anywhere.**
679
+
680
+ 1. **Table row actions** (View, Edit, Delete):
681
+ - "View" / "Details" → HTMX link to `/{app_slug}/{role}/{module}_detail`
682
+ - "Edit" → HTMX link to `/{app_slug}/{role}/{module}_edit`
683
+ - "Delete" → Alpine.js inline confirm dialog (`href="javascript:void(0)"`)
684
+ - "Add New" / "Create" → HTMX link to `/{app_slug}/{role}/{module}_create`
685
+
686
+ 2. **Tabs within a screen**:
687
+ - Each tab MUST HTMX-link to its corresponding content file
688
+ - The current tab is visually active; other tabs link to their respective content pages
689
+
690
+ 3. **Header links**:
691
+ - Notification bell icon → HTMX nav to `notifications`
692
+ - Notification dropdown "View all notifications" → HTMX nav to `notifications`
693
+ - Locale dropdown options → `javascript:void(0)` (static language switcher mockup)
694
+ - Night mode toggle → Alpine.js `@click="toggleDark()"` (no href)
695
+ - Profile dropdown → HTMX nav to `profile`
696
+ - Account dropdown → HTMX nav to `account`
697
+ - Logout → `href="/"` (returns to the hub landing page)
698
+
699
+ 4. **Sidebar links**: HTMX links to correct module screen routes (already enforced)
700
+
701
+ 5. **Breadcrumb links**: HTMX links
702
+ - Home → `/{app_slug}/{role}/home`
703
+ - Module → `/{app_slug}/{role}/{module}`
704
+ - Detail / current → plain text, no link
705
+
706
+ 6. **Pagination links**: HTMX `hx-get` links to the same route (self-referential) are acceptable. Pagination is MANDATORY on every list — page buttons must use `hx-get` with the same route, not `href="#"`
707
+
708
+ 7. **Back / Cancel buttons**: HTMX link to the parent screen
709
+
710
+ 8. **Images** (inline previews, thumbnails, etc.):
711
+ - Must open the full image in a **new tab** via `<a href="..." target="_blank" rel="noopener noreferrer">`
712
+ - Use placeholder image URLs like `https://placehold.co/800x600`
713
+
714
+ 9. **PDFs and documents** (download/view links):
715
+ - Must open in a **new tab** via `<a href="..." target="_blank" rel="noopener noreferrer">`
716
+ - Never render PDFs inline within the mockup
717
+
718
+ **Content guidelines:**
719
+ - Use placeholder/sample data that reflects the module context
720
+ - Include appropriate form fields based on NFRs and constraints
721
+ - Show the user story tags with their version as HTML comments for traceability
722
+ (e.g., `<!-- USHM00012 [v1.0.1] -->`)
723
+ - All interactive elements use Alpine.js (`x-data`, `x-show`, `@click`, `:class`)
724
+ - Use Tailwind utility classes for all styling
725
+ - Use inline Heroicons SVG (no external icon dependencies)
726
+
727
+ #### Common Screens Content
728
+
729
+ **profile.html**: User profile page showing:
730
+ - User avatar, full name, email, role badge
731
+ - Personal information form (read-only display): Name, Email, Phone, Department
732
+ - "Edit Profile" button (HTMX links to self since it's a mockup)
733
+
734
+ **account.html**: Account settings page showing:
735
+ - Change Password section (current password, new password, confirm password fields)
736
+ - Notification Preferences (Alpine.js email/SMS toggles)
737
+ - Language/Locale selector (Alpine.js)
738
+ - Session Management (active sessions table)
739
+
740
+ **notifications.html**: Notifications list page showing:
741
+ - Alpine.js filter tabs: All, Unread, Read
742
+ - List of notification cards with: icon, title, message preview, timestamp, read/unread dot
743
+ - Mark all as read button
744
+ - **Pagination** (MANDATORY): Pagination bar below the notification list, default 10 items per page. Same Alpine.js + HTMX pattern as list screens.
745
+
746
+ #### Sub-Screen Content
747
+
748
+ **{module}_detail.html**: Record detail page showing:
749
+ - Page title with record identifier
750
+ - Back button (HTMX link to `{module}`)
751
+ - Detail cards/panels with all relevant fields from user stories
752
+ - Action buttons: Edit (HTMX to `{module}_edit`), Delete (Alpine.js confirm), Back to List
753
+ - Related data sections if applicable
754
+ - If the entity has sub-entities, show them in HTMX-linked tabs or sections
755
+
756
+ **{module}_create.html**: Create/add form page showing:
757
+ - Page title: "Add New {Entity}"
758
+ - Breadcrumb: Home > {Module} > Add New
759
+ - Form with all required fields derived from user stories
760
+ - Submit and Cancel buttons (Cancel: HTMX link to `{module}`)
761
+
762
+ **{module}_edit.html**: Edit form page showing:
763
+ - Page title: "Edit {Entity}"
764
+ - Breadcrumb: Home > {Module} > Edit
765
+ - Pre-filled form with sample data
766
+ - Save and Cancel buttons (Cancel: HTMX link to `{module}_detail` or `{module}`)
767
+
768
+ ### Step 7: Output Summary
769
+
770
+ After generation, print a summary:
771
+
772
+ ```
773
+ Mockup Generation Complete
774
+ ===========================
775
+ Application: {App Name} ({Initials})
776
+ Target Version: {version or "latest (all versions)"}
777
+ Module Filter: {module name or "all modules"}
778
+ Output: {path}/mockup/
779
+
780
+ Filtering Summary:
781
+ - User stories included: {count}
782
+ - User stories excluded (strikethrough): {count}
783
+ - User stories excluded (version filter): {count}
784
+ - User stories excluded (module filter): {count}
785
+ - NFRs/Constraints included: {count}
786
+ - NFRs/Constraints excluded: {count}
787
+
788
+ | Role | Screens | Content Folder |
789
+ |-----------------------|---------|-----------------------------------|
790
+ | Hub Administrator | 8 | hub_administrator/content/ |
791
+ | Hub Operation Support | 6 | hub_operation_support/content/ |
792
+
793
+ Files generated:
794
+ - mockup-manifest.json
795
+ - MOCKUP.html
796
+ - partials/shell.html, header.html, footer.html
797
+ - partials/sidebar-hub_administrator.html
798
+ - partials/sidebar-hub_operation_support.html
799
+ - {N} content fragment files
800
+ - Mockup Hub: {created at <root>/mockup | upgraded to v{N} | already present}
801
+
802
+ Total: {N} files
803
+
804
+ Quick Start
805
+ ===========
806
+ 1. cd <root>/mockup
807
+ 2. npm start (zero dependencies — no npm install required)
808
+ 3. Open http://localhost:{port} in your browser (first unused port from 4000 —
809
+ the exact URL is printed on start)
810
+ - Landing page lists ALL applications and roles
811
+ - This app's screen index: http://localhost:{port}/{app_slug}
812
+ 4. Change port: the landing page's Port input, PORT=4100 npm start, or edit
813
+ <root>/mockup/mockup.config.json — or use Compound Context Studio's Mockup page
814
+ (topbar port input + Start/Stop Hub)
815
+ ```
816
+
817
+ ### Step 7b: Link Integrity Validation (MANDATORY)
818
+
819
+ Before finalizing output, perform a link integrity check across ALL generated files:
820
+
821
+ 1. **Scan every generated file** for all `href`, `hx-get`, and `hx-push-url` attribute values
822
+ 2. **Build a link registry**: map every route reference to the file that should exist
823
+ 3. **Verify each HTMX route** resolves to an existing content fragment:
824
+ - `hx-get="/api/content/{app_slug}/{role}/{page}"` → verify `{role}/content/{page}.html` exists
825
+ - Every internal route MUST start with `/{app_slug}/` (or `/api/content/{app_slug}/`)
826
+ — un-prefixed routes like `/{role}/{page}` are dead links under the hub
827
+ - `href="javascript:void(0)"` → acceptable for delete confirm, locale switcher
828
+ - `href="/"` → acceptable for logout
829
+ - `target="_blank"` links → acceptable for images, PDFs, external resources
830
+ - `href="#"` → **NOT ALLOWED** — dead link, must be fixed
831
+ 4. **For any missing target file**, either:
832
+ - Generate the missing content fragment, OR
833
+ - Update the link to point to an existing route
834
+ 5. **Report any fixes** made during validation in the output summary
835
+
836
+ If any `href="#"` is found in the final output (excluding anchor-only usage), the generation
837
+ is **incomplete**.
838
+
839
+ ## Changelog Append
840
+
841
+ After all mockup files are successfully generated, append an entry to `CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
842
+
843
+ 1. Read `<app_folder>/CHANGELOG.md`. If it does not exist, create it with:
844
+ ```markdown
845
+ # Changelog
846
+
847
+ - This file tracks all skill executions by version for this application.
848
+ - The highest version recorded here is the current application version.
849
+ - Skills MUST NOT execute for a version lower than the highest version in this file.
850
+
851
+ ---
852
+ ```
853
+ 2. Search for a `## {version}` heading matching the current version.
854
+ 3. If the section **exists**: append a new row to its table.
855
+ 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.
856
+ 5. Row format: `| {YYYY-MM-DD} | {application_name} | mockgen-tailwind | {module or "All"} | Generated HTML mockup screens |`
857
+ 6. **Never modify or delete existing rows.**
858
+
859
+ ## Important Rules
860
+
861
+ - **Module filter is additive, not destructive**: When `module:` is specified, only the named
862
+ module's content files are written/overwritten (plus manifest/MOCKUP.html updates). All
863
+ other files (partials, other module content) remain untouched. If the target module does
864
+ not exist in PRD.md, stop and report available module names before doing any file writes.
865
+ - **No per-app server**: NEVER generate `server.js`/`package.json` inside the application's
866
+ mockup folder. All serving is done by the shared hub at `<root>/mockup/` (ensure it per
867
+ Step 4c). All npm/machine artifacts stay inside `<root>/mockup/` and are gitignored there.
868
+ - **Manifest is mandatory**: every run writes/updates `mockup-manifest.json` — without it
869
+ the hub cannot route the app and the landing page shows it as not ready.
870
+ - **Root-relative links only**: never hardcode `http://localhost:<port>` in any generated
871
+ file — the hub port is user-configurable.
872
+ - **Version + module are independent axes**: Both may be combined freely. `module:Employer
873
+ v1.0.2` means "generate Employer module screens as they exist at v1.0.2". Version filtering
874
+ and module filtering each apply independently; a story must satisfy BOTH to be included.
875
+ - **ZERO dead links**: Every `href` and `hx-get` in every file must resolve. No `href="#"`
876
+ - **Pagination on every list** (MANDATORY): Every screen that renders a table or card list of records MUST include a pagination bar below it. Default page size is **10 items per page**. Applies to: module list screens, history/audit screens, notifications screen, and any embedded sub-tables within detail screens that may grow unbounded. Use Alpine.js `x-data` for page state and HTMX `hx-get` (self-referential) for page navigation. Omitting pagination from any list is a generation error.
877
+ - **Partials for layout**: Header, footer, and sidebar are partial files, NOT duplicated inline
878
+ - **Content fragments only**: Role screen files contain only page content — no `<html>/<head>/<body>`
879
+ - **HTMX navigation**: All in-app navigation uses HTMX (`hx-get`, `hx-target`, `hx-push-url`)
880
+ - **Alpine.js for interactivity**: Dropdowns, toggles, confirm dialogs use Alpine.js
881
+ - **Images open in new tab**: Any `<img>` link or image view action uses `target="_blank"`
882
+ - **PDFs open in new tab**: Any PDF/document view link uses `target="_blank" rel="noopener noreferrer"`
883
+ - **MOCKUP.html links open in new tab**: All screen card links in the index use `target="_blank"`
884
+ - No external image dependencies; use `https://placehold.co/` for placeholder images
885
+ - Use inline SVG Heroicons only; no icon CDN dependencies
886
+ - Sidebar navigation must link between screens within the same role using HTMX
887
+ - Header navigation (notification, profile, account) links use HTMX
888
+ - Table action buttons (View, Edit, Add) use HTMX navigation
889
+ - Tabs within screens each link to a corresponding content fragment via HTMX
890
+ - Back/Cancel buttons use HTMX to navigate to the parent list or detail screen
891
+ - Preserve traceability: include user story tags with version as HTML comments in each screen
892
+ (e.g., `<!-- USHM00012 [v1.0.1] -->`)
893
+ - Do not generate screens for modules that have no user stories for a given role
894
+ - Common screens (home, profile, account, notifications) are generated for EVERY role
895
+ - Use consistent color scheme from the design system across all partials and content fragments
896
+ - The version displayed in footer should be the target version if specified, or the latest version
897
+ found in PRD.md
898
+ - **Strikethrough items MUST always be excluded** — lines wrapped in `~~` are deprecated/removed
899
+ - **Version filtering**: When a target version is provided, only include items from sections
900
+ with version tags <= target version
901
+ - **Model-driven screens**: When a module model file exists at `model/{kebab-module}/model.md`,
902
+ use the actual field definitions (field names, types, required/nullable, enums) for all
903
+ form inputs, table columns, and detail panels. Generic placeholder field names are NOT
904
+ acceptable when a model is available. See Step 1b and the "Model-Driven Field Usage" section.
905
+ - **Enum accuracy**: Enum select options must use the exact values from the model's Enum
906
+ Definitions (Section 7), not inferred strings
907
+ - **Constraint-aware sample data**: Sample values must respect field constraints noted in the
908
+ model (e.g., use `MYS`, `BHR`, `MDV` for countryCode fields constrained by CONSHM018)
909
+ - **Report layouts**: When PRD.md contains report-related NFRs or user stories, generate
910
+ standalone HTML report layout files in `reports/` subfolder. These are self-contained A4
911
+ mockups (not content fragments) for stakeholder review of report structure before coding.
912
+ Use actual module model fields for column headers and realistic sample data rows. See
913
+ Step 3f for full report layout generation rules.