start-vibing-stacks 1.0.0

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.
Files changed (40) hide show
  1. package/README.md +100 -0
  2. package/dist/detector.d.ts +16 -0
  3. package/dist/detector.js +103 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +239 -0
  6. package/dist/installer.d.ts +30 -0
  7. package/dist/installer.js +224 -0
  8. package/dist/setup.d.ts +17 -0
  9. package/dist/setup.js +161 -0
  10. package/dist/types.d.ts +88 -0
  11. package/dist/types.js +4 -0
  12. package/dist/ui.d.ts +11 -0
  13. package/dist/ui.js +47 -0
  14. package/package.json +57 -0
  15. package/stacks/_shared/agents/claude-md-compactor.md +44 -0
  16. package/stacks/_shared/agents/commit-manager.md +65 -0
  17. package/stacks/_shared/agents/documenter.md +82 -0
  18. package/stacks/_shared/agents/domain-updater.md +51 -0
  19. package/stacks/_shared/agents/research-web.md +60 -0
  20. package/stacks/_shared/agents/tester.md +61 -0
  21. package/stacks/_shared/commands/feature.md +13 -0
  22. package/stacks/_shared/commands/fix.md +9 -0
  23. package/stacks/_shared/commands/validate.md +10 -0
  24. package/stacks/_shared/config/domain-mapping.json +41 -0
  25. package/stacks/_shared/config/security-rules.json +31 -0
  26. package/stacks/_shared/hooks/stop-validator.ts +171 -0
  27. package/stacks/_shared/hooks/user-prompt-submit.ts +77 -0
  28. package/stacks/_shared/skills/debugging-patterns/SKILL.md +39 -0
  29. package/stacks/_shared/skills/docker-patterns/SKILL.md +47 -0
  30. package/stacks/_shared/skills/git-workflow/SKILL.md +35 -0
  31. package/stacks/nodejs/stack.json +87 -0
  32. package/stacks/php/config/quality-gates.json +23 -0
  33. package/stacks/php/skills/composer-workflow/SKILL.md +78 -0
  34. package/stacks/php/skills/php-patterns/SKILL.md +119 -0
  35. package/stacks/php/skills/phpstan-analysis/SKILL.md +68 -0
  36. package/stacks/php/skills/phpunit-testing/SKILL.md +122 -0
  37. package/stacks/php/skills/security-scan-php/SKILL.md +80 -0
  38. package/stacks/php/stack.json +95 -0
  39. package/templates/CLAUDE-default.md +54 -0
  40. package/templates/CLAUDE-php.md +88 -0
