@mohammadhprp/system-prompt 0.10.1
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/LICENSE +21 -0
- package/README.md +35 -0
- package/bin/system-prompt.js +8 -0
- package/framework/README.md +163 -0
- package/framework/agents/README.md +49 -0
- package/framework/agents/backend-architect.md +146 -0
- package/framework/agents/researcher.md +79 -0
- package/framework/agents/reviewer.md +183 -0
- package/framework/agents/security-auditor.md +131 -0
- package/framework/commands/README.md +43 -0
- package/framework/commands/changelog.md +44 -0
- package/framework/commands/commit.md +31 -0
- package/framework/commands/learn.md +24 -0
- package/framework/commands/mr.md +46 -0
- package/framework/commands/pr.md +39 -0
- package/framework/commands/release.md +34 -0
- package/framework/commands/review.md +24 -0
- package/framework/commands/summarize-changes.md +49 -0
- package/framework/mcps/README.md +78 -0
- package/framework/mcps/excalidraw/README.md +37 -0
- package/framework/mcps/excalidraw/capabilities.md +54 -0
- package/framework/mcps/excalidraw/configs/opencode.json +8 -0
- package/framework/mcps/excalidraw/install.md +92 -0
- package/framework/mcps/excalidraw/troubleshooting.md +67 -0
- package/framework/mcps/figma-mcp-go/README.md +51 -0
- package/framework/mcps/figma-mcp-go/capabilities.md +190 -0
- package/framework/mcps/figma-mcp-go/configs/opencode.json +9 -0
- package/framework/mcps/figma-mcp-go/install.md +74 -0
- package/framework/mcps/figma-mcp-go/troubleshooting.md +99 -0
- package/framework/mcps/github-mcp/README.md +51 -0
- package/framework/mcps/github-mcp/capabilities.md +83 -0
- package/framework/mcps/github-mcp/configs/.env.example +1 -0
- package/framework/mcps/github-mcp/configs/opencode.json +13 -0
- package/framework/mcps/github-mcp/install.md +60 -0
- package/framework/mcps/github-mcp/troubleshooting.md +79 -0
- package/framework/mcps/gitlab-mcp/README.md +54 -0
- package/framework/mcps/gitlab-mcp/capabilities.md +216 -0
- package/framework/mcps/gitlab-mcp/configs/.env.example +2 -0
- package/framework/mcps/gitlab-mcp/configs/opencode.json +13 -0
- package/framework/mcps/gitlab-mcp/install.md +99 -0
- package/framework/mcps/gitlab-mcp/troubleshooting.md +116 -0
- package/framework/mcps/jira-mcp/README.md +53 -0
- package/framework/mcps/jira-mcp/capabilities.md +79 -0
- package/framework/mcps/jira-mcp/configs/.env.example +2 -0
- package/framework/mcps/jira-mcp/configs/opencode.json +13 -0
- package/framework/mcps/jira-mcp/install.md +94 -0
- package/framework/mcps/jira-mcp/troubleshooting.md +113 -0
- package/framework/mcps/laravel-boost/README.md +53 -0
- package/framework/mcps/laravel-boost/capabilities.md +92 -0
- package/framework/mcps/laravel-boost/configs/opencode.json +9 -0
- package/framework/mcps/laravel-boost/install.md +106 -0
- package/framework/mcps/laravel-boost/troubleshooting.md +119 -0
- package/framework/mcps/notion-mcp/README.md +58 -0
- package/framework/mcps/notion-mcp/capabilities.md +118 -0
- package/framework/mcps/notion-mcp/configs/opencode.json +9 -0
- package/framework/mcps/notion-mcp/install.md +70 -0
- package/framework/mcps/notion-mcp/troubleshooting.md +95 -0
- package/framework/mcps/playwright-mcp/README.md +50 -0
- package/framework/mcps/playwright-mcp/capabilities.md +149 -0
- package/framework/mcps/playwright-mcp/configs/opencode.json +9 -0
- package/framework/mcps/playwright-mcp/install.md +136 -0
- package/framework/mcps/playwright-mcp/troubleshooting.md +154 -0
- package/framework/mcps/supabase-mcp/README.md +66 -0
- package/framework/mcps/supabase-mcp/capabilities.md +127 -0
- package/framework/mcps/supabase-mcp/configs/opencode.json +9 -0
- package/framework/mcps/supabase-mcp/install.md +85 -0
- package/framework/mcps/supabase-mcp/troubleshooting.md +113 -0
- package/framework/memory/README.md +17 -0
- package/framework/memory/codebase-insights.md +6 -0
- package/framework/memory/user-preferences.md +5 -0
- package/framework/modes/README.md +52 -0
- package/framework/modes/audit.md +88 -0
- package/framework/plugins/README.md +65 -0
- package/framework/plugins/opencode-goal-plugin/README.md +45 -0
- package/framework/plugins/opencode-goal-plugin/capabilities.md +127 -0
- package/framework/plugins/opencode-goal-plugin/install.md +71 -0
- package/framework/plugins/opencode-goal-plugin/troubleshooting.md +112 -0
- package/framework/plugins/ponytail/README.md +44 -0
- package/framework/plugins/ponytail/capabilities.md +112 -0
- package/framework/plugins/ponytail/install.md +77 -0
- package/framework/plugins/ponytail/troubleshooting.md +116 -0
- package/framework/references/standards/api.md +44 -0
- package/framework/references/standards/architecture.md +43 -0
- package/framework/references/standards/database.md +43 -0
- package/framework/references/standards/debugging.md +44 -0
- package/framework/references/standards/documentation.md +43 -0
- package/framework/references/standards/logging.md +43 -0
- package/framework/references/standards/naming.md +43 -0
- package/framework/references/standards/observability.md +43 -0
- package/framework/references/standards/performance.md +43 -0
- package/framework/references/standards/pull-requests.md +43 -0
- package/framework/references/standards/security.md +43 -0
- package/framework/references/standards/testing.md +43 -0
- package/framework/references/templates/adr.md +28 -0
- package/framework/references/templates/api-spec.md +56 -0
- package/framework/references/templates/design-document.md +39 -0
- package/framework/references/templates/incident-report.md +38 -0
- package/framework/references/templates/postmortem.md +41 -0
- package/framework/references/templates/pull-request.md +34 -0
- package/framework/references/templates/runbook.md +48 -0
- package/framework/references/templates/task.md +27 -0
- package/framework/skills/README.md +68 -0
- package/framework/skills/agent-browser/SKILL.md +51 -0
- package/framework/skills/backend-best-practices/SKILL.md +136 -0
- package/framework/skills/backend-best-practices/examples.md +31 -0
- package/framework/skills/backend-best-practices/references/api-design.md +79 -0
- package/framework/skills/backend-best-practices/references/architecture-review.md +77 -0
- package/framework/skills/backend-best-practices/references/database-design.md +78 -0
- package/framework/skills/backend-best-practices/references/debugging.md +76 -0
- package/framework/skills/backend-best-practices/references/observability.md +78 -0
- package/framework/skills/backend-best-practices/references/performance.md +78 -0
- package/framework/skills/backend-best-practices/references/refactoring.md +77 -0
- package/framework/skills/backend-best-practices/references/security.md +80 -0
- package/framework/skills/backend-best-practices/references/testing.md +77 -0
- package/framework/skills/backend-engineer/SKILL.md +76 -0
- package/framework/skills/backend-engineer/examples.md +31 -0
- package/framework/skills/brainstorming/SKILL.md +159 -0
- package/framework/skills/brainstorming/examples.md +49 -0
- package/framework/skills/brainstorming/scripts/frame-template.html +213 -0
- package/framework/skills/brainstorming/scripts/helper.js +167 -0
- package/framework/skills/brainstorming/scripts/server.cjs +723 -0
- package/framework/skills/brainstorming/scripts/start-server.sh +209 -0
- package/framework/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/framework/skills/brainstorming/visual-companion.md +291 -0
- package/framework/skills/brand-guidelines/LICENSE.txt +202 -0
- package/framework/skills/brand-guidelines/SKILL.md +73 -0
- package/framework/skills/code-review/SKILL.md +72 -0
- package/framework/skills/code-review/examples.md +31 -0
- package/framework/skills/design/SKILL.md +399 -0
- package/framework/skills/design/examples.md +34 -0
- package/framework/skills/diagram-design/SKILL.md +485 -0
- package/framework/skills/diagram-design/assets/example-architecture-dark.html +180 -0
- package/framework/skills/diagram-design/assets/example-architecture-full.html +192 -0
- package/framework/skills/diagram-design/assets/example-architecture.html +181 -0
- package/framework/skills/diagram-design/assets/example-bar-dark.html +127 -0
- package/framework/skills/diagram-design/assets/example-bar-full.html +103 -0
- package/framework/skills/diagram-design/assets/example-bar.html +127 -0
- package/framework/skills/diagram-design/assets/example-data-flow-dark.html +143 -0
- package/framework/skills/diagram-design/assets/example-data-flow-full.html +185 -0
- package/framework/skills/diagram-design/assets/example-data-flow.html +143 -0
- package/framework/skills/diagram-design/assets/example-datalake-dark.html +241 -0
- package/framework/skills/diagram-design/assets/example-datalake-full.html +246 -0
- package/framework/skills/diagram-design/assets/example-datalake.html +267 -0
- package/framework/skills/diagram-design/assets/example-dp-integration-dark.html +78 -0
- package/framework/skills/diagram-design/assets/example-dp-integration-full.html +88 -0
- package/framework/skills/diagram-design/assets/example-dp-integration.html +78 -0
- package/framework/skills/diagram-design/assets/example-dp-security-matrix-dark.html +31 -0
- package/framework/skills/diagram-design/assets/example-dp-security-matrix-full.html +32 -0
- package/framework/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
- package/framework/skills/diagram-design/assets/example-er-dark.html +200 -0
- package/framework/skills/diagram-design/assets/example-er-full.html +203 -0
- package/framework/skills/diagram-design/assets/example-er.html +200 -0
- package/framework/skills/diagram-design/assets/example-flowchart-dark.html +154 -0
- package/framework/skills/diagram-design/assets/example-flowchart-full.html +157 -0
- package/framework/skills/diagram-design/assets/example-flowchart.html +154 -0
- package/framework/skills/diagram-design/assets/example-gantt-dark.html +135 -0
- package/framework/skills/diagram-design/assets/example-gantt-full.html +125 -0
- package/framework/skills/diagram-design/assets/example-gantt.html +135 -0
- package/framework/skills/diagram-design/assets/example-high-level-dark.html +249 -0
- package/framework/skills/diagram-design/assets/example-high-level-full.html +245 -0
- package/framework/skills/diagram-design/assets/example-high-level-vertical-dark.html +272 -0
- package/framework/skills/diagram-design/assets/example-high-level-vertical-full.html +250 -0
- package/framework/skills/diagram-design/assets/example-high-level-vertical.html +323 -0
- package/framework/skills/diagram-design/assets/example-high-level.html +299 -0
- package/framework/skills/diagram-design/assets/example-it-state-dark.html +90 -0
- package/framework/skills/diagram-design/assets/example-it-state-full.html +69 -0
- package/framework/skills/diagram-design/assets/example-it-state.html +128 -0
- package/framework/skills/diagram-design/assets/example-layers-dark.html +121 -0
- package/framework/skills/diagram-design/assets/example-layers-full.html +124 -0
- package/framework/skills/diagram-design/assets/example-layers.html +121 -0
- package/framework/skills/diagram-design/assets/example-line-dark.html +109 -0
- package/framework/skills/diagram-design/assets/example-line-full.html +103 -0
- package/framework/skills/diagram-design/assets/example-line.html +109 -0
- package/framework/skills/diagram-design/assets/example-loop-dark.html +100 -0
- package/framework/skills/diagram-design/assets/example-loop-full.html +137 -0
- package/framework/skills/diagram-design/assets/example-loop-terminal.html +347 -0
- package/framework/skills/diagram-design/assets/example-loop.html +100 -0
- package/framework/skills/diagram-design/assets/example-medallion-dark.html +159 -0
- package/framework/skills/diagram-design/assets/example-medallion-full.html +201 -0
- package/framework/skills/diagram-design/assets/example-medallion.html +159 -0
- package/framework/skills/diagram-design/assets/example-nested-dark.html +130 -0
- package/framework/skills/diagram-design/assets/example-nested-full.html +133 -0
- package/framework/skills/diagram-design/assets/example-nested.html +134 -0
- package/framework/skills/diagram-design/assets/example-org-chart-dark.html +45 -0
- package/framework/skills/diagram-design/assets/example-org-chart-full.html +45 -0
- package/framework/skills/diagram-design/assets/example-org-chart.html +45 -0
- package/framework/skills/diagram-design/assets/example-process-dark.html +62 -0
- package/framework/skills/diagram-design/assets/example-process-full.html +72 -0
- package/framework/skills/diagram-design/assets/example-process.html +62 -0
- package/framework/skills/diagram-design/assets/example-pyramid-dark.html +117 -0
- package/framework/skills/diagram-design/assets/example-pyramid-full.html +120 -0
- package/framework/skills/diagram-design/assets/example-pyramid.html +117 -0
- package/framework/skills/diagram-design/assets/example-quadrant-consultant.html +164 -0
- package/framework/skills/diagram-design/assets/example-quadrant-dark.html +133 -0
- package/framework/skills/diagram-design/assets/example-quadrant-full.html +136 -0
- package/framework/skills/diagram-design/assets/example-quadrant.html +133 -0
- package/framework/skills/diagram-design/assets/example-radar-dark.html +137 -0
- package/framework/skills/diagram-design/assets/example-radar-full.html +133 -0
- package/framework/skills/diagram-design/assets/example-radar.html +137 -0
- package/framework/skills/diagram-design/assets/example-scatter-dark.html +139 -0
- package/framework/skills/diagram-design/assets/example-scatter-full.html +114 -0
- package/framework/skills/diagram-design/assets/example-scatter.html +139 -0
- package/framework/skills/diagram-design/assets/example-sequence-dark.html +220 -0
- package/framework/skills/diagram-design/assets/example-sequence-full.html +386 -0
- package/framework/skills/diagram-design/assets/example-sequence.html +220 -0
- package/framework/skills/diagram-design/assets/example-state-dark.html +145 -0
- package/framework/skills/diagram-design/assets/example-state-full.html +148 -0
- package/framework/skills/diagram-design/assets/example-state.html +145 -0
- package/framework/skills/diagram-design/assets/example-swimlane-dark.html +170 -0
- package/framework/skills/diagram-design/assets/example-swimlane-full.html +173 -0
- package/framework/skills/diagram-design/assets/example-swimlane.html +170 -0
- package/framework/skills/diagram-design/assets/example-timeline-dark.html +133 -0
- package/framework/skills/diagram-design/assets/example-timeline-full.html +136 -0
- package/framework/skills/diagram-design/assets/example-timeline.html +133 -0
- package/framework/skills/diagram-design/assets/example-tree-dark.html +171 -0
- package/framework/skills/diagram-design/assets/example-tree-full.html +174 -0
- package/framework/skills/diagram-design/assets/example-tree.html +171 -0
- package/framework/skills/diagram-design/assets/example-venn-dark.html +130 -0
- package/framework/skills/diagram-design/assets/example-venn-full.html +133 -0
- package/framework/skills/diagram-design/assets/example-venn.html +108 -0
- package/framework/skills/diagram-design/assets/icons.html +230 -0
- package/framework/skills/diagram-design/assets/index.html +333 -0
- package/framework/skills/diagram-design/assets/template-dark.html +82 -0
- package/framework/skills/diagram-design/assets/template-full.html +410 -0
- package/framework/skills/diagram-design/assets/template-terminal.html +170 -0
- package/framework/skills/diagram-design/assets/template.html +83 -0
- package/framework/skills/diagram-design/references/export.md +107 -0
- package/framework/skills/diagram-design/references/onboarding.md +268 -0
- package/framework/skills/diagram-design/references/primitive-annotation.md +36 -0
- package/framework/skills/diagram-design/references/primitive-icons.md +821 -0
- package/framework/skills/diagram-design/references/primitive-sketchy.md +43 -0
- package/framework/skills/diagram-design/references/primitive-terminal.md +76 -0
- package/framework/skills/diagram-design/references/style-guide.md +139 -0
- package/framework/skills/diagram-design/references/type-architecture.md +78 -0
- package/framework/skills/diagram-design/references/type-bar.md +48 -0
- package/framework/skills/diagram-design/references/type-data-flow.md +374 -0
- package/framework/skills/diagram-design/references/type-dp-integration.md +410 -0
- package/framework/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
- package/framework/skills/diagram-design/references/type-er.md +23 -0
- package/framework/skills/diagram-design/references/type-flowchart.md +23 -0
- package/framework/skills/diagram-design/references/type-gantt.md +45 -0
- package/framework/skills/diagram-design/references/type-high-level.md +458 -0
- package/framework/skills/diagram-design/references/type-it-state.md +470 -0
- package/framework/skills/diagram-design/references/type-layers.md +26 -0
- package/framework/skills/diagram-design/references/type-line.md +44 -0
- package/framework/skills/diagram-design/references/type-loop.md +223 -0
- package/framework/skills/diagram-design/references/type-medallion.md +356 -0
- package/framework/skills/diagram-design/references/type-nested.md +22 -0
- package/framework/skills/diagram-design/references/type-org-chart.md +44 -0
- package/framework/skills/diagram-design/references/type-process.md +495 -0
- package/framework/skills/diagram-design/references/type-pyramid.md +33 -0
- package/framework/skills/diagram-design/references/type-quadrant.md +81 -0
- package/framework/skills/diagram-design/references/type-radar.md +80 -0
- package/framework/skills/diagram-design/references/type-scatter.md +39 -0
- package/framework/skills/diagram-design/references/type-sequence.md +35 -0
- package/framework/skills/diagram-design/references/type-state.md +21 -0
- package/framework/skills/diagram-design/references/type-swimlane.md +20 -0
- package/framework/skills/diagram-design/references/type-timeline.md +20 -0
- package/framework/skills/diagram-design/references/type-tree.md +24 -0
- package/framework/skills/diagram-design/references/type-venn.md +26 -0
- package/framework/skills/documentation/SKILL.md +74 -0
- package/framework/skills/documentation/examples.md +31 -0
- package/framework/skills/find-skills/SKILL.md +141 -0
- package/framework/skills/find-skills/examples.md +35 -0
- package/framework/skills/gitlab-mcp/SKILL.md +83 -0
- package/framework/skills/gitlab-mcp/examples.md +31 -0
- package/framework/skills/gitlab-mcp/references/code-review.md +110 -0
- package/framework/skills/gitlab-mcp/references/issues.md +141 -0
- package/framework/skills/gitlab-mcp/references/merge-requests.md +120 -0
- package/framework/skills/gitlab-mcp/references/pipelines.md +67 -0
- package/framework/skills/gitlab-mcp/references/search.md +17 -0
- package/framework/skills/gitlab-mcp/references/webhooks.md +32 -0
- package/framework/skills/gitlab-mcp/references/work-items.md +50 -0
- package/framework/skills/jira-mcp/SKILL.md +57 -0
- package/framework/skills/jira-mcp/examples.md +31 -0
- package/framework/skills/jira-mcp/references/comments.md +27 -0
- package/framework/skills/jira-mcp/references/issues.md +97 -0
- package/framework/skills/jira-mcp/references/projects.md +39 -0
- package/framework/skills/laravel-best-practices/SKILL.md +229 -0
- package/framework/skills/laravel-best-practices/examples.md +31 -0
- package/framework/skills/laravel-best-practices/references/advanced-queries.md +106 -0
- package/framework/skills/laravel-best-practices/references/architecture.md +202 -0
- package/framework/skills/laravel-best-practices/references/blade-views.md +36 -0
- package/framework/skills/laravel-best-practices/references/caching.md +70 -0
- package/framework/skills/laravel-best-practices/references/collections.md +44 -0
- package/framework/skills/laravel-best-practices/references/config.md +73 -0
- package/framework/skills/laravel-best-practices/references/db-performance.md +192 -0
- package/framework/skills/laravel-best-practices/references/eloquent.md +148 -0
- package/framework/skills/laravel-best-practices/references/error-handling.md +72 -0
- package/framework/skills/laravel-best-practices/references/events-notifications.md +52 -0
- package/framework/skills/laravel-best-practices/references/http-client.md +160 -0
- package/framework/skills/laravel-best-practices/references/mail.md +27 -0
- package/framework/skills/laravel-best-practices/references/migrations.md +121 -0
- package/framework/skills/laravel-best-practices/references/passport.md +197 -0
- package/framework/skills/laravel-best-practices/references/pennant.md +61 -0
- package/framework/skills/laravel-best-practices/references/pest-testing.md +166 -0
- package/framework/skills/laravel-best-practices/references/pulse.md +196 -0
- package/framework/skills/laravel-best-practices/references/queue-jobs.md +144 -0
- package/framework/skills/laravel-best-practices/references/routing.md +99 -0
- package/framework/skills/laravel-best-practices/references/scheduling.md +39 -0
- package/framework/skills/laravel-best-practices/references/scout.md +176 -0
- package/framework/skills/laravel-best-practices/references/security.md +198 -0
- package/framework/skills/laravel-best-practices/references/spatie-laravel-backup.md +222 -0
- package/framework/skills/laravel-best-practices/references/spatie-laravel-permission.md +272 -0
- package/framework/skills/laravel-best-practices/references/spatie-medialibrary.md +672 -0
- package/framework/skills/laravel-best-practices/references/style.md +125 -0
- package/framework/skills/laravel-best-practices/references/tailwindcss.md +112 -0
- package/framework/skills/laravel-best-practices/references/testing.md +43 -0
- package/framework/skills/laravel-best-practices/references/validation.md +75 -0
- package/framework/skills/lavish/SKILL.md +67 -0
- package/framework/skills/lavish/examples.md +31 -0
- package/framework/skills/notion-mcp/SKILL.md +57 -0
- package/framework/skills/notion-mcp/examples.md +31 -0
- package/framework/skills/notion-mcp/references/comments.md +112 -0
- package/framework/skills/notion-mcp/references/databases.md +193 -0
- package/framework/skills/notion-mcp/references/pages.md +235 -0
- package/framework/skills/skill-creator/LICENSE.txt +202 -0
- package/framework/skills/skill-creator/SKILL.md +485 -0
- package/framework/skills/skill-creator/agents/analyzer.md +274 -0
- package/framework/skills/skill-creator/agents/comparator.md +202 -0
- package/framework/skills/skill-creator/agents/grader.md +223 -0
- package/framework/skills/skill-creator/assets/eval_review.html +146 -0
- package/framework/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/framework/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/framework/skills/skill-creator/examples.md +31 -0
- package/framework/skills/skill-creator/references/schemas.md +430 -0
- package/framework/skills/skill-creator/scripts/__init__.py +0 -0
- package/framework/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/framework/skills/skill-creator/scripts/generate_report.py +326 -0
- package/framework/skills/skill-creator/scripts/improve_description.py +247 -0
- package/framework/skills/skill-creator/scripts/package_skill.py +136 -0
- package/framework/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/framework/skills/skill-creator/scripts/run_eval.py +310 -0
- package/framework/skills/skill-creator/scripts/run_loop.py +328 -0
- package/framework/skills/skill-creator/scripts/utils.py +47 -0
- package/framework/styles/README.md +35 -0
- package/framework/styles/linear/DESIGN.md +478 -0
- package/framework/styles/linear/README.md +36 -0
- package/framework/styles/linear/assets/preview.jpg +0 -0
- package/framework/styles/raycast/DESIGN.md +495 -0
- package/framework/styles/raycast/README.md +35 -0
- package/framework/styles/raycast/assets/preview.jpg +0 -0
- package/package.json +33 -0
- package/src/agent-configs.js +96 -0
- package/src/catalog.js +145 -0
- package/src/cli.js +254 -0
- package/src/installer.js +303 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Architecture Best Practices
|
|
2
|
+
|
|
3
|
+
## Single-Purpose Action Classes
|
|
4
|
+
|
|
5
|
+
Extract discrete business operations into invokable Action classes.
|
|
6
|
+
|
|
7
|
+
```php
|
|
8
|
+
class CreateOrderAction
|
|
9
|
+
{
|
|
10
|
+
public function __construct(private InventoryService $inventory) {}
|
|
11
|
+
|
|
12
|
+
public function execute(array $data): Order
|
|
13
|
+
{
|
|
14
|
+
$order = Order::create($data);
|
|
15
|
+
$this->inventory->reserve($order);
|
|
16
|
+
|
|
17
|
+
return $order;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Use Dependency Injection
|
|
23
|
+
|
|
24
|
+
Always use constructor injection. Avoid `app()` or `resolve()` inside classes.
|
|
25
|
+
|
|
26
|
+
Incorrect:
|
|
27
|
+
```php
|
|
28
|
+
class OrderController extends Controller
|
|
29
|
+
{
|
|
30
|
+
public function store(StoreOrderRequest $request)
|
|
31
|
+
{
|
|
32
|
+
$service = app(OrderService::class);
|
|
33
|
+
|
|
34
|
+
return $service->create($request->validated());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Correct:
|
|
40
|
+
```php
|
|
41
|
+
class OrderController extends Controller
|
|
42
|
+
{
|
|
43
|
+
public function __construct(private OrderService $service) {}
|
|
44
|
+
|
|
45
|
+
public function store(StoreOrderRequest $request)
|
|
46
|
+
{
|
|
47
|
+
return $this->service->create($request->validated());
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Code to Interfaces
|
|
53
|
+
|
|
54
|
+
Depend on contracts at system boundaries (payment gateways, notification channels, external APIs) for testability and swappability.
|
|
55
|
+
|
|
56
|
+
Incorrect (concrete dependency):
|
|
57
|
+
```php
|
|
58
|
+
class OrderService
|
|
59
|
+
{
|
|
60
|
+
public function __construct(private StripeGateway $gateway) {}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Correct (interface dependency):
|
|
65
|
+
```php
|
|
66
|
+
interface PaymentGateway
|
|
67
|
+
{
|
|
68
|
+
public function charge(int $amount, string $customerId): PaymentResult;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class OrderService
|
|
72
|
+
{
|
|
73
|
+
public function __construct(private PaymentGateway $gateway) {}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Bind in a service provider:
|
|
78
|
+
|
|
79
|
+
```php
|
|
80
|
+
$this->app->bind(PaymentGateway::class, StripeGateway::class);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Default Sort by Descending
|
|
84
|
+
|
|
85
|
+
When no explicit order is specified, sort by `id` or `created_at` descending. Without an explicit `ORDER BY`, row order is undefined.
|
|
86
|
+
|
|
87
|
+
Incorrect:
|
|
88
|
+
```php
|
|
89
|
+
$posts = Post::paginate();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Correct:
|
|
93
|
+
```php
|
|
94
|
+
$posts = Post::latest()->paginate();
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Use Atomic Locks for Race Conditions
|
|
98
|
+
|
|
99
|
+
Prevent race conditions with `Cache::lock()` or `lockForUpdate()`.
|
|
100
|
+
|
|
101
|
+
```php
|
|
102
|
+
Cache::lock('order-processing-'.$order->id, 10)->block(5, function () use ($order) {
|
|
103
|
+
$order->process();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Or at query level
|
|
107
|
+
$product = Product::where('id', $id)->lockForUpdate()->first();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Use `mb_*` String Functions
|
|
111
|
+
|
|
112
|
+
When no Laravel helper exists, prefer `mb_strlen`, `mb_strtolower`, etc. for UTF-8 safety. Standard PHP string functions count bytes, not characters.
|
|
113
|
+
|
|
114
|
+
Incorrect:
|
|
115
|
+
```php
|
|
116
|
+
strlen('José'); // 5 (bytes, not characters)
|
|
117
|
+
strtolower('MÜNCHEN'); // 'mÜnchen' — fails on multibyte
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Correct:
|
|
121
|
+
```php
|
|
122
|
+
mb_strlen('José'); // 4 (characters)
|
|
123
|
+
mb_strtolower('MÜNCHEN'); // 'münchen'
|
|
124
|
+
|
|
125
|
+
// Prefer Laravel's Str helpers when available
|
|
126
|
+
Str::length('José'); // 4
|
|
127
|
+
Str::lower('MÜNCHEN'); // 'münchen'
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Use `defer()` for Post-Response Work
|
|
131
|
+
|
|
132
|
+
For lightweight tasks that don't need to survive a crash (logging, analytics, cleanup), use `defer()` instead of dispatching a job. The callback runs after the HTTP response is sent — no queue overhead.
|
|
133
|
+
|
|
134
|
+
Incorrect (job overhead for trivial work):
|
|
135
|
+
```php
|
|
136
|
+
dispatch(new LogPageView($page));
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Correct (runs after response, same process):
|
|
140
|
+
```php
|
|
141
|
+
defer(fn () => PageView::create(['page_id' => $page->id, 'user_id' => auth()->id()]));
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use jobs when the work must survive process crashes or needs retry logic. Use `defer()` for fire-and-forget work.
|
|
145
|
+
|
|
146
|
+
## Use `Context` for Request-Scoped Data
|
|
147
|
+
|
|
148
|
+
The `Context` facade passes data through the entire request lifecycle — middleware, controllers, jobs, logs — without passing arguments manually.
|
|
149
|
+
|
|
150
|
+
```php
|
|
151
|
+
// In middleware
|
|
152
|
+
Context::add('tenant_id', $request->header('X-Tenant-ID'));
|
|
153
|
+
|
|
154
|
+
// Anywhere later — controllers, jobs, log context
|
|
155
|
+
$tenantId = Context::get('tenant_id');
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Context data automatically propagates to queued jobs and is included in log entries. Use `Context::addHidden()` for sensitive data that should be available in queued jobs but excluded from log context. If data must not leave the current process, do not store it in `Context`.
|
|
159
|
+
|
|
160
|
+
## Use `Concurrency::run()` for Parallel Execution
|
|
161
|
+
|
|
162
|
+
Run independent operations in parallel using child processes — no async libraries needed.
|
|
163
|
+
|
|
164
|
+
```php
|
|
165
|
+
use Illuminate\Support\Facades\Concurrency;
|
|
166
|
+
|
|
167
|
+
[$users, $orders] = Concurrency::run([
|
|
168
|
+
fn () => User::count(),
|
|
169
|
+
fn () => Order::where('status', 'pending')->count(),
|
|
170
|
+
]);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Each closure runs in a separate process with full Laravel access. Use for independent database queries, API calls, or computations that would otherwise run sequentially.
|
|
174
|
+
|
|
175
|
+
## Convention Over Configuration
|
|
176
|
+
|
|
177
|
+
Follow Laravel conventions. Don't override defaults unnecessarily.
|
|
178
|
+
|
|
179
|
+
Incorrect:
|
|
180
|
+
```php
|
|
181
|
+
class Customer extends Model
|
|
182
|
+
{
|
|
183
|
+
protected $table = 'Customer';
|
|
184
|
+
protected $primaryKey = 'customer_id';
|
|
185
|
+
|
|
186
|
+
public function roles(): BelongsToMany
|
|
187
|
+
{
|
|
188
|
+
return $this->belongsToMany(Role::class, 'role_customer', 'customer_id', 'role_id');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Correct:
|
|
194
|
+
```php
|
|
195
|
+
class Customer extends Model
|
|
196
|
+
{
|
|
197
|
+
public function roles(): BelongsToMany
|
|
198
|
+
{
|
|
199
|
+
return $this->belongsToMany(Role::class);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Blade & Views Best Practices
|
|
2
|
+
|
|
3
|
+
## Use `$attributes->merge()` in Component Templates
|
|
4
|
+
|
|
5
|
+
Hardcoding classes prevents consumers from adding their own. `merge()` combines class attributes cleanly.
|
|
6
|
+
|
|
7
|
+
```blade
|
|
8
|
+
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
|
|
9
|
+
{{ $message }}
|
|
10
|
+
</div>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Use `@pushOnce` for Per-Component Scripts
|
|
14
|
+
|
|
15
|
+
If a component renders inside a `@foreach`, `@push` inserts the script N times. `@pushOnce` guarantees it's included exactly once.
|
|
16
|
+
|
|
17
|
+
## Prefer Blade Components Over `@include`
|
|
18
|
+
|
|
19
|
+
`@include` shares all parent variables implicitly (hidden coupling). Components have explicit props, attribute bags, and slots.
|
|
20
|
+
|
|
21
|
+
## Use View Composers for Shared View Data
|
|
22
|
+
|
|
23
|
+
If every controller rendering a sidebar must pass `$categories`, that's duplicated code. A View Composer centralizes it.
|
|
24
|
+
|
|
25
|
+
## Use Blade Fragments for Partial Re-Renders (htmx/Turbo)
|
|
26
|
+
|
|
27
|
+
A single view can return either the full page or just a fragment, keeping routing clean.
|
|
28
|
+
|
|
29
|
+
```php
|
|
30
|
+
return view('dashboard', compact('users'))
|
|
31
|
+
->fragmentIf($request->hasHeader('HX-Request'), 'user-list');
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Use `@aware` for Deeply Nested Component Props
|
|
35
|
+
|
|
36
|
+
Avoids re-passing parent props through every level of nested components.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Caching Best Practices
|
|
2
|
+
|
|
3
|
+
## Use `Cache::remember()` Instead of Manual Get/Put
|
|
4
|
+
|
|
5
|
+
Cleaner cache-aside pattern that removes boilerplate. use `Cache::lock()` for race conditions.
|
|
6
|
+
|
|
7
|
+
Incorrect:
|
|
8
|
+
```php
|
|
9
|
+
$val = Cache::get('stats');
|
|
10
|
+
if (! $val) {
|
|
11
|
+
$val = $this->computeStats();
|
|
12
|
+
Cache::put('stats', $val, 60);
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Correct:
|
|
17
|
+
```php
|
|
18
|
+
$val = Cache::remember('stats', 60, fn () => $this->computeStats());
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Use `Cache::flexible()` for Stale-While-Revalidate
|
|
22
|
+
|
|
23
|
+
On high-traffic keys, one user always gets a slow response when the cache expires. `flexible()` serves slightly stale data while refreshing in the background.
|
|
24
|
+
|
|
25
|
+
Incorrect: `Cache::remember('users', 300, fn () => User::all());`
|
|
26
|
+
|
|
27
|
+
Correct: `Cache::flexible('users', [300, 600], fn () => User::all());` — fresh for 5 min, stale-but-served up to 10 min, refreshes via deferred function.
|
|
28
|
+
|
|
29
|
+
## Use `Cache::memo()` to Avoid Redundant Hits Within a Request
|
|
30
|
+
|
|
31
|
+
If the same cache key is read multiple times per request (e.g., a service called from multiple places), `memo()` stores the resolved value in memory.
|
|
32
|
+
|
|
33
|
+
`Cache::memo()->get('settings');` — 5 calls = 1 Redis round-trip instead of 5.
|
|
34
|
+
|
|
35
|
+
## Use Cache Tags to Invalidate Related Groups
|
|
36
|
+
|
|
37
|
+
Without tags, invalidating a group of entries requires tracking every key. Tags let you flush atomically. Only works with `redis`, `memcached`, `dynamodb` — not `file` or `database`.
|
|
38
|
+
|
|
39
|
+
```php
|
|
40
|
+
Cache::tags(['user-1'])->flush();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Use `Cache::add()` for Atomic Conditional Writes
|
|
44
|
+
|
|
45
|
+
`add()` only writes if the key does not exist — atomic, no race condition between checking and writing.
|
|
46
|
+
|
|
47
|
+
Incorrect: `if (! Cache::has('lock')) { Cache::put('lock', true, 10); }`
|
|
48
|
+
|
|
49
|
+
Correct: `Cache::add('lock', true, 10);`
|
|
50
|
+
|
|
51
|
+
## Use `once()` for Per-Request Memoization
|
|
52
|
+
|
|
53
|
+
`once()` memoizes a function's return value for the lifetime of the object (or request for closures). Unlike `Cache::memo()`, it doesn't hit the cache store at all — pure in-memory.
|
|
54
|
+
|
|
55
|
+
```php
|
|
56
|
+
public function roles(): Collection
|
|
57
|
+
{
|
|
58
|
+
return once(fn () => $this->loadRoles());
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Multiple calls return the cached result without re-executing. Use `once()` for expensive computations called multiple times per request. Use `Cache::memo()` when you also want cross-request caching.
|
|
63
|
+
|
|
64
|
+
## Configure Failover Cache Stores in Production
|
|
65
|
+
|
|
66
|
+
If Redis goes down, the app falls back to a secondary store automatically.
|
|
67
|
+
|
|
68
|
+
```php
|
|
69
|
+
'failover' => ['driver' => 'failover', 'stores' => ['redis', 'database']],
|
|
70
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Collection Best Practices
|
|
2
|
+
|
|
3
|
+
## Use Higher-Order Messages for Simple Operations
|
|
4
|
+
|
|
5
|
+
Incorrect:
|
|
6
|
+
```php
|
|
7
|
+
$users->each(function (User $user) {
|
|
8
|
+
$user->markAsVip();
|
|
9
|
+
});
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Correct: `$users->each->markAsVip();`
|
|
13
|
+
|
|
14
|
+
Works with `each`, `map`, `sum`, `filter`, `reject`, `contains`, etc.
|
|
15
|
+
|
|
16
|
+
## Choose `cursor()` vs. `lazy()` Correctly
|
|
17
|
+
|
|
18
|
+
- `cursor()` — one model in memory, but cannot eager-load relationships (N+1 risk).
|
|
19
|
+
- `lazy()` — chunked pagination returning a flat LazyCollection, supports eager loading.
|
|
20
|
+
|
|
21
|
+
Incorrect: `User::with('roles')->cursor()` — eager loading silently ignored.
|
|
22
|
+
|
|
23
|
+
Correct: `User::with('roles')->lazy()` for relationship access; `User::cursor()` for attribute-only work.
|
|
24
|
+
|
|
25
|
+
## Use `lazyById()` When Updating Records While Iterating
|
|
26
|
+
|
|
27
|
+
`lazy()` uses offset pagination — updating records during iteration can skip or double-process. `lazyById()` uses `id > last_id`, safe against mutation.
|
|
28
|
+
|
|
29
|
+
## Use `toQuery()` for Bulk Operations on Collections
|
|
30
|
+
|
|
31
|
+
Avoids manual `whereIn` construction.
|
|
32
|
+
|
|
33
|
+
Incorrect: `User::whereIn('id', $users->pluck('id'))->update([...]);`
|
|
34
|
+
|
|
35
|
+
Correct: `$users->toQuery()->update([...]);`
|
|
36
|
+
|
|
37
|
+
## Use `#[CollectedBy]` for Custom Collection Classes
|
|
38
|
+
|
|
39
|
+
More declarative than overriding `newCollection()`.
|
|
40
|
+
|
|
41
|
+
```php
|
|
42
|
+
#[CollectedBy(UserCollection::class)]
|
|
43
|
+
class User extends Model {}
|
|
44
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Configuration Best Practices
|
|
2
|
+
|
|
3
|
+
## `env()` Only in Config Files
|
|
4
|
+
|
|
5
|
+
Direct `env()` calls may return `null` when config is cached.
|
|
6
|
+
|
|
7
|
+
Incorrect:
|
|
8
|
+
```php
|
|
9
|
+
$key = env('API_KEY');
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Correct:
|
|
13
|
+
```php
|
|
14
|
+
// config/services.php
|
|
15
|
+
'key' => env('API_KEY'),
|
|
16
|
+
|
|
17
|
+
// Application code
|
|
18
|
+
$key = config('services.key');
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Use Encrypted Env or External Secrets
|
|
22
|
+
|
|
23
|
+
Never store production secrets in plain `.env` files in version control.
|
|
24
|
+
|
|
25
|
+
Incorrect:
|
|
26
|
+
```bash
|
|
27
|
+
|
|
28
|
+
# .env committed to repo or shared in Slack
|
|
29
|
+
|
|
30
|
+
STRIPE_SECRET=sk_live_abc123
|
|
31
|
+
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Correct:
|
|
35
|
+
```bash
|
|
36
|
+
php artisan env:encrypt --env=production --readable
|
|
37
|
+
php artisan env:decrypt --env=production
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For cloud deployments, prefer the platform's native secret store (AWS Secrets Manager, Vault, etc.) and inject at runtime.
|
|
41
|
+
|
|
42
|
+
## Use `App::environment()` for Environment Checks
|
|
43
|
+
|
|
44
|
+
Incorrect:
|
|
45
|
+
```php
|
|
46
|
+
if (env('APP_ENV') === 'production') {
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Correct:
|
|
50
|
+
```php
|
|
51
|
+
if (app()->isProduction()) {
|
|
52
|
+
// or
|
|
53
|
+
if (App::environment('production')) {
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Use Constants and Language Files
|
|
57
|
+
|
|
58
|
+
Use class constants instead of hardcoded magic strings for model states, types, and statuses.
|
|
59
|
+
|
|
60
|
+
```php
|
|
61
|
+
// Incorrect
|
|
62
|
+
return $this->type === 'normal';
|
|
63
|
+
|
|
64
|
+
// Correct
|
|
65
|
+
return $this->type === self::TYPE_NORMAL;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If the application already uses language files for localization, use `__()` for user-facing strings too. Do not introduce language files purely for English-only apps — simple string literals are fine there.
|
|
69
|
+
|
|
70
|
+
```php
|
|
71
|
+
// Only when lang files already exist in the project
|
|
72
|
+
return back()->with('message', __('app.article_added'));
|
|
73
|
+
```
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Database Performance Best Practices
|
|
2
|
+
|
|
3
|
+
## Always Eager Load Relationships
|
|
4
|
+
|
|
5
|
+
Lazy loading causes N+1 query problems — one query per loop iteration. Always use `with()` to load relationships upfront.
|
|
6
|
+
|
|
7
|
+
Incorrect (N+1 — executes 1 + N queries):
|
|
8
|
+
```php
|
|
9
|
+
$posts = Post::all();
|
|
10
|
+
foreach ($posts as $post) {
|
|
11
|
+
echo $post->author->name;
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Correct (2 queries total):
|
|
16
|
+
```php
|
|
17
|
+
$posts = Post::with('author')->get();
|
|
18
|
+
foreach ($posts as $post) {
|
|
19
|
+
echo $post->author->name;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Constrain eager loads to select only needed columns (always include the foreign key):
|
|
24
|
+
|
|
25
|
+
```php
|
|
26
|
+
$users = User::with(['posts' => function ($query) {
|
|
27
|
+
$query->select('id', 'user_id', 'title')
|
|
28
|
+
->where('published', true)
|
|
29
|
+
->latest()
|
|
30
|
+
->limit(10);
|
|
31
|
+
}])->get();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Prevent Lazy Loading in Development
|
|
35
|
+
|
|
36
|
+
Enable this in `AppServiceProvider::boot()` to catch N+1 issues during development.
|
|
37
|
+
|
|
38
|
+
```php
|
|
39
|
+
public function boot(): void
|
|
40
|
+
{
|
|
41
|
+
Model::preventLazyLoading(! app()->isProduction());
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Throws `LazyLoadingViolationException` when a relationship is accessed without being eager-loaded.
|
|
46
|
+
|
|
47
|
+
## Select Only Needed Columns
|
|
48
|
+
|
|
49
|
+
Avoid `SELECT *` — especially when tables have large text or JSON columns.
|
|
50
|
+
|
|
51
|
+
Incorrect:
|
|
52
|
+
```php
|
|
53
|
+
$posts = Post::with('author')->get();
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Correct:
|
|
57
|
+
```php
|
|
58
|
+
$posts = Post::select('id', 'title', 'user_id', 'created_at')
|
|
59
|
+
->with(['author:id,name,avatar'])
|
|
60
|
+
->get();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
When selecting columns on eager-loaded relationships, always include the foreign key column or the relationship won't match.
|
|
64
|
+
|
|
65
|
+
## Chunk Large Datasets
|
|
66
|
+
|
|
67
|
+
Never load thousands of records at once. Use chunking for batch processing.
|
|
68
|
+
|
|
69
|
+
Incorrect:
|
|
70
|
+
```php
|
|
71
|
+
$users = User::all();
|
|
72
|
+
foreach ($users as $user) {
|
|
73
|
+
$user->notify(new WeeklyDigest);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Correct:
|
|
78
|
+
```php
|
|
79
|
+
User::where('subscribed', true)->chunk(200, function ($users) {
|
|
80
|
+
foreach ($users as $user) {
|
|
81
|
+
$user->notify(new WeeklyDigest);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use `chunkById()` when modifying records during iteration — standard `chunk()` uses OFFSET which shifts when rows change:
|
|
87
|
+
|
|
88
|
+
```php
|
|
89
|
+
User::where('active', false)->chunkById(200, function ($users) {
|
|
90
|
+
$users->each->delete();
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Add Database Indexes
|
|
95
|
+
|
|
96
|
+
Index columns that appear in `WHERE`, `ORDER BY`, `JOIN`, and `GROUP BY` clauses.
|
|
97
|
+
|
|
98
|
+
Incorrect:
|
|
99
|
+
```php
|
|
100
|
+
Schema::create('orders', function (Blueprint $table) {
|
|
101
|
+
$table->id();
|
|
102
|
+
$table->foreignId('user_id')->constrained();
|
|
103
|
+
$table->string('status');
|
|
104
|
+
$table->timestamps();
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Correct:
|
|
109
|
+
```php
|
|
110
|
+
Schema::create('orders', function (Blueprint $table) {
|
|
111
|
+
$table->id();
|
|
112
|
+
$table->foreignId('user_id')->index()->constrained();
|
|
113
|
+
$table->string('status')->index();
|
|
114
|
+
$table->timestamps();
|
|
115
|
+
$table->index(['status', 'created_at']);
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Add composite indexes for common query patterns (e.g., `WHERE status = ? ORDER BY created_at`).
|
|
120
|
+
|
|
121
|
+
## Use `withCount()` for Counting Relations
|
|
122
|
+
|
|
123
|
+
Never load entire collections just to count them.
|
|
124
|
+
|
|
125
|
+
Incorrect:
|
|
126
|
+
```php
|
|
127
|
+
$posts = Post::all();
|
|
128
|
+
foreach ($posts as $post) {
|
|
129
|
+
echo $post->comments->count();
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Correct:
|
|
134
|
+
```php
|
|
135
|
+
$posts = Post::withCount('comments')->get();
|
|
136
|
+
foreach ($posts as $post) {
|
|
137
|
+
echo $post->comments_count;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Conditional counting:
|
|
142
|
+
|
|
143
|
+
```php
|
|
144
|
+
$posts = Post::withCount([
|
|
145
|
+
'comments',
|
|
146
|
+
'comments as approved_comments_count' => function ($query) {
|
|
147
|
+
$query->where('approved', true);
|
|
148
|
+
},
|
|
149
|
+
])->get();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Use `cursor()` for Memory-Efficient Iteration
|
|
153
|
+
|
|
154
|
+
For read-only iteration over large result sets, `cursor()` loads one record at a time via a PHP generator.
|
|
155
|
+
|
|
156
|
+
Incorrect:
|
|
157
|
+
```php
|
|
158
|
+
$users = User::where('active', true)->get();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Correct:
|
|
162
|
+
```php
|
|
163
|
+
foreach (User::where('active', true)->cursor() as $user) {
|
|
164
|
+
ProcessUser::dispatch($user->id);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Use `cursor()` for read-only iteration. Use `chunk()` / `chunkById()` when modifying records.
|
|
169
|
+
|
|
170
|
+
## No Queries in Blade Templates
|
|
171
|
+
|
|
172
|
+
Never execute queries in Blade templates. Pass data from controllers.
|
|
173
|
+
|
|
174
|
+
Incorrect:
|
|
175
|
+
```blade
|
|
176
|
+
@foreach (User::all() as $user)
|
|
177
|
+
{{ $user->profile->name }}
|
|
178
|
+
@endforeach
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Correct:
|
|
182
|
+
```php
|
|
183
|
+
// Controller
|
|
184
|
+
$users = User::with('profile')->get();
|
|
185
|
+
return view('users.index', compact('users'));
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```blade
|
|
189
|
+
@foreach ($users as $user)
|
|
190
|
+
{{ $user->profile->name }}
|
|
191
|
+
@endforeach
|
|
192
|
+
```
|