@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,144 @@
|
|
|
1
|
+
# Queue & Job Best Practices
|
|
2
|
+
|
|
3
|
+
## Set `retry_after` Greater Than `timeout`
|
|
4
|
+
|
|
5
|
+
If `retry_after` is shorter than the job's `timeout`, the queue worker re-dispatches the job while it's still running, causing duplicate execution.
|
|
6
|
+
|
|
7
|
+
Incorrect (`retry_after` ≤ `timeout`):
|
|
8
|
+
```php
|
|
9
|
+
class ProcessReport implements ShouldQueue
|
|
10
|
+
{
|
|
11
|
+
public $timeout = 120;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// config/queue.php — retry_after: 90 ← job retried while still running!
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Correct (`retry_after` > `timeout`):
|
|
18
|
+
```php
|
|
19
|
+
class ProcessReport implements ShouldQueue
|
|
20
|
+
{
|
|
21
|
+
public $timeout = 120;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// config/queue.php — retry_after: 180 ← safely longer than any job timeout
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Use Exponential Backoff
|
|
28
|
+
|
|
29
|
+
Use progressively longer delays between retries to avoid hammering failing services.
|
|
30
|
+
|
|
31
|
+
Incorrect (fixed retry interval):
|
|
32
|
+
```php
|
|
33
|
+
class SyncWithStripe implements ShouldQueue
|
|
34
|
+
{
|
|
35
|
+
public $tries = 3;
|
|
36
|
+
// Default: retries immediately, overwhelming the API
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Correct (exponential backoff):
|
|
41
|
+
```php
|
|
42
|
+
class SyncWithStripe implements ShouldQueue
|
|
43
|
+
{
|
|
44
|
+
public $tries = 3;
|
|
45
|
+
public $backoff = [1, 5, 10];
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Implement `ShouldBeUnique`
|
|
50
|
+
|
|
51
|
+
Prevent duplicate job processing.
|
|
52
|
+
|
|
53
|
+
```php
|
|
54
|
+
class GenerateInvoice implements ShouldQueue, ShouldBeUnique
|
|
55
|
+
{
|
|
56
|
+
public function uniqueId(): string
|
|
57
|
+
{
|
|
58
|
+
return $this->order->id;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public $uniqueFor = 3600;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Always Implement `failed()`
|
|
66
|
+
|
|
67
|
+
Handle errors explicitly — don't rely on silent failure.
|
|
68
|
+
|
|
69
|
+
```php
|
|
70
|
+
public function failed(?Throwable $exception): void
|
|
71
|
+
{
|
|
72
|
+
$this->podcast->update(['status' => 'failed']);
|
|
73
|
+
Log::error('Processing failed', ['id' => $this->podcast->id, 'error' => $exception->getMessage()]);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Rate Limit External API Calls in Jobs
|
|
78
|
+
|
|
79
|
+
Use `RateLimited` middleware to throttle jobs calling third-party APIs.
|
|
80
|
+
|
|
81
|
+
```php
|
|
82
|
+
public function middleware(): array
|
|
83
|
+
{
|
|
84
|
+
return [new RateLimited('external-api')];
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Batch Related Jobs
|
|
89
|
+
|
|
90
|
+
Use `Bus::batch()` when jobs should succeed or fail together.
|
|
91
|
+
|
|
92
|
+
```php
|
|
93
|
+
Bus::batch([
|
|
94
|
+
new ImportCsvChunk($chunk1),
|
|
95
|
+
new ImportCsvChunk($chunk2),
|
|
96
|
+
])
|
|
97
|
+
->then(fn (Batch $batch) => Notification::send($user, new ImportComplete))
|
|
98
|
+
->catch(fn (Batch $batch, Throwable $e) => Log::error('Batch failed'))
|
|
99
|
+
->dispatch();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## `retryUntil()` Needs `$tries = 0`
|
|
103
|
+
|
|
104
|
+
When using time-based retry limits, set `$tries = 0` to avoid premature failure.
|
|
105
|
+
|
|
106
|
+
```php
|
|
107
|
+
public $tries = 0;
|
|
108
|
+
|
|
109
|
+
public function retryUntil(): \DateTimeInterface
|
|
110
|
+
{
|
|
111
|
+
return now()->addHours(4);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Use `ShouldBeUniqueUntilProcessing` for Early Lock Release
|
|
116
|
+
|
|
117
|
+
`ShouldBeUnique` holds the lock until the job completes. `ShouldBeUniqueUntilProcessing` releases it when processing starts, allowing new instances to queue.
|
|
118
|
+
|
|
119
|
+
```php
|
|
120
|
+
class UpdateSearchIndex implements ShouldQueue, ShouldBeUniqueUntilProcessing
|
|
121
|
+
{
|
|
122
|
+
// Lock releases when processing begins, not when it finishes
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Use Horizon for Complex Queue Scenarios
|
|
127
|
+
|
|
128
|
+
Use Laravel Horizon when you need monitoring, auto-scaling, failure tracking, or multiple queues with different priorities.
|
|
129
|
+
|
|
130
|
+
```php
|
|
131
|
+
// config/horizon.php
|
|
132
|
+
'environments' => [
|
|
133
|
+
'production' => [
|
|
134
|
+
'supervisor-1' => [
|
|
135
|
+
'connection' => 'redis',
|
|
136
|
+
'queue' => ['high', 'default', 'low'],
|
|
137
|
+
'balance' => 'auto',
|
|
138
|
+
'minProcesses' => 1,
|
|
139
|
+
'maxProcesses' => 10,
|
|
140
|
+
'tries' => 3,
|
|
141
|
+
],
|
|
142
|
+
],
|
|
143
|
+
],
|
|
144
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Routing & Controllers Best Practices
|
|
2
|
+
|
|
3
|
+
## Use Implicit Route Model Binding
|
|
4
|
+
|
|
5
|
+
Let Laravel resolve models automatically from route parameters.
|
|
6
|
+
|
|
7
|
+
Incorrect:
|
|
8
|
+
```php
|
|
9
|
+
public function show(int $id)
|
|
10
|
+
{
|
|
11
|
+
$post = Post::findOrFail($id);
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Correct:
|
|
16
|
+
```php
|
|
17
|
+
public function show(Post $post)
|
|
18
|
+
{
|
|
19
|
+
return view('posts.show', ['post' => $post]);
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Use Scoped Bindings for Nested Resources
|
|
24
|
+
|
|
25
|
+
Enforce parent-child relationships automatically.
|
|
26
|
+
|
|
27
|
+
```php
|
|
28
|
+
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
|
|
29
|
+
// $post is automatically scoped to $user
|
|
30
|
+
})->scopeBindings();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Use Resource Controllers
|
|
34
|
+
|
|
35
|
+
Use `Route::resource()` or `apiResource()` for RESTful endpoints.
|
|
36
|
+
|
|
37
|
+
```php
|
|
38
|
+
Route::resource('posts', PostController::class);
|
|
39
|
+
// In routes/api.php — the /api prefix is applied automatically
|
|
40
|
+
Route::apiResource('posts', Api\PostController::class);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Keep Controllers Thin
|
|
44
|
+
|
|
45
|
+
Aim for under 10 lines per method. Extract business logic to action or service classes.
|
|
46
|
+
|
|
47
|
+
Incorrect:
|
|
48
|
+
```php
|
|
49
|
+
public function store(Request $request)
|
|
50
|
+
{
|
|
51
|
+
$validated = $request->validate([...]);
|
|
52
|
+
if ($request->hasFile('image')) {
|
|
53
|
+
$request->file('image')->move(public_path('images'));
|
|
54
|
+
}
|
|
55
|
+
$post = Post::create($validated);
|
|
56
|
+
$post->tags()->sync($validated['tags']);
|
|
57
|
+
event(new PostCreated($post));
|
|
58
|
+
return redirect()->route('posts.show', $post);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Correct:
|
|
63
|
+
```php
|
|
64
|
+
public function store(StorePostRequest $request, CreatePostAction $create)
|
|
65
|
+
{
|
|
66
|
+
$post = $create->execute($request->validated());
|
|
67
|
+
|
|
68
|
+
return redirect()->route('posts.show', $post);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Type-Hint Form Requests
|
|
73
|
+
|
|
74
|
+
Type-hinting Form Requests triggers automatic validation and authorization before the method executes.
|
|
75
|
+
|
|
76
|
+
Incorrect:
|
|
77
|
+
```php
|
|
78
|
+
public function store(Request $request): RedirectResponse
|
|
79
|
+
{
|
|
80
|
+
$validated = $request->validate([
|
|
81
|
+
'title' => ['required', 'max:255'],
|
|
82
|
+
'body' => ['required'],
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
Post::create($validated);
|
|
86
|
+
|
|
87
|
+
return redirect()->route('posts.index');
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Correct:
|
|
92
|
+
```php
|
|
93
|
+
public function store(StorePostRequest $request): RedirectResponse
|
|
94
|
+
{
|
|
95
|
+
Post::create($request->validated());
|
|
96
|
+
|
|
97
|
+
return redirect()->route('posts.index');
|
|
98
|
+
}
|
|
99
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Task Scheduling Best Practices
|
|
2
|
+
|
|
3
|
+
## Use `withoutOverlapping()` on Variable-Duration Tasks
|
|
4
|
+
|
|
5
|
+
Without it, a long-running task spawns a second instance on the next tick, causing double-processing or resource exhaustion.
|
|
6
|
+
|
|
7
|
+
## Use `onOneServer()` on Multi-Server Deployments
|
|
8
|
+
|
|
9
|
+
Without it, every server runs the same task simultaneously. Requires a shared cache driver (Redis, database, Memcached).
|
|
10
|
+
|
|
11
|
+
## Use `runInBackground()` for Concurrent Long Tasks
|
|
12
|
+
|
|
13
|
+
By default, tasks at the same tick run sequentially. A slow first task delays all subsequent ones. `runInBackground()` runs them as separate processes.
|
|
14
|
+
|
|
15
|
+
## Use `environments()` to Restrict Tasks
|
|
16
|
+
|
|
17
|
+
Prevent accidental execution of production-only tasks (billing, reporting) on staging.
|
|
18
|
+
|
|
19
|
+
```php
|
|
20
|
+
Schedule::command('billing:charge')->monthly()->environments(['production']);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Use `takeUntilTimeout()` for Time-Bounded Processing
|
|
24
|
+
|
|
25
|
+
A task running every 15 minutes that processes an unbounded cursor can overlap with the next run. Bound execution time.
|
|
26
|
+
|
|
27
|
+
## Use Schedule Groups for Shared Configuration
|
|
28
|
+
|
|
29
|
+
Avoid repeating `->onOneServer()->timezone('America/New_York')` across many tasks.
|
|
30
|
+
|
|
31
|
+
```php
|
|
32
|
+
Schedule::daily()
|
|
33
|
+
->onOneServer()
|
|
34
|
+
->timezone('America/New_York')
|
|
35
|
+
->group(function () {
|
|
36
|
+
Schedule::command('emails:send --force');
|
|
37
|
+
Schedule::command('emails:prune');
|
|
38
|
+
});
|
|
39
|
+
```
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Scout Full-Text Search
|
|
2
|
+
|
|
3
|
+
## Documentation First
|
|
4
|
+
|
|
5
|
+
**Always use `search-docs` before writing Scout code.** The documentation covers every engine, configuration option, and edge case in detail. This skill teaches you how to navigate Scout — the docs have the implementation specifics.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
search-docs(queries: ["Scout installation"], packages: ["laravel/framework@12.x"])
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The Scout docs live under the `laravel/framework` package — not `laravel/scout`.
|
|
12
|
+
|
|
13
|
+
Effective search patterns:
|
|
14
|
+
|
|
15
|
+
- Installation & setup: `"Scout installation"`, `"Scout queueing"`
|
|
16
|
+
- Engine setup: `"Scout Algolia"`, `"Scout Meilisearch"`, `"Scout Typesense"`
|
|
17
|
+
- Model configuration: `"Scout configuring searchable data"`, `"Scout configuring model indexes"`
|
|
18
|
+
- Searching: `"Scout searching"`, `"Scout where clauses"`, `"Scout pagination"`
|
|
19
|
+
- Indexing: `"Scout batch import"`, `"Scout adding records"`, `"Scout removing records"`
|
|
20
|
+
- Advanced: `"Scout soft deleting"`, `"Scout customizing engine searches"`, `"Scout custom engines"`
|
|
21
|
+
|
|
22
|
+
The docs are organized into these main sections: Installation, Driver Prerequisites, Configuration, Database/Collection Engines, Indexing, Searching, Custom Engines. Use these section names as search anchors.
|
|
23
|
+
|
|
24
|
+
## When to Apply
|
|
25
|
+
|
|
26
|
+
Activate this skill when:
|
|
27
|
+
|
|
28
|
+
- Installing or configuring Scout
|
|
29
|
+
- Choosing a search engine for a Laravel application
|
|
30
|
+
- Making Eloquent models searchable
|
|
31
|
+
- Customizing indexed data or index names
|
|
32
|
+
- Writing search queries, filters, or pagination
|
|
33
|
+
- Importing or flushing search indexes
|
|
34
|
+
- Troubleshooting search results or indexing issues
|
|
35
|
+
- Choosing between search engines
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
Before installing, check if Scout is already in the project — look for `laravel/scout` in `composer.json` and `config/scout.php`. If already installed, skip to the relevant section (engine configuration, model setup, or searching).
|
|
40
|
+
|
|
41
|
+
### 1. Install Scout
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
composer require laravel/scout
|
|
45
|
+
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Add the Searchable trait
|
|
49
|
+
|
|
50
|
+
```php
|
|
51
|
+
use Illuminate\Database\Eloquent\Model;
|
|
52
|
+
use Laravel\Scout\Searchable;
|
|
53
|
+
|
|
54
|
+
class Post extends Model
|
|
55
|
+
{
|
|
56
|
+
use Searchable;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This registers a model observer that automatically keeps your search index in sync with Eloquent records.
|
|
61
|
+
|
|
62
|
+
## Choosing an Engine
|
|
63
|
+
|
|
64
|
+
Before presenting engine options, check if Scout is already configured in the application:
|
|
65
|
+
|
|
66
|
+
1. Check `.env` for `SCOUT_DRIVER` — if set, the application already has a configured engine.
|
|
67
|
+
2. Check `config/scout.php` for the `driver` key and any engine-specific settings.
|
|
68
|
+
3. Check `composer.json` for engine SDKs (`algolia/algoliasearch-client-php`, `meilisearch/meilisearch-php`, `typesense/typesense-php`).
|
|
69
|
+
|
|
70
|
+
If an engine is already configured, skip the engine selection step and work with the existing setup. Only present the engine comparison if Scout is not yet installed or the user explicitly wants to switch engines.
|
|
71
|
+
|
|
72
|
+
When no engine is configured, present these options and let the user decide — never choose for them.
|
|
73
|
+
|
|
74
|
+
| Engine | Type | Best For | Tradeoffs |
|
|
75
|
+
|--------|------|----------|-----------|
|
|
76
|
+
| **Database** | Built-in | Typical applications, simple search | No external deps. MySQL/PostgreSQL only. LIKE + full-text indexes. No typo tolerance. |
|
|
77
|
+
| **Collection** | Built-in | Local dev, tiny datasets (<500 records) | Loads all records into memory. Most portable but least efficient. |
|
|
78
|
+
| **Algolia** | Hosted SaaS | Advanced search without managing infra | Typo tolerance, analytics, faceting. Paid service. No self-hosting. |
|
|
79
|
+
| **Meilisearch** | Self-hosted / Cloud | Teams wanting infrastructure control | Fast, open-source. Self-hostable or cloud. Requires filterable attribute config. |
|
|
80
|
+
| **Typesense** | Self-hosted / Cloud | Keyword, semantic, geo, vector search | Open-source. Self-hostable or cloud. Strict schema requirements. |
|
|
81
|
+
|
|
82
|
+
After the user chooses, use `search-docs` for that engine's prerequisites and configuration.
|
|
83
|
+
|
|
84
|
+
Set the engine in `.env`:
|
|
85
|
+
|
|
86
|
+
```ini
|
|
87
|
+
SCOUT_DRIVER=database
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For third-party engines (Algolia, Meilisearch, Typesense): install their PHP SDK and strongly consider enabling queue support in `config/scout.php` for production.
|
|
91
|
+
|
|
92
|
+
## Model Configuration
|
|
93
|
+
|
|
94
|
+
Use `search-docs` for full configuration details. Key customization points:
|
|
95
|
+
|
|
96
|
+
```php
|
|
97
|
+
// Control what data gets indexed
|
|
98
|
+
public function toSearchableArray(): array
|
|
99
|
+
{
|
|
100
|
+
return [
|
|
101
|
+
'id' => $this->id,
|
|
102
|
+
'title' => $this->title,
|
|
103
|
+
'body' => $this->body,
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Custom index name (no effect with database engine)
|
|
108
|
+
public function searchableAs(): string
|
|
109
|
+
{
|
|
110
|
+
return 'posts_index';
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For Algolia/Meilisearch/Typesense: configure index settings (filterable, sortable, searchable attributes) in `config/scout.php`, then sync:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
php artisan scout:sync-index-settings
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Searching
|
|
121
|
+
|
|
122
|
+
Basic patterns:
|
|
123
|
+
|
|
124
|
+
```php
|
|
125
|
+
// Simple search
|
|
126
|
+
$results = Model::search('query')->get();
|
|
127
|
+
|
|
128
|
+
// With filtering
|
|
129
|
+
$results = Model::search('query')->where('status', 'active')->get();
|
|
130
|
+
|
|
131
|
+
// Paginated
|
|
132
|
+
$results = Model::search('query')->paginate(15);
|
|
133
|
+
|
|
134
|
+
// Eager load relationships on results
|
|
135
|
+
$results = Model::search('query')
|
|
136
|
+
->query(fn ($q) => $q->with('category'))
|
|
137
|
+
->get();
|
|
138
|
+
|
|
139
|
+
// Raw engine results
|
|
140
|
+
$results = Model::search('query')->raw();
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use `search-docs` for advanced querying — `whereIn`, `whereNotIn`, soft deletes, custom indexes, and engine-specific options.
|
|
144
|
+
|
|
145
|
+
## Key Artisan Commands
|
|
146
|
+
|
|
147
|
+
| Command | Purpose |
|
|
148
|
+
|---------|---------|
|
|
149
|
+
| `php artisan scout:import "App\Models\Post"` | Import model records into search index |
|
|
150
|
+
| `php artisan scout:queue-import "App\Models\Post"` | Import via queued jobs (large datasets) |
|
|
151
|
+
| `php artisan scout:flush "App\Models\Post"` | Remove all model records from search index |
|
|
152
|
+
| `php artisan scout:sync-index-settings` | Sync index settings to the search engine |
|
|
153
|
+
| `php artisan scout:index posts` | Create a search index |
|
|
154
|
+
| `php artisan scout:delete-index posts` | Delete a search index |
|
|
155
|
+
|
|
156
|
+
## Testing
|
|
157
|
+
|
|
158
|
+
Scout does **not** have a `Scout::fake()` method. Available approaches:
|
|
159
|
+
|
|
160
|
+
- **NullEngine** — set `SCOUT_DRIVER=null` to disable all indexing in tests
|
|
161
|
+
- **CollectionEngine** — set `SCOUT_DRIVER=collection` for in-memory search without external services
|
|
162
|
+
- **`Model::withoutSyncingToSearch(fn() => ...)`** — temporarily pause indexing in a callback
|
|
163
|
+
- **`Model::disableSearchSyncing()`** — globally disable syncing in test setUp
|
|
164
|
+
|
|
165
|
+
Use `search-docs` for detailed testing patterns.
|
|
166
|
+
|
|
167
|
+
## Common Pitfalls
|
|
168
|
+
|
|
169
|
+
- **Meilisearch filterable attributes** — you must configure filterable attributes in `config/scout.php` under `meilisearch.index-settings` and run `scout:sync-index-settings` **before** using `where`, `whereIn`, or `whereNotIn`. Without this, filtering silently returns wrong results.
|
|
170
|
+
- **Meilisearch data type casting** — `toSearchableArray()` must return properly cast values: integers as `(int)`, floats as `(float)`. Wrong types cause silent filter failures.
|
|
171
|
+
- **Database engine limitations** — `searchableAs()`, `getScoutKey()`, `getScoutKeyName()`, and `shouldBeSearchable()` have no effect with the database engine. It queries your actual tables directly.
|
|
172
|
+
- **Global scopes break pagination** — search engines are not aware of Eloquent global scopes. Recreate scope constraints using Scout `where` clauses instead.
|
|
173
|
+
- **`query()` is not for filtering** — with third-party engines, the `query()` callback runs after results are already retrieved. Use Scout `where` clauses for filtering; use `query()` only for eager-loading or customizing the Eloquent hydration query.
|
|
174
|
+
- **Missing queue configuration** — third-party engines should always have `scout.queue` enabled in production. Without it, indexing runs synchronously and slows down requests.
|
|
175
|
+
- **Typesense schema requirements** — `id` must be cast as `(string)` and timestamps as Unix integers (`$this->created_at->timestamp`).
|
|
176
|
+
- **`shouldBeSearchable()` bypass** — this method only applies via `save()`, `create()`, queries, or relationships. Calling `searchable()` directly on a model or collection bypasses it entirely.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Security Best Practices
|
|
2
|
+
|
|
3
|
+
## Mass Assignment Protection
|
|
4
|
+
|
|
5
|
+
Every model must define `$fillable` (whitelist) or `$guarded` (blacklist).
|
|
6
|
+
|
|
7
|
+
Incorrect:
|
|
8
|
+
```php
|
|
9
|
+
class User extends Model
|
|
10
|
+
{
|
|
11
|
+
protected $guarded = []; // All fields are mass assignable
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Correct:
|
|
16
|
+
```php
|
|
17
|
+
class User extends Model
|
|
18
|
+
{
|
|
19
|
+
protected $fillable = [
|
|
20
|
+
'name',
|
|
21
|
+
'email',
|
|
22
|
+
'password',
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Never use `$guarded = []` on models that accept user input.
|
|
28
|
+
|
|
29
|
+
## Authorize Every Action
|
|
30
|
+
|
|
31
|
+
Use policies or gates in controllers. Never skip authorization.
|
|
32
|
+
|
|
33
|
+
Incorrect:
|
|
34
|
+
```php
|
|
35
|
+
public function update(UpdatePostRequest $request, Post $post)
|
|
36
|
+
{
|
|
37
|
+
$post->update($request->validated());
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Correct:
|
|
42
|
+
```php
|
|
43
|
+
public function update(UpdatePostRequest $request, Post $post)
|
|
44
|
+
{
|
|
45
|
+
Gate::authorize('update', $post);
|
|
46
|
+
|
|
47
|
+
$post->update($request->validated());
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or via Form Request:
|
|
52
|
+
|
|
53
|
+
```php
|
|
54
|
+
public function authorize(): bool
|
|
55
|
+
{
|
|
56
|
+
return $this->user()->can('update', $this->route('post'));
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Prevent SQL Injection
|
|
61
|
+
|
|
62
|
+
Always use parameter binding. Never interpolate user input into queries.
|
|
63
|
+
|
|
64
|
+
Incorrect:
|
|
65
|
+
```php
|
|
66
|
+
DB::select("SELECT * FROM users WHERE name = '{$request->name}'");
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Correct:
|
|
70
|
+
```php
|
|
71
|
+
User::where('name', $request->name)->get();
|
|
72
|
+
|
|
73
|
+
// Raw expressions with bindings
|
|
74
|
+
User::whereRaw('LOWER(name) = ?', [strtolower($request->name)])->get();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Escape Output to Prevent XSS
|
|
78
|
+
|
|
79
|
+
Use `{{ }}` for HTML escaping. Only use `{!! !!}` for trusted, pre-sanitized content.
|
|
80
|
+
|
|
81
|
+
Incorrect:
|
|
82
|
+
```blade
|
|
83
|
+
{!! $user->bio !!}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Correct:
|
|
87
|
+
```blade
|
|
88
|
+
{{ $user->bio }}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## CSRF Protection
|
|
92
|
+
|
|
93
|
+
Include `@csrf` in all POST/PUT/DELETE Blade forms. In Inertia apps, the `@csrf` directive is automatically applied.
|
|
94
|
+
|
|
95
|
+
Incorrect:
|
|
96
|
+
```blade
|
|
97
|
+
<form method="POST" action="/posts">
|
|
98
|
+
<input type="text" name="title">
|
|
99
|
+
</form>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Correct:
|
|
103
|
+
```blade
|
|
104
|
+
<form method="POST" action="/posts">
|
|
105
|
+
@csrf
|
|
106
|
+
<input type="text" name="title">
|
|
107
|
+
</form>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Rate Limit Auth and API Routes
|
|
111
|
+
|
|
112
|
+
Apply `throttle` middleware to authentication and API routes.
|
|
113
|
+
|
|
114
|
+
```php
|
|
115
|
+
RateLimiter::for('login', function (Request $request) {
|
|
116
|
+
return Limit::perMinute(5)->by($request->ip());
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
Route::post('/login', LoginController::class)->middleware('throttle:login');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Validate File Uploads
|
|
123
|
+
|
|
124
|
+
Validate extension, MIME type, and size. The `mimes` rule checks extensions; use `mimetypes` for actual MIME type validation. Never trust client-provided filenames.
|
|
125
|
+
|
|
126
|
+
```php
|
|
127
|
+
public function rules(): array
|
|
128
|
+
{
|
|
129
|
+
return [
|
|
130
|
+
'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Store with generated filenames:
|
|
136
|
+
|
|
137
|
+
```php
|
|
138
|
+
$path = $request->file('avatar')->store('avatars', 'public');
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Keep Secrets Out of Code
|
|
142
|
+
|
|
143
|
+
Never commit `.env`. Access secrets via `config()` only.
|
|
144
|
+
|
|
145
|
+
Incorrect:
|
|
146
|
+
```php
|
|
147
|
+
$key = env('API_KEY');
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Correct:
|
|
151
|
+
```php
|
|
152
|
+
// config/services.php
|
|
153
|
+
'api_key' => env('API_KEY'),
|
|
154
|
+
|
|
155
|
+
// In application code
|
|
156
|
+
$key = config('services.api_key');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Audit Dependencies
|
|
160
|
+
|
|
161
|
+
Run `composer audit` periodically to check for known vulnerabilities in dependencies. Automate this in CI to catch issues before deployment.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
composer audit
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Encrypt Sensitive Database Fields
|
|
168
|
+
|
|
169
|
+
Use `encrypted` cast for API keys/tokens and mark the attribute as `hidden`.
|
|
170
|
+
|
|
171
|
+
Incorrect:
|
|
172
|
+
```php
|
|
173
|
+
class Integration extends Model
|
|
174
|
+
{
|
|
175
|
+
protected function casts(): array
|
|
176
|
+
{
|
|
177
|
+
return [
|
|
178
|
+
'api_key' => 'string',
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Correct:
|
|
185
|
+
```php
|
|
186
|
+
class Integration extends Model
|
|
187
|
+
{
|
|
188
|
+
protected $hidden = ['api_key', 'api_secret'];
|
|
189
|
+
|
|
190
|
+
protected function casts(): array
|
|
191
|
+
{
|
|
192
|
+
return [
|
|
193
|
+
'api_key' => 'encrypted',
|
|
194
|
+
'api_secret' => 'encrypted',
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|