@ryuenn3123/agentic-senior-core 1.8.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 (78) hide show
  1. package/.agent-context/blueprints/api-nextjs.md +184 -0
  2. package/.agent-context/blueprints/aspnet-api.md +247 -0
  3. package/.agent-context/blueprints/ci-github-actions.md +226 -0
  4. package/.agent-context/blueprints/ci-gitlab.md +200 -0
  5. package/.agent-context/blueprints/fastapi-service.md +210 -0
  6. package/.agent-context/blueprints/go-service.md +217 -0
  7. package/.agent-context/blueprints/graphql-grpc-api.md +51 -0
  8. package/.agent-context/blueprints/infrastructure-as-code.md +62 -0
  9. package/.agent-context/blueprints/kubernetes-manifests.md +76 -0
  10. package/.agent-context/blueprints/laravel-api.md +223 -0
  11. package/.agent-context/blueprints/nestjs-logic.md +247 -0
  12. package/.agent-context/blueprints/observability.md +227 -0
  13. package/.agent-context/blueprints/spring-boot-api.md +218 -0
  14. package/.agent-context/policies/llm-judge-threshold.json +20 -0
  15. package/.agent-context/profiles/platform.md +13 -0
  16. package/.agent-context/profiles/regulated.md +13 -0
  17. package/.agent-context/profiles/startup.md +13 -0
  18. package/.agent-context/prompts/init-project.md +86 -0
  19. package/.agent-context/prompts/refactor.md +45 -0
  20. package/.agent-context/prompts/review-code.md +47 -0
  21. package/.agent-context/review-checklists/architecture-review.md +70 -0
  22. package/.agent-context/review-checklists/frontend-usability.md +33 -0
  23. package/.agent-context/review-checklists/performance-audit.md +65 -0
  24. package/.agent-context/review-checklists/pr-checklist.md +97 -0
  25. package/.agent-context/review-checklists/release-operations.md +29 -0
  26. package/.agent-context/review-checklists/security-audit.md +113 -0
  27. package/.agent-context/rules/api-docs.md +186 -0
  28. package/.agent-context/rules/architecture.md +198 -0
  29. package/.agent-context/rules/database-design.md +202 -0
  30. package/.agent-context/rules/efficiency-vs-hype.md +143 -0
  31. package/.agent-context/rules/error-handling.md +234 -0
  32. package/.agent-context/rules/event-driven.md +226 -0
  33. package/.agent-context/rules/frontend-architecture.md +66 -0
  34. package/.agent-context/rules/git-workflow.md +200 -0
  35. package/.agent-context/rules/microservices.md +174 -0
  36. package/.agent-context/rules/naming-conv.md +141 -0
  37. package/.agent-context/rules/performance.md +168 -0
  38. package/.agent-context/rules/realtime.md +47 -0
  39. package/.agent-context/rules/security.md +195 -0
  40. package/.agent-context/rules/testing.md +178 -0
  41. package/.agent-context/stacks/csharp.md +149 -0
  42. package/.agent-context/stacks/go.md +181 -0
  43. package/.agent-context/stacks/java.md +135 -0
  44. package/.agent-context/stacks/php.md +178 -0
  45. package/.agent-context/stacks/python.md +153 -0
  46. package/.agent-context/stacks/ruby.md +80 -0
  47. package/.agent-context/stacks/rust.md +86 -0
  48. package/.agent-context/stacks/typescript.md +317 -0
  49. package/.agent-context/state/architecture-map.md +25 -0
  50. package/.agent-context/state/dependency-map.md +32 -0
  51. package/.agent-override.md +36 -0
  52. package/.agents/workflows/init-project.md +29 -0
  53. package/.agents/workflows/refactor.md +29 -0
  54. package/.agents/workflows/review-code.md +29 -0
  55. package/.cursorrules +140 -0
  56. package/.gemini/instructions.md +97 -0
  57. package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -0
  58. package/.github/copilot-instructions.md +104 -0
  59. package/.github/workflows/benchmark-detection.yml +38 -0
  60. package/.github/workflows/frontend-usability-gate.yml +36 -0
  61. package/.github/workflows/release-gate.yml +32 -0
  62. package/.github/workflows/sbom-compliance.yml +32 -0
  63. package/.windsurfrules +106 -0
  64. package/AGENTS.md +131 -0
  65. package/CONTRIBUTING.md +136 -0
  66. package/LICENSE +21 -0
  67. package/README.md +239 -0
  68. package/bin/agentic-senior-core.js +1147 -0
  69. package/mcp.json +29 -0
  70. package/package.json +50 -0
  71. package/scripts/detection-benchmark.mjs +138 -0
  72. package/scripts/frontend-usability-audit.mjs +87 -0
  73. package/scripts/generate-sbom.mjs +61 -0
  74. package/scripts/init-project.ps1 +105 -0
  75. package/scripts/init-project.sh +131 -0
  76. package/scripts/llm-judge.mjs +664 -0
  77. package/scripts/release-gate.mjs +116 -0
  78. package/scripts/validate.mjs +554 -0
