@rashidee/co2 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25449 -0
- package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
- package/drizzle/0001_wise_wolf_cub.sql +13 -0
- package/drizzle/0002_secret_spyke.sql +16 -0
- package/drizzle/0003_workspace_config_singleton.sql +16 -0
- package/drizzle/0004_terminal_claim_v120.sql +11 -0
- package/drizzle/0005_brainstorm_v124.sql +10 -0
- package/drizzle/0006_project_v140.sql +6 -0
- package/drizzle/0007_prd_wizard_v124.sql +14 -0
- package/drizzle/0008_workflow_artifact_v126.sql +24 -0
- package/drizzle/0009_project_import_v150.sql +7 -0
- package/drizzle/0010_quality_v151.sql +3 -0
- package/drizzle/meta/0000_snapshot.json +1335 -0
- package/drizzle/meta/0001_snapshot.json +1416 -0
- package/drizzle/meta/0002_snapshot.json +1510 -0
- package/drizzle/meta/_journal.json +83 -0
- package/package.json +41 -0
- package/plugin/.claude-plugin/marketplace.json +36 -0
- package/plugin/.claude-plugin/plugin.json +22 -0
- package/plugin/README.md +625 -0
- package/plugin/SKILLS.md +350 -0
- package/plugin/co2.svg +5 -0
- package/plugin/commands/brainstorm-loop.md +129 -0
- package/plugin/skills/conductor-defect/SKILL.md +898 -0
- package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
- package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
- package/plugin/skills/depgen-k8s/SKILL.md +468 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
- package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
- package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
- package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
- package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
- package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
- package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
- package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
- package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
- package/plugin/skills/modelgen-relational/SKILL.md +707 -0
- package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
- package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
- package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
- package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
- package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
- package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
- package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
- package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
- package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
- package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
- package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
- package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
- package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
- package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
- package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
- package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
- package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
- package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
- package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
- package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
- package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
- package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
- package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
- package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
- package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
- package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
- package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
- package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
- package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
- package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
- package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
- package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
- package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
- package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
- package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
- package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
- package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
- package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
- package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
- package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
- package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
- package/plugin/skills/testgen-functional/SKILL.md +1381 -0
- package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
- package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
- package/plugin/skills/util-projectinit/SKILL.md +307 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
- package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
- package/plugin/skills/util-projectsync/SKILL.md +501 -0
- package/plugin/skills/util-updprd/SKILL.md +324 -0
- package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
- package/plugin/skills/util-ustagger/SKILL.md +154 -0
- package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
- package/static/assets/arc-DRKw7sjs.js +1 -0
- package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
- package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
- package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
- package/static/assets/channel-C2nVbuwv.js +1 -0
- package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
- package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
- package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
- package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
- package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
- package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
- package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
- package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
- package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
- package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
- package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
- package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
- package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
- package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
- package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
- package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
- package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
- package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
- package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
- package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
- package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
- package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
- package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
- package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
- package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
- package/static/assets/graph-C9eacEi8.js +1 -0
- package/static/assets/index-LZSQkLE2.css +41 -0
- package/static/assets/index-y7XDSgMG.js +495 -0
- package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
- package/static/assets/init-Gi6I4Gst.js +1 -0
- package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
- package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
- package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
- package/static/assets/katex-C5jXJg4s.js +257 -0
- package/static/assets/layout-DEXfKzaS.js +1 -0
- package/static/assets/linear-CLO--ryk.js +1 -0
- package/static/assets/map-Czzmt4hB.js +1 -0
- package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
- package/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
- package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
- package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
- package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
- package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
- package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
- package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
- package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
- package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
- package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
- package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
- package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
- package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
- package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
- package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
- package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
- package/static/index.html +24 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Web Application Patterns — Layouts, Components, and Frontend
|
|
2
|
+
|
|
3
|
+
This reference describes the web-specific patterns for the server-rendered monolith.
|
|
4
|
+
Include this content in Sections 7-12 of the generated specification.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Architecture Overview
|
|
9
|
+
|
|
10
|
+
The web application uses a layered composition model:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Request → Middleware (Auth, CSP Nonce, Theme) → Controller
|
|
14
|
+
→ Service (queries DB via Eloquent Model / Repository)
|
|
15
|
+
→ View Model (spatie/laravel-view-models — encapsulates all template data)
|
|
16
|
+
→ Blade Template (renders HTML using Tailwind CSS)
|
|
17
|
+
→ Response (full page or htmx fragment)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Blade templates are organized following Laravel conventions with module separation:
|
|
21
|
+
|
|
22
|
+
- `resources/views/layouts/` — Layouts (app, auth, error)
|
|
23
|
+
- `resources/views/partials/` — Shared partials (header, sidebar, footer)
|
|
24
|
+
- `resources/views/components/` — Reusable Blade components
|
|
25
|
+
- `Modules/<Module>/resources/views/pages/` — Module page templates
|
|
26
|
+
- `Modules/<Module>/resources/views/fragments/` — Module htmx fragment templates
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## View Model Pattern
|
|
31
|
+
|
|
32
|
+
Every Blade page receives a strongly-typed view model via `spatie/laravel-view-models`.
|
|
33
|
+
Never pass raw arrays or unstructured data to templates.
|
|
34
|
+
|
|
35
|
+
```php
|
|
36
|
+
namespace Modules\Order\ViewModels;
|
|
37
|
+
|
|
38
|
+
use Spatie\ViewModels\ViewModel;
|
|
39
|
+
|
|
40
|
+
class OrderListViewModel extends ViewModel
|
|
41
|
+
{
|
|
42
|
+
public function __construct(
|
|
43
|
+
public readonly \Illuminate\Pagination\LengthAwarePaginator $items,
|
|
44
|
+
public readonly string $theme,
|
|
45
|
+
public readonly array $user,
|
|
46
|
+
) {}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Usage in controller:
|
|
51
|
+
```php
|
|
52
|
+
public function index(Request $request): View
|
|
53
|
+
{
|
|
54
|
+
$items = $this->orderService->list($request->integer('page', 1));
|
|
55
|
+
return (new OrderListViewModel(
|
|
56
|
+
items: $items,
|
|
57
|
+
theme: $request->cookie('theme', 'light'),
|
|
58
|
+
user: auth()->user(),
|
|
59
|
+
))->view('order::pages.index');
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Page Composition Flow
|
|
66
|
+
|
|
67
|
+
1. Request hits middleware (auth, CSP nonce, theme injection)
|
|
68
|
+
2. Controller calls service to get data
|
|
69
|
+
3. Controller builds view model with all needed data
|
|
70
|
+
4. View model resolves to Blade view
|
|
71
|
+
5. Blade layout wraps the page content via `@extends` or component slots
|
|
72
|
+
6. Blade page renders view model data using shared components
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
<x-app-layout :title="$title" :theme="$theme">
|
|
76
|
+
├── @include('partials.header')
|
|
77
|
+
├── @include('partials.sidebar', ['navItems' => $navItems])
|
|
78
|
+
├── <main> content area
|
|
79
|
+
│ └── {{ $slot }} ← page body injected via component slot
|
|
80
|
+
│ └── pages/index.blade.php
|
|
81
|
+
│ └── <x-pagination :paginator="$items" />
|
|
82
|
+
│ └── @include('order::fragments.order-row', ['item' => $item])
|
|
83
|
+
├── @include('partials.footer')
|
|
84
|
+
└── <x-toast-container />
|
|
85
|
+
</x-app-layout>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Tailwind CSS Component Strategy
|
|
91
|
+
|
|
92
|
+
All UI components use pure Tailwind CSS utility classes. No DaisyUI or other component
|
|
93
|
+
framework is used.
|
|
94
|
+
|
|
95
|
+
### Design Tokens via CSS Custom Properties
|
|
96
|
+
|
|
97
|
+
Define a semantic color system using CSS custom properties that Tailwind references:
|
|
98
|
+
|
|
99
|
+
```css
|
|
100
|
+
/* themes/light.css */
|
|
101
|
+
[data-theme="light"] {
|
|
102
|
+
--color-bg-primary: theme('colors.white');
|
|
103
|
+
--color-bg-secondary: theme('colors.gray.50');
|
|
104
|
+
--color-text-primary: theme('colors.gray.900');
|
|
105
|
+
--color-text-secondary: theme('colors.gray.500');
|
|
106
|
+
--color-border: theme('colors.gray.200');
|
|
107
|
+
--color-accent: theme('colors.blue.600');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* themes/dark.css */
|
|
111
|
+
[data-theme="dark"] {
|
|
112
|
+
--color-bg-primary: theme('colors.gray.900');
|
|
113
|
+
--color-bg-secondary: theme('colors.gray.800');
|
|
114
|
+
--color-text-primary: theme('colors.gray.100');
|
|
115
|
+
--color-text-secondary: theme('colors.gray.400');
|
|
116
|
+
--color-border: theme('colors.gray.700');
|
|
117
|
+
--color-accent: theme('colors.blue.400');
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Component Convention
|
|
122
|
+
|
|
123
|
+
Each Tailwind component follows this pattern:
|
|
124
|
+
- Anonymous Blade component (`resources/views/components/`) defining the component's props
|
|
125
|
+
- Blade template using Tailwind utility classes with `dark:` variants
|
|
126
|
+
- Conditional styling via Blade expressions (match on type/tone/variant)
|
|
127
|
+
|
|
128
|
+
Example pattern:
|
|
129
|
+
```blade
|
|
130
|
+
{{-- resources/views/components/alert.blade.php --}}
|
|
131
|
+
@props(['type' => 'info', 'message'])
|
|
132
|
+
|
|
133
|
+
@php
|
|
134
|
+
$colors = match($type) {
|
|
135
|
+
'success' => 'bg-green-50 text-green-800 dark:bg-green-900/20 dark:text-green-400',
|
|
136
|
+
'error' => 'bg-red-50 text-red-800 dark:bg-red-900/20 dark:text-red-400',
|
|
137
|
+
default => 'bg-blue-50 text-blue-800 dark:bg-blue-900/20 dark:text-blue-400',
|
|
138
|
+
};
|
|
139
|
+
@endphp
|
|
140
|
+
|
|
141
|
+
<div class="p-4 rounded-lg border {{ $colors }}" role="alert">
|
|
142
|
+
<span class="text-sm font-medium">{{ $message }}</span>
|
|
143
|
+
</div>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Usage:
|
|
147
|
+
```blade
|
|
148
|
+
<x-alert type="success" message="Order saved successfully" />
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## htmx Integration Pattern
|
|
154
|
+
|
|
155
|
+
For partial page updates, controllers return Blade fragment views:
|
|
156
|
+
|
|
157
|
+
```php
|
|
158
|
+
// Fragment controller method
|
|
159
|
+
public function search(Request $request): View
|
|
160
|
+
{
|
|
161
|
+
$results = $this->orderService->search($request->input('q'));
|
|
162
|
+
return view('order::fragments.search-results', ['items' => $results]);
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```blade
|
|
167
|
+
{{-- In the page template --}}
|
|
168
|
+
<input type="search" name="q"
|
|
169
|
+
hx-get="{{ route('order.fragments.search') }}"
|
|
170
|
+
hx-target="#results"
|
|
171
|
+
hx-trigger="keyup changed delay:300ms" />
|
|
172
|
+
<div id="results">
|
|
173
|
+
@each('order::fragments.order-row', $items, 'item')
|
|
174
|
+
</div>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### htmx Request Detection
|
|
178
|
+
|
|
179
|
+
Detect htmx requests to return fragments vs full pages:
|
|
180
|
+
|
|
181
|
+
```php
|
|
182
|
+
// In a controller or middleware
|
|
183
|
+
if ($request->header('HX-Request')) {
|
|
184
|
+
return view('order::fragments.order-row', ['item' => $order]);
|
|
185
|
+
}
|
|
186
|
+
return view('order::pages.show', new OrderDetailViewModel($order));
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### htmx Error Handling
|
|
190
|
+
|
|
191
|
+
Global error handler detects htmx requests and returns toast triggers instead of error pages:
|
|
192
|
+
|
|
193
|
+
```php
|
|
194
|
+
// In app/Exceptions/Handler.php
|
|
195
|
+
public function render($request, Throwable $e)
|
|
196
|
+
{
|
|
197
|
+
if ($request->header('HX-Request')) {
|
|
198
|
+
return response('', $e->getCode() ?: 500)
|
|
199
|
+
->header('HX-Trigger', json_encode([
|
|
200
|
+
'showToast' => [
|
|
201
|
+
'type' => 'error',
|
|
202
|
+
'message' => $e->getMessage(),
|
|
203
|
+
],
|
|
204
|
+
]));
|
|
205
|
+
}
|
|
206
|
+
return parent::render($request, $e);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Asset Resolution
|
|
213
|
+
|
|
214
|
+
Laravel's Vite plugin handles manifest resolution automatically. Templates include assets
|
|
215
|
+
via Blade directives:
|
|
216
|
+
|
|
217
|
+
```blade
|
|
218
|
+
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
In development, Vite's dev server provides HMR. In production, `@vite` reads the manifest
|
|
222
|
+
and generates hashed URLs automatically.
|
|
223
|
+
|
|
224
|
+
For CSP nonce integration:
|
|
225
|
+
```blade
|
|
226
|
+
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
227
|
+
{{-- Vite automatically includes nonce when configured --}}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Configure in `app/Providers/AppServiceProvider.php`:
|
|
231
|
+
```php
|
|
232
|
+
use Illuminate\Support\Facades\Vite;
|
|
233
|
+
|
|
234
|
+
public function boot(): void
|
|
235
|
+
{
|
|
236
|
+
Vite::useCspNonce();
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Pagination Contract
|
|
243
|
+
|
|
244
|
+
All list endpoints must be paginated. The pagination flow:
|
|
245
|
+
|
|
246
|
+
1. Controller calls `->paginate($perPage)` on Eloquent query
|
|
247
|
+
2. `LengthAwarePaginator` is returned with data + pagination metadata
|
|
248
|
+
3. Blade template renders the custom pagination component
|
|
249
|
+
|
|
250
|
+
Default page size: 20. Maximum page size: 100.
|
|
251
|
+
|
|
252
|
+
```php
|
|
253
|
+
// In controller
|
|
254
|
+
$items = $this->service->list(
|
|
255
|
+
page: $request->integer('page', 1),
|
|
256
|
+
perPage: min($request->integer('per_page', 20), 100),
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// In Blade
|
|
260
|
+
<x-pagination :paginator="$items" />
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Form Request Validation
|
|
266
|
+
|
|
267
|
+
Each form submission uses a dedicated Form Request class for validation:
|
|
268
|
+
|
|
269
|
+
```php
|
|
270
|
+
namespace Modules\Order\Http\Requests;
|
|
271
|
+
|
|
272
|
+
use Illuminate\Foundation\Http\FormRequest;
|
|
273
|
+
|
|
274
|
+
class StoreOrderRequest extends FormRequest
|
|
275
|
+
{
|
|
276
|
+
public function authorize(): bool
|
|
277
|
+
{
|
|
278
|
+
return true; // Authorization handled by middleware
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
public function rules(): array
|
|
282
|
+
{
|
|
283
|
+
return [
|
|
284
|
+
'customer_id' => ['required', 'string', 'max:36'],
|
|
285
|
+
'items' => ['required', 'array', 'min:1'],
|
|
286
|
+
'items.*.product_id' => ['required', 'string'],
|
|
287
|
+
'items.*.quantity' => ['required', 'integer', 'min:1'],
|
|
288
|
+
];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Validation errors are automatically available in Blade via `$errors`:
|
|
294
|
+
```blade
|
|
295
|
+
<x-form-control label="Customer" name="customer_id" :required="true">
|
|
296
|
+
<x-input name="customer_id" :value="old('customer_id')" />
|
|
297
|
+
@error('customer_id')
|
|
298
|
+
<p class="text-xs text-red-500 mt-1">{{ $message }}</p>
|
|
299
|
+
@enderror
|
|
300
|
+
</x-form-control>
|
|
301
|
+
```
|