cortex-agents 1.0.1 → 2.1.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 (34) hide show
  1. package/.opencode/agents/build.md +34 -3
  2. package/.opencode/agents/debug.md +24 -2
  3. package/.opencode/agents/devops.md +1 -2
  4. package/.opencode/agents/fullstack.md +1 -2
  5. package/.opencode/agents/plan.md +5 -3
  6. package/.opencode/agents/security.md +1 -2
  7. package/.opencode/agents/testing.md +1 -2
  8. package/.opencode/skills/api-design/SKILL.md +348 -0
  9. package/.opencode/skills/architecture-patterns/SKILL.md +323 -0
  10. package/.opencode/skills/backend-development/SKILL.md +329 -0
  11. package/.opencode/skills/code-quality/SKILL.md +12 -0
  12. package/.opencode/skills/database-design/SKILL.md +347 -0
  13. package/.opencode/skills/deployment-automation/SKILL.md +7 -0
  14. package/.opencode/skills/design-patterns/SKILL.md +295 -0
  15. package/.opencode/skills/desktop-development/SKILL.md +295 -0
  16. package/.opencode/skills/frontend-development/SKILL.md +210 -0
  17. package/.opencode/skills/mobile-development/SKILL.md +407 -0
  18. package/.opencode/skills/performance-optimization/SKILL.md +330 -0
  19. package/.opencode/skills/testing-strategies/SKILL.md +33 -0
  20. package/README.md +390 -76
  21. package/dist/cli.js +355 -68
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +38 -0
  24. package/dist/plugin.js +3 -2
  25. package/dist/registry.d.ts +45 -0
  26. package/dist/registry.d.ts.map +1 -0
  27. package/dist/registry.js +140 -0
  28. package/dist/tools/cortex.d.ts.map +1 -1
  29. package/dist/tools/cortex.js +2 -3
  30. package/dist/tools/docs.d.ts +52 -0
  31. package/dist/tools/docs.d.ts.map +1 -0
  32. package/dist/tools/docs.js +328 -0
  33. package/package.json +11 -4
  34. package/.opencode/skills/web-development/SKILL.md +0 -122