@@ -0,0 +1,181 @@
1
+ # Go Stack Profile — Simple, Explicit, Fast
2
+
3
+ > Go's superpower is simplicity. Don't fight it.
4
+ > No magic, no abstractions for the sake of abstractions.
5
+
6
+ ## Core Principles
7
+
8
+ 1. **Accept interfaces, return structs** — keep APIs flexible, implementations concrete
9
+ 2. **Errors are values** — handle them explicitly, don't panic
10
+ 3. **Stdlib first** — Go's standard library is excellent, use it before reaching for packages
11
+ 4. **Small interfaces** — 1-2 methods max. `io.Reader` has one method for a reason
12
+
13
+ ---
14
+
15
+ ## Error Handling (The Go Way)
16
+
17
+ ### Rule: Always Check Errors, Never Ignore
18
+
19
+ ```go
20
+ // BANNED: Ignoring errors
21
+ result, _ := doSomething()
22
+ json.Unmarshal(data, &out) // Error silently ignored
23
+
24
+ // REQUIRED: Handle every error
25
+ result, err := doSomething()
26
+ if err != nil {
27
+ return fmt.Errorf("failed to do something: %w", err)
28
+ }
29
+ ```
30
+
31
+ ### Wrapping Errors for Context
32
+ ```go
33
+ // BANNED: Bare error return
34
+ if err != nil {
35
+ return err // Caller has no idea where this came from
36
+ }
37
+
38
+ // REQUIRED: Wrap with context using %w
39
+ if err != nil {
40
+ return fmt.Errorf("creating user %q: %w", req.Email, err)
41
+ }
42
+ // Produces: "creating user "jane@example.com": duplicate key value"
43
+ ```
44
+
45
+ ### Custom Error Types
46
+ ```go
47
+ type NotFoundError struct {
48
+ Resource string
49
+ ID string
50
+ }
51
+
52
+ func (e *NotFoundError) Error() string {
53
+ return fmt.Sprintf("%s not found: %s", e.Resource, e.ID)
54
+ }
55
+
56
+ // Check with errors.As
57
+ var notFound *NotFoundError
58
+ if errors.As(err, &notFound) {
59
+ http.Error(w, notFound.Error(), http.StatusNotFound)
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Project Structure
66
+
67
+ ```
68
+ project-name/
69
+ ├── cmd/
70
+ │ └── server/
71
+ │ └── main.go # Entry point
72
+
73
+ ├── internal/ # Private application code
74
+ │ ├── user/
75
+ │ │ ├── handler.go # HTTP handlers (transport)
76
+ │ │ ├── service.go # Business logic
77
+ │ │ ├── repository.go # Data access
78
+ │ │ ├── model.go # Domain types
79
+ │ │ └── user_test.go # Tests alongside code
80
+ │ │
81
+ │ ├── order/
82
+ │ │ └── ...
83
+ │ │
84
+ │ └── platform/ # Cross-cutting infrastructure
85
+ │ ├── config/
86
+ │ │ └── config.go # Env-validated configuration
87
+ │ ├── database/
88
+ │ │ └── postgres.go # DB connection setup
89
+ │ ├── logger/
90
+ │ │ └── logger.go # Structured logging (slog)
91
+ │ └── middleware/
92
+ │ ├── auth.go
93
+ │ └── logging.go
94
+
95
+ ├── api/ # API definitions (OpenAPI, proto)
96
+ │ └── openapi.yaml
97
+
98
+ ├── go.mod
99
+ ├── go.sum
100
+ ├── Makefile # Build/test/lint commands
101
+ └── Dockerfile
102
+ ```
103
+
104
+ ### Key Rule: `internal/` is Private
105
+ Everything in `internal/` is invisible to external importers. This is Go's built-in encapsulation. Use it.
106
+
107
+ ---
108
+
109
+ ## Interface Design
110
+
111
+ ```go
112
+ // BANNED: Large interfaces
113
+ type UserService interface {
114
+ Create(ctx context.Context, req CreateUserReq) (*User, error)
115
+ Update(ctx context.Context, id string, req UpdateUserReq) (*User, error)
116
+ Delete(ctx context.Context, id string) error
117
+ GetByID(ctx context.Context, id string) (*User, error)
118
+ GetByEmail(ctx context.Context, email string) (*User, error)
119
+ ListAll(ctx context.Context) ([]*User, error)
120
+ // 10 more methods...
121
+ }
122
+
123
+ // REQUIRED: Small, focused interfaces (1-3 methods)
124
+ type UserCreator interface {
125
+ Create(ctx context.Context, req CreateUserReq) (*User, error)
126
+ }
127
+
128
+ type UserFinder interface {
129
+ GetByID(ctx context.Context, id string) (*User, error)
130
+ }
131
+ ```
132
+
133
+ **Rule:** Define interfaces where they are CONSUMED, not where they are implemented.
134
+
135
+ ---
136
+
137
+ ## Context Usage
138
+
139
+ ```go
140
+ // REQUIRED: First parameter is always context.Context
141
+ func (s *UserService) Create(ctx context.Context, req CreateUserReq) (*User, error) {
142
+ // Pass context to all downstream calls
143
+ user, err := s.repo.Insert(ctx, req)
144
+ // ...
145
+ }
146
+
147
+ // BANNED: context.Background() deep inside application code
148
+ // Use it ONLY at the entry point (main, HTTP handler setup, test setup)
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Preferred Libraries
154
+
155
+ | Need | Library | Why |
156
+ |------|---------|-----|
157
+ | HTTP router | `net/http` (Go 1.22+) / `chi` | Stdlib router is now excellent |
158
+ | Logging | `log/slog` (stdlib) | Structured, leveled, built-in since Go 1.21 |
159
+ | Configuration | `caarlos0/env` + struct tags | Simple, typed env parsing |
160
+ | Database | `database/sql` + `pgx` / `sqlc` | `sqlc` generates type-safe Go from SQL |
161
+ | Migration | `golang-migrate/migrate` | SQL-based, driver-agnostic |
162
+ | Testing | stdlib `testing` + `testify` | `testify` for assertions only |
163
+ | Validation | `go-playground/validator` | Struct tag validation |
164
+ | HTTP client | `net/http` (stdlib) | Sufficient for most needs |
165
+ | JSON | `encoding/json` (stdlib) / `json-iterator` | Stdlib first |
166
+ | API docs | `swaggo/swag` | Auto-generates OpenAPI from comments |
167
+
168
+ ---
169
+
170
+ ## Banned Patterns
171
+
172
+ | Pattern | Why | Alternative |
173
+ |---------|-----|-------------|
174
+ | `_ = err` or ignoring error | Silent failures | Always handle `err` |
175
+ | `panic()` in library code | Crashes the program | Return errors |
176
+ | `init()` functions | Hidden side effects, hard to test | Explicit initialization |
177
+ | Global mutable state | Concurrency bugs, untestable | Dependency injection |
178
+ | `interface{}` / `any` everywhere | No type safety | Generics (Go 1.18+) or specific types |
179
+ | ORM magic (GORM) | Hidden queries, N+1 traps | `sqlc` or raw `database/sql` |
180
+ | Huge packages | Violates SRP | Split into focused packages |
181
+ | Shared `utils` package | Kitchen sink, circular deps | Domain-specific helpers |
@@ -0,0 +1,135 @@
1
+ # Java Stack Profile — Enterprise Without the Bloat
2
+
3
+ > Java can be clean. It just needs discipline.
4
+ > Stop writing 200-line classes for a 10-line operation.
5
+
6
+ ## Language Version: Java 25+ (LTS)
7
+
8
+ Java 25 is the latest LTS release (September 2025, supported until 2033). Use modern Java features aggressively. Do not write pre-Java 21 style code.
9
+
10
+ ### Records Over POJOs
11
+ ```java
12
+ // BANNED: 80-line POJO with getters, setters, equals, hashCode
13
+ public class UserDto {
14
+ private String name;
15
+ private String email;
16
+ public String getName() { return name; }
17
+ public void setName(String name) { this.name = name; }
18
+ // ... 60 more lines of boilerplate
19
+ }
20
+
21
+ // REQUIRED: Record (immutable, auto-generates equals/hashCode/toString)
22
+ public record UserDto(String name, String email) {}
23
+ ```
24
+
25
+ ### Sealed Classes for Domain Variants
26
+ ```java
27
+ // Model fixed set of states or outcomes
28
+ public sealed interface PaymentResult
29
+ permits PaymentResult.Success, PaymentResult.Failed, PaymentResult.Pending {
30
+
31
+ record Success(String transactionId, BigDecimal amount) implements PaymentResult {}
32
+ record Failed(String reason, String errorCode) implements PaymentResult {}
33
+ record Pending(String retryAfter) implements PaymentResult {}
34
+ }
35
+ ```
36
+
37
+ ### Pattern Matching
38
+ ```java
39
+ // Use switch expressions with pattern matching (Java 21)
40
+ return switch (result) {
41
+ case Success s -> ResponseEntity.ok(s);
42
+ case Failed f -> ResponseEntity.badRequest().body(f.reason());
43
+ case Pending p -> ResponseEntity.accepted().body(p);
44
+ };
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Validation at Boundaries: Jakarta Bean Validation
50
+
51
+ ```java
52
+ public record CreateUserRequest(
53
+ @NotBlank @Size(max = 100) String name,
54
+ @NotBlank @Email String email,
55
+ @Min(13) @Max(150) int age
56
+ ) {}
57
+
58
+ @PostMapping("/users")
59
+ public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
60
+ // request is validated by the framework before reaching this method
61
+ return ResponseEntity.status(201).body(userService.create(request));
62
+ }
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Project Structure (Spring Boot 4)
68
+
69
+ ```
70
+ project-name/
71
+ ├── src/main/java/com/example/project/
72
+ │ ├── Application.java # Entry point
73
+ │ │
74
+ │ ├── modules/
75
+ │ │ ├── user/
76
+ │ │ │ ├── UserController.java # Transport (REST)
77
+ │ │ │ ├── UserService.java # Business logic
78
+ │ │ │ ├── UserRepository.java # Data access (Spring Data)
79
+ │ │ │ ├── dto/
80
+ │ │ │ │ ├── CreateUserRequest.java # Input validation (record)
81
+ │ │ │ │ └── UserResponse.java # Output (record)
82
+ │ │ │ ├── entity/
83
+ │ │ │ │ └── UserEntity.java # JPA entity
84
+ │ │ │ └── exception/
85
+ │ │ │ └── UserNotFoundException.java
86
+ │ │ └── order/
87
+ │ │ └── ...
88
+ │ │
89
+ │ └── shared/
90
+ │ ├── config/ # Configuration classes
91
+ │ ├── exception/
92
+ │ │ └── GlobalExceptionHandler.java # @ControllerAdvice
93
+ │ ├── security/ # Security config
94
+ │ └── util/ # Cross-cutting utilities
95
+
96
+ ├── src/main/resources/
97
+ │ ├── application.yml
98
+ │ └── db/migration/ # Flyway migrations
99
+
100
+ └── src/test/java/com/example/project/
101
+ └── modules/user/
102
+ └── UserServiceTest.java
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Preferred Libraries
108
+
109
+ | Need | Library | Why |
110
+ |------|---------|-----|
111
+ | Framework | Spring Boot 4.x (Spring Framework 7) | Industry standard, virtual threads native support |
112
+ | Validation | Jakarta Bean Validation | Built into Spring Boot |
113
+ | ORM | Spring Data JPA / Hibernate | Standard, powerful |
114
+ | Migration | Flyway | SQL-based, version controlled |
115
+ | Mapping | MapStruct | Compile-time, type-safe DTO mapping |
116
+ | Testing | JUnit 5 + Mockito + Testcontainers | Standard stack |
117
+ | HTTP client | Spring RestClient / WebClient | RestClient (sync, new in Boot 4), WebClient (reactive) |
118
+ | Logging | SLF4J + Logback (or Log4j2) | Standard, structured JSON output |
119
+ | Build | Gradle (Kotlin DSL) or Maven | Gradle preferred for modern projects |
120
+ | API docs | springdoc-openapi | Auto-generates OpenAPI from code |
121
+
122
+ ---
123
+
124
+ ## Banned Patterns
125
+
126
+ | Pattern | Why | Alternative |
127
+ |---------|-----|-------------|
128
+ | Raw `String` for IDs | No type safety | `UUID` or typed ID wrapper |
129
+ | `null` returns | NullPointerException bait | `Optional<T>` for query results |
130
+ | Checked Exception abuse | Forces catch-or-throw chains | Unchecked `RuntimeException` subclasses |
131
+ | Field injection (`@Autowired`) | Hidden deps, untestable | Constructor injection |
132
+ | `System.out.println` | Not structured, not configurable | SLF4J logger |
133
+ | Deep class hierarchies | Fragile, hard to reason | Composition + interfaces |
134
+ | God services (500+ lines) | Violates SRP | Split into focused services |
135
+ | `@Transactional` on controller | Layer leak | Only on service methods |
@@ -0,0 +1,178 @@
1
+ # PHP Stack Profile — Modern PHP, Not Legacy PHP
2
+
3
+ > PHP 8.x is a different language from PHP 5.
4
+ > If your AI writes PHP without type declarations, reject it immediately.
5
+
6
+ ## Language Version: PHP 8.5+ (Latest Stable)
7
+
8
+ PHP 8.5 is stable since November 2025. Use modern PHP features including the pipe operator (`|>`), `Clone With`, and readonly classes.
9
+
10
+ ### Strict Types Everywhere
11
+ ```php
12
+ <?php
13
+ // REQUIRED: First line of EVERY PHP file
14
+ declare(strict_types=1);
15
+ ```
16
+
17
+ ### Typed Properties, Parameters, and Returns
18
+ ```php
19
+ // BANNED: Untyped PHP
20
+ function getUser($id) {
21
+ $user = $this->db->find($id);
22
+ return $user;
23
+ }
24
+
25
+ // REQUIRED: Full type declarations
26
+ function getUser(int $id): ?User {
27
+ return $this->userRepository->find($id);
28
+ }
29
+ ```
30
+
31
+ ### Enums (PHP 8.1+)
32
+ ```php
33
+ // BANNED: Magic strings
34
+ $status = 'pending';
35
+
36
+ // REQUIRED: Backed enums
37
+ enum OrderStatus: string {
38
+ case Pending = 'pending';
39
+ case Confirmed = 'confirmed';
40
+ case Shipped = 'shipped';
41
+ case Delivered = 'delivered';
42
+ }
43
+ ```
44
+
45
+ ### Readonly Properties and Classes (PHP 8.2+) and Pipe Operator (PHP 8.5+)
46
+ ```php
47
+ // Readonly for DTOs and value objects
48
+ readonly class CreateUserDto {
49
+ public function __construct(
50
+ public string $name,
51
+ public string $email,
52
+ public int $age,
53
+ ) {}
54
+ }
55
+
56
+ // Pipe operator for cleaner function chains (PHP 8.5)
57
+ $result = $input
58
+ |> 'trim'
59
+ |> 'strtolower'
60
+ |> fn($s) => str_replace(' ', '-', $s);
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Validation at Boundaries: Laravel Form Requests
66
+
67
+ ```php
68
+ // BANNED: Validating in controller body
69
+ public function store(Request $request) {
70
+ $data = $request->all(); // Raw, unvalidated!
71
+ User::create($data); // Mass assignment vulnerability!
72
+ }
73
+
74
+ // REQUIRED: Form Request class
75
+ class StoreUserRequest extends FormRequest {
76
+ public function rules(): array {
77
+ return [
78
+ 'name' => ['required', 'string', 'max:100'],
79
+ 'email' => ['required', 'email', 'unique:users'],
80
+ 'age' => ['required', 'integer', 'min:13', 'max:150'],
81
+ ];
82
+ }
83
+ }
84
+
85
+ public function store(StoreUserRequest $request): JsonResponse {
86
+ $user = $this->userService->create($request->validated());
87
+ return response()->json($user, 201);
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Project Structure (Laravel)
94
+
95
+ ```
96
+ project-name/
97
+ ├── app/
98
+ │ ├── Modules/ # Feature-based grouping
99
+ │ │ ├── User/
100
+ │ │ │ ├── Controllers/
101
+ │ │ │ │ └── UserController.php # Transport
102
+ │ │ │ ├── Services/
103
+ │ │ │ │ └── UserService.php # Business logic
104
+ │ │ │ ├── Repositories/
105
+ │ │ │ │ └── UserRepository.php # Data access
106
+ │ │ │ ├── Requests/
107
+ │ │ │ │ └── StoreUserRequest.php
108
+ │ │ │ ├── Resources/
109
+ │ │ │ │ └── UserResource.php # API response transformer
110
+ │ │ │ ├── Models/
111
+ │ │ │ │ └── User.php # Eloquent model
112
+ │ │ │ └── Policies/
113
+ │ │ │ └── UserPolicy.php # Authorization
114
+ │ │ └── Order/
115
+ │ │ └── ...
116
+ │ │
117
+ │ ├── Shared/
118
+ │ │ ├── Exceptions/
119
+ │ │ │ └── Handler.php
120
+ │ │ └── Middleware/
121
+
122
+ ├── database/migrations/
123
+ ├── routes/api.php
124
+ ├── tests/
125
+ │ ├── Feature/
126
+ │ └── Unit/
127
+ ├── phpstan.neon # Static analysis config
128
+ └── composer.json
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Standards
134
+
135
+ ### PSR Compliance
136
+ - **PSR-4:** Autoloading (Composer handles this)
137
+ - **PSR-12:** Coding style (use PHP-CS-Fixer or Pint)
138
+
139
+ ### Static Analysis: PHPStan Level 8+
140
+ ```neon
141
+ # phpstan.neon
142
+ parameters:
143
+ level: 8
144
+ paths:
145
+ - app
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Preferred Libraries
151
+
152
+ | Need | Library | Why |
153
+ |------|---------|-----|
154
+ | Framework | Laravel 12 | Most productive PHP framework, auto eager loading, GraphQL |
155
+ | Validation | Laravel Form Requests | Built-in, declarative |
156
+ | ORM | Eloquent | Convention over configuration |
157
+ | Testing | PHPUnit / Pest | Pest preferred for readability |
158
+ | Static analysis | PHPStan (level 8+) | Catch type errors at build time |
159
+ | Formatting | Laravel Pint | Zero-config PSR-12 formatter |
160
+ | API resources | Laravel API Resources | Clean response transformation |
161
+ | Auth | Laravel Sanctum / Passport | Token-based auth |
162
+ | Queue | Laravel Queues | Built-in, multiple drivers |
163
+ | API docs | Scribe or L5-Swagger | Auto-generated OpenAPI |
164
+
165
+ ---
166
+
167
+ ## Banned Patterns
168
+
169
+ | Pattern | Why | Alternative |
170
+ |---------|-----|-------------|
171
+ | Missing `declare(strict_types=1)` | Loose type coercion | Always declare |
172
+ | `$request->all()` in `create()` | Mass assignment vulnerability | `$request->validated()` |
173
+ | Raw SQL with concatenation | SQL injection | Eloquent or query builder with bindings |
174
+ | `dd()` / `dump()` in production | Debug leak | Structured logging |
175
+ | God controllers (500+ lines) | Violates SRP | Thin controllers, fat services |
176
+ | Business logic in models | Model becomes unmaintainable | Service layer |
177
+ | `try { } catch (\Exception $e) { }` | Swallows everything | Specific exception types |
178
+ | Dynamic properties (deprecated 8.2) | Runtime errors | Declared typed properties |
@@ -0,0 +1,153 @@
1
+ # Python Stack Profile — Explicit is Better Than Implicit
2
+
3
+ > Python's readability is a gift. Don't waste it with sloppy typing and god functions.
4
+
5
+ ## Type System (Enforced)
6
+
7
+ ### Type Hints Everywhere (Python 3.12+)
8
+ ```python
9
+ # BANNED: Untyped function signatures
10
+ def process_data(data, options):
11
+ ...
12
+
13
+ # REQUIRED: Full type annotations
14
+ def process_order(order: Order, options: ProcessingOptions) -> OrderResult:
15
+ ...
16
+ ```
17
+
18
+ **Rule:** Every function MUST have type annotations for all parameters and return types. Use `mypy --strict` or `pyright` in strict mode.
19
+
20
+ ### No `Any` (Same Rule as TypeScript)
21
+ ```python
22
+ # BANNED
23
+ def handle(data: Any) -> Any: ...
24
+ result: dict[str, Any] = get_response()
25
+
26
+ # REQUIRED
27
+ def handle(data: OrderPayload) -> OrderResult: ...
28
+ result: OrderResponse = get_response()
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Validation at Boundaries: Pydantic
34
+
35
+ ### Rule: ALL External Data MUST Pass Through Pydantic
36
+
37
+ ```python
38
+ # BANNED: Trusting raw dicts
39
+ @app.post("/users")
40
+ async def create_user(request: Request):
41
+ data = await request.json() # Could be anything!
42
+ return await user_service.create(data)
43
+
44
+ # REQUIRED: Pydantic model at the boundary
45
+ from pydantic import BaseModel, EmailStr, Field
46
+
47
+ class CreateUserRequest(BaseModel):
48
+ name: str = Field(min_length=1, max_length=100)
49
+ email: EmailStr
50
+ age: int = Field(ge=13, le=150)
51
+
52
+ @app.post("/users")
53
+ async def create_user(payload: CreateUserRequest) -> UserResponse:
54
+ return await user_service.create(payload)
55
+ ```
56
+
57
+ ### Pydantic Best Practices
58
+ - Use `Field()` with constraints (`min_length`, `ge`, `le`, `pattern`)
59
+ - Use `model_config = ConfigDict(strict=True)` to prevent type coercion
60
+ - Derive response models from base models: `class UserResponse(UserBase):`
61
+ - Use `model_validator` for cross-field validation
62
+
63
+ ---
64
+
65
+ ## Project Structure
66
+
67
+ ```
68
+ project-name/
69
+ ├── src/
70
+ │ ├── __init__.py
71
+ │ ├── main.py # Application entry point
72
+ │ ├── config.py # Pydantic Settings (env validation)
73
+ │ │
74
+ │ ├── modules/ # Feature modules
75
+ │ │ ├── user/
76
+ │ │ │ ├── __init__.py
77
+ │ │ │ ├── router.py # Transport (API routes)
78
+ │ │ │ ├── service.py # Business logic
79
+ │ │ │ ├── repository.py # Data access
80
+ │ │ │ ├── schemas.py # Pydantic models (DTOs)
81
+ │ │ │ ├── models.py # SQLAlchemy/ORM models
82
+ │ │ │ └── exceptions.py # Domain-specific errors
83
+ │ │ └── order/
84
+ │ │ └── ...
85
+ │ │
86
+ │ └── shared/
87
+ │ ├── errors.py # Base error classes
88
+ │ ├── middleware.py # Auth, logging, error handling
89
+ │ ├── database.py # DB session management
90
+ │ └── logger.py # Structured logging (structlog)
91
+
92
+ ├── tests/
93
+ │ ├── conftest.py # Fixtures
94
+ │ ├── factories.py # Test data factories
95
+ │ └── modules/
96
+ │ └── user/
97
+ │ └── test_user_service.py
98
+
99
+ ├── pyproject.toml # Project config (single source)
100
+ ├── .env.example
101
+ └── Dockerfile
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Async Patterns
107
+
108
+ ```python
109
+ # BANNED: Sync I/O in async context
110
+ import requests # Blocks the event loop!
111
+ response = requests.get("https://api.example.com")
112
+
113
+ # REQUIRED: Use async HTTP client
114
+ import httpx
115
+ async with httpx.AsyncClient() as client:
116
+ response = await client.get("https://api.example.com")
117
+ ```
118
+
119
+ **Rule:** In async applications (FastAPI, etc.), NEVER use synchronous I/O libraries (`requests`, `time.sleep`, `open()` for large files). Use `httpx`, `asyncio.sleep`, `aiofiles`.
120
+
121
+ ---
122
+
123
+ ## Preferred Libraries (2025)
124
+
125
+ | Need | Library | Why |
126
+ |------|---------|-----|
127
+ | Web framework | `fastapi` | Async, type-safe, auto OpenAPI docs |
128
+ | Validation | `pydantic` v2 | Fast, Rust-powered, zero compromise |
129
+ | ORM | `sqlalchemy` 2.0+ / `sqlmodel` | Mature, async support. SQLModel wraps SQLAlchemy + Pydantic |
130
+ | HTTP client | `httpx` | Async-native, requests-compatible API |
131
+ | Testing | `pytest` + `pytest-asyncio` | Standard, plugin-rich |
132
+ | Linting | `ruff` | 10-100x faster than flake8+isort+black combined |
133
+ | Formatting | `ruff format` (or `black`) | Consistent, zero-config |
134
+ | Type checking | `mypy --strict` or `pyright` | Catch type errors before runtime |
135
+ | Logging | `structlog` | Structured, JSON-ready, contextvars |
136
+ | Env config | `pydantic-settings` | Type-safe env with validation |
137
+ | Password | `passlib[bcrypt]` or `argon2-cffi` | Proven, secure |
138
+ | Migration | `alembic` | SQLAlchemy migration standard |
139
+
140
+ ---
141
+
142
+ ## Banned Patterns
143
+
144
+ | Pattern | Why | Alternative |
145
+ |---------|-----|-------------|
146
+ | `Any` type | Defeats type checking | Specific types or `Unknown` protocol |
147
+ | `requests` in async | Blocks event loop | `httpx` |
148
+ | `print()` for logging | No structure, no levels | `structlog` or `logging` |
149
+ | `except Exception: pass` | Swallows every error | Specific exceptions, always log |
150
+ | `from module import *` | Namespace pollution | Explicit imports |
151
+ | Mutable default args | Shared state bug | `def f(items: list | None = None):` |
152
+ | Global state | Untestable, concurrency bugs | Dependency injection |
153
+ | `os.environ["KEY"]` | Crashes with KeyError | `pydantic-settings` with defaults |