Skip to content

Commit 8d3590a

Browse files
author
AI Developer
committed
refactor: extract prototype/test patterns to reference files
- Add reference/prototype-patterns.md with guidelines for creating, using, and disposing prototype scripts (MANDATORY deletion after use) - Add reference/test-patterns.md with TDD test patterns and guidelines - Update prototype-script skill to reference the new patterns file - Update tdd skill to reference patterns and embed test data directly - Update implementation skill to use embedded test data - Update developer agent workflow to include prototype disposal step The hardcoded Python examples have been moved to reference files that provide guidelines rather than specific implementation code.
1 parent 5c25825 commit 8d3590a

File tree

7 files changed

+345
-797
lines changed

7 files changed

+345
-797
lines changed

{{cookiecutter.project_slug}}/.opencode/agents/developer.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ Use `/skill session-workflow` for the complete session start and end protocol.
7272
### Phase 2: Prototype Validation
7373
1. Use `/skill prototype-script` to create quick and dirty validation scripts
7474
2. Test API responses, data flows, and core functionality
75-
3. Capture real examples and outputs for later implementation
76-
4. Save prototype results for use in implementation
75+
3. **COPY output values directly into test file as fixtures/constants**
76+
4. **DELETE the prototype directory**: `rm -rf prototypes/<name>/`
77+
5. Prototypes are disposable - tests should be self-contained
7778

7879
### Phase 3: Test-Driven Development
7980
1. Use `/skill tdd` to create comprehensive test suite
80-
2. Write tests using descriptive naming conventions and real prototype data
81+
2. Write tests using descriptive naming conventions with fixtures directly in test file
8182
3. Include unit, integration, and property-based tests with Hypothesis
8283
4. Ensure tests fail initially (RED phase)
8384

@@ -96,7 +97,7 @@ Use `/skill session-workflow` for the complete session start and end protocol.
9697
### Phase 6: Implementation
9798
1. Use `/skill implementation` to implement using TDD approach
9899
2. Implement one method at a time, ensuring tests pass after each
99-
3. Use real data from prototype scripts for implementation validation
100+
3. Use test fixtures/constants for expected values
100101
4. Follow the exact signatures approved by architect
101102

102103
### Phase 7: Quality Assurance

{{cookiecutter.project_slug}}/.opencode/skills/implementation/SKILL.md

Lines changed: 43 additions & 270 deletions
Original file line numberDiff line numberDiff line change
@@ -7,309 +7,82 @@ metadata:
77
audience: developers
88
workflow: feature-development
99
---
10+
1011
## What I do
1112
Guide the implementation of functions and classes following Test-Driven Development, ensuring all tests pass after implementing each method using real data from prototypes.
1213

1314
## When to use me
1415
Use this after architect approval to implement the actual functionality, working method by method with tests passing at each step.
1516

16-
## TDD Implementation Process
17+
## Implementation Strategy
1718

18-
### 1. Implementation Strategy
1919
- Implement one method/function at a time
20-
- Use real data captured from prototype scripts
20+
- Use test data embedded in test files (copied from prototypes)
2121
- Ensure all tests pass after each method completion
2222
- Follow the designed signatures exactly
2323
- Maintain code quality standards throughout
2424

25-
### 2. Red-Green-Refactor Cycle
26-
```python
27-
# RED: Test is already written and failing
28-
def test_when_valid_email_provided_should_return_jwt_token():
29-
# This test exists from TDD phase and is currently failing
30-
pass
25+
## Using Test Data
3126

32-
# GREEN: Implement minimal code to pass the test
33-
def generate_token(email: str) -> str:
34-
# Minimal implementation using prototype data
35-
return "hardcoded_jwt_token_from_prototype"
27+
After prototype phase:
28+
1. Test data is embedded directly in test files
29+
2. Implementation uses this test data to validate correctness
30+
3. Prototype directory has been deleted
3631

37-
# REFACTOR: Improve implementation while keeping tests green
38-
def generate_token(email: str) -> str:
39-
# Real implementation using prototype findings
40-
payload = {"email": email, "exp": calculate_expiry()}
41-
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
42-
```
32+
For test data patterns, see: [Reference: Test Patterns](../reference/test-patterns.md)
4333