@@ -0,0 +1,347 @@
1
+ ---
2
+ name: database-design
3
+ description: Schema design, normalization, indexing, SQL and NoSQL patterns, ORM strategies, migrations, and caching layers
4
+ license: Apache-2.0
5
+ compatibility: opencode
6
+ ---
7
+
8
+ # Database Design Skill
9
+
10
+ This skill provides patterns and best practices for designing, optimizing, and managing databases.
11
+
12
+ ## When to Use
13
+
14
+ Use this skill when:
15
+ - Designing database schemas for new applications
16
+ - Optimizing slow queries or improving performance
17
+ - Choosing between SQL and NoSQL databases
18
+ - Setting up ORM patterns and migration strategies
19
+ - Implementing caching layers
20
+
21
+ ## Database Selection Guide
22
+
23
+ | Database | Type | Best For |
24
+ |----------|------|----------|
25
+ | PostgreSQL | Relational | Complex queries, ACID, JSON support, full-text search |
26
+ | MySQL | Relational | Web applications, read-heavy workloads |
27
+ | SQLite | Relational | Embedded, mobile, local development, single-writer |
28
+ | MongoDB | Document | Flexible schemas, rapid prototyping, content management |
29
+ | Redis | Key-Value | Caching, sessions, rate limiting, pub/sub, leaderboards |
30
+ | Cassandra | Wide-Column | High write throughput, time-series, globally distributed |
31
+ | Neo4j | Graph | Social networks, recommendations, knowledge graphs |
32
+ | Elasticsearch | Search | Full-text search, log analytics, geo-spatial queries |
33
+ | DynamoDB | Key-Value/Doc | Serverless, predictable performance, AWS-native |
34
+ | ClickHouse | Columnar | Analytics, OLAP, real-time reporting |
35
+
36
+ ## Relational Design
37
+
38
+ ### Normalization
39
+
40
+ | Form | Rule | Example |
41
+ |------|------|---------|
42
+ | 1NF | Atomic values, no repeating groups | Split `tags: "a,b,c"` into separate rows |
43
+ | 2NF | 1NF + no partial dependencies | Move non-key attributes that depend only on part of composite key |
44
+ | 3NF | 2NF + no transitive dependencies | Move `city → state` to a separate table |
45
+
46
+ ### When to Denormalize
47
+ - Read-heavy workloads where joins are expensive
48
+ - Reporting/analytics tables (materialized views)
49
+ - Caching computed values that change infrequently
50
+ - Always measure first — premature denormalization adds complexity
51
+
52
+ ### Schema Design Best Practices
53
+ ```sql
54
+ -- Good: clear naming, constraints, timestamps
55
+ CREATE TABLE users (
56
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
57
+ email VARCHAR(255) NOT NULL UNIQUE,
58
+ name VARCHAR(100) NOT NULL,
59
+ role VARCHAR(20) NOT NULL DEFAULT 'user'
60
+ CHECK (role IN ('user', 'admin', 'moderator')),
61
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
62
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
63
+ );
64
+
65
+ -- Add index for common queries
66
+ CREATE INDEX idx_users_email ON users(email);
67
+ CREATE INDEX idx_users_role ON users(role) WHERE role != 'user';
68
+ ```
69
+
70
+ ### Naming Conventions
71
+ - Tables: plural, snake_case (`order_items`, `user_roles`)
72
+ - Columns: snake_case, descriptive (`created_at`, not `ca`)
73
+ - Primary keys: `id` (or `{table}_id` for clarity)
74
+ - Foreign keys: `{referenced_table}_id` (`user_id`, `order_id`)
75
+ - Indexes: `idx_{table}_{columns}` (`idx_users_email`)
76
+ - Constraints: `chk_{table}_{column}`, `uq_{table}_{column}`
77
+
78
+ ## Indexing
79
+
80
+ ### Index Types (PostgreSQL)
81
+ | Type | Use Case |
82
+ |------|----------|
83
+ | B-tree (default) | Equality, range, sorting, LIKE 'prefix%' |
84
+ | Hash | Equality only (rarely needed, B-tree covers this) |
85
+ | GIN | Arrays, JSONB, full-text search |
86
+ | GiST | Geometry, ranges, full-text search |
87
+ | BRIN | Large sequential tables (time-series, logs) |
88
+
89
+ ### Indexing Best Practices
90
+ - Index columns used in WHERE, JOIN, ORDER BY
91
+ - Composite indexes: put high-selectivity columns first
92
+ - Partial indexes to index only relevant rows
93
+ - Covering indexes to avoid table lookups
94
+ - Don't over-index — each index slows writes and uses storage
95
+
96
+ ```sql
97
+ -- Composite index for common query pattern
98
+ CREATE INDEX idx_orders_user_status
99
+ ON orders(user_id, status);
100
+
101
+ -- Partial index for active records only
102
+ CREATE INDEX idx_users_active_email
103
+ ON users(email) WHERE deleted_at IS NULL;
104
+
105
+ -- Covering index (includes all needed columns)
106
+ CREATE INDEX idx_products_category_price
107
+ ON products(category_id, price)
108
+ INCLUDE (name, image_url);
109
+ ```
110
+
111
+ ### Index Analysis
112
+ ```sql
113
+ -- Check if queries use indexes
114
+ EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
115
+
116
+ -- Find unused indexes
117
+ SELECT indexrelname, idx_scan, idx_tup_read
118
+ FROM pg_stat_user_indexes
119
+ WHERE idx_scan = 0 AND indexrelname NOT LIKE 'pg_%';
120
+ ```
121
+
122
+ ## Query Optimization
123
+
124
+ ### Common Performance Issues
125
+ | Issue | Symptom | Solution |
126
+ |-------|---------|----------|
127
+ | Missing index | Sequential scan on large table | Add appropriate index |
128
+ | N+1 queries | Hundreds of queries for one page | Eager load relations |
129
+ | SELECT * | Fetching unused columns | Select only needed columns |
130
+ | Large offset | Slow pagination (`OFFSET 10000`) | Use cursor-based pagination |
131
+ | Cartesian join | Exploding row count | Check JOIN conditions |
132
+ | Missing WHERE | Full table scan | Add filter conditions |
133
+
134
+ ### Query Patterns
135
+ ```sql
136
+ -- Cursor-based pagination (fast, stable)
137
+ SELECT * FROM orders
138
+ WHERE created_at < :last_cursor
139
+ ORDER BY created_at DESC
140
+ LIMIT 25;
141
+
142
+ -- Avoiding N+1 with JOIN
143
+ SELECT u.*, COUNT(o.id) as order_count
144
+ FROM users u
145
+ LEFT JOIN orders o ON o.user_id = u.id
146
+ GROUP BY u.id;
147
+
148
+ -- Upsert (INSERT or UPDATE)
149
+ INSERT INTO user_settings (user_id, key, value)
150
+ VALUES (:user_id, :key, :value)
151
+ ON CONFLICT (user_id, key)
152
+ DO UPDATE SET value = EXCLUDED.value, updated_at = NOW();
153
+ ```
154
+
155
+ ## NoSQL Patterns
156
+
157
+ ### MongoDB (Document)
158
+ - **Embed** when data is accessed together and doesn't grow unbounded
159
+ - **Reference** when data is accessed independently or is large
160
+ - Schema validation with JSON Schema for data integrity
161
+ - Use compound indexes for common query patterns
162
+ ```javascript
163
+ // Embed: address always accessed with user
164
+ {
165
+ _id: ObjectId("..."),
166
+ name: "John",
167
+ address: { street: "123 Main", city: "NYC" } // embedded
168
+ }
169
+
170
+ // Reference: orders queried independently
171
+ {
172
+ _id: ObjectId("..."),
173
+ user_id: ObjectId("..."), // reference to users collection
174
+ items: [...]
175
+ }
176
+ ```
177
+
178
+ ### Redis Patterns
179
+ | Pattern | Structure | Use Case |
180
+ |---------|-----------|----------|
181
+ | Cache | `cache:user:{id}` → JSON | Query result caching |
182
+ | Session | `session:{token}` → hash | User session data |
183
+ | Rate limit | `ratelimit:{ip}:{window}` → counter | API rate limiting |
184
+ | Queue | List with LPUSH/BRPOP | Simple job queue |
185
+ | Leaderboard | Sorted set | Rankings, top-N queries |
186
+ | Pub/Sub | Channel subscription | Real-time notifications |
187
+
188
+ ### Redis Best Practices
189
+ - Set TTL on all cache keys — avoid stale data and memory bloat
190
+ - Use pipelining for multiple operations — reduce round trips
191
+ - Choose data structures wisely — sorted sets for ranking, hashes for objects
192
+ - Monitor memory usage — configure maxmemory and eviction policy
193
+
194
+ ## ORM Patterns
195
+
196
+ ### Active Record vs Data Mapper
197
+
198
+ | Pattern | How It Works | Best For |
199
+ |---------|-------------|----------|
200
+ | Active Record | Model class handles its own persistence | Simple CRUD, rapid development |
201
+ | Data Mapper | Separate mapper handles persistence | Complex domains, testability |
202
+
203
+ ### ORM Best Practices
204
+ - Define relations explicitly — avoid lazy loading in production
205
+ - Use eager loading for known access patterns
206
+ - Raw queries for complex analytics — ORMs aren't for everything
207
+ - Database-level constraints — don't rely solely on ORM validation
208
+
209
+ ### Recommended ORMs
210
+ | Language | ORM | Style |
211
+ |----------|-----|-------|
212
+ | PHP | Eloquent | Active Record, expressive API, Laravel-native |
213
+ | PHP | Doctrine | Data Mapper, enterprise, Symfony-native |
214
+ | TypeScript | Prisma | Schema-first, generated client |
215
+ | TypeScript | Drizzle | SQL-like, lightweight, type-safe |
216
+ | TypeScript | TypeORM | Decorator-based, Active Record/Data Mapper |
217
+ | Python | SQLAlchemy | Data Mapper (or Active Record with ORM) |
218
+ | Python | Django ORM | Active Record, tightly integrated |
219
+ | Go | GORM | Convention-based, struct tags |
220
+ | Go | sqlc | SQL-first, generates Go code |
221
+ | Rust | Diesel | Compile-time checked queries |
222
+ | Rust | SQLx | Async, compile-time checked SQL |
223
+
224
+ ### Eloquent ORM Patterns (Laravel)
225
+ ```php
226
+ // Expressive relationships
227
+ class User extends Model {
228
+ public function orders(): HasMany {
229
+ return $this->hasMany(Order::class);
230
+ }
231
+
232
+ public function roles(): BelongsToMany {
233
+ return $this->belongsToMany(Role::class);
234
+ }
235
+
236
+ // Scopes for reusable query logic
237
+ public function scopeActive(Builder $query): Builder {
238
+ return $query->where('status', 'active');
239
+ }
240
+ }
241
+
242
+ // Eager loading to prevent N+1
243
+ $users = User::with(['orders', 'roles'])->active()->paginate(25);
244
+
245
+ // Query scopes, accessors, casts for clean models
246
+ ```
247
+
248
+ - Use `with()` for eager loading — always avoid N+1
249
+ - Use scopes for reusable query constraints
250
+ - Use casts for attribute type conversion (JSON, dates, enums)
251
+ - Use observers or model events for side effects
252
+ - Use `chunk()` or `lazy()` for large dataset processing
253
+
254
+ ## Migration Strategies
255
+
256
+ ### Best Practices
257
+ - One migration per change — small, focused, reversible
258
+ - Never edit a deployed migration — create a new one
259
+ - Test migrations against production-like data
260
+ - Separate schema changes from data migrations
261
+
262
+ ### Zero-Downtime Migrations
263
+ ```
264
+ 1. ADD new column (nullable or with default)
265
+ 2. DEPLOY code that writes to both old and new columns
266
+ 3. BACKFILL data from old column to new column
267
+ 4. DEPLOY code that reads from new column only
268
+ 5. DROP old column
269
+
270
+ Never: Rename column, change type, or drop column in one step
271
+ ```
272
+
273
+ ### Migration Tools
274
+ | Tool | Language | Features |
275
+ |------|----------|----------|
276
+ | Laravel Migrations | PHP | Schema builder, rollback, seeding, `artisan migrate` |
277
+ | Doctrine Migrations | PHP | Diff-based, Symfony integration |
278
+ | Prisma Migrate | TypeScript | Schema-diff based, auto-generated |
279
+ | Drizzle Kit | TypeScript | Schema-diff, push/pull |
280
+ | Alembic | Python | Revision-based, auto-detect |
281
+ | golang-migrate | Go | SQL files, multiple DB drivers |
282
+ | Diesel CLI | Rust | Schema-diff, reversible |
283
+ | Flyway | Java/Any | SQL-based, versioned, widely used |
284
+
285
+ ## Caching Layer
286
+
287
+ ### Caching Strategies
288
+ | Strategy | Description | Consistency |
289
+ |----------|-------------|-------------|
290
+ | Cache-aside | App checks cache, loads from DB on miss | Application-managed |
291
+ | Read-through | Cache loads from DB transparently | Cache-managed |
292
+ | Write-through | Write to cache and DB simultaneously | Strong |
293
+ | Write-behind | Write to cache, async write to DB | Eventual |
294
+
295
+ ### Cache Invalidation
296
+ ```typescript
297
+ // Pattern: Cache-aside with TTL + event invalidation
298
+ async function getUser(id: string): Promise<User> {
299
+ const cacheKey = `user:${id}`;
300
+
301
+ // Check cache first
302
+ const cached = await redis.get(cacheKey);
303
+ if (cached) return JSON.parse(cached);
304
+
305
+ // Load from DB
306
+ const user = await db.user.findUnique({ where: { id } });
307
+ if (!user) throw new NotFoundError("User");
308
+
309
+ // Cache with TTL
310
+ await redis.set(cacheKey, JSON.stringify(user), "EX", 3600);
311
+ return user;
312
+ }
313
+
314
+ // Invalidate on write
315
+ async function updateUser(id: string, data: UpdateUserDTO) {
316
+ const user = await db.user.update({ where: { id }, data });
317
+ await redis.del(`user:${id}`); // Invalidate cache
318
+ return user;
319
+ }
320
+ ```
321
+
322
+ ### Cache Key Design
323
+ - Include version: `v1:user:{id}`
324
+ - Include context: `user:{id}:orders:page:{page}`
325
+ - Use hash tags for Redis Cluster: `{user:123}:profile`
326
+ - Set appropriate TTL based on data freshness requirements
327
+
328
+ ## Connection Management
329
+
330
+ ### Connection Pooling
331
+ - Always use connection pools — never open/close per query
332
+ - Size pool based on: `pool_size = (core_count * 2) + spindle_count`
333
+ - Monitor active/idle connections
334
+ - Set connection timeout and idle timeout
335
+
336
+ ### Connection Pool Configuration
337
+ ```typescript
338
+ // Prisma — connection pool in connection string
339
+ // postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10
340
+
341
+ // Node.js pg pool
342
+ const pool = new Pool({
343
+ max: 20, // Maximum connections
344
+ idleTimeoutMillis: 30000,
345
+ connectionTimeoutMillis: 2000,
346
+ });
347
+ ```
@@ -117,6 +117,13 @@ CMD ["node", "dist/index.js"]
117
117
 