@@ -0,0 +1,39 @@
1
+ # Debugging Patterns
2
+
3
+ ## Universal Approach
4
+
5
+ 1. **Read the error** — fully, including stack trace
6
+ 2. **Reproduce** — confirm you can trigger it
7
+ 3. **Isolate** — minimal reproduction
8
+ 4. **Fix** — one change at a time
9
+ 5. **Test** — verify fix, add regression test
10
+ 6. **Document** — add to domain attention points
11
+
12
+ ## Stack-Specific Tools
13
+
14
+ ### PHP
15
+ ```bash
16
+ # Error logs
17
+ tail -f /var/log/php/error.log
18
+ # Xdebug
19
+ php -dxdebug.mode=debug script.php
20
+ # Built-in server with errors
21
+ php -S localhost:8000 -d display_errors=1
22
+ ```
23
+
24
+ ### Node.js
25
+ ```bash
26
+ # Debug mode
27
+ node --inspect script.js
28
+ # Verbose logging
29
+ DEBUG=* node script.js
30
+ ```
31
+
32
+ ## Anti-Patterns
33
+
34
+ | Don't | Do |
35
+ |-------|-----|
36
+ | `var_dump` / `console.log` everywhere | Use proper debugger |
37
+ | Fix symptom, not cause | Trace to root cause |
38
+ | Skip writing test for fix | Always add regression test |
39
+ | Leave debug code in commit | Clean before commit |
@@ -0,0 +1,47 @@
1
+ # Docker Patterns
2
+
3
+ ## PHP (PHP-FPM + Nginx)
4
+
5
+ ```dockerfile
6
+ FROM php:8.3-fpm-alpine
7
+
8
+ RUN apk add --no-cache \
9
+ libzip-dev \
10
+ && docker-php-ext-install pdo_mysql zip opcache
11
+
12
+ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
13
+ COPY . /var/www/html
14
+ WORKDIR /var/www/html
15
+
16
+ RUN composer install --no-dev --optimize-autoloader
17
+ RUN chown -R www-data:www-data /var/www/html
18
+
19
+ EXPOSE 9000
20
+ CMD ["php-fpm"]
21
+ ```
22
+
23
+ ## Node.js (Multi-stage)
24
+
25
+ ```dockerfile
26
+ FROM node:20-alpine AS builder
27
+ WORKDIR /app
28
+ COPY package*.json ./
29
+ RUN npm ci
30
+ COPY . .
31
+ RUN npm run build
32
+
33
+ FROM node:20-alpine
34
+ WORKDIR /app
35
+ COPY --from=builder /app/dist ./dist
36
+ COPY --from=builder /app/node_modules ./node_modules
37
+ EXPOSE 3000
38
+ CMD ["node", "dist/index.js"]
39
+ ```
40
+
41
+ ## Rules
42
+
43
+ 1. **Multi-stage builds** — smaller images
44
+ 2. **Alpine base** — minimal attack surface
45
+ 3. **.dockerignore** — exclude node_modules, .git
46
+ 4. **Non-root user** — security
47
+ 5. **Health checks** — always include
@@ -0,0 +1,35 @@
1
+ # Git Workflow
2
+
3
+ ## Branch Naming
4
+
5
+ ```
6
+ feature/short-description
7
+ fix/bug-description
8
+ refactor/what-changed
9
+ chore/maintenance-task
10
+ ```
11
+
12
+ ## Commit Format (Conventional)
13
+
14
+ ```
15
+ type(scope): description
16
+
17
+ Body explaining what and why.
18
+
19
+ Generated with Claude Code
20
+ Co-Authored-By: Claude <noreply@anthropic.com>
21
+ ```
22
+
23
+ ## Flow
24
+
25
+ 1. Create branch from main: `git checkout -b feature/name`
26
+ 2. Work, commit incrementally
27
+ 3. When done: merge to main, delete branch
28
+ 4. Push main to remote
29
+
30
+ ## Rules
31
+
32
+ - NEVER force push main
33
+ - ALWAYS conventional commits
34
+ - ALWAYS end on main branch
35
+ - ONE feature per branch
@@ -0,0 +1,87 @@
1
+ {
2
+ "id": "nodejs",
3
+ "name": "Node.js / TypeScript",
4
+ "icon": "📦",
5
+ "runtime": "Bun / Node.js 20+",
6
+ "minVersion": "20.0.0",
7
+ "packageManager": "bun|npm|pnpm",
8
+ "extensions": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
9
+ "testExtensions": ["*.test.ts", "*.spec.ts", "*.test.tsx"],
10
+ "detectFiles": ["package.json", "tsconfig.json", "bun.lockb", "next.config.js"],
11
+ "commands": {
12
+ "test": "bun run test",
13
+ "lint": "bun run lint",
14
+ "format": "bun run format",
15
+ "serve": "bun run dev",
16
+ "build": "bun run build",
17
+ "typecheck": "bun run typecheck"
18
+ },
19
+ "qualityGates": [
20
+ { "name": "TypeCheck", "command": "bun run typecheck", "required": true, "order": 1 },
21
+ { "name": "Lint", "command": "bun run lint", "required": true, "order": 2 },
22
+ { "name": "Tests", "command": "bun run test", "required": true, "order": 3 },
23
+ { "name": "Build", "command": "bun run build", "required": true, "order": 4 }
24
+ ],
25
+ "frameworks": [
26
+ { "id": "nextjs", "name": "Next.js (App Router)", "icon": "▲", "detectFiles": ["next.config.js", "next.config.ts", "next.config.mjs"] },
27
+ { "id": "nuxt", "name": "Nuxt", "icon": "💚", "detectFiles": ["nuxt.config.ts"] },
28
+ { "id": "astro", "name": "Astro", "icon": "🚀", "detectFiles": ["astro.config.mjs"] },
29
+ { "id": "express", "name": "Express", "icon": "⚡" },
30
+ { "id": "fastify", "name": "Fastify", "icon": "🏎️" },
31
+ { "id": "vanilla", "name": "Vanilla Node.js", "icon": "📄" }
32
+ ],
33
+ "databases": [
34
+ { "id": "mongodb", "name": "MongoDB", "icon": "🍃" },
35
+ { "id": "postgresql", "name": "PostgreSQL", "icon": "🐘" },
36
+ { "id": "mysql", "name": "MySQL / MariaDB", "icon": "🐬" },
37
+ { "id": "sqlite", "name": "SQLite (Turso / libSQL)", "icon": "📁" },
38
+ { "id": "redis", "name": "Redis (Upstash)", "icon": "🔴" },
39
+ { "id": "none", "name": "None", "icon": "❌" }
40
+ ],
41
+ "frontendOptions": [
42
+ { "id": "react-tailwind", "name": "React 19+ / TailwindCSS 4+", "icon": "⚛️" },
43
+ { "id": "vue", "name": "Vue.js / Nuxt", "icon": "💚" },
44
+ { "id": "svelte", "name": "Svelte / SvelteKit", "icon": "🔥" },
45
+ { "id": "shadcn", "name": "shadcn/ui + Tailwind", "icon": "🎨" },
46
+ { "id": "none", "name": "API only — no frontend", "icon": "❌" }
47
+ ],
48
+ "deployTargets": [
49
+ { "id": "vercel", "name": "Vercel", "icon": "▲" },
50
+ { "id": "docker", "name": "Docker", "icon": "🐳" },
51
+ { "id": "vps-ssh", "name": "VPS (SSH)", "icon": "☁️" },
52
+ { "id": "railway", "name": "Railway", "icon": "🚂" },
53
+ { "id": "fly", "name": "Fly.io", "icon": "✈️" },
54
+ { "id": "netlify", "name": "Netlify", "icon": "🌐" }
55
+ ],
56
+ "skills": [
57
+ "typescript-strict",
58
+ "react-patterns",
59
+ "nextjs-app-router",
60
+ "zod-validation",
61
+ "vitest-testing"
62
+ ],
63
+ "requirements": [
64
+ {
65
+ "name": "Node.js",
66
+ "command": "node",
67
+ "versionFlag": "--version",
68
+ "minVersion": "20.0.0",
69
+ "installCommand": {
70
+ "macos": "brew install node",
71
+ "linux": "curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt install -y nodejs"
72
+ },
73
+ "versionRegex": "v?(\\d+\\.\\d+\\.\\d+)"
74
+ },
75
+ {
76
+ "name": "Bun",
77
+ "command": "bun",
78
+ "versionFlag": "--version",
79
+ "minVersion": "1.0.0",
80
+ "installCommand": {
81
+ "macos": "brew install oven-sh/bun/bun",
82
+ "linux": "curl -fsSL https://bun.sh/install | bash"
83
+ },
84
+ "versionRegex": "(\\d+\\.\\d+\\.\\d+)"
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "gates": {
3
+ "phpstan": {
4
+ "command": "vendor/bin/phpstan analyse --level=6",
5
+ "description": "PHPStan static analysis (level 6)",
6
+ "required": true,
7
+ "order": 1
8
+ },
9
+ "phpunit": {
10
+ "command": "vendor/bin/phpunit",
11
+ "description": "PHPUnit tests",
12
+ "required": true,
13
+ "order": 2
14
+ },
15
+ "csFixer": {
16
+ "command": "vendor/bin/php-cs-fixer fix --dry-run --diff",
17
+ "description": "PHP-CS-Fixer code style",
18
+ "required": false,
19
+ "order": 3
20
+ }
21
+ },
22
+ "runAll": "vendor/bin/phpstan analyse --level=6 && vendor/bin/phpunit"
23
+ }
@@ -0,0 +1,78 @@
1
+ # Composer Workflow
2
+
3
+ ## Requirements
4
+
5
+ - **Composer >= 2.0**
6
+ - **PHP >= 8.3**
7
+
8
+ ## Essential Commands
9
+
10
+ ```bash
11
+ composer install # Install from lock file (CI/deploy)
12
+ composer update # Update dependencies (dev only)
13
+ composer require package/name # Add dependency
14
+ composer require --dev pkg # Add dev dependency
15
+ composer dump-autoload -o # Optimize autoloader (production)
16
+ ```
17
+
18
+ ## composer.json Structure
19
+
20
+ ```json
21
+ {
22
+ "name": "vendor/project",
23
+ "type": "project",
24
+ "require": {
25
+ "php": ">=8.3"
26
+ },
27
+ "require-dev": {
28
+ "phpunit/phpunit": "^11.0",
29
+ "phpstan/phpstan": "^2.0",
30
+ "friendsofphp/php-cs-fixer": "^3.0"
31
+ },
32
+ "autoload": {
33
+ "psr-4": {
34
+ "App\\": "src/"
35
+ }
36
+ },
37
+ "autoload-dev": {
38
+ "psr-4": {
39
+ "Tests\\": "tests/"
40
+ }
41
+ },
42
+ "scripts": {
43
+ "test": "phpunit",
44
+ "lint": "phpstan analyse --level=6",
45
+ "format": "php-cs-fixer fix",
46
+ "check": [
47
+ "@lint",
48
+ "@test"
49
+ ]
50
+ },
51
+ "config": {
52
+ "sort-packages": true,
53
+ "allow-plugins": {}
54
+ }
55
+ }
56
+ ```
57
+
58
+ ## PSR-4 Autoloading
59
+
60
+ ```
61
+ src/
62
+ ├── Controllers/
63
+ │ └── UserController.php → App\Controllers\UserController
64
+ ├── Services/
65
+ │ └── UserService.php → App\Services\UserService
66
+ ├── Models/
67
+ │ └── User.php → App\Models\User
68
+ └── Middleware/
69
+ └── AuthMiddleware.php → App\Middleware\AuthMiddleware
70
+ ```
71
+
72
+ ## Rules
73
+
74
+ 1. **Always commit composer.lock**
75
+ 2. **Never edit vendor/**
76
+ 3. **Use `composer install` in CI/production** (not update)
77
+ 4. **PHP >= 8.3 in require** — enforce minimum version
78
+ 5. **PSR-4 autoloading** — no manual includes
@@ -0,0 +1,119 @@
1
+ # PHP 8.3+ Patterns
2
+
3
+ ## Version Requirements
4
+
5
+ - **PHP >= 8.3** — MANDATORY. Do not use deprecated patterns.
6
+ - **Composer >= 2.0** — For dependency management.
7
+ - Use strict types: `declare(strict_types=1);` in EVERY file.
8
+
9
+ ## Modern PHP Features (USE THESE)
10
+
11
+ ### Typed Properties & Constructor Promotion
12
+
13
+ ```php
14
+ class User {
15
+ public function __construct(
16
+ private readonly string $name,
17
+ private readonly string $email,
18
+ private readonly int $age,
19
+ ) {}
20
+ }
21
+ ```
22
+
23
+ ### Enums
24
+
25
+ ```php
26
+ enum Status: string {
27
+ case Active = 'active';
28
+ case Inactive = 'inactive';
29
+ case Suspended = 'suspended';
30
+ }
31
+ ```
32
+
33
+ ### Readonly Classes (8.2+)
34
+
35
+ ```php
36
+ readonly class UserDTO {
37
+ public function __construct(
38
+ public string $name,
39
+ public string $email,
40
+ ) {}
41
+ }
42
+ ```
43
+
44
+ ### Typed Class Constants (8.3+)
45
+
46
+ ```php
47
+ class Config {
48
+ public const string APP_NAME = 'MyApp';
49
+ public const int MAX_RETRIES = 3;
50
+ }
51
+ ```
52
+
53
+ ### Match Expression
54
+
55
+ ```php
56
+ $result = match($status) {
57
+ 'active' => handleActive(),
58
+ 'inactive' => handleInactive(),
59
+ default => throw new \InvalidArgumentException("Unknown status: {$status}"),
60
+ };
61
+ ```
62
+
63
+ ### Named Arguments
64
+
65
+ ```php
66
+ $response = new Response(
67
+ content: $html,
68
+ status: 200,
69
+ headers: ['Content-Type' => 'text/html'],
70
+ );
71
+ ```
72
+
73
+ ### Null-safe Operator
74
+
75
+ ```php
76
+ $country = $user?->address?->country?->name;
77
+ ```
78
+
79
+ ### Fibers (8.1+)
80
+
81
+ ```php
82
+ $fiber = new Fiber(function (): void {
83
+ $value = Fiber::suspend('fiber started');
84
+ echo "Resumed with: {$value}";
85
+ });
86
+ ```
87
+
88
+ ## FORBIDDEN Patterns
89
+
90
+ | Don't | Do Instead |
91
+ |-------|------------|
92
+ | `$var = isset($x) ? $x : $default` | `$var = $x ?? $default` |
93
+ | `function foo($x)` (no types) | `function foo(string $x): void` |
94
+ | `array()` | `[]` |
95
+ | `mysql_*` functions | PDO or Doctrine |
96
+ | Global variables | Dependency injection |
97
+ | `eval()` | Never use eval |
98
+ | Untyped properties | Always type properties |
99
+
100
+ ## Error Handling
101
+
102
+ ```php
103
+ try {
104
+ $result = riskyOperation();
105
+ } catch (SpecificException $e) {
106
+ logger()->error('Operation failed', [
107
+ 'error' => $e->getMessage(),
108
+ 'trace' => $e->getTraceAsString(),
109
+ ]);
110
+ throw new DomainException('Friendly message', 0, $e);
111
+ }
112
+ ```
113
+
114
+ ## PSR Standards
115
+
116
+ - **PSR-4**: Autoloading
117
+ - **PSR-7**: HTTP Messages (if not using framework)
118
+ - **PSR-12**: Coding Style
119
+ - **PSR-15**: HTTP Handlers
@@ -0,0 +1,68 @@
1
+ # PHPStan Static Analysis
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ composer require --dev phpstan/phpstan
7
+ ```
8
+
9
+ ## Configuration (phpstan.neon)
10
+
11
+ ```neon
12
+ parameters:
13
+ level: 6
14
+ paths:
15
+ - src
16
+ - app
17
+ excludePaths:
18
+ - vendor
19
+ - storage
20
+ - bootstrap/cache
21
+ checkMissingIterableValueType: false
22
+ ```
23
+
24
+ ## Levels
25
+
26
+ | Level | What it checks |
27
+ |-------|---------------|
28
+ | 0 | Basic checks (unknown classes, functions) |
29
+ | 1 | Possibly undefined variables, return types |
30
+ | 2 | Unknown methods on all expressions |
31
+ | 3 | Return types, property types |
32
+ | 4 | Dead code, always true/false |
33
+ | 5 | Argument types |
34
+ | **6** | **MINIMUM for this project** — strict types |
35
+ | 7 | Union types |
36
+ | 8 | Nullable types everywhere |
37
+ | 9 | Mixed type restrictions |
38
+
39
+ ## Running
40
+
41
+ ```bash
42
+ vendor/bin/phpstan analyse # Default config
43
+ vendor/bin/phpstan analyse --level=6 src/ # Specific level & path
44
+ vendor/bin/phpstan analyse --generate-baseline # Generate baseline for legacy code
45
+ ```
46
+
47
+ ## Common Fixes
48
+
49
+ ```php
50
+ // ❌ PHPStan error: Parameter $data has no type hint
51
+ function process($data) {}
52
+
53
+ // ✅ Fixed
54
+ function process(array $data): void {}
55
+
56
+ // ❌ PHPStan error: Method returns mixed
57
+ function getData() { return $this->db->query(); }
58
+
59
+ // ✅ Fixed
60
+ /** @return array<string, mixed> */
61
+ function getData(): array { return $this->db->query(); }
62
+ ```
63
+
64
+ ## Rules
65
+
66
+ 1. **Level 6 minimum** — no exceptions
67
+ 2. **Fix errors, don't ignore** — use baseline only for legacy code
68
+ 3. **Run before commit** — part of quality gates
@@ -0,0 +1,122 @@
1
+ # PHPUnit Testing Skill
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ composer require --dev phpunit/phpunit
7
+ ```
8
+
9
+ ## Test File Location
10
+
11
+ ```
12
+ tests/
13
+ ├── Unit/
14
+ │ ├── Services/
15
+ │ │ └── UserServiceTest.php
16
+ │ └── Helpers/
17
+ │ └── StringHelperTest.php
18
+ ├── Feature/
19
+ │ └── Api/
20
+ │ └── UserApiTest.php
21
+ └── phpunit.xml
22
+ ```
23
+
24
+ ## Test Template
25
+
26
+ ```php
27
+ <?php
28
+
29
+ declare(strict_types=1);
30
+
31
+ namespace Tests\Unit\Services;
32
+
33
+ use PHPUnit\Framework\TestCase;
34
+ use App\Services\UserService;
35
+
36
+ final class UserServiceTest extends TestCase
37
+ {
38
+ private UserService $service;
39
+
40
+ protected function setUp(): void
41
+ {
42
+ parent::setUp();
43
+ $this->service = new UserService();
44
+ }
45
+
46
+ public function testCreateUserWithValidData(): void
47
+ {
48
+ // Arrange
49
+ $data = ['name' => 'John', 'email' => 'john@test.com'];
50
+
51
+ // Act
52
+ $user = $this->service->create($data);
53
+
54
+ // Assert
55
+ $this->assertSame('John', $user->name);
56
+ $this->assertSame('john@test.com', $user->email);
57
+ }
58
+
59
+ public function testCreateUserThrowsOnInvalidEmail(): void
60
+ {
61
+ $this->expectException(\InvalidArgumentException::class);
62
+ $this->expectExceptionMessage('Invalid email');
63
+
64
+ $this->service->create(['name' => 'John', 'email' => 'invalid']);
65
+ }
66
+
67
+ /**
68
+ * @dataProvider invalidDataProvider
69
+ */
70
+ public function testCreateUserRejectsInvalidData(array $data, string $expectedError): void
71
+ {
72
+ $this->expectException(\InvalidArgumentException::class);
73
+ $this->expectExceptionMessage($expectedError);
74
+
75
+ $this->service->create($data);
76
+ }
77
+
78
+ public static function invalidDataProvider(): array
79
+ {
80
+ return [
81
+ 'empty name' => [['name' => '', 'email' => 'a@b.com'], 'Name required'],
82
+ 'empty email' => [['name' => 'John', 'email' => ''], 'Email required'],
83
+ 'null data' => [[], 'Name required'],
84
+ ];
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Mocking
90
+
91
+ ```php
92
+ public function testServiceCallsRepository(): void
93
+ {
94
+ $repo = $this->createMock(UserRepository::class);
95
+ $repo->expects($this->once())
96
+ ->method('save')
97
+ ->with($this->isInstanceOf(User::class))
98
+ ->willReturn(true);
99
+
100
+ $service = new UserService($repo);
101
+ $result = $service->create(['name' => 'John', 'email' => 'j@t.com']);
102
+
103
+ $this->assertTrue($result);
104
+ }
105
+ ```
106
+
107
+ ## Running
108
+
109
+ ```bash
110
+ vendor/bin/phpunit # All tests
111
+ vendor/bin/phpunit tests/Unit/ # Unit only
112
+ vendor/bin/phpunit --filter testCreateUser # Specific test
113
+ vendor/bin/phpunit --coverage-text # With coverage
114
+ ```
115
+
116
+ ## Rules
117
+
118
+ 1. **One assertion concept per test**
119
+ 2. **Descriptive method names**: `testMethodName_Scenario_ExpectedResult`
120
+ 3. **Use data providers** for multiple inputs
121
+ 4. **setUp/tearDown** for shared state
122
+ 5. **Never skip tests** in commits
@@ -0,0 +1,80 @@
1
+ # PHP Security Scan
2
+
3
+ ## OWASP Top 10 for PHP
4
+
5
+ ### A01 - Broken Access Control
6
+
7
+ ```php
8
+ // ❌ NEVER trust user input for authorization
9
+ $userId = $_GET['user_id'];
10
+ $user = User::find($userId);
11
+
12
+ // ✅ Use authenticated session
13
+ $user = Auth::user();
14
+ ```
15
+
16
+ ### A02 - Cryptographic Failures
17
+
18
+ ```php
19
+ // ❌ NEVER
20
+ md5($password);
21
+ sha1($password);
22
+
23
+ // ✅ ALWAYS
24
+ password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
25
+ password_verify($input, $hash);
26
+ ```
27
+
28
+ ### A03 - Injection
29
+
30
+ ```php
31
+ // ❌ SQL Injection
32
+ $db->query("SELECT * FROM users WHERE id = {$_GET['id']}");
33
+
34
+ // ✅ Prepared statements (PDO)
35
+ $stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
36
+ $stmt->execute([':id' => $id]);
37
+
38
+ // ✅ Prepared statements (MySQLi)
39
+ $stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
40
+ $stmt->bind_param('i', $id);
41
+ $stmt->execute();
42
+ ```
43
+
44
+ ### A07 - XSS Prevention
45
+
46
+ ```php
47
+ // ❌ Raw output
48
+ echo $userInput;
49
+
50
+ // ✅ Always escape
51
+ echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
52
+
53
+ // ✅ In templates (Blade)
54
+ {{ $userInput }} // Auto-escaped
55
+ {!! $trustedHtml !!} // Only for trusted content
56
+ ```
57
+
58
+ ## Security Checklist
59
+
60
+ - [ ] All SQL uses prepared statements
61
+ - [ ] All output is escaped (htmlspecialchars)
62
+ - [ ] CSRF tokens on all forms
63
+ - [ ] Passwords use password_hash/verify
64
+ - [ ] File uploads validated (type, size, extension)
65
+ - [ ] Sessions use httpOnly + secure cookies
66
+ - [ ] Input validated before processing
67
+ - [ ] No `eval()`, `exec()` with user input
68
+ - [ ] No `extract()` on user data
69
+ - [ ] Headers: X-Content-Type-Options, X-Frame-Options, CSP
70
+
71
+ ## Sensitive Data Patterns (FORBIDDEN)
72
+
73
+ | Pattern | Risk |
74
+ |---------|------|
75
+ | `$_GET` used directly in SQL | SQL Injection |
76
+ | `echo $_POST[...]` | XSS |
77
+ | `md5()` / `sha1()` for passwords | Weak hashing |
78
+ | `eval($userInput)` | RCE |
79
+ | `include $_GET['page']` | LFI/RFI |
80
+ | `serialize()` user data | Object injection |