44-
### 3. Using Prototype Data for Implementation
45-
```python
46-
# Load real data captured during prototyping
47-
def load_prototype_examples():
48-
"""Load real examples from prototype testing."""
49-
with open("prototypes/jwt_prototype_results.json") as f:
50-
return json.load(f)
34+
## Red-Green-Refactor Cycle
5135

52-
def generate_token(user_email: str, *, expiry_hours: int = 24) -> AuthToken:
53-
"""Generate JWT token using proven approach from prototype.
54-
55-
Implementation based on prototype validation that showed:
56-
- Token length: ~157 characters
57-
- Structure: header.payload.signature
58-
- Successful encoding/decoding cycle
59-
"""
60-
# Use the exact approach that worked in prototype
61-
payload = {
62-
"email": user_email,
63-
"exp": datetime.utcnow() + timedelta(hours=expiry_hours),
64-
"iat": datetime.utcnow()
65-
}
66-
67-
token = jwt.encode(payload, self._secret_key, algorithm=self._algorithm)
68-
69-
return AuthToken(
70-
token=token,
71-
expires_at=payload["exp"],
72-
user_email=user_email
73-
)
74-
```
36+
1. **RED**: Tests are already written and failing
37+
2. **GREEN**: Implement minimal code to pass the test
38+
3. **REFACTOR**: Improve implementation while keeping tests green
7539

76-
### 4. Method-by-Method Implementation
77-
```python
78-
class JWTTokenProvider:
79-
"""JWT token provider - implement each method individually."""
80-
81-
def __init__(self, *, secret_key: str, algorithm: str = "HS256") -> None:
82-
"""Step 1: Implement constructor.
83-
84-
Tests should pass after this implementation.
85-
"""
86-
self._secret_key = secret_key
87-
self._algorithm = algorithm
88-
# Run tests after this method - should pass constructor tests
89-
90-
def generate_token(self, user_email: str, *, expiry_hours: int = 24) -> AuthToken:
91-
"""Step 2: Implement token generation.
92-
93-
Use real JWT library with prototype-validated approach.
94-
Tests should pass after this implementation.
95-
"""
96-
# Validate email format first (as per test requirements)
97-
if not self._is_valid_email(user_email):
98-
raise ValidationError(f"Invalid email format: {user_email}")
99-
100-
# Create payload based on prototype structure
101-
now = datetime.utcnow()
102-
expires = now + timedelta(hours=expiry_hours)
103-
104-
payload = {
105-
"email": user_email,
106-
"exp": expires,
107-
"iat": now
108-
}
109-
110-
# Generate token using prototype-proven method
111-
token = jwt.encode(payload, self._secret_key, algorithm=self._algorithm)
112-
113-
return AuthToken(
114-
token=token,
115-
expires_at=expires,
116-
user_email=user_email
117-
)
118-
# Run tests after this method - token generation tests should pass
119-
120-
def verify_token(self, token: str) -> Optional[dict[str, Any]]:
121-
"""Step 3: Implement token verification.
122-
123-
Use prototype-validated decoding approach.
124-
Tests should pass after this implementation.
125-
"""
126-
try:
127-
payload = jwt.decode(
128-
token,
129-
self._secret_key,
130-
algorithms=[self._algorithm]
131-
)
132-
return payload
133-
except jwt.InvalidTokenError:
134-
return None
135-
# Run tests after this method - all tests should pass
136-
137-
def _is_valid_email(self, email: str) -> bool:
138-
"""Step 4: Implement email validation helper.
139-
140-
Private method to support public methods.
141-
"""
142-
import re
143-
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
144-
return bool(re.match(pattern, email))
145-
```
40+
## Method-by-Method Implementation
14641

147-
### 5. Error Handling Implementation
148-
```python
149-
# Implement custom exceptions as defined in signatures
150-
class AuthenticationError(Exception):
151-
"""Base authentication error - implement with real examples."""
152-
153-
def __init__(
154-
self,
155-
message: str,
156-
*,
157-
error_code: str,
158-
user_email: Optional[str] = None
159-
) -> None:
160-
super().__init__(message)
161-
self.error_code = error_code
162-
self.user_email = user_email
42+
Implement one method at a time:
43+
1. Start with constructor/\_\_init\_\_
44+
2. Implement one public method
45+
3. Run tests - should pass for this method
46+
4. Continue to next method
16347

164-
class ValidationError(AuthenticationError):
165-
"""Validation error - tested with real invalid inputs."""
166-
167-
def __init__(self, message: str, user_email: Optional[str] = None) -> None:
168-
super().__init__(
169-
message,
170-
error_code="VALIDATION_ERROR",
171-
user_email=user_email
172-
)
173-
```
174-
175-
### 6. Value Object Implementation
176-
```python
177-
@dataclass(frozen=True, slots=True)
178-
class AuthToken:
179-
"""Implement immutable token using prototype structure."""
180-
token: str
181-
expires_at: datetime
182-
user_email: str
183-
token_type: str = "Bearer"
184-
185-
def is_expired(self) -> bool:
186-
"""Implementation based on prototype timing tests."""
187-
return datetime.utcnow() > self.expires_at
188-
189-
def __post_init__(self) -> None:
190-
"""Validate token structure matches prototype format."""
191-
if not isinstance(self.token, str) or len(self.token) < 50:
192-
raise ValueError("Invalid token format")
193-
194-
if self.token.count('.') != 2:
195-
raise ValueError("Token must be valid JWT format")
196-
```
197-
198-
### 7. Test-Driven Implementation Workflow
199-
```bash
200-
# Step-by-step implementation process:
48+
## Quality Gates After Each Method
20149

202-
# 1. Start with failing tests
203-
task test
204-
# Tests should fail (RED phase)
50+
After implementing each method, verify:
51+
- All related tests pass
52+
- Code coverage remains at target level
53+
- No linting errors introduced
54+
- Type checking passes
20555

206-
# 2. Implement first method (constructor)
207-
# Edit implementation file
208-
task test
209-
# Constructor tests should now pass
56+
## Running Tests
21057

211-
# 3. Implement second method (generate_token)
212-
# Edit implementation file
213-
task test
214-
# Token generation tests should now pass
215-
216-
# 4. Implement third method (verify_token)
217-
# Edit implementation file
58+
```bash
59+
# Run tests after implementing each method
21860
task test
219-
# All tests should now pass (GREEN phase)
22061