118
118
  ### Platform-Specific
119
119
 
120
+ #### Laravel-Specific Deployment
121
+ - **Laravel Forge** — Server provisioning and deployment for PHP (Nginx, MySQL, Redis, SSL)
122
+ - **Laravel Vapor** — Serverless deployment on AWS Lambda (auto-scaling, zero maintenance)
123
+ - **Laravel Envoyer** — Zero-downtime deployment with rollback
124
+ - **Laravel Cloud** — Managed Laravel hosting (PaaS)
125
+ - Traditional: Nginx + PHP-FPM + Supervisor (queues) + Redis + MySQL/PostgreSQL
126
+
120
127
  #### AWS
121
128
  - ECS (Elastic Container Service)
122
129
  - EKS (Elastic Kubernetes Service)
@@ -0,0 +1,295 @@
1
+ ---
2
+ name: design-patterns
3
+ description: Gang of Four patterns, enterprise patterns, functional patterns, domain-driven design, and anti-patterns
4
+ license: Apache-2.0
5
+ compatibility: opencode
6
+ ---
7
+
8
+ # Design Patterns Skill
9
+
10
+ This skill provides guidance on applying proven software design patterns to solve recurring problems.
11
+
12
+ ## When to Use
13
+
14
+ Use this skill when:
15
+ - Solving recurring design problems in code
16
+ - Refactoring code for better maintainability
17
+ - Reviewing code architecture and structure
18
+ - Implementing domain-driven design
19
+ - Identifying and eliminating anti-patterns
20
+
21
+ ## Creational Patterns
22
+
23
+ ### Singleton
24
+ - **Intent**: Ensure a class has only one instance with global access
25
+ - **Use when**: Database connections, configuration, logging
26
+ - **Avoid when**: It creates hidden global state or hinders testing
27
+ ```typescript
28
+ class Database {
29
+ private static instance: Database;
30
+ private constructor(private connection: Connection) {}
31
+
32
+ static getInstance(): Database {
33
+ if (!Database.instance) {
34
+ Database.instance = new Database(createConnection());
35
+ }
36
+ return Database.instance;
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### Factory Method
42
+ - **Intent**: Define an interface for creating objects, let subclasses decide which class
43
+ - **Use when**: Object creation logic varies by context
44
+ - **Example**: `createNotifier("email")` returns EmailNotifier, `createNotifier("sms")` returns SMSNotifier
45
+
46
+ ### Abstract Factory
47
+ - **Intent**: Create families of related objects without specifying concrete classes
48
+ - **Use when**: Multiple related objects need consistent creation (e.g., UI themes)
49
+
50
+ ### Builder
51
+ - **Intent**: Construct complex objects step by step
52
+ - **Use when**: Object has many optional parameters or complex construction
53
+ ```typescript
54
+ const query = new QueryBuilder()
55
+ .select("name", "email")
56
+ .from("users")
57
+ .where("active", true)
58
+ .orderBy("name")
59
+ .limit(10)
60
+ .build();
61
+ ```
62
+
63
+ ### Prototype
64
+ - **Intent**: Create new objects by cloning existing ones
65
+ - **Use when**: Object creation is expensive, need copies with slight variations
66
+
67
+ ## Structural Patterns
68
+
69
+ ### Adapter
70
+ - **Intent**: Convert one interface to another that clients expect
71
+ - **Use when**: Integrating third-party libraries, legacy code migration
72
+ ```typescript
73
+ // Adapt old payment API to new interface
74
+ class StripeAdapter implements PaymentGateway {
75
+ constructor(private stripe: StripeSDK) {}
76
+
77
+ async charge(amount: number, currency: string): Promise<PaymentResult> {
78
+ const result = await this.stripe.paymentIntents.create({
79
+ amount: amount * 100, // Stripe uses cents
80
+ currency,
81
+ });
82
+ return { id: result.id, status: result.status };
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### Decorator
88
+ - **Intent**: Attach additional behavior dynamically without altering the class
89
+ - **Use when**: Adding logging, caching, validation to existing objects
90
+ - **Common in**: Middleware chains, TypeScript decorators, Python decorators
91
+
92
+ ### Facade
93
+ - **Intent**: Provide a simplified interface to a complex subsystem
94
+ - **Use when**: Hiding complexity behind a clean API
95
+ - **Example**: A `PaymentService` that orchestrates cart, pricing, gateway, and receipt subsystems
96
+
97
+ ### Proxy
98
+ - **Intent**: Control access to an object (lazy loading, access control, logging)
99
+ - **Use when**: Adding cross-cutting concerns transparently
100
+
101
+ ### Composite
102
+ - **Intent**: Treat individual objects and compositions uniformly
103
+ - **Use when**: Tree structures (file systems, UI components, org charts)
104
+
105
+ ## Behavioral Patterns
106
+
107
+ ### Observer
108
+ - **Intent**: Define a one-to-many dependency — when one changes, dependents are notified
109
+ - **Use when**: Event systems, reactive state, pub/sub
110
+ ```typescript
111
+ class EventEmitter<T extends Record<string, unknown[]>> {
112
+ private listeners = new Map<keyof T, Set<Function>>();
113
+
114
+ on<K extends keyof T>(event: K, handler: (...args: T[K]) => void) {
115
+ if (!this.listeners.has(event)) this.listeners.set(event, new Set());
116
+ this.listeners.get(event)!.add(handler);
117
+ return () => this.listeners.get(event)?.delete(handler);
118
+ }
119
+
120
+ emit<K extends keyof T>(event: K, ...args: T[K]) {
121
+ this.listeners.get(event)?.forEach((handler) => handler(...args));
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Strategy
127
+ - **Intent**: Define a family of algorithms, make them interchangeable
128
+ - **Use when**: Multiple ways to accomplish something (sorting, validation, pricing)
129
+ ```typescript
130
+ interface CompressionStrategy {
131
+ compress(data: Buffer): Buffer;
132
+ }
133
+
134
+ class FileProcessor {
135
+ constructor(private strategy: CompressionStrategy) {}
136
+ process(file: Buffer): Buffer {
137
+ return this.strategy.compress(file);
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### Command
143
+ - **Intent**: Encapsulate a request as an object for queuing, logging, undo
144
+ - **Use when**: Undo/redo, task queues, macro recording
145
+
146
+ ### State
147
+ - **Intent**: Object behavior changes based on internal state
148
+ - **Use when**: Complex state machines (order status, UI modes, workflows)
149
+
150
+ ### Template Method
151
+ - **Intent**: Define skeleton of algorithm, let subclasses fill in steps
152
+ - **Use when**: Common workflow with varying steps (report generation, ETL)
153
+
154
+ ### Chain of Responsibility
155
+ - **Intent**: Pass request along a chain of handlers until one processes it
156
+ - **Use when**: Middleware pipelines, event bubbling, validation chains
157
+
158
+ ### Iterator
159
+ - **Intent**: Access elements sequentially without exposing representation
160
+ - **Use when**: Custom collections, lazy evaluation, streaming data
161
+
162
+ ## Enterprise Patterns
163
+
164
+ ### Repository
165
+ - **Intent**: Mediate between domain and data mapping layers
166
+ - **Use when**: Abstracting data access from business logic
167
+ - **Benefit**: Testable — swap real DB for in-memory implementation
168
+
169
+ ### Unit of Work
170
+ - **Intent**: Track changes and coordinate writing to DB as a single transaction
171
+ - **Use when**: Complex operations that must succeed or fail together
172
+
173
+ ### Service Layer
174
+ - **Intent**: Define application boundary with a layer of services
175
+ - **Use when**: Orchestrating business operations across multiple domain objects
176
+
177
+ ### Domain Model
178
+ - **Intent**: Object model of the domain that incorporates behavior and data
179
+ - **Use when**: Complex business logic that belongs in domain objects, not services
180
+
181
+ ### Data Mapper
182
+ - **Intent**: Move data between objects and database while keeping them independent
183
+ - **Use when**: Domain model should be free of persistence concerns
184
+
185
+ ### Data Transfer Object (DTO)
186
+ - **Intent**: Carry data between processes to reduce number of method calls
187
+ - **Use when**: API request/response shapes differ from domain models
188
+
189
+ ## Functional Patterns
190
+
191
+ ### Pipe / Compose
192
+ ```typescript
193
+ // Function composition — chain transformations
194
+ const pipe = <T>(...fns: ((arg: T) => T)[]) =>
195
+ (value: T) => fns.reduce((acc, fn) => fn(acc), value);
196
+
197
+ const processUser = pipe(
198
+ validateEmail,
199
+ normalizeUsername,
200
+ hashPassword,
201
+ createUserRecord,
202
+ );
203
+ ```
204
+
205
+ ### Immutability
206
+ - Prefer `const`, `readonly`, `Object.freeze()`
207
+ - Return new objects instead of mutating — `{ ...obj, key: newValue }`
208
+ - Use immutable data structures for shared state
209
+
210
+ ### Currying & Partial Application
211
+ - Transform multi-arg function into sequence of single-arg functions
212
+ - Create specialized functions from general ones
213
+
214
+ ### Monads (Optional/Result)
215
+ - Wrap values in context (Maybe/Option for nullability, Result/Either for errors)
216
+ - Chain operations safely without null checks at each step
217
+ ```typescript
218
+ // Result type for error handling without exceptions
219
+ type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
220
+ ```
221
+
222
+ ## Domain-Driven Design (DDD)
223
+
224
+ ### Core Concepts
225
+ | Concept | Description |
226
+ |---------|-------------|
227
+ | Bounded Context | Explicit boundary with a specific domain model |
228
+ | Aggregate | Cluster of objects treated as a single unit for data changes |
229
+ | Entity | Object with identity that persists over time |
230
+ | Value Object | Immutable object defined by its attributes, no identity |
231
+ | Domain Event | Something meaningful that happened in the domain |
232
+ | Repository | Interface for accessing aggregates |
233
+ | Domain Service | Logic that doesn't belong to any single entity |
234
+
235
+ ### Strategic Design
236
+ - Identify bounded contexts by business capabilities
237
+ - Define context maps — relationships between contexts
238
+ - Use ubiquitous language — domain experts and developers share vocabulary
239
+ - Anti-corruption layer between contexts with different models
240
+
241
+ ### Tactical Design
242
+ - Aggregates enforce invariants — validate rules at aggregate root
243
+ - Entities have identity — compare by ID, not attributes
244
+ - Value objects are immutable — compare by value, not reference
245
+ - Domain events for cross-aggregate communication
246
+
247
+ ## Anti-Patterns to Avoid
248
+
249
+ | Anti-Pattern | Problem | Solution |
250
+ |-------------|---------|----------|
251
+ | God Object | One class does everything | Split into focused classes (SRP) |
252
+ | Spaghetti Code | Tangled dependencies, no structure | Layer architecture, extract modules |
253
+ | Golden Hammer | Using one solution for everything | Choose tools based on problem |
254
+ | Premature Optimization | Optimizing before profiling | Measure first, optimize bottlenecks |
255
+ | Shotgun Surgery | One change requires editing many files | Consolidate related logic |
256
+ | Feature Envy | Method uses another class's data more than its own | Move method to the class it envies |
257
+ | Primitive Obsession | Using primitives instead of domain types | Create value objects (Email, Money) |
258
+ | Leaky Abstraction | Internal details exposed through interface | Design clean, minimal interfaces |
259
+
260
+ ## Language-Specific Idioms
261
+
262
+ ### PHP / Laravel
263
+ - **Facades** — Static-like access to services resolved from the container (`Cache::get()`, `Log::info()`)
264
+ - **Service Container** — Powerful DI container with auto-resolution, contextual binding
265
+ - **Service Providers** — Bootstrap and register application services (deferred loading)
266
+ - **Contracts** — Interfaces for framework services (swap implementations easily)
267
+ - **Pipelines** — Chain of responsibility pattern (`Pipeline::send($data)->through($pipes)`)
268
+ - **Observers** — Model lifecycle hooks (creating, updating, deleting events)
269
+ - **Policies** — Authorization logic encapsulated per model
270
+ - **Actions / Services** — Single-responsibility classes for business logic
271
+ - **Enums** — PHP 8.1+ backed enums for type-safe constants
272
+ - **Value Objects** — Use readonly classes (PHP 8.2+) or custom casts for domain types
273
+
274
+ ### TypeScript/JavaScript
275
+ - Use interfaces for contracts, classes for implementation
276
+ - Prefer composition with mixins or higher-order functions
277
+ - Use discriminated unions for type-safe state variants
278
+
279
+ ### Python
280
+ - Protocols and ABCs for interfaces
281
+ - Dataclasses and `__slots__` for value objects
282
+ - Context managers (`with`) for resource management
283
+ - Descriptors and metaclasses for advanced patterns
284
+
285
+ ### Go
286
+ - Interfaces are implicit — define behavior, not structure
287
+ - Embed structs for composition (no inheritance)
288
+ - Accept interfaces, return structs
289
+ - Table-driven tests for pattern verification
290
+
291
+ ### Rust
292
+ - Traits for polymorphism, generics for compile-time dispatch
293
+ - Enums with data for state machines (sum types)
294
+ - `Result<T, E>` for error handling (no exceptions)
295
+ - Ownership system enforces resource management patterns