[{"data":1,"prerenderedAt":412},["ShallowReactive",2],{"page-\u002Fv1\u002Fadapters\u002Flaravel\u002Ftooling":3},{"id":4,"title":5,"body":6,"description":405,"extension":406,"meta":407,"navigation":318,"path":408,"seo":409,"stem":410,"__hash__":411},"content\u002Fv1\u002Fadapters\u002Flaravel\u002Ftooling.md","Laravel tooling",{"type":7,"value":8,"toc":398},"minimark",[9,14,18,23,68,100,104,107,128,131,155,159,166,205,208,259,265,269,290,297,350,353,357,380,394],[10,11,13],"h1",{"id":12},"tooling","Tooling",[15,16,17],"p",{},"Tooling enforces and accelerates the Laravel adapter. It does not redefine Core.",[19,20,22],"h2",{"id":21},"module-scaffolds","Module scaffolds",[24,25,30],"pre",{"className":26,"code":27,"language":28,"meta":29,"style":29},"language-bash shiki shiki-themes github-light github-dark","php artisan make:module {ModuleName}\nphp artisan make:module-model {ModuleName} {ModelName}\n","bash","",[31,32,33,52],"code",{"__ignoreMap":29},[34,35,38,42,46,49],"span",{"class":36,"line":37},"line",1,[34,39,41],{"class":40},"sScJk","php",[34,43,45],{"class":44},"sZZnC"," artisan",[34,47,48],{"class":44}," make:module",[34,50,51],{"class":44}," {ModuleName}\n",[34,53,55,57,59,62,65],{"class":36,"line":54},2,[34,56,41],{"class":40},[34,58,45],{"class":44},[34,60,61],{"class":44}," make:module-model",[34,63,64],{"class":44}," {ModuleName}",[34,66,67],{"class":44}," {ModelName}\n",[15,69,70,71,74,75,78,79,83,84,87,88,91,92,95,96,99],{},"Scaffolds should generate Application \u002F Domain \u002F Infrastructure \u002F UI, plus ",[31,72,73],{},"Ports\u002FAcl"," and ",[31,76,77],{},"Ports\u002FModule",". They must ",[80,81,82],"strong",{},"not"," create a literal ",[31,85,86],{},"Feature\u002F"," directory — ",[31,89,90],{},"{Capability}"," folders use real names (",[31,93,94],{},"Order\u002F",", ",[31,97,98],{},"Fulfillment\u002F",").",[19,101,103],{"id":102},"architecture-boundary-tests-pest","Architecture boundary tests (Pest)",[15,105,106],{},"Enforce Core cross-module isolation so Application\u002FDomain of module A cannot import Application\u002FDomain of module B.",[24,108,110],{"className":26,"code":109,"language":28,"meta":29,"style":29},"php artisan test --compact tests\u002FUnit\u002FModuleBoundaryArchTest.php\n",[31,111,112],{"__ignoreMap":29},[34,113,114,116,118,121,125],{"class":36,"line":37},[34,115,41],{"class":40},[34,117,45],{"class":44},[34,119,120],{"class":44}," test",[34,122,124],{"class":123},"sj4cs"," --compact",[34,126,127],{"class":44}," tests\u002FUnit\u002FModuleBoundaryArchTest.php\n",[15,129,130],{},"Typical guards:",[132,133,134,138,141,148],"ul",{},[135,136,137],"li",{},"No foreign module namespaces inside Application\u002FDomain",[135,139,140],{},"No Eloquent models inside Application\u002FDomain",[135,142,143,144,147],{},"No PHP under a literal ",[31,145,146],{},"*\u002FFeature\u002F"," path",[135,149,150,151,154],{},"When adding a module, append its name to the ",[31,152,153],{},"$modules"," list in the arch test",[19,156,158],{"id":157},"laravel-pint","Laravel Pint",[15,160,161,162,165],{},"Every PHP change should follow a shared ",[31,163,164],{},"pint.json"," (Laravel preset + project rules). Prefer Composer scripts:",[24,167,169],{"className":26,"code":168,"language":28,"meta":29,"style":29},"composer lint                 # .\u002Fvendor\u002Fbin\u002Fpint\n.\u002Fvendor\u002Fbin\u002Fpint --dirty     # while coding\n.\u002Fvendor\u002Fbin\u002Fpint --test      # CI check-only\n",[31,170,171,183,194],{"__ignoreMap":29},[34,172,173,176,179],{"class":36,"line":37},[34,174,175],{"class":40},"composer",[34,177,178],{"class":44}," lint",[34,180,182],{"class":181},"sJ8bj","                 # .\u002Fvendor\u002Fbin\u002Fpint\n",[34,184,185,188,191],{"class":36,"line":54},[34,186,187],{"class":40},".\u002Fvendor\u002Fbin\u002Fpint",[34,189,190],{"class":123}," --dirty",[34,192,193],{"class":181},"     # while coding\n",[34,195,197,199,202],{"class":36,"line":196},3,[34,198,187],{"class":40},[34,200,201],{"class":123}," --test",[34,203,204],{"class":181},"      # CI check-only\n",[15,206,207],{},"Useful alignments with Core naming:",[209,210,211,224],"table",{},[212,213,214],"thead",{},[215,216,217,221],"tr",{},[218,219,220],"th",{},"Area",[218,222,223],{},"Typical Pint focus",[225,226,227,240,251],"tbody",{},[215,228,229,233],{},[230,231,232],"td",{},"Class layout",[230,234,235,236,239],{},"traits → constants → properties → ",[31,237,238],{},"__construct"," → methods",[215,241,242,245],{},[230,243,244],{},"Types",[230,246,247,250],{},[31,248,249],{},"declare_strict_types",", return types",[215,252,253,256],{},[230,254,255],{},"Imports",[230,257,258],{},"ordered, unused removed",[15,260,261,262,264],{},"Pint does ",[80,263,82],{}," replace boundary tests.",[19,266,268],{"id":267},"phpstan-larastan","PHPStan \u002F Larastan",[24,270,272],{"className":26,"code":271,"language":28,"meta":29,"style":29},"composer require --dev phpstan\u002Fphpstan larastan\u002Flarastan\n",[31,273,274],{"__ignoreMap":29},[34,275,276,278,281,284,287],{"class":36,"line":37},[34,277,175],{"class":40},[34,279,280],{"class":44}," require",[34,282,283],{"class":123}," --dev",[34,285,286],{"class":44}," phpstan\u002Fphpstan",[34,288,289],{"class":44}," larastan\u002Flarastan\n",[15,291,292,293,296],{},"Example ",[31,294,295],{},"phpstan.neon"," sketch:",[24,298,302],{"className":299,"code":300,"language":301,"meta":29,"style":29},"language-neon shiki shiki-themes github-light github-dark","includes:\n    - .\u002Fvendor\u002Flarastan\u002Flarastan\u002Fextension.neon\n\nparameters:\n    phpVersion: 80400\n    level: 5\n    paths:\n        - app\n","neon",[31,303,304,309,314,320,326,332,338,344],{"__ignoreMap":29},[34,305,306],{"class":36,"line":37},[34,307,308],{},"includes:\n",[34,310,311],{"class":36,"line":54},[34,312,313],{},"    - .\u002Fvendor\u002Flarastan\u002Flarastan\u002Fextension.neon\n",[34,315,316],{"class":36,"line":196},[34,317,319],{"emptyLinePlaceholder":318},true,"\n",[34,321,323],{"class":36,"line":322},4,[34,324,325],{},"parameters:\n",[34,327,329],{"class":36,"line":328},5,[34,330,331],{},"    phpVersion: 80400\n",[34,333,335],{"class":36,"line":334},6,[34,336,337],{},"    level: 5\n",[34,339,341],{"class":36,"line":340},7,[34,342,343],{},"    paths:\n",[34,345,347],{"class":36,"line":346},8,[34,348,349],{},"        - app\n",[15,351,352],{},"Raise levels gradually. Static analysis catches illegal types that style tools miss.",[19,354,356],{"id":355},"suggested-local-loop","Suggested local loop",[358,359,360,363,368,371,377],"ol",{},[135,361,362],{},"Implement behind ports (fake\u002Fin-memory in tests).",[135,364,365],{},[31,366,367],{},".\u002Fvendor\u002Fbin\u002Fpint --dirty",[135,369,370],{},"Feature + unit tests for the Use Case.",[135,372,373,376],{},[31,374,375],{},"ModuleBoundaryArchTest"," green.",[135,378,379],{},"PHPStan on touched paths.",[15,381,382,383,388,389,393],{},"Core reference: ",[384,385,387],"a",{"href":386},"\u002Fv1\u002Fcore\u002Fanti-patterns","Anti-patterns"," · ",[384,390,392],{"href":391},"\u002Fv1\u002Fcore\u002Fdecision-tree","Decision tree",".",[395,396,397],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":29,"searchDepth":54,"depth":54,"links":399},[400,401,402,403,404],{"id":21,"depth":54,"text":22},{"id":102,"depth":54,"text":103},{"id":157,"depth":54,"text":158},{"id":267,"depth":54,"text":268},{"id":355,"depth":54,"text":356},"Pint, Pest architecture boundary tests, PHPStan\u002FLarastan, and module scaffolds for the Laravel host.","md",{},"\u002Fv1\u002Fadapters\u002Flaravel\u002Ftooling",{"title":5,"description":405},"v1\u002Fadapters\u002Flaravel\u002Ftooling","Qxc2RJDLz19lqskSTjsRp8tl6Iv7PVSP-yyD0_MCHOc",1786241414043]