specgen-laravel-eloquent-bladehtmx — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited specgen-laravel-eloquent-bladehtmx (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill generates a comprehensive specification document (Markdown) that serves as a blueprint for building a monolith Laravel 12 web application with server-rendered views. The spec is intended to be followed by a developer or a coding agent to produce a fully functional project scaffold.
The specification does NOT generate code. It produces a detailed, opinionated technical document describing every layer of the application — from Composer configuration to Blade layouts to middleware chains — so that implementation becomes a mechanical exercise.
These are the fixed versions the spec targets. Do not deviate unless the user explicitly requests different versions.
| Component | Version |
|---|---|
| PHP | 8.3+ |
| Laravel | 12.x |
| Composer | 2.x |
| Blade | Built-in |
| Tailwind CSS | 4.x |
| Alpine.js | 3.x |
| htmx | 2.x |
| Vite | 6.x |
| Node.js | 22.x LTS |
Include in the version table only when the corresponding integration is selected.
| Component | Version | When Selected |
|---|---|---|
| MongoDB | 8.0.x | Database = MongoDB |
| PostgreSQL | 17.x | Database = PostgreSQL |
| MySQL | 8.4.x | Database = MySQL |
| Keycloak | 26.5.x | Auth = Keycloak |
| RabbitMQ | 4.x | Messaging = yes OR Queue driver = rabbitmq |
The spec must include these in the Composer configuration section (always):
laravel/framework — Core frameworknwidart/laravel-modules — Modular architecturespatie/laravel-data — Typed DTOs with transformation and validationlaravel-vite-plugin — Vite integration (npm)If Database = MongoDB:
mongodb/laravel-mongodb — Official MongoDB Eloquent driverIf Database = PostgreSQL or MySQL:
If Auth = Keycloak:
laravel/socialite — OAuth2 abstractionsocialiteproviders/keycloak — Keycloak OAuth2 providerIf Auth = Laravel Breeze (form login):
laravel/breeze — Simple authentication scaffoldingIf Scheduling = yes:
Illuminate\Console\Scheduling)If Scheduling = yes AND Batch Processing = yes:
Illuminate\Bus\Batch (Bus::batch())If Messaging = yes:
vladimir-yuldashev/laravel-queue-rabbitmq — RabbitMQ queue driverphp-amqplib/php-amqplib — Low-level AMQP for advanced exchange patternsIf i18n = yes:
lang/ directory, __() /trans() / @lang helpers, trans_choice() for pluralization, app()->setLocale()).
SetLocale middleware (session → cookie →Accept-Language header → configured default).
(loadTranslationsFrom()), keeping module strings self-contained.
If Reporting = yes:
spatie/browsershot — PDF generation via Puppeteer (headless Chrome) with full CSS supportmaatwebsite/excel — XLSX and CSV exportnpm install puppeteer on the server (Node.js + headless Chrome binary)Additional cross-cutting packages:
spatie/laravel-permission — RBAC (roles and permissions)owen-it/laravel-auditing — Audit trail (created_by, updated_by, field change history)spatie/laravel-health — Health check endpointsspatie/laravel-view-models — Typed view models for Blade templatesGenerate the spec when the user provides an application name and version that corresponds to one of the custom applications defined in CLAUDE.md. The skill reads all required inputs from the project's context files — no interactive Q&A is needed for the core inputs.
The user invokes this skill by specifying the target application and version, for example:
/specgen-laravel-eloquent-bladehtmx hub_middleware v1.0.3/specgen-laravel-eloquent-bladehtmx hub_middleware v1.0.3 module:Location Information/specgen-laravel-eloquent-bladehtmx "Hub Middleware" v1.0.3The skill then locates the matching context folder and reads all input files automatically.
Before starting any work, resolve the application folder first (see Input Resolution below), then check CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md does not exist, skip this check (first-ever execution for this application).<app_folder>/CHANGELOG.md exists, scan all ## vX.Y.Z headings and determine the highest version using semantic versioning comparison."Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected." Do NOT proceed with any work.This skill uses standardized input resolution. Provide:
| Argument | Required | Example | Description |
|---|---|---|---|
<application> | Yes | hub_middleware | Application name to locate the context folder |
<version> | Yes | v1.0.3 | Version to scope processing |
module:<name> | No | module:Location Information | Limit generation to a single module |
The application name is matched against root-level application folders:
<number>_ prefix from folder names (e.g., 1_hub_middleware → hub_middleware)| File | Resolved Path |
|---|---|
| PRD.md | <app_folder>/context/PRD.md |
| Module Models | <app_folder>/context/model/ |
| HTML Mockups | <app_folder>/context/mockup/ |
| Output (specification) | <app_folder>/context/specification/ |
/specgen-laravel-eloquent-bladehtmx hub_middleware v1.0.3 (all modules)/specgen-laravel-eloquent-bladehtmx hub_middleware v1.0.3 module:Location Information (one module)/specgen-laravel-eloquent-bladehtmx "Hub Middleware" v1.0.3When a version is provided, only include user stories, NFRs, and constraints from versions <= the provided version. For example, if v1.0.3 is specified:
[v1.0.0], [v1.0.1], [v1.0.2], [v1.0.3][v1.0.4] or laterWhen module:<name> is provided:
SPEC.md for that specific moduleSPECIFICATION.md (root) gets a partial update — only that module's entry in the TOCis added or updated; all other TOC entries are preserved as-is
The specification is driven by six input sources that are read from the project's context files. The skill does NOT ask the user for database, authentication, scheduling, or messaging choices — it determines these automatically from the context.
From CLAUDE.md (already loaded in context), locate the target application under the Custom Applications section. Extract:
optional components (see Determining Optional Components)
The application name is used to derive:
hub-middleware)App\Modules (for nwidart/laravel-modules) or App (for core)Read <app_folder>/context/PRD.md. This file contains all user stories organized by module. Extract:
# System Module heading (e.g., User, Notification,Activities, Audit Trail). These become system-level modules in the spec.
# Business Module heading (e.g., LocationInformation, Corridor, Employer). These become business-level modules.
### User Story section contains tagged items like[USHM00108] As a user, I want to.... These define the functional requirements for each module's service interface and page controllers.
The user stories directly inform:
Important: Items with strikethrough (~~text~~) are deprecated — do NOT include them as active requirements. Instead, list them in the "Removed / Replaced" subsection of the traceability table (see spec-template.md) so that developers can see what was removed and which version removed it. If a deprecated item has a replacement (e.g., USHM00015 replaced by USHM00222), note the replacement ID.
### User Story, ### Non Functional Requirement,and ### Constraint section contains one or more version blocks formatted as [v1.0.x]. Items listed under each version tag belong to that version. The skill must track the version tag for each item (user story, NFR, constraint) and carry it through to the generated specification's traceability section. When a version block explicitly lists "Removed ... from previous version", record those removals in a "Removed / Replaced" subsection with the version that removed them and the replacement ID (if any).
Within the same PRD.md, each module has a ### Non Functional Requirement section with tagged items like [NFRHM0120]. These inform:
NFRs should be mapped to specific technical decisions in the spec — for example, an NFR stating "stored in JWT token" confirms stateless auth, while "sent asynchronously" confirms event-driven processing.
Within the same PRD.md, each module has a ### Constraint section with tagged items like [CONSHM042]. These define hard boundaries that the spec must enforce:
Constraints are embedded directly into the relevant module blueprint — they inform service interface contracts, validation rules, and UI form configurations.
Read <app_folder>/context/model/MODEL.md first as the index, then read the individual module model files in each module subfolder.
MODEL.md provides:
Per-module files (e.g., model/location-information/model.md):
Per-module schema (e.g., model/location-information/schemas.json):
Per-module diagram (e.g., model/location-information/document-model.mermaid):
The module model directly maps to:
which versions each module participates in (e.g., "1.0.0, 1.0.1, 1.0.3"). Per-module model.md files may also include version annotations on fields and indexes. The skill must carry these version tags into the generated specification.
Read <app_folder>/context/mockup/MOCKUP.html first as the index page, then read the HTML files organized by role in subfolders.
MOCKUP.html provides:
Role-specific subfolders (e.g., mockup/hub_administrator/content/):
IMPORTANT — Role folders inform access control, NOT URL paths. The role-specific folder structure (e.g., mockup/hub_administrator/content/corridor.html) determines:
middleware('role:hub_administrator')It does NOT determine the URL path. The URL path is always module-based:
Route::get('/corridor', ...) — NOT Route::get('/hub_administrator/corridor', ...)Route::get('/corridor/fragments/...', ...) — NOT role-prefixedShared partials (e.g., mockup/partials/):
header.html — Header bar layout and elementsfooter.html — Footer layoutsidebar-<role>.html — Per-role navigation menusshell.html — Page shell/wrapper structureThe mockup screens directly map to:
card (e.g., v1.0.0, v1.0.3). Individual mockup screens may include version annotations. The skill must associate each mockup screen with its version and carry this through to the generated specification.
Before determining optional components, check PRD.md for the following extended sections and extract their content for use throughout specification generation:
If PRD.md contains an # Architecture Principle section, read it and extract architectural patterns as a structured context object. These patterns serve as primary signals for optional component determination and specification content:
| Pattern to Extract | How It Influences the Specification |
|---|---|
| Framework mention (e.g., "Laravel") | Validates technology stack choice |
| "Monolithic" / "modular architecture" | Validates nwidart/laravel-modules structure; inter-module via Laravel events |
| "Stateless" | Confirms no server-side session — JWT/OAuth2 token-based auth |
| "Event-driven" | Map to Laravel Event Broadcasting and Event Listeners; include event catalog |
| "Message driven" / "message queue" | Map to Laravel Queue Jobs; validate RabbitMQ integration |
| "Document based database" / "MongoDB" | Primary signal for Database = MongoDB |
| "Container based deployment" | Confirms .env environment variable configuration |
If the section is absent, proceed with existing CLAUDE.md-only detection.
If PRD.md contains a # Design System section with a file reference (e.g., [DESIGN_SYSTEM.md](reference/DESIGN_SYSTEM.md)):
If the section is absent, use design tokens from MOCKUP.html Tailwind config (existing behavior).
If PRD.md contains a # High Level Process Flow section:
If the section is absent, derive messaging patterns from NFRs only (existing behavior).
Instead of asking the user, the skill determines optional components by analyzing the dependencies listed in CLAUDE.md, the # Architecture Principle section in PRD.md (if present), and cross-referencing with PRD.md NFRs and constraints.
First check PRD.md `# Architecture Principle`: If it explicitly mentions a database type (e.g., "document based database", "MongoDB", "relational database", "MySQL"), use that as the primary signal.
Fallback to CLAUDE.md: Examine the "Depends on" list in CLAUDE.md for the target application:
| Dependency Pattern | Database Selection |
|---|---|
| References "Hub Database" (MongoDB) | Database = MongoDB |
| References "HC Database" or "SC Database" (MySQL) | Database = MySQL |
| No database dependency listed | Database = none |
Also check CLAUDE.md's database section for the exact database name, and read ENVIRONMENT.md (in the project root) for host, port, and credentials to use in the spec's application configuration.
| Dependency Pattern | Auth Selection |
|---|---|
| References "Hub Single Sign On" (Keycloak) | Auth = Keycloak |
| PRD.md constraint says "does not manage any user, permissions and roles" | Auth = none |
| PRD.md NFRs reference "SSO service" or "JWT token" | Auth = Keycloak |
| No SSO/Keycloak dependency but has user management stories | Auth = form |
If Auth = Keycloak, also extract from CLAUDE.md:
<project-slug>-webhttp://localhost:8180/realms/<realm>hub_administrator → HUB_ADMINISTRATOR)| Dependency Pattern | Messaging Selection |
|---|---|
| References "Hub to HC Adapter Message Queue" or "Hub to SC Adapter Message Queue" (RabbitMQ) | Messaging = yes |
| No message queue dependency listed | Messaging = no |
If Messaging = yes, also extract the RabbitMQ version from the corresponding message queue section in CLAUDE.md.
Scheduling is determined from PRD.md content:
| Content Pattern | Scheduling Selection |
|---|---|
| NFRs mention "automatically deleted after X days", "scheduled", "periodic", "batch processing" | Scheduling = yes |
| User stories describe recurring jobs, cleanup tasks, or time-triggered operations | Scheduling = yes |
| No scheduling-related requirements found | Scheduling = no |
If Scheduling = yes, further determine:
or processing large volumes of data with reader/processor/writer patterns
Reporting is determined from PRD.md content:
| Content Pattern | Reporting Selection |
|---|---|
| NFRs mention "report", "Report interface", "generate report", "report generation" | Reporting = yes |
| User stories describe generating/downloading PDF, Excel, or CSV reports | Reporting = yes |
| A "Report" module exists in PRD.md with NFRs defining a Report interface | Reporting = yes |
| No reporting-related requirements found | Reporting = no |
If Reporting = yes, the spec includes:
ReportDefinition interface for modules to implementReportService orchestrating render → exportInternationalisation is determined from PRD.md content:
| Content Pattern | i18n Selection |
|---|---|
| PRD.md mentions multiple languages or localization (e.g., "English and Bahasa Malaysia", "multilingual", "support multiple locales") | i18n = yes |
| NFRs require translatable UI, locale-specific date/number formatting, or a language switcher | i18n = yes |
| User stories describe choosing/switching the interface language | i18n = yes |
| No language/localization requirements found | i18n = no |
If i18n = yes, the spec includes:
config/app.php locale / fallback_locale + an app.supported_locales listSetLocale middleware (session → cookie → Accept-Language → default) registered on the web grouplang/<locale>/...) plus per-module translation namespaceslang/<locale>/validation.php)If i18n = no, do NOT generate a locale/language switcher or any translation scaffolding — Blade templates use literal copy. Never add a non-functional language switcher "for future use".
After analyzing all inputs, produce a determination summary before generating the spec. Present it to the user for confirmation:
Optional Component Determination:
- Database: MongoDB (from CLAUDE.md → depends on Hub Database)
- Authentication: Keycloak (from CLAUDE.md → depends on Hub Single Sign On)
- Scheduling: yes (from PRD.md → NFR mentions automatic deletion)
- Batch Processing: no
- Messaging: yes (from CLAUDE.md → depends on Hub to HC/SC Adapter Message Queue)
- Reporting: yes (from PRD.md → Report module with Report interface NFR)
- Internationalisation: yes (en, ms) (from PRD.md → English + Bahasa Malaysia required)If the user disagrees with any determination, allow them to override before proceeding.
After determination, these values are needed. Most are derived automatically:
Auto-derived from context files:
App (core) / Modules\<ModuleName> (for modules)Auto-derived from CLAUDE.md (Port Allocation table):
Port Allocation table in the Custom Applications section of CLAUDE.md. Do NOT hardcode a default — the port MUST match the allocated port for this application.Optional (use sensible defaults if not found in context):
light (supports light/dark)info for application, warning for frameworksen (only relevant if i18n = yes)en, ms); default ['en']Once inputs are gathered from context files and optional components are determined, generate the specification as a multi-file output split by module. Read the spec template at references/spec-template.md for the exact structure and content of each section. The template is the authoritative guide — follow it closely.
The specification is split into two categories:
and application-level sections that apply across all modules.
a self-contained specification file covering that module's complete blueprint.
This split enables a coding agent to:
SPECIFICATION.md<module>/SPEC.mdImportant: The generated spec must use real module data from the context files, not generic placeholders. Specifically:
(e.g., LocationInformation, Corridor, Employer — not Module1, Module2)
files (e.g., model/location-information/model.md), not placeholder field_one/field_two
a story says "view provinces by country", the service needs listProvincesByCountry())
hub_administrator/content/location_information.html exists, there must be a matching controller endpoint and Blade page). The controller URL is module-based (e.g., /location-information), NOT role-prefixed (e.g., NOT /hub_administrator/location-information). The mockup's role folder determines middleware('role:...') annotations, not URL structure.
module-based paths (e.g., /corridor, /quota) — the role determines which items appear in the sidebar, not the URL prefix
the traceability section must include its version tag (e.g., USHM00228 [v1.0.3]). This enables incremental implementation by version. ALL traceability sub-tables (User Stories, NFRs, AND Constraints) MUST include the `| Version |` column. Do not omit the Version column from any table — even if a module only has v1.0.0 items.
subsection listing any deprecated items from previous versions — showing the removed ID, the version that removed it, the replacement ID (if any), and a brief reason. This ensures developers can see what was removed and understand the evolution of requirements. If a module has no removed items, include the subsection with _None._ to make it explicit that nothing was removed.
<app_folder>/context/specification/
├── SPECIFICATION.md ↠TOC + shared/application-level specs
├── location-information/
│ └── SPEC.md ↠Module blueprint for Location Information
├── corridor/
│ └── SPEC.md ↠Module blueprint for Corridor
├── employer/
│ └── SPEC.md ↠Module blueprint for Employer
├── ... ↠One folder per module from PRD.mdSPECIFICATION.md (Root)The root file contains the TOC and all shared/application-level sections. These are the sections that a coding agent implements first before any module work:
#### 1. Project Overview Project metadata, application description, technology stack summary, the complete list of user roles extracted from mockup sidebar files, and the Module Index — a table listing every module with a link to its <module>/SPEC.md file.
#### 2. Composer & npm Configuration Complete composer.json structure with all dependencies (core + selected conditional). Complete package.json with Vite, Tailwind CSS, Alpine.js, htmx, and build scripts.
#### 3. Application Configuration (conditional content varies) Full config/ files covering database connection (MongoDB URI or SQL DSN depending on selection), auth settings (Keycloak/OAuth2 if selected, or Breeze if selected), scheduling config (if selected), theme defaults, and logging configuration. All environment-sensitive values (ports, hostnames, credentials, URIs) MUST be externalized using Laravel's `env('VAR', 'default')` helper in config files, with sensible defaults for local development. Production overrides via system environment variables or .env.production.
#### 3a. Application Version Configuration The application configuration MUST include a version value set via environment variable with a default derived from the version argument provided during skill invocation. If multiple versions were provided, use the highest one.
In config/app.php:
'version' => env('APP_VERSION', '1.0.0'),The application MUST expose this version in the footer of every page. The shared footer Blade partial (resources/views/partials/footer.blade.php) must render config('app.version') as: v{version} (e.g., v1.0.3).
The .env file must include APP_VERSION={version} with the actual version value.
The composer.json version field MUST also be set to the version value (e.g., 1.0.3).
#### 3b. .env File Generation from ENVIRONMENT.md Generate the .env file at the project root by reading ENVIRONMENT.md from the project root. The .env file maps ENVIRONMENT.md credential and platform values to the environment variable names referenced in config/ files via env() calls. The spec must define the complete .env content with actual values from ENVIRONMENT.md.
Process:
ENVIRONMENT.md from the project rootENVIRONMENT.md (# Supporting 3rd Party Applicationsfor database hosts, ports, usernames, passwords, plus Keycloak/Mail/RabbitMQ); read toolchain paths (Node.js, PHP) from DEVTOOL.md
env('VAR') name used in Laravel config files.env file with KEY=value pairsExample `.env` output (derived from ENVIRONMENT.md):
APP_NAME="HC Support Portal"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:<port from CLAUDE.md Port Allocation table>
# Database
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=hc_support_my
DB_USERNAME=root
DB_PASSWORD=B3st1n3t@2025
# Authentication (Keycloak)
KEYCLOAK_BASE_URL=http://localhost:8180
KEYCLOAK_REALM=urp
KEYCLOAK_CLIENT_ID=hc-support-portal-web
KEYCLOAK_CLIENT_SECRET=
# Mail (Mailcatcher)
MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
# Messaging (RabbitMQ)
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guestRules:
config/ files via env() callsTODOdevelopment (e.g., localhost, default ports)
.env file is gitignored (already covered in .gitignore)#### 4. Build & Tooling Vite configuration (vite.config.js), Tailwind CSS setup (using design tokens from MOCKUP.html), PostCSS config, and resources/ directory structure.
#### 4b. .gitignore Generate a .gitignore file at the project root. Laravel's default .gitignore plus:
# Laravel
/vendor/
/node_modules/
/public/build/
/public/hot
/storage/*.key
.env
.env.backup
.env.production
# IDE
.idea/
*.iml
.vscode/
*.swp
*~
# OS
.DS_Store
Thumbs.db
# Testing
/coverage/
.phpunit.result.cache
# E2E
e2e/node_modules/
e2e/test-results/
e2e/playwright-report/
e2e/visual-baselines/
# Logs
*.log
storage/logs/*
!storage/logs/.gitkeepConditional additions:
#### 5. Directory Structure The complete directory tree rooted at the project. The structure follows Domain-Driven Design with nwidart/laravel-modules conventions, adapted for server-rendered web with page and fragment separation. Use actual module names from the context. Read references/modulith-patterns.md for the detailed module layout and inter-module communication rules.
#### 6. Security Configuration (conditional — include only if Auth != none) If Auth = Keycloak: OAuth2 Client setup with Keycloak OIDC via Laravel Socialite, custom KeycloakGuard, middleware for role extraction from OIDC ID token claims, CSP nonce middleware, automatic redirect to Keycloak login, and public route configuration. Session-based. Read references/security-patterns.md for the full security architecture.
If Auth = form: Laravel Breeze form login configuration, custom UserDetailsService backed by the selected database, password hashing with bcrypt, role-based access control via spatie/laravel-permission, CSRF enabled (standard for form login), and remember-me.
#### 7. Layouts (Blade) Three layouts: app.blade.php (header/sidebar/footer for authenticated pages), auth.blade.php (split-screen for login), error.blade.php (centered error display). Each uses Blade component syntax with slots. Layout structure should match the mockup shell/partials. Note: If Auth = none, auth layout may be omitted or simplified.
#### 8. Partials & Includes Reusable Blade partials: header, sidebar, footer, theme-switcher. Sidebar must include the actual navigation items from the mockup sidebar files, organized per role.
#### 9. UI Components (Blade + Tailwind) Pure Tailwind CSS components (no DaisyUI): Alert, Avatar, Badge, Breadcrumb, Button, Card, Drawer, Dropdown, FormControl/Input/Select/Textarea/Checkbox/Radio/Toggle, Loading, Menu, Modal, Navbar, Pagination, Progress, Stats, Steps, Table, Tabs, Toast, Tooltip. Each as an anonymous Blade component with Tailwind utility classes.
#### 10. Frontend JS Structure Alpine.js stores (toast, modal, drawer, theme), htmx extensions (loading states, toast errors), ES module organization, and CSP nonce integration.
#### 11. Styles Tailwind CSS organization: base (reset, typography), components (buttons, forms, cards, tables, modals, navigation), layouts (sidebar, navbar, footer responsive), themes (light/dark CSS custom properties). Use the actual design tokens (colors, fonts) from MOCKUP.html.
#### 12. Authentication Pages (conditional — include only if Auth != none) If Auth = Keycloak: No custom login page needed. Middleware automatically redirects unauthenticated users to Keycloak login. Keycloak handles the login form, social login providers, and credential management. After successful authentication, Keycloak redirects back with an authorization code which the app exchanges for tokens.
If Auth = form: Login page with email/password form, CSRF token, remember-me checkbox. Logout endpoint. Optionally a registration page if user self-registration is desired. Provided by Laravel Breeze scaffolding.
#### 13. Data Access (conditional content varies) If Database = MongoDB: Eloquent models per module using mongodb/laravel-mongodb. DTO mapping via spatie/laravel-data. Pagination via Laravel's built-in paginate(). All list endpoints paginated. Use actual collection names from the module model.
If Database = PostgreSQL/MySQL: Eloquent models per module with standard Eloquent ORM. Laravel Migrations for schema versioning. UUIDs via $table->uuid('id')->primary() or Laravel's built-in HasUuids trait. DTO mapping via spatie/laravel-data. Pagination via built-in paginate(). All list endpoints paginated. Use actual table names from the module model.
If Database = none: In-memory data structures or stubs. The spec should note that a database integration can be added later.
#### 14. Error Handling & Exceptions Base WebApplicationException with status/code/userMessage. Handler.php returning error pages for full requests and toast fragments for htmx requests (detected via request()->header('HX-Request')).
#### 15. Theming Light/dark theme switching via cookie. Server reads cookie via middleware and shares $theme with all views. Alpine store syncs toggle with cookie and data-theme attribute.
#### 16. Pagination Support Laravel's built-in ->paginate() with custom Blade pagination component matching the Tailwind design system.
#### 17. Logging Strategy Laravel Log (Monolog) configuration, correlation ID middleware (from JWT if auth is enabled, or request-scoped UUID otherwise), contextual logging via Log::withContext(), per-channel log levels.
#### 18. Scheduling and Batch Processing (conditional — include only if Scheduling = yes) Laravel Task Scheduling via routes/console.php with Schedule facade. If Batch Processing = yes, includes Bus::batch() patterns with Batchable trait on jobs for chunk-oriented processing. Read references/batch-patterns.md for the full scaffolding spec.
#### 19. Event-Driven Architecture Laravel Events & Listeners for inter-module communication. Event classes in module's public namespace, listeners in internal namespace. ShouldQueue for async processing, $afterCommit = true for post-transaction delivery. Read references/modulith-patterns.md for details.
#### 20. Messaging (RabbitMQ Pub/Sub) (conditional — include only if Messaging = yes) Standalone RabbitMQ publisher/consumer services for inter-system communication. Topic exchange for event broadcasting, direct exchange for point-to-point commands. Read references/messaging-patterns.md for the full messaging architecture.
#### 21. DTO & Data Transformation Per-module spatie/laravel-data DTO conventions and mapping flow patterns (Model → DTO → View, Request → DTO → Model).
#### 22. Testing Strategy Overview of testing approach — unit tests (PHPUnit), feature tests (Laravel HTTP tests), module isolation tests, security test utilities (Socialite fake for Keycloak, actingAs() for form login), view model tests.
#### 23. Reporting (Puppeteer / Browsershot) (conditional — include only if Reporting = yes) Puppeteer via spatie/browsershot for PDF generation from Blade templates with full CSS/Tailwind support (headless Chrome rendering), Laravel Excel for XLSX/CSV export. Includes ReportDefinition interface for modules to implement, ReportService orchestrating HTML render → Browsershot PDF conversion → export, ReportRegistry for auto-discovering and persisting report definitions at startup, report controller with parameter form and download endpoint, Blade templates for report list, parameter form, and self-contained PDF report layouts (including Tailwind CDN for standalone rendering), multi-format export. Report Blade templates are fully AI-agent-developed — no visual designers needed. Read references/reporting-patterns.md for the full reporting architecture.
#### 24. Internationalisation (Localization) (conditional — include only if i18n = yes) Laravel's built-in localization. Covers: config/app.php locale/fallback_locale and the app.supported_locales list; a SetLocale middleware resolving the active locale (session → cookie → Accept-Language header → default) and calling app()->setLocale(), registered on the web middleware group; per-locale translation files under lang/ (lang/<locale>/messages.php, lang/<locale>/validation.php) plus per-module translation namespaces loaded via each module's service provider (loadTranslationsFrom()); a locale-switch route + controller that validates the requested locale against the supported list and persists it to session and a long-lived cookie (htmx-aware — returns HX-Refresh for partial requests); a language switcher partial (Alpine.js dropdown in the header, CSRF-protected); and Blade usage conventions (__('messages.welcome'), @lang, trans_choice() for pluralization, namespaced __('locationinformation::messages.title')), including locale-aware date formatting via Carbon::setLocale() / ->translatedFormat(). The language switcher is the ONLY locale UI element and MUST NOT be rendered when i18n = no.
<module>/SPEC.md (Per-Module)For EACH module from PRD.md and MODEL.md, create a folder named after the module (kebab-case, e.g., location-information/) and generate a SPEC.md inside it.
Each module SPEC.md is a self-contained blueprint that a coding agent can pick up and implement independently (after the shared infrastructure is in place). It must include:
SPECIFICATION.mdmockup screen filenames
model/<module>/model.md andmodel/<module>/schemas.json
(e.g., Modules/<Module>/lang/<locale>/messages.php) registered via the module service provider's loadTranslationsFrom(..., '<module-slug>'), and Blade templates that reference keys through the namespace (__('<module-slug>::messages.<key>')) instead of literal copy
Separating UI Layer from Messaging/Async Pipeline:
When a module has BOTH user-facing screens (user stories) AND async processing NFRs (e.g., RabbitMQ message consumption, message validation, ACK publishing, forwarding), the SPEC.md MUST clearly separate these into distinct sections:
getHistory), page controllers, fragment controllers, Blade templates. These are driven by user stories (USHMxxxxx).
ACK publisher, forward publisher, queue configuration, domain events, processIncomingMessage() service method. These are driven by NFRs (NFRHMxxxx).
This separation enables the implementation orchestrator to track and implement each concern independently. A module may have its UI layer fully implemented while its messaging pipeline remains pending.
See references/spec-template.md for the exact template structure.
After all specification files are successfully generated, append an entry to CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md. If it does not exist, create it with: # Changelog
- This file tracks all skill executions by version for this application.
- The highest version recorded here is the current application version.
- Skills MUST NOT execute for a version lower than the highest version in this file.
---## {version} heading matching the current version.--- below the context header and before any existing ## vX.Y.Z section (newest-first ordering), with a new table header and the first row.| {YYYY-MM-DD} | {application_name} | specgen-laravel-eloquent-bladehtmx | {module or "All"} | Generated Laravel web application technical specification |The generated specification is a folder of files, not a single document:
<app_folder>/context/specification/
├── SPECIFICATION.md ↠Root: TOC + shared/application-level specs
├── <module-1>/
│ └── SPEC.md ↠Module blueprint (self-contained)
├── <module-2>/
│ └── SPEC.md
├── <module-N>/
│ └── SPEC.md<app_folder>/context/specification/SPECIFICATION.md — contains the Table of Contents (with links toeach module's SPEC.md), all shared infrastructure sections (1–9), and all application-level cross-cutting sections (10–24, excluding module blueprints)
(e.g., location-information/, corridor/, employer/)
SPEC.md is self-contained with full code samples for thatmodule's module — service, DTOs, model, migration, controller, views, and Blade templates
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.