trinity-method-sdk 2.0.9 → 2.2.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.
- package/CHANGELOG.md +702 -267
- package/README.md +550 -540
- package/dist/cli/commands/deploy/agents.js +1 -1
- package/dist/cli/commands/deploy/ci-cd.d.ts +4 -3
- package/dist/cli/commands/deploy/ci-cd.js +10 -9
- package/dist/cli/commands/deploy/claude-setup.js +28 -35
- package/dist/cli/commands/deploy/configuration.js +10 -11
- package/dist/cli/commands/deploy/directories.js +13 -14
- package/dist/cli/commands/deploy/gitignore.js +3 -5
- package/dist/cli/commands/deploy/index.d.ts +1 -1
- package/dist/cli/commands/deploy/index.js +7 -3
- package/dist/cli/commands/deploy/knowledge-base.js +3 -3
- package/dist/cli/commands/deploy/pre-flight.js +1 -1
- package/dist/cli/commands/deploy/root-files.js +3 -18
- package/dist/cli/commands/deploy/sdk-install.js +1 -1
- package/dist/cli/commands/deploy/summary.js +3 -3
- package/dist/cli/commands/deploy/templates.js +33 -20
- package/dist/cli/commands/update/agents.js +1 -1
- package/dist/cli/commands/update/backup.js +6 -12
- package/dist/cli/commands/update/commands.d.ts +1 -0
- package/dist/cli/commands/update/commands.js +18 -45
- package/dist/cli/commands/update/knowledge-base.js +2 -2
- package/dist/cli/commands/update/pre-flight.js +11 -11
- package/dist/cli/commands/update/summary.js +5 -5
- package/dist/cli/commands/update/templates.js +35 -13
- package/dist/cli/commands/update/verification.js +5 -5
- package/dist/cli/commands/update/version.js +1 -1
- package/dist/cli/utils/deploy-ci.d.ts +3 -2
- package/dist/cli/utils/deploy-ci.js +24 -24
- package/dist/cli/utils/deploy-linting.js +101 -6
- package/dist/cli/utils/error-classes.d.ts +2 -2
- package/dist/cli/utils/linting-tools.js +14 -6
- package/dist/cli/utils/template-processor.js +2 -4
- package/dist/templates/{claude → .claude}/EMPLOYEE-DIRECTORY.md.template +16 -22
- package/dist/templates/{agents → .claude/agents}/aj-team/apo-documentation-specialist.md.template +10 -10
- package/dist/templates/{agents → .claude/agents}/aj-team/bas-quality-gate.md.template +13 -15
- package/dist/templates/{agents → .claude/agents}/aj-team/bon-dependency-manager.md.template +4 -4
- package/dist/templates/{agents → .claude/agents}/aj-team/cap-configuration-specialist.md.template +3 -3
- package/dist/templates/{agents → .claude/agents}/aj-team/dra-code-reviewer.md.template +8 -10
- package/dist/templates/{agents → .claude/agents}/aj-team/kil-task-executor.md.template +11 -13
- package/dist/templates/{agents → .claude/agents}/aj-team/uro-refactoring-specialist.md.template +3 -3
- package/dist/templates/{agents → .claude/agents}/audit/juno-auditor.md.template +46 -42
- package/dist/templates/{agents → .claude/agents}/deployment/ein-cicd.md.template +59 -164
- package/dist/templates/{agents → .claude/agents}/deployment/ino-context.md.template +25 -22
- package/dist/templates/{agents → .claude/agents}/deployment/tan-structure.md.template +32 -30
- package/dist/templates/{agents → .claude/agents}/deployment/zen-knowledge.md.template +28 -23
- package/dist/templates/{agents → .claude/agents}/leadership/aj-maestro.md.template +10 -6
- package/dist/templates/{agents → .claude/agents}/leadership/aly-cto.md.template +22 -19
- package/dist/templates/{agents → .claude/agents}/planning/eus-decomposer.md.template +8 -4
- package/dist/templates/{agents → .claude/agents}/planning/mon-requirements.md.template +8 -4
- package/dist/templates/{agents → .claude/agents}/planning/ror-design.md.template +8 -4
- package/dist/templates/{agents → .claude/agents}/planning/tra-planner.md.template +10 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-audit.md.template +15 -15
- package/dist/templates/.claude/commands/execution/trinity-breakdown.md.template +535 -0
- package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-orchestrate.md.template +48 -48
- package/dist/templates/{shared/claude-commands → .claude/commands/infrastructure}/trinity-init.md.template +32 -54
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-create-investigation.md.template +13 -7
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-investigate-templates.md.template +19 -15
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-plan-investigation.md.template +12 -6
- package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-changelog.md.template +9 -8
- package/dist/templates/.claude/commands/maintenance/trinity-docs-update.md.template +279 -0
- package/dist/templates/.claude/commands/maintenance/trinity-docs.md.template +2828 -0
- package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-readme.md.template +21 -20
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-decompose.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-design.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-plan.md.template +7 -5
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-requirements.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-continue.md.template +30 -24
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-end.md.template +403 -397
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-start.md.template +9 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-agents.md.template +11 -8
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-verify.md.template +56 -57
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-workorder.md.template +13 -9
- package/dist/templates/ci/ci.yml.template +2 -2
- package/dist/templates/root/CLAUDE.md.template +9 -9
- package/dist/templates/root/linting/nodejs/.husky-pre-commit.template +5 -0
- package/dist/templates/source/base-CLAUDE.md.template +310 -310
- package/dist/templates/source/flutter-CLAUDE.md.template +593 -593
- package/dist/templates/source/nodejs-CLAUDE.md.template +531 -531
- package/dist/templates/source/python-CLAUDE.md.template +510 -510
- package/dist/templates/source/react-CLAUDE.md.template +513 -513
- package/dist/templates/source/rust-CLAUDE.md.template +653 -653
- package/dist/templates/trinity/CLAUDE.md.template +14 -14
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/AI-DEVELOPMENT-GUIDE.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/ARCHITECTURE.md.template +5 -5
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/CODING-PRINCIPLES.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/DOCUMENTATION-CRITERIA.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/ISSUES.md.template +9 -9
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/TESTING-PRINCIPLES.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/Technical-Debt.md.template +2 -4
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/To-do.md.template +2 -2
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/Trinity.md.template +6 -6
- package/dist/templates/trinity/templates/documentation/api-docs/README.md.template +218 -0
- package/dist/templates/trinity/templates/documentation/configuration/documentation-structure.md.template +71 -0
- package/dist/templates/trinity/templates/documentation/configuration/env-example-generator.md.template +387 -0
- package/dist/templates/trinity/templates/documentation/discovery/api-endpoint-scanner.md.template +343 -0
- package/dist/templates/trinity/templates/documentation/discovery/component-discovery.md.template +254 -0
- package/dist/templates/trinity/templates/documentation/discovery/env-variable-extraction.md.template +316 -0
- package/dist/templates/trinity/templates/documentation/discovery/framework-detection.md.template +205 -0
- package/dist/templates/trinity/templates/documentation/guides/api-development.md.template +375 -0
- package/dist/templates/trinity/templates/documentation/guides/contributing.md.template +488 -0
- package/dist/templates/trinity/templates/documentation/guides/deployment.md.template +565 -0
- package/dist/templates/trinity/templates/documentation/guides/getting-started.md.template +118 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/api-endpoint-map.md.template +56 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/component-hierarchy.md.template +60 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/database-er.md.template +49 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/mvc-flow.md.template +41 -0
- package/dist/templates/trinity/templates/documentation/processes/error-handling-protocol.md.template +166 -0
- package/dist/templates/trinity/templates/documentation/processes/fallback-mechanism.md.template +88 -0
- package/dist/templates/trinity/templates/documentation/reports/apo-docs-update-checklist.md.template +343 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-docs-update-checklist.md.template +1337 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-final-report.md.template +237 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-internal-report.md.template +461 -0
- package/dist/templates/trinity/templates/documentation/validation/documentation-verification-rules.md.template +379 -0
- package/dist/templates/trinity/templates/documentation/validation/juno-quality-gates.md.template +282 -0
- package/dist/templates/{investigations → trinity/templates/investigations}/bug.md.template +14 -14
- package/dist/templates/{investigations → trinity/templates/investigations}/feature.md.template +14 -14
- package/dist/templates/{investigations → trinity/templates/investigations}/performance.md.template +14 -14
- package/dist/templates/{investigations → trinity/templates/investigations}/security.md.template +14 -14
- package/dist/templates/{investigations → trinity/templates/investigations}/technical.md.template +14 -14
- package/dist/templates/{work-orders → trinity/templates/work-orders}/ANALYSIS-TEMPLATE.md.template +10 -13
- package/dist/templates/{work-orders → trinity/templates/work-orders}/AUDIT-TEMPLATE.md.template +10 -26
- package/dist/templates/{work-orders → trinity/templates/work-orders}/IMPLEMENTATION-TEMPLATE.md.template +10 -26
- package/dist/templates/{work-orders → trinity/templates/work-orders}/INVESTIGATION-TEMPLATE.md.template +10 -25
- package/dist/templates/{work-orders → trinity/templates/work-orders}/PATTERN-TEMPLATE.md.template +10 -26
- package/dist/templates/{work-orders → trinity/templates/work-orders}/VERIFICATION-TEMPLATE.md.template +10 -26
- package/package.json +99 -94
- package/dist/templates/agents/leadership/aj-cc.md.template +0 -462
- package/dist/templates/ci/cd.yml.template +0 -175
- package/dist/templates/ci/github-actions.yml +0 -86
- package/dist/templates/root/TRINITY.md.template +0 -52
- package/dist/templates/shared/claude-commands/trinity-docs.md.template +0 -2577
- /package/dist/templates/{linting → root/linting}/flutter/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/flutter/analysis_options.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-commonjs.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-esm.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-typescript.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.prettierrc.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/.flake8.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/pyproject.toml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/clippy.toml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/rustfmt.toml.template +0 -0
- /package/dist/templates/{documentation → trinity/templates/documentation}/ROOT-README.md.template +0 -0
- /package/dist/templates/{documentation → trinity/templates/documentation}/SUBDIRECTORY-README.md.template +0 -0
|
@@ -1,510 +1,510 @@
|
|
|
1
|
-
# CLAUDE.md - Python Technology-Specific Rules
|
|
2
|
-
## {{PROJECT_NAME}} - Python Implementation
|
|
3
|
-
|
|
4
|
-
**Framework:** {{FRAMEWORK}}
|
|
5
|
-
**Language:** Python
|
|
6
|
-
**Source Directory:** {{SOURCE_DIR}}
|
|
7
|
-
**Package Manager:** pip/poetry/pipenv
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Technology Stack Behavioral Modifications
|
|
12
|
-
|
|
13
|
-
### Python-Specific Requirements
|
|
14
|
-
- **PEP 8 Compliance**: Follow PEP 8 style guide rigorously
|
|
15
|
-
- **Type Hints**: Use type hints for all function signatures (PEP 484)
|
|
16
|
-
- **Async/Await**: Use async/await for I/O-bound operations
|
|
17
|
-
- **Virtual Environments**: Always use virtual environments (venv, virtualenv, conda)
|
|
18
|
-
- **Context Managers**: Use context managers for resource management
|
|
19
|
-
|
|
20
|
-
### Framework-Specific Adaptations
|
|
21
|
-
- **Django**: Follow Django best practices and MVT pattern
|
|
22
|
-
- **FastAPI**: Implement dependency injection and Pydantic models
|
|
23
|
-
- **Flask**: Use blueprints for modular architecture
|
|
24
|
-
- **Data Science**: Use NumPy/Pandas best practices for data processing
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Technology Debugging Standards
|
|
29
|
-
|
|
30
|
-
### Python Debugging Framework
|
|
31
|
-
```python
|
|
32
|
-
# Standard debugging format for Python applications
|
|
33
|
-
import logging
|
|
34
|
-
import functools
|
|
35
|
-
import time
|
|
36
|
-
from typing import Any, Callable
|
|
37
|
-
from datetime import datetime
|
|
38
|
-
|
|
39
|
-
# Configure logging
|
|
40
|
-
logging.basicConfig(
|
|
41
|
-
level=logging.DEBUG,
|
|
42
|
-
format='[%(levelname)s] %(name)s.%(funcName)s - %(message)s'
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
class DebugLogger:
|
|
46
|
-
"""Standard debugging logger for Trinity Method"""
|
|
47
|
-
|
|
48
|
-
def __init__(self, module_name: str):
|
|
49
|
-
self.logger = logging.getLogger(module_name)
|
|
50
|
-
self.module_name = module_name
|
|
51
|
-
|
|
52
|
-
def entry(self, func_name: str, params: dict[str, Any] | None = None) -> None:
|
|
53
|
-
"""Log function entry"""
|
|
54
|
-
self.logger.debug(f"[ENTRY] {func_name}", extra={
|
|
55
|
-
'params': params or {},
|
|
56
|
-
'timestamp': datetime.now().isoformat(),
|
|
57
|
-
'module': self.module_name
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
def exit(self, func_name: str, result: Any, duration: float) -> None:
|
|
61
|
-
"""Log function exit"""
|
|
62
|
-
self.logger.debug(f"[EXIT] {func_name}", extra={
|
|
63
|
-
'result': str(result)[:200], # Truncate large results
|
|
64
|
-
'duration_ms': f"{duration * 1000:.2f}",
|
|
65
|
-
'timestamp': datetime.now().isoformat()
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
def error(self, func_name: str, error: Exception, context: dict[str, Any] | None = None) -> None:
|
|
69
|
-
"""Log errors"""
|
|
70
|
-
self.logger.error(f"[ERROR] {func_name}", extra={
|
|
71
|
-
'error': str(error),
|
|
72
|
-
'error_type': type(error).__name__,
|
|
73
|
-
'context': context or {},
|
|
74
|
-
'timestamp': datetime.now().isoformat()
|
|
75
|
-
}, exc_info=True)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# Decorator for automatic logging
|
|
79
|
-
def debug_function(logger: DebugLogger) -> Callable:
|
|
80
|
-
"""Decorator to automatically log function calls"""
|
|
81
|
-
|
|
82
|
-
def decorator(func: Callable) -> Callable:
|
|
83
|
-
@functools.wraps(func)
|
|
84
|
-
def wrapper(*args, **kwargs):
|
|
85
|
-
start_time = time.time()
|
|
86
|
-
logger.entry(func.__name__, {'args': args, 'kwargs': kwargs})
|
|
87
|
-
|
|
88
|
-
try:
|
|
89
|
-
result = func(*args, **kwargs)
|
|
90
|
-
duration = time.time() - start_time
|
|
91
|
-
logger.exit(func.__name__, result, duration)
|
|
92
|
-
return result
|
|
93
|
-
except Exception as e:
|
|
94
|
-
logger.error(func.__name__, e, {'args': args, 'kwargs': kwargs})
|
|
95
|
-
raise
|
|
96
|
-
|
|
97
|
-
return wrapper
|
|
98
|
-
|
|
99
|
-
return decorator
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# Usage example
|
|
103
|
-
logger = DebugLogger('UserService')
|
|
104
|
-
|
|
105
|
-
@debug_function(logger)
|
|
106
|
-
def get_user(user_id: str) -> dict[str, Any]:
|
|
107
|
-
"""Fetch user by ID"""
|
|
108
|
-
# Implementation
|
|
109
|
-
return {"id": user_id, "name": "John Doe"}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Performance Optimization Rules
|
|
115
|
-
|
|
116
|
-
### Python Performance Monitoring
|
|
117
|
-
```python
|
|
118
|
-
# Performance measurement utilities
|
|
119
|
-
import time
|
|
120
|
-
import cProfile
|
|
121
|
-
import pstats
|
|
122
|
-
from contextlib import contextmanager
|
|
123
|
-
from typing import Generator
|
|
124
|
-
|
|
125
|
-
class PerformanceMonitor:
|
|
126
|
-
"""Performance monitoring utilities"""
|
|
127
|
-
|
|
128
|
-
@staticmethod
|
|
129
|
-
@contextmanager
|
|
130
|
-
def measure(operation_name: str) -> Generator[None, None, None]:
|
|
131
|
-
"""Context manager for measuring operation duration"""
|
|
132
|
-
start_time = time.perf_counter()
|
|
133
|
-
|
|
134
|
-
try:
|
|
135
|
-
yield
|
|
136
|
-
finally:
|
|
137
|
-
duration = time.perf_counter() - start_time
|
|
138
|
-
print(f"[PERF] {operation_name}: {duration * 1000:.2f}ms")
|
|
139
|
-
|
|
140
|
-
@staticmethod
|
|
141
|
-
def profile(func: Callable) -> Callable:
|
|
142
|
-
"""Decorator to profile function execution"""
|
|
143
|
-
|
|
144
|
-
@functools.wraps(func)
|
|
145
|
-
def wrapper(*args, **kwargs):
|
|
146
|
-
profiler = cProfile.Profile()
|
|
147
|
-
profiler.enable()
|
|
148
|
-
|
|
149
|
-
result = func(*args, **kwargs)
|
|
150
|
-
|
|
151
|
-
profiler.disable()
|
|
152
|
-
stats = pstats.Stats(profiler)
|
|
153
|
-
stats.strip_dirs()
|
|
154
|
-
stats.sort_stats('cumulative')
|
|
155
|
-
print(f"\n[PROFILE] {func.__name__}")
|
|
156
|
-
stats.print_stats(10) # Top 10 functions
|
|
157
|
-
|
|
158
|
-
return result
|
|
159
|
-
|
|
160
|
-
return wrapper
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
# Usage
|
|
164
|
-
with PerformanceMonitor.measure("database_query"):
|
|
165
|
-
users = db.query(User).all()
|
|
166
|
-
|
|
167
|
-
@PerformanceMonitor.profile
|
|
168
|
-
def expensive_operation():
|
|
169
|
-
# Implementation
|
|
170
|
-
pass
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## Security Best Practices
|
|
176
|
-
|
|
177
|
-
### Input Validation
|
|
178
|
-
```python
|
|
179
|
-
# Input validation patterns
|
|
180
|
-
from pydantic import BaseModel, EmailStr, validator, constr
|
|
181
|
-
|
|
182
|
-
class UserInput(BaseModel):
|
|
183
|
-
"""Validated user input model"""
|
|
184
|
-
email: EmailStr
|
|
185
|
-
username: constr(min_length=3, max_length=50)
|
|
186
|
-
password: constr(min_length=8)
|
|
187
|
-
|
|
188
|
-
@validator('password')
|
|
189
|
-
def password_strength(cls, v):
|
|
190
|
-
"""Validate password strength"""
|
|
191
|
-
if not any(c.isupper() for c in v):
|
|
192
|
-
raise ValueError('Password must contain uppercase letter')
|
|
193
|
-
if not any(c.isdigit() for c in v):
|
|
194
|
-
raise ValueError('Password must contain digit')
|
|
195
|
-
return v
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# SQL injection prevention (use parameterized queries)
|
|
199
|
-
from sqlalchemy import text
|
|
200
|
-
|
|
201
|
-
# ❌ BAD: String concatenation
|
|
202
|
-
query = f"SELECT * FROM users WHERE id = {user_id}"
|
|
203
|
-
|
|
204
|
-
# ✅ GOOD: Parameterized query
|
|
205
|
-
query = text("SELECT * FROM users WHERE id = :user_id")
|
|
206
|
-
result = db.execute(query, {"user_id": user_id})
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Secure Configuration
|
|
210
|
-
```python
|
|
211
|
-
# Environment variable handling
|
|
212
|
-
from pydantic import BaseSettings
|
|
213
|
-
|
|
214
|
-
class Settings(BaseSettings):
|
|
215
|
-
"""Application settings from environment"""
|
|
216
|
-
database_url: str
|
|
217
|
-
secret_key: str
|
|
218
|
-
api_key: str
|
|
219
|
-
|
|
220
|
-
class Config:
|
|
221
|
-
env_file = ".env"
|
|
222
|
-
case_sensitive = False
|
|
223
|
-
|
|
224
|
-
settings = Settings()
|
|
225
|
-
|
|
226
|
-
# Never log sensitive values
|
|
227
|
-
logger.info(f"Database: {settings.database_url.split('@')[1]}") # Hide credentials
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## Testing Requirements
|
|
233
|
-
|
|
234
|
-
### pytest Patterns
|
|
235
|
-
```python
|
|
236
|
-
# Unit testing with pytest
|
|
237
|
-
import pytest
|
|
238
|
-
from unittest.mock import Mock, patch
|
|
239
|
-
|
|
240
|
-
class TestUserService:
|
|
241
|
-
"""Test suite for UserService"""
|
|
242
|
-
|
|
243
|
-
@pytest.fixture
|
|
244
|
-
def user_service(self):
|
|
245
|
-
"""Fixture for UserService instance"""
|
|
246
|
-
return UserService()
|
|
247
|
-
|
|
248
|
-
@pytest.fixture
|
|
249
|
-
def mock_database(self):
|
|
250
|
-
"""Fixture for mocked database"""
|
|
251
|
-
return Mock()
|
|
252
|
-
|
|
253
|
-
def test_get_user_success(self, user_service, mock_database):
|
|
254
|
-
"""Test successful user retrieval"""
|
|
255
|
-
user_service.db = mock_database
|
|
256
|
-
mock_database.query.return_value.first.return_value = User(id="123", name="John")
|
|
257
|
-
|
|
258
|
-
user = user_service.get_user("123")
|
|
259
|
-
|
|
260
|
-
assert user is not None
|
|
261
|
-
assert user.id == "123"
|
|
262
|
-
assert user.name == "John"
|
|
263
|
-
|
|
264
|
-
def test_get_user_not_found(self, user_service, mock_database):
|
|
265
|
-
"""Test user not found scenario"""
|
|
266
|
-
user_service.db = mock_database
|
|
267
|
-
mock_database.query.return_value.first.return_value = None
|
|
268
|
-
|
|
269
|
-
with pytest.raises(UserNotFoundException):
|
|
270
|
-
user_service.get_user("invalid")
|
|
271
|
-
|
|
272
|
-
@pytest.mark.asyncio
|
|
273
|
-
async def test_async_operation(self, user_service):
|
|
274
|
-
"""Test async operations"""
|
|
275
|
-
result = await user_service.fetch_user_async("123")
|
|
276
|
-
assert result is not None
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Integration Testing
|
|
280
|
-
```python
|
|
281
|
-
# Integration testing with FastAPI/Django
|
|
282
|
-
from fastapi.testclient import TestClient
|
|
283
|
-
|
|
284
|
-
def test_api_endpoint():
|
|
285
|
-
"""Test API endpoint"""
|
|
286
|
-
client = TestClient(app)
|
|
287
|
-
|
|
288
|
-
response = client.get("/api/users/123")
|
|
289
|
-
|
|
290
|
-
assert response.status_code == 200
|
|
291
|
-
assert response.json()["id"] == "123"
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
---
|
|
295
|
-
|
|
296
|
-
## Framework Best Practices
|
|
297
|
-
|
|
298
|
-
### FastAPI Pattern
|
|
299
|
-
```python
|
|
300
|
-
# FastAPI application structure
|
|
301
|
-
from fastapi import FastAPI, Depends, HTTPException
|
|
302
|
-
from pydantic import BaseModel
|
|
303
|
-
|
|
304
|
-
app = FastAPI()
|
|
305
|
-
logger = DebugLogger('FastAPI')
|
|
306
|
-
|
|
307
|
-
class UserResponse(BaseModel):
|
|
308
|
-
id: str
|
|
309
|
-
name: str
|
|
310
|
-
email: str
|
|
311
|
-
|
|
312
|
-
@app.get("/users/{user_id}", response_model=UserResponse)
|
|
313
|
-
async def get_user(user_id: str, db: Database = Depends(get_database)):
|
|
314
|
-
"""Get user by ID"""
|
|
315
|
-
start_time = time.time()
|
|
316
|
-
logger.entry('get_user', {'user_id': user_id})
|
|
317
|
-
|
|
318
|
-
try:
|
|
319
|
-
user = await db.users.find_one({"id": user_id})
|
|
320
|
-
|
|
321
|
-
if not user:
|
|
322
|
-
raise HTTPException(status_code=404, detail="User not found")
|
|
323
|
-
|
|
324
|
-
duration = time.time() - start_time
|
|
325
|
-
logger.exit('get_user', user, duration)
|
|
326
|
-
|
|
327
|
-
return UserResponse(**user)
|
|
328
|
-
except Exception as e:
|
|
329
|
-
logger.error('get_user', e, {'user_id': user_id})
|
|
330
|
-
raise
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Django Pattern
|
|
334
|
-
```python
|
|
335
|
-
# Django view with logging
|
|
336
|
-
from django.http import JsonResponse
|
|
337
|
-
from django.views import View
|
|
338
|
-
|
|
339
|
-
logger = DebugLogger('DjangoViews')
|
|
340
|
-
|
|
341
|
-
class UserView(View):
|
|
342
|
-
"""User view handler"""
|
|
343
|
-
|
|
344
|
-
@debug_function(logger)
|
|
345
|
-
def get(self, request, user_id):
|
|
346
|
-
"""Get user by ID"""
|
|
347
|
-
try:
|
|
348
|
-
user = User.objects.get(id=user_id)
|
|
349
|
-
return JsonResponse({
|
|
350
|
-
'id': user.id,
|
|
351
|
-
'name': user.name,
|
|
352
|
-
'email': user.email
|
|
353
|
-
})
|
|
354
|
-
except User.DoesNotExist:
|
|
355
|
-
return JsonResponse({'error': 'User not found'}, status=404)
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Error Handling Patterns
|
|
361
|
-
|
|
362
|
-
### Custom Exceptions
|
|
363
|
-
```python
|
|
364
|
-
# Custom exception hierarchy
|
|
365
|
-
class ApplicationError(Exception):
|
|
366
|
-
"""Base application exception"""
|
|
367
|
-
|
|
368
|
-
def __init__(self, message: str, status_code: int = 500, context: dict | None = None):
|
|
369
|
-
super().__init__(message)
|
|
370
|
-
self.message = message
|
|
371
|
-
self.status_code = status_code
|
|
372
|
-
self.context = context or {}
|
|
373
|
-
|
|
374
|
-
class ValidationError(ApplicationError):
|
|
375
|
-
"""Validation error"""
|
|
376
|
-
|
|
377
|
-
def __init__(self, message: str, context: dict | None = None):
|
|
378
|
-
super().__init__(message, status_code=400, context=context)
|
|
379
|
-
|
|
380
|
-
class DatabaseError(ApplicationError):
|
|
381
|
-
"""Database operation error"""
|
|
382
|
-
|
|
383
|
-
def __init__(self, message: str, context: dict | None = None):
|
|
384
|
-
super().__init__(message, status_code=500, context=context)
|
|
385
|
-
|
|
386
|
-
class NotFoundError(ApplicationError):
|
|
387
|
-
"""Resource not found error"""
|
|
388
|
-
|
|
389
|
-
def __init__(self, message: str, context: dict | None = None):
|
|
390
|
-
super().__init__(message, status_code=404, context=context)
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### Exception Handling
|
|
394
|
-
```python
|
|
395
|
-
# Comprehensive error handling
|
|
396
|
-
async def safe_operation(operation: Callable, context: dict | None = None) -> Any:
|
|
397
|
-
"""Execute operation with error handling"""
|
|
398
|
-
logger = DebugLogger('SafeOperation')
|
|
399
|
-
|
|
400
|
-
try:
|
|
401
|
-
return await operation()
|
|
402
|
-
except ValidationError as e:
|
|
403
|
-
logger.error('safe_operation', e, context)
|
|
404
|
-
raise
|
|
405
|
-
except DatabaseError as e:
|
|
406
|
-
logger.error('safe_operation', e, context)
|
|
407
|
-
# Retry logic or fallback
|
|
408
|
-
raise
|
|
409
|
-
except Exception as e:
|
|
410
|
-
logger.error('safe_operation', e, context)
|
|
411
|
-
raise ApplicationError(f"Unexpected error: {str(e)}", context=context)
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
---
|
|
415
|
-
|
|
416
|
-
## Technology-Specific Command References
|
|
417
|
-
|
|
418
|
-
### Development Commands
|
|
419
|
-
```bash
|
|
420
|
-
# Python Development
|
|
421
|
-
python {{SOURCE_DIR}}/main.py # Run application
|
|
422
|
-
python -m {{SOURCE_DIR}}.main # Run as module
|
|
423
|
-
uvicorn main:app --reload # FastAPI development
|
|
424
|
-
python manage.py runserver # Django development
|
|
425
|
-
|
|
426
|
-
# Virtual Environment
|
|
427
|
-
python -m venv venv # Create venv
|
|
428
|
-
source venv/bin/activate # Activate (Unix)
|
|
429
|
-
venv\Scripts\activate # Activate (Windows)
|
|
430
|
-
pip install -r requirements.txt # Install dependencies
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### Testing Commands
|
|
434
|
-
```bash
|
|
435
|
-
# Testing
|
|
436
|
-
pytest # Run tests
|
|
437
|
-
pytest -v # Verbose output
|
|
438
|
-
pytest --cov={{SOURCE_DIR}} # Coverage report
|
|
439
|
-
pytest -k "test_user" # Run specific tests
|
|
440
|
-
pytest --pdb # Debug on failure
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
### Code Quality Commands
|
|
444
|
-
```bash
|
|
445
|
-
# Code Quality
|
|
446
|
-
black {{SOURCE_DIR}}/ # Format code
|
|
447
|
-
flake8 {{SOURCE_DIR}}/ # Lint code
|
|
448
|
-
mypy {{SOURCE_DIR}}/ # Type checking
|
|
449
|
-
pylint {{SOURCE_DIR}}/ # Comprehensive linting
|
|
450
|
-
isort {{SOURCE_DIR}}/ # Sort imports
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
## Type Hints Best Practices
|
|
456
|
-
|
|
457
|
-
### Comprehensive Type Annotations
|
|
458
|
-
```python
|
|
459
|
-
# Complete type hints
|
|
460
|
-
from typing import List, Dict, Optional, Union, Callable, Any
|
|
461
|
-
|
|
462
|
-
def process_users(
|
|
463
|
-
users: List[Dict[str, Any]],
|
|
464
|
-
filter_func: Optional[Callable[[Dict], bool]] = None,
|
|
465
|
-
limit: int = 100
|
|
466
|
-
) -> List[Dict[str, Any]]:
|
|
467
|
-
"""Process users with optional filtering"""
|
|
468
|
-
if filter_func:
|
|
469
|
-
users = [u for u in users if filter_func(u)]
|
|
470
|
-
return users[:limit]
|
|
471
|
-
|
|
472
|
-
# Generic types
|
|
473
|
-
from typing import TypeVar, Generic
|
|
474
|
-
|
|
475
|
-
T = TypeVar('T')
|
|
476
|
-
|
|
477
|
-
class Repository(Generic[T]):
|
|
478
|
-
"""Generic repository pattern"""
|
|
479
|
-
|
|
480
|
-
def find_by_id(self, id: str) -> Optional[T]:
|
|
481
|
-
"""Find entity by ID"""
|
|
482
|
-
pass
|
|
483
|
-
|
|
484
|
-
def find_all(self) -> List[T]:
|
|
485
|
-
"""Find all entities"""
|
|
486
|
-
pass
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
---
|
|
490
|
-
|
|
491
|
-
## Reference to Parent Context
|
|
492
|
-
|
|
493
|
-
This file extends the Trinity Method protocols defined in
|
|
494
|
-
|
|
495
|
-
- Trinity Method investigation requirements ([
|
|
496
|
-
- Global performance baselines ([
|
|
497
|
-
- Quality gate standards (BAS 6-phase) ([
|
|
498
|
-
- Crisis management protocols ([
|
|
499
|
-
|
|
500
|
-
All Python code must implement the debugging frameworks, error handling patterns, and performance monitoring specified in this document.
|
|
501
|
-
|
|
502
|
-
---
|
|
503
|
-
|
|
504
|
-
**Technology Context**: Python Implementation
|
|
505
|
-
**Parent References**:
|
|
506
|
-
- `../CLAUDE.md` - Global project requirements
|
|
507
|
-
-
|
|
508
|
-
|
|
509
|
-
**Last Updated**: {{CURRENT_DATE}}
|
|
510
|
-
**Trinity Version**: {{TRINITY_VERSION}}
|
|
1
|
+
# CLAUDE.md - Python Technology-Specific Rules
|
|
2
|
+
## {{PROJECT_NAME}} - Python Implementation
|
|
3
|
+
|
|
4
|
+
**Framework:** {{FRAMEWORK}}
|
|
5
|
+
**Language:** Python
|
|
6
|
+
**Source Directory:** {{SOURCE_DIR}}
|
|
7
|
+
**Package Manager:** pip/poetry/pipenv
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Technology Stack Behavioral Modifications
|
|
12
|
+
|
|
13
|
+
### Python-Specific Requirements
|
|
14
|
+
- **PEP 8 Compliance**: Follow PEP 8 style guide rigorously
|
|
15
|
+
- **Type Hints**: Use type hints for all function signatures (PEP 484)
|
|
16
|
+
- **Async/Await**: Use async/await for I/O-bound operations
|
|
17
|
+
- **Virtual Environments**: Always use virtual environments (venv, virtualenv, conda)
|
|
18
|
+
- **Context Managers**: Use context managers for resource management
|
|
19
|
+
|
|
20
|
+
### Framework-Specific Adaptations
|
|
21
|
+
- **Django**: Follow Django best practices and MVT pattern
|
|
22
|
+
- **FastAPI**: Implement dependency injection and Pydantic models
|
|
23
|
+
- **Flask**: Use blueprints for modular architecture
|
|
24
|
+
- **Data Science**: Use NumPy/Pandas best practices for data processing
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Technology Debugging Standards
|
|
29
|
+
|
|
30
|
+
### Python Debugging Framework
|
|
31
|
+
```python
|
|
32
|
+
# Standard debugging format for Python applications
|
|
33
|
+
import logging
|
|
34
|
+
import functools
|
|
35
|
+
import time
|
|
36
|
+
from typing import Any, Callable
|
|
37
|
+
from datetime import datetime
|
|
38
|
+
|
|
39
|
+
# Configure logging
|
|
40
|
+
logging.basicConfig(
|
|
41
|
+
level=logging.DEBUG,
|
|
42
|
+
format='[%(levelname)s] %(name)s.%(funcName)s - %(message)s'
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
class DebugLogger:
|
|
46
|
+
"""Standard debugging logger for Trinity Method"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, module_name: str):
|
|
49
|
+
self.logger = logging.getLogger(module_name)
|
|
50
|
+
self.module_name = module_name
|
|
51
|
+
|
|
52
|
+
def entry(self, func_name: str, params: dict[str, Any] | None = None) -> None:
|
|
53
|
+
"""Log function entry"""
|
|
54
|
+
self.logger.debug(f"[ENTRY] {func_name}", extra={
|
|
55
|
+
'params': params or {},
|
|
56
|
+
'timestamp': datetime.now().isoformat(),
|
|
57
|
+
'module': self.module_name
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
def exit(self, func_name: str, result: Any, duration: float) -> None:
|
|
61
|
+
"""Log function exit"""
|
|
62
|
+
self.logger.debug(f"[EXIT] {func_name}", extra={
|
|
63
|
+
'result': str(result)[:200], # Truncate large results
|
|
64
|
+
'duration_ms': f"{duration * 1000:.2f}",
|
|
65
|
+
'timestamp': datetime.now().isoformat()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
def error(self, func_name: str, error: Exception, context: dict[str, Any] | None = None) -> None:
|
|
69
|
+
"""Log errors"""
|
|
70
|
+
self.logger.error(f"[ERROR] {func_name}", extra={
|
|
71
|
+
'error': str(error),
|
|
72
|
+
'error_type': type(error).__name__,
|
|
73
|
+
'context': context or {},
|
|
74
|
+
'timestamp': datetime.now().isoformat()
|
|
75
|
+
}, exc_info=True)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# Decorator for automatic logging
|
|
79
|
+
def debug_function(logger: DebugLogger) -> Callable:
|
|
80
|
+
"""Decorator to automatically log function calls"""
|
|
81
|
+
|
|
82
|
+
def decorator(func: Callable) -> Callable:
|
|
83
|
+
@functools.wraps(func)
|
|
84
|
+
def wrapper(*args, **kwargs):
|
|
85
|
+
start_time = time.time()
|
|
86
|
+
logger.entry(func.__name__, {'args': args, 'kwargs': kwargs})
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
result = func(*args, **kwargs)
|
|
90
|
+
duration = time.time() - start_time
|
|
91
|
+
logger.exit(func.__name__, result, duration)
|
|
92
|
+
return result
|
|
93
|
+
except Exception as e:
|
|
94
|
+
logger.error(func.__name__, e, {'args': args, 'kwargs': kwargs})
|
|
95
|
+
raise
|
|
96
|
+
|
|
97
|
+
return wrapper
|
|
98
|
+
|
|
99
|
+
return decorator
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# Usage example
|
|
103
|
+
logger = DebugLogger('UserService')
|
|
104
|
+
|
|
105
|
+
@debug_function(logger)
|
|
106
|
+
def get_user(user_id: str) -> dict[str, Any]:
|
|
107
|
+
"""Fetch user by ID"""
|
|
108
|
+
# Implementation
|
|
109
|
+
return {"id": user_id, "name": "John Doe"}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Performance Optimization Rules
|
|
115
|
+
|
|
116
|
+
### Python Performance Monitoring
|
|
117
|
+
```python
|
|
118
|
+
# Performance measurement utilities
|
|
119
|
+
import time
|
|
120
|
+
import cProfile
|
|
121
|
+
import pstats
|
|
122
|
+
from contextlib import contextmanager
|
|
123
|
+
from typing import Generator
|
|
124
|
+
|
|
125
|
+
class PerformanceMonitor:
|
|
126
|
+
"""Performance monitoring utilities"""
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
@contextmanager
|
|
130
|
+
def measure(operation_name: str) -> Generator[None, None, None]:
|
|
131
|
+
"""Context manager for measuring operation duration"""
|
|
132
|
+
start_time = time.perf_counter()
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
yield
|
|
136
|
+
finally:
|
|
137
|
+
duration = time.perf_counter() - start_time
|
|
138
|
+
print(f"[PERF] {operation_name}: {duration * 1000:.2f}ms")
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def profile(func: Callable) -> Callable:
|
|
142
|
+
"""Decorator to profile function execution"""
|
|
143
|
+
|
|
144
|
+
@functools.wraps(func)
|
|
145
|
+
def wrapper(*args, **kwargs):
|
|
146
|
+
profiler = cProfile.Profile()
|
|
147
|
+
profiler.enable()
|
|
148
|
+
|
|
149
|
+
result = func(*args, **kwargs)
|
|
150
|
+
|
|
151
|
+
profiler.disable()
|
|
152
|
+
stats = pstats.Stats(profiler)
|
|
153
|
+
stats.strip_dirs()
|
|
154
|
+
stats.sort_stats('cumulative')
|
|
155
|
+
print(f"\n[PROFILE] {func.__name__}")
|
|
156
|
+
stats.print_stats(10) # Top 10 functions
|
|
157
|
+
|
|
158
|
+
return result
|
|
159
|
+
|
|
160
|
+
return wrapper
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# Usage
|
|
164
|
+
with PerformanceMonitor.measure("database_query"):
|
|
165
|
+
users = db.query(User).all()
|
|
166
|
+
|
|
167
|
+
@PerformanceMonitor.profile
|
|
168
|
+
def expensive_operation():
|
|
169
|
+
# Implementation
|
|
170
|
+
pass
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Security Best Practices
|
|
176
|
+
|
|
177
|
+
### Input Validation
|
|
178
|
+
```python
|
|
179
|
+
# Input validation patterns
|
|
180
|
+
from pydantic import BaseModel, EmailStr, validator, constr
|
|
181
|
+
|
|
182
|
+
class UserInput(BaseModel):
|
|
183
|
+
"""Validated user input model"""
|
|
184
|
+
email: EmailStr
|
|
185
|
+
username: constr(min_length=3, max_length=50)
|
|
186
|
+
password: constr(min_length=8)
|
|
187
|
+
|
|
188
|
+
@validator('password')
|
|
189
|
+
def password_strength(cls, v):
|
|
190
|
+
"""Validate password strength"""
|
|
191
|
+
if not any(c.isupper() for c in v):
|
|
192
|
+
raise ValueError('Password must contain uppercase letter')
|
|
193
|
+
if not any(c.isdigit() for c in v):
|
|
194
|
+
raise ValueError('Password must contain digit')
|
|
195
|
+
return v
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
# SQL injection prevention (use parameterized queries)
|
|
199
|
+
from sqlalchemy import text
|
|
200
|
+
|
|
201
|
+
# ❌ BAD: String concatenation
|
|
202
|
+
query = f"SELECT * FROM users WHERE id = {user_id}"
|
|
203
|
+
|
|
204
|
+
# ✅ GOOD: Parameterized query
|
|
205
|
+
query = text("SELECT * FROM users WHERE id = :user_id")
|
|
206
|
+
result = db.execute(query, {"user_id": user_id})
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Secure Configuration
|
|
210
|
+
```python
|
|
211
|
+
# Environment variable handling
|
|
212
|
+
from pydantic import BaseSettings
|
|
213
|
+
|
|
214
|
+
class Settings(BaseSettings):
|
|
215
|
+
"""Application settings from environment"""
|
|
216
|
+
database_url: str
|
|
217
|
+
secret_key: str
|
|
218
|
+
api_key: str
|
|
219
|
+
|
|
220
|
+
class Config:
|
|
221
|
+
env_file = ".env"
|
|
222
|
+
case_sensitive = False
|
|
223
|
+
|
|
224
|
+
settings = Settings()
|
|
225
|
+
|
|
226
|
+
# Never log sensitive values
|
|
227
|
+
logger.info(f"Database: {settings.database_url.split('@')[1]}") # Hide credentials
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Testing Requirements
|
|
233
|
+
|
|
234
|
+
### pytest Patterns
|
|
235
|
+
```python
|
|
236
|
+
# Unit testing with pytest
|
|
237
|
+
import pytest
|
|
238
|
+
from unittest.mock import Mock, patch
|
|
239
|
+
|
|
240
|
+
class TestUserService:
|
|
241
|
+
"""Test suite for UserService"""
|
|
242
|
+
|
|
243
|
+
@pytest.fixture
|
|
244
|
+
def user_service(self):
|
|
245
|
+
"""Fixture for UserService instance"""
|
|
246
|
+
return UserService()
|
|
247
|
+
|
|
248
|
+
@pytest.fixture
|
|
249
|
+
def mock_database(self):
|
|
250
|
+
"""Fixture for mocked database"""
|
|
251
|
+
return Mock()
|
|
252
|
+
|
|
253
|
+
def test_get_user_success(self, user_service, mock_database):
|
|
254
|
+
"""Test successful user retrieval"""
|
|
255
|
+
user_service.db = mock_database
|
|
256
|
+
mock_database.query.return_value.first.return_value = User(id="123", name="John")
|
|
257
|
+
|
|
258
|
+
user = user_service.get_user("123")
|
|
259
|
+
|
|
260
|
+
assert user is not None
|
|
261
|
+
assert user.id == "123"
|
|
262
|
+
assert user.name == "John"
|
|
263
|
+
|
|
264
|
+
def test_get_user_not_found(self, user_service, mock_database):
|
|
265
|
+
"""Test user not found scenario"""
|
|
266
|
+
user_service.db = mock_database
|
|
267
|
+
mock_database.query.return_value.first.return_value = None
|
|
268
|
+
|
|
269
|
+
with pytest.raises(UserNotFoundException):
|
|
270
|
+
user_service.get_user("invalid")
|
|
271
|
+
|
|
272
|
+
@pytest.mark.asyncio
|
|
273
|
+
async def test_async_operation(self, user_service):
|
|
274
|
+
"""Test async operations"""
|
|
275
|
+
result = await user_service.fetch_user_async("123")
|
|
276
|
+
assert result is not None
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Integration Testing
|
|
280
|
+
```python
|
|
281
|
+
# Integration testing with FastAPI/Django
|
|
282
|
+
from fastapi.testclient import TestClient
|
|
283
|
+
|
|
284
|
+
def test_api_endpoint():
|
|
285
|
+
"""Test API endpoint"""
|
|
286
|
+
client = TestClient(app)
|
|
287
|
+
|
|
288
|
+
response = client.get("/api/users/123")
|
|
289
|
+
|
|
290
|
+
assert response.status_code == 200
|
|
291
|
+
assert response.json()["id"] == "123"
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Framework Best Practices
|
|
297
|
+
|
|
298
|
+
### FastAPI Pattern
|
|
299
|
+
```python
|
|
300
|
+
# FastAPI application structure
|
|
301
|
+
from fastapi import FastAPI, Depends, HTTPException
|
|
302
|
+
from pydantic import BaseModel
|
|
303
|
+
|
|
304
|
+
app = FastAPI()
|
|
305
|
+
logger = DebugLogger('FastAPI')
|
|
306
|
+
|
|
307
|
+
class UserResponse(BaseModel):
|
|
308
|
+
id: str
|
|
309
|
+
name: str
|
|
310
|
+
email: str
|
|
311
|
+
|
|
312
|
+
@app.get("/users/{user_id}", response_model=UserResponse)
|
|
313
|
+
async def get_user(user_id: str, db: Database = Depends(get_database)):
|
|
314
|
+
"""Get user by ID"""
|
|
315
|
+
start_time = time.time()
|
|
316
|
+
logger.entry('get_user', {'user_id': user_id})
|
|
317
|
+
|
|
318
|
+
try:
|
|
319
|
+
user = await db.users.find_one({"id": user_id})
|
|
320
|
+
|
|
321
|
+
if not user:
|
|
322
|
+
raise HTTPException(status_code=404, detail="User not found")
|
|
323
|
+
|
|
324
|
+
duration = time.time() - start_time
|
|
325
|
+
logger.exit('get_user', user, duration)
|
|
326
|
+
|
|
327
|
+
return UserResponse(**user)
|
|
328
|
+
except Exception as e:
|
|
329
|
+
logger.error('get_user', e, {'user_id': user_id})
|
|
330
|
+
raise
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Django Pattern
|
|
334
|
+
```python
|
|
335
|
+
# Django view with logging
|
|
336
|
+
from django.http import JsonResponse
|
|
337
|
+
from django.views import View
|
|
338
|
+
|
|
339
|
+
logger = DebugLogger('DjangoViews')
|
|
340
|
+
|
|
341
|
+
class UserView(View):
|
|
342
|
+
"""User view handler"""
|
|
343
|
+
|
|
344
|
+
@debug_function(logger)
|
|
345
|
+
def get(self, request, user_id):
|
|
346
|
+
"""Get user by ID"""
|
|
347
|
+
try:
|
|
348
|
+
user = User.objects.get(id=user_id)
|
|
349
|
+
return JsonResponse({
|
|
350
|
+
'id': user.id,
|
|
351
|
+
'name': user.name,
|
|
352
|
+
'email': user.email
|
|
353
|
+
})
|
|
354
|
+
except User.DoesNotExist:
|
|
355
|
+
return JsonResponse({'error': 'User not found'}, status=404)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Error Handling Patterns
|
|
361
|
+
|
|
362
|
+
### Custom Exceptions
|
|
363
|
+
```python
|
|
364
|
+
# Custom exception hierarchy
|
|
365
|
+
class ApplicationError(Exception):
|
|
366
|
+
"""Base application exception"""
|
|
367
|
+
|
|
368
|
+
def __init__(self, message: str, status_code: int = 500, context: dict | None = None):
|
|
369
|
+
super().__init__(message)
|
|
370
|
+
self.message = message
|
|
371
|
+
self.status_code = status_code
|
|
372
|
+
self.context = context or {}
|
|
373
|
+
|
|
374
|
+
class ValidationError(ApplicationError):
|
|
375
|
+
"""Validation error"""
|
|
376
|
+
|
|
377
|
+
def __init__(self, message: str, context: dict | None = None):
|
|
378
|
+
super().__init__(message, status_code=400, context=context)
|
|
379
|
+
|
|
380
|
+
class DatabaseError(ApplicationError):
|
|
381
|
+
"""Database operation error"""
|
|
382
|
+
|
|
383
|
+
def __init__(self, message: str, context: dict | None = None):
|
|
384
|
+
super().__init__(message, status_code=500, context=context)
|
|
385
|
+
|
|
386
|
+
class NotFoundError(ApplicationError):
|
|
387
|
+
"""Resource not found error"""
|
|
388
|
+
|
|
389
|
+
def __init__(self, message: str, context: dict | None = None):
|
|
390
|
+
super().__init__(message, status_code=404, context=context)
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Exception Handling
|
|
394
|
+
```python
|
|
395
|
+
# Comprehensive error handling
|
|
396
|
+
async def safe_operation(operation: Callable, context: dict | None = None) -> Any:
|
|
397
|
+
"""Execute operation with error handling"""
|
|
398
|
+
logger = DebugLogger('SafeOperation')
|
|
399
|
+
|
|
400
|
+
try:
|
|
401
|
+
return await operation()
|
|
402
|
+
except ValidationError as e:
|
|
403
|
+
logger.error('safe_operation', e, context)
|
|
404
|
+
raise
|
|
405
|
+
except DatabaseError as e:
|
|
406
|
+
logger.error('safe_operation', e, context)
|
|
407
|
+
# Retry logic or fallback
|
|
408
|
+
raise
|
|
409
|
+
except Exception as e:
|
|
410
|
+
logger.error('safe_operation', e, context)
|
|
411
|
+
raise ApplicationError(f"Unexpected error: {str(e)}", context=context)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Technology-Specific Command References
|
|
417
|
+
|
|
418
|
+
### Development Commands
|
|
419
|
+
```bash
|
|
420
|
+
# Python Development
|
|
421
|
+
python {{SOURCE_DIR}}/main.py # Run application
|
|
422
|
+
python -m {{SOURCE_DIR}}.main # Run as module
|
|
423
|
+
uvicorn main:app --reload # FastAPI development
|
|
424
|
+
python manage.py runserver # Django development
|
|
425
|
+
|
|
426
|
+
# Virtual Environment
|
|
427
|
+
python -m venv venv # Create venv
|
|
428
|
+
source venv/bin/activate # Activate (Unix)
|
|
429
|
+
venv\Scripts\activate # Activate (Windows)
|
|
430
|
+
pip install -r requirements.txt # Install dependencies
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Testing Commands
|
|
434
|
+
```bash
|
|
435
|
+
# Testing
|
|
436
|
+
pytest # Run tests
|
|
437
|
+
pytest -v # Verbose output
|
|
438
|
+
pytest --cov={{SOURCE_DIR}} # Coverage report
|
|
439
|
+
pytest -k "test_user" # Run specific tests
|
|
440
|
+
pytest --pdb # Debug on failure
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Code Quality Commands
|
|
444
|
+
```bash
|
|
445
|
+
# Code Quality
|
|
446
|
+
black {{SOURCE_DIR}}/ # Format code
|
|
447
|
+
flake8 {{SOURCE_DIR}}/ # Lint code
|
|
448
|
+
mypy {{SOURCE_DIR}}/ # Type checking
|
|
449
|
+
pylint {{SOURCE_DIR}}/ # Comprehensive linting
|
|
450
|
+
isort {{SOURCE_DIR}}/ # Sort imports
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Type Hints Best Practices
|
|
456
|
+
|
|
457
|
+
### Comprehensive Type Annotations
|
|
458
|
+
```python
|
|
459
|
+
# Complete type hints
|
|
460
|
+
from typing import List, Dict, Optional, Union, Callable, Any
|
|
461
|
+
|
|
462
|
+
def process_users(
|
|
463
|
+
users: List[Dict[str, Any]],
|
|
464
|
+
filter_func: Optional[Callable[[Dict], bool]] = None,
|
|
465
|
+
limit: int = 100
|
|
466
|
+
) -> List[Dict[str, Any]]:
|
|
467
|
+
"""Process users with optional filtering"""
|
|
468
|
+
if filter_func:
|
|
469
|
+
users = [u for u in users if filter_func(u)]
|
|
470
|
+
return users[:limit]
|
|
471
|
+
|
|
472
|
+
# Generic types
|
|
473
|
+
from typing import TypeVar, Generic
|
|
474
|
+
|
|
475
|
+
T = TypeVar('T')
|
|
476
|
+
|
|
477
|
+
class Repository(Generic[T]):
|
|
478
|
+
"""Generic repository pattern"""
|
|
479
|
+
|
|
480
|
+
def find_by_id(self, id: str) -> Optional[T]:
|
|
481
|
+
"""Find entity by ID"""
|
|
482
|
+
pass
|
|
483
|
+
|
|
484
|
+
def find_all(self) -> List[T]:
|
|
485
|
+
"""Find all entities"""
|
|
486
|
+
pass
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Reference to Parent Context
|
|
492
|
+
|
|
493
|
+
This file extends the Trinity Method protocols defined in `../.claude/trinity/CLAUDE.md` and global requirements from `../CLAUDE.md`. Python implementations must comply with:
|
|
494
|
+
|
|
495
|
+
- Trinity Method investigation requirements ([../.claude/trinity/CLAUDE.md](../.claude/trinity/CLAUDE.md))
|
|
496
|
+
- Global performance baselines ([../.claude/trinity/knowledge-base/ARCHITECTURE.md](../.claude/trinity/knowledge-base/ARCHITECTURE.md#performance-baseline))
|
|
497
|
+
- Quality gate standards (BAS 6-phase) ([../.claude/trinity/CLAUDE.md](../.claude/trinity/CLAUDE.md#quality-standards))
|
|
498
|
+
- Crisis management protocols ([../.claude/trinity/CLAUDE.md](../.claude/trinity/CLAUDE.md#crisis-management))
|
|
499
|
+
|
|
500
|
+
All Python code must implement the debugging frameworks, error handling patterns, and performance monitoring specified in this document.
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
**Technology Context**: Python Implementation
|
|
505
|
+
**Parent References**:
|
|
506
|
+
- `../CLAUDE.md` - Global project requirements
|
|
507
|
+
- `../.claude/trinity/CLAUDE.md` - Trinity Method enforcement
|
|
508
|
+
|
|
509
|
+
**Last Updated**: {{CURRENT_DATE}}
|
|
510
|
+
**Trinity Version**: {{TRINITY_VERSION}}
|