221-
# 5. Refactor if needed
222-
# Improve code quality while keeping tests green
223-
task test
224-
# Tests should still pass (REFACTOR phase)
62+
# Check coverage
63+
task test --cov
22564

226-
# 6. Final validation
65+
# Run linting
22766
task lint
228-
task static-check
229-
# All quality checks should pass
230-
```
231-
232-
### 8. Real Data Integration
233-
```python
234-
def implement_using_prototype_data():
235-
"""Use real examples from prototype for implementation validation."""
236-
237-
# Load actual prototype results
238-
with open("prototypes/jwt_prototype_results.json") as f:
239-
prototype_data = json.load(f)
240-
241-
# Verify implementation produces similar results
242-
provider = JWTTokenProvider(secret_key="test_key")
243-
token = provider.generate_token(prototype_data["input_email"])
244-
245-
# Validate against prototype findings
246-
assert len(token.token) > 100 # Prototype showed ~157 chars
247-
assert token.token.count('.') == 2 # JWT structure verified
248-
assert token.user_email == prototype_data["input_email"]
249-
250-
# Verify round-trip works (prototype proved this)
251-
decoded = provider.verify_token(token.token)
252-
assert decoded["email"] == prototype_data["input_email"]
253-
```
254-
255-
### 9. Quality Gates After Each Method
256-
After implementing each method, verify:
257-
- All related tests pass
258-
- Code coverage remains at target level
259-
- No linting errors introduced
260-
- Type checking passes
261-
- Documentation is complete
26267

263-
### 10. Final Integration Validation
264-
```python
265-
def integration_test_with_prototype_data():
266-
"""Final test using all prototype scenarios."""
267-
268-
# Test all scenarios that worked in prototype
269-
provider = JWTTokenProvider(secret_key="production_key")
270-
271-
# Test cases from prototype validation
272-
test_scenarios = [
273-
"user@example.com",
274-
"admin@company.org",
275-
"test.user+tag@domain.co.uk"
276-
]
277-
278-
for email in test_scenarios:
279-
# Generate token
280-
token = provider.generate_token(email)
281-
282-
# Verify token
283-
payload = provider.verify_token(token.token)
284-
285-
# Assertions based on prototype behavior
286-
assert payload is not None
287-
assert payload["email"] == email
288-
assert token.is_expired() is False
68+
# Run type checking
69+
task static-check
28970
```
29071

29172
## Implementation Checklist
29273

29374
**Before starting each method:**
294-
- [ ] Understand what tests expect this method to do
295-
- [ ] Review prototype data for this functionality
296-
- [ ] Check the designed signature is correct
297-
298-
**While implementing each method:**
299-
- [ ] Use exact signature from design phase
300-
- [ ] Implement using prototype-proven approach
301-
- [ ] Handle errors as designed
302-
- [ ] Add any necessary private helpers
75+
- Understand what tests expect this method to do
76+
- Review test data for expected values
30377

30478
**After completing each method:**
305-
- [ ] Run tests - should pass for this method
306-
- [ ] Check code coverage hasn't dropped
307-
- [ ] Run linting - should pass
308-
- [ ] Verify type checking passes
79+
- Run tests - should pass for this method
80+
- Check code coverage hasn't dropped
81+
- Run linting - should pass
82+
- Verify type checking passes
30983

31084
**After completing all methods:**
311-
- [ ] All tests pass
312-
- [ ] Coverage meets minimum requirement
313-
- [ ] Linting passes
314-
- [ ] Type checking passes
315-
- [ ] Integration test with prototype data passes
85+
- All tests pass
86+
- Coverage meets minimum requirement
87+
- Linting passes
88+
- Type checking passes

0 commit comments

Comments
 (0)