create-baton 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/bin/create-baton.js +9 -0
- package/package.json +36 -0
- package/src/constants.js +30 -0
- package/src/index.js +35 -0
- package/src/prompts.js +54 -0
- package/src/scaffold.js +193 -0
- package/templates/BATON_v3.1.md +849 -0
- package/templates/ide/CLAUDE.md.template +105 -0
- package/templates/ide/cursorrules.template +64 -0
- package/templates/skills/core/anti-overengineering/SKILL.md +180 -0
- package/templates/skills/core/cost-awareness/SKILL.md +207 -0
- package/templates/skills/core/launch-prep/SKILL.md +232 -0
- package/templates/skills/core/milestones/SKILL.md +167 -0
- package/templates/skills/core/production-readiness/SKILL.md +307 -0
- package/templates/skills/core/security/SKILL.md +309 -0
- package/templates/skills/core/testing/SKILL.md +307 -0
- package/templates/skills/core/ui-ux/SKILL.md +155 -0
- package/templates/skills/patterns/api-integration/SKILL.md +143 -0
- package/templates/skills/stacks/nextjs/SKILL.md +230 -0
- package/templates/skills/stacks/supabase/SKILL.md +402 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security
|
|
3
|
+
description: >-
|
|
4
|
+
Universal security rules for every project. Covers secrets management,
|
|
5
|
+
database security, input validation, authentication, API security, and
|
|
6
|
+
common vulnerabilities. Use when building auth, handling user data,
|
|
7
|
+
setting up databases, or reviewing security.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Security Skill — Universal Rules
|
|
11
|
+
|
|
12
|
+
> These rules apply to EVERY project, regardless of stack or domain.
|
|
13
|
+
> Violations are blockers. Do not ship without addressing them.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Secrets Management
|
|
18
|
+
|
|
19
|
+
### Never Commit Secrets
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
# BLOCKED - Never do this
|
|
23
|
+
const API_KEY = "sk-live-abc123..."
|
|
24
|
+
const DATABASE_URL = "postgres://user:password@..."
|
|
25
|
+
|
|
26
|
+
# CORRECT - Use environment variables
|
|
27
|
+
const API_KEY = process.env.API_KEY
|
|
28
|
+
const DATABASE_URL = process.env.DATABASE_URL
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Environment Variable Rules
|
|
32
|
+
|
|
33
|
+
| Variable Type | Prefix | Exposed To |
|
|
34
|
+
|--------------|--------|------------|
|
|
35
|
+
| Server-only secrets | None | Server only |
|
|
36
|
+
| Public keys | NEXT_PUBLIC_ / VITE_ | Client + Server |
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# .env.local (never commit)
|
|
40
|
+
DATABASE_URL=... # Server only
|
|
41
|
+
API_SECRET=... # Server only
|
|
42
|
+
NEXT_PUBLIC_APP_URL=... # Safe for client
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Check Before Commit
|
|
46
|
+
|
|
47
|
+
Before every commit, verify:
|
|
48
|
+
- [ ] No hardcoded secrets in code
|
|
49
|
+
- [ ] .env files in .gitignore
|
|
50
|
+
- [ ] No secrets in error messages or logs
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Database Security
|
|
55
|
+
|
|
56
|
+
### Row Level Security (RLS)
|
|
57
|
+
|
|
58
|
+
**MANDATORY for all tables.** No exceptions.
|
|
59
|
+
|
|
60
|
+
```sql
|
|
61
|
+
-- Enable RLS on every table
|
|
62
|
+
ALTER TABLE items ENABLE ROW LEVEL SECURITY;
|
|
63
|
+
|
|
64
|
+
-- Default deny - explicit policies required
|
|
65
|
+
CREATE POLICY "Users see own data"
|
|
66
|
+
ON items FOR SELECT
|
|
67
|
+
USING (auth.uid() = user_id);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Verify RLS Is Enabled
|
|
71
|
+
|
|
72
|
+
```sql
|
|
73
|
+
-- Check all tables have RLS
|
|
74
|
+
SELECT tablename, rowsecurity
|
|
75
|
+
FROM pg_tables
|
|
76
|
+
WHERE schemaname = 'public';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Every table should show `rowsecurity = true`.
|
|
80
|
+
|
|
81
|
+
### Service Role Key
|
|
82
|
+
|
|
83
|
+
- Use ONLY in server-side code
|
|
84
|
+
- NEVER expose to client
|
|
85
|
+
- Use for admin operations and background jobs only
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Input Validation
|
|
90
|
+
|
|
91
|
+
### Validate All Inputs
|
|
92
|
+
|
|
93
|
+
Every form, API endpoint, and server action MUST validate input.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// REQUIRED - Use Zod or similar
|
|
97
|
+
import { z } from 'zod'
|
|
98
|
+
|
|
99
|
+
const schema = z.object({
|
|
100
|
+
email: z.string().email(),
|
|
101
|
+
name: z.string().min(1).max(100),
|
|
102
|
+
age: z.number().int().positive().optional(),
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// Validate before using
|
|
106
|
+
const result = schema.safeParse(input)
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
return { error: 'Invalid input' }
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Never Trust Client Data
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// BAD - Trusting client-provided user ID
|
|
116
|
+
const userId = req.body.userId // User can send any ID!
|
|
117
|
+
|
|
118
|
+
// GOOD - Get user ID from authenticated session
|
|
119
|
+
const userId = session.user.id // Server-verified
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Authentication
|
|
125
|
+
|
|
126
|
+
### Verify Auth on Every Protected Route
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Server component
|
|
130
|
+
const user = await getAuthenticatedUser()
|
|
131
|
+
if (!user) {
|
|
132
|
+
redirect('/login')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// API route
|
|
136
|
+
export async function POST(req: Request) {
|
|
137
|
+
const user = await getAuthenticatedUser()
|
|
138
|
+
if (!user) {
|
|
139
|
+
return Response.json({ error: 'Unauthorized' }, { status: 401 })
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Session Security
|
|
145
|
+
|
|
146
|
+
- Use HTTP-only cookies for tokens (not localStorage)
|
|
147
|
+
- Set secure flag in production
|
|
148
|
+
- Implement session expiry
|
|
149
|
+
- Rotate tokens on privilege changes
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## API Security
|
|
154
|
+
|
|
155
|
+
### Rate Limiting
|
|
156
|
+
|
|
157
|
+
All public endpoints MUST have rate limiting.
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Example with Upstash
|
|
161
|
+
import { Ratelimit } from '@upstash/ratelimit'
|
|
162
|
+
|
|
163
|
+
const ratelimit = new Ratelimit({
|
|
164
|
+
limiter: Ratelimit.slidingWindow(10, '10 s'), // 10 requests per 10 seconds
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
const { success } = await ratelimit.limit(identifier)
|
|
168
|
+
if (!success) {
|
|
169
|
+
return Response.json({ error: 'Too many requests' }, { status: 429 })
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### CORS
|
|
174
|
+
|
|
175
|
+
Configure CORS to allow only trusted origins:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// Only allow your domain
|
|
179
|
+
const allowedOrigins = ['https://yourdomain.com']
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## File Uploads
|
|
185
|
+
|
|
186
|
+
### Validate Before Accepting
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// Check file type
|
|
190
|
+
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']
|
|
191
|
+
if (!allowedTypes.includes(file.type)) {
|
|
192
|
+
return { error: 'Invalid file type' }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Check file size (e.g., 5MB max)
|
|
196
|
+
const maxSize = 5 * 1024 * 1024
|
|
197
|
+
if (file.size > maxSize) {
|
|
198
|
+
return { error: 'File too large' }
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Store Securely
|
|
203
|
+
|
|
204
|
+
- Use signed URLs for private files
|
|
205
|
+
- Set appropriate expiry times
|
|
206
|
+
- Never serve user uploads from your main domain (use CDN/storage domain)
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Error Handling
|
|
211
|
+
|
|
212
|
+
### Never Expose Internal Errors
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// BAD - Exposes internal details
|
|
216
|
+
catch (error) {
|
|
217
|
+
return { error: error.message } // Could leak DB schema, paths, etc.
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// GOOD - Generic message, log internally
|
|
221
|
+
catch (error) {
|
|
222
|
+
console.error('Operation failed:', error) // Log for debugging
|
|
223
|
+
return { error: 'Something went wrong' } // Safe for user
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Log Sensitive Operations
|
|
228
|
+
|
|
229
|
+
Log but don't expose:
|
|
230
|
+
- Failed login attempts
|
|
231
|
+
- Permission denied events
|
|
232
|
+
- Unusual patterns (many requests, odd hours)
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## HTTPS
|
|
237
|
+
|
|
238
|
+
### Enforce HTTPS Everywhere
|
|
239
|
+
|
|
240
|
+
- All production traffic over HTTPS
|
|
241
|
+
- Redirect HTTP to HTTPS
|
|
242
|
+
- Use HSTS headers
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Middleware example
|
|
246
|
+
if (process.env.NODE_ENV === 'production' && !req.secure) {
|
|
247
|
+
return Response.redirect(`https://${req.host}${req.url}`)
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Security Headers
|
|
254
|
+
|
|
255
|
+
Add these headers in production:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// next.config.js or middleware
|
|
259
|
+
const securityHeaders = [
|
|
260
|
+
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
261
|
+
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
262
|
+
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
|
263
|
+
{ key: 'X-XSS-Protection', value: '1; mode=block' },
|
|
264
|
+
]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Content Security Policy (CSP)
|
|
268
|
+
|
|
269
|
+
For apps with user content or third-party scripts:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
{
|
|
273
|
+
key: 'Content-Security-Policy',
|
|
274
|
+
value: "default-src 'self'; script-src 'self' 'unsafe-inline'..."
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Quick Checklist
|
|
281
|
+
|
|
282
|
+
Before any release:
|
|
283
|
+
|
|
284
|
+
- [ ] No secrets in code or logs
|
|
285
|
+
- [ ] RLS enabled on all tables
|
|
286
|
+
- [ ] All inputs validated with Zod
|
|
287
|
+
- [ ] Auth checked on all protected routes
|
|
288
|
+
- [ ] Rate limiting on public APIs
|
|
289
|
+
- [ ] File uploads validated (type + size)
|
|
290
|
+
- [ ] Error messages don't leak internals
|
|
291
|
+
- [ ] HTTPS enforced
|
|
292
|
+
- [ ] Security headers configured
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Common Vulnerabilities to Avoid
|
|
297
|
+
|
|
298
|
+
| Vulnerability | Prevention |
|
|
299
|
+
|--------------|------------|
|
|
300
|
+
| SQL Injection | Use parameterized queries (ORMs do this) |
|
|
301
|
+
| XSS | Escape user content, use CSP |
|
|
302
|
+
| CSRF | Use anti-CSRF tokens (frameworks handle this) |
|
|
303
|
+
| Broken Auth | Verify session on every request |
|
|
304
|
+
| Sensitive Data Exposure | Encrypt at rest, HTTPS in transit |
|
|
305
|
+
| Insecure File Upload | Validate type/size, use signed URLs |
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
*Last updated: Baton Protocol v3.1*
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: >-
|
|
4
|
+
Universal testing standards for any project. Covers build verification,
|
|
5
|
+
smoke testing, automated test levels, and session testing protocol.
|
|
6
|
+
Use when setting up tests, reviewing test coverage, discussing testing
|
|
7
|
+
strategy, or when the user asks about testing.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Testing Skill — Universal Rules
|
|
11
|
+
|
|
12
|
+
> Testing standards that apply to every project.
|
|
13
|
+
> Not all projects need all tests, but all projects need SOME testing.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Testing Philosophy
|
|
18
|
+
|
|
19
|
+
### The Minimum Viable Testing Rule
|
|
20
|
+
|
|
21
|
+
Every project MUST have at least:
|
|
22
|
+
1. **Build verification** — Code compiles without errors
|
|
23
|
+
2. **Smoke test** — Core user flows work manually
|
|
24
|
+
3. **Critical path coverage** — Main features don't break
|
|
25
|
+
|
|
26
|
+
### When to Add More Testing
|
|
27
|
+
|
|
28
|
+
| Project Stage | Testing Level |
|
|
29
|
+
|---------------|--------------|
|
|
30
|
+
| MVP / Prototype | Build + manual smoke test |
|
|
31
|
+
| Beta / Early users | Add critical path tests |
|
|
32
|
+
| Production / Paying users | Comprehensive test suite |
|
|
33
|
+
|
|
34
|
+
Don't over-test early. Don't under-test late.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Build Verification
|
|
39
|
+
|
|
40
|
+
### Always Required
|
|
41
|
+
|
|
42
|
+
Before ending ANY session:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Must pass with no errors
|
|
46
|
+
npm run build # or yarn build, pnpm build
|
|
47
|
+
|
|
48
|
+
# TypeScript projects
|
|
49
|
+
npx tsc --noEmit # Type check only
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### What "Build Passes" Means
|
|
53
|
+
|
|
54
|
+
- [ ] No compilation errors
|
|
55
|
+
- [ ] No TypeScript errors
|
|
56
|
+
- [ ] No unresolved imports
|
|
57
|
+
- [ ] Build output generated successfully
|
|
58
|
+
|
|
59
|
+
**If build fails, session is NOT complete.**
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Manual Smoke Testing
|
|
64
|
+
|
|
65
|
+
### What to Test Each Session
|
|
66
|
+
|
|
67
|
+
After completing tasks, manually verify:
|
|
68
|
+
|
|
69
|
+
1. **New features work** — Demo what you just built
|
|
70
|
+
2. **Core flows still work** — Login, main action, logout
|
|
71
|
+
3. **No visual regressions** — UI looks correct
|
|
72
|
+
|
|
73
|
+
### Smoke Test Checklist Template
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
## Session N Smoke Test
|
|
77
|
+
|
|
78
|
+
### New Features
|
|
79
|
+
- [ ] [Feature 1] works as expected
|
|
80
|
+
- [ ] [Feature 2] works as expected
|
|
81
|
+
|
|
82
|
+
### Core Flows
|
|
83
|
+
- [ ] Can log in
|
|
84
|
+
- [ ] Can perform main action
|
|
85
|
+
- [ ] Can log out
|
|
86
|
+
|
|
87
|
+
### Visual Check
|
|
88
|
+
- [ ] No layout breaks
|
|
89
|
+
- [ ] No missing elements
|
|
90
|
+
- [ ] Mobile view works (if applicable)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Automated Testing Levels
|
|
96
|
+
|
|
97
|
+
### Level 1: Unit Tests
|
|
98
|
+
|
|
99
|
+
Test individual functions in isolation.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// Example: Testing a utility function
|
|
103
|
+
import { formatCurrency } from '@/lib/utils'
|
|
104
|
+
|
|
105
|
+
describe('formatCurrency', () => {
|
|
106
|
+
it('formats cents to dollars', () => {
|
|
107
|
+
expect(formatCurrency(1000)).toBe('$10.00')
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('handles zero', () => {
|
|
111
|
+
expect(formatCurrency(0)).toBe('$0.00')
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**When to add:** When you have pure functions with business logic.
|
|
117
|
+
|
|
118
|
+
### Level 2: Integration Tests
|
|
119
|
+
|
|
120
|
+
Test multiple components working together.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Example: Testing a server action
|
|
124
|
+
import { createItem } from '@/lib/actions/items'
|
|
125
|
+
|
|
126
|
+
describe('createItem', () => {
|
|
127
|
+
it('creates item and returns it', async () => {
|
|
128
|
+
const result = await createItem({
|
|
129
|
+
name: 'Test Item',
|
|
130
|
+
userId: 'test-user-id',
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
expect(result.success).toBe(true)
|
|
134
|
+
expect(result.data.name).toBe('Test Item')
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**When to add:** When you have server actions or API routes with critical logic.
|
|
140
|
+
|
|
141
|
+
### Level 3: End-to-End Tests
|
|
142
|
+
|
|
143
|
+
Test full user flows in a browser.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Example: Playwright E2E test
|
|
147
|
+
import { test, expect } from '@playwright/test'
|
|
148
|
+
|
|
149
|
+
test('user can create an item', async ({ page }) => {
|
|
150
|
+
await page.goto('/login')
|
|
151
|
+
await page.fill('[name="email"]', 'test@example.com')
|
|
152
|
+
await page.fill('[name="password"]', 'password')
|
|
153
|
+
await page.click('button[type="submit"]')
|
|
154
|
+
|
|
155
|
+
await page.goto('/items/new')
|
|
156
|
+
await page.fill('[name="name"]', 'New Item')
|
|
157
|
+
await page.click('button[type="submit"]')
|
|
158
|
+
|
|
159
|
+
await expect(page.locator('text=New Item')).toBeVisible()
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**When to add:** When you have paying users and can't afford broken flows.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Test File Organization
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
src/
|
|
171
|
+
├── lib/
|
|
172
|
+
│ ├── utils.ts
|
|
173
|
+
│ └── utils.test.ts # Co-located unit tests
|
|
174
|
+
├── actions/
|
|
175
|
+
│ ├── items.ts
|
|
176
|
+
│ └── items.test.ts # Co-located action tests
|
|
177
|
+
tests/
|
|
178
|
+
├── e2e/ # End-to-end tests
|
|
179
|
+
│ ├── auth.spec.ts
|
|
180
|
+
│ └── items.spec.ts
|
|
181
|
+
└── setup.ts # Test configuration
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Testing Tools by Stack
|
|
187
|
+
|
|
188
|
+
### Next.js / React
|
|
189
|
+
|
|
190
|
+
| Type | Tool | Why |
|
|
191
|
+
|------|------|-----|
|
|
192
|
+
| Unit | Vitest or Jest | Fast, good DX |
|
|
193
|
+
| Component | React Testing Library | Tests user behavior |
|
|
194
|
+
| E2E | Playwright | Reliable, fast |
|
|
195
|
+
|
|
196
|
+
### Node.js / Backend
|
|
197
|
+
|
|
198
|
+
| Type | Tool | Why |
|
|
199
|
+
|------|------|-----|
|
|
200
|
+
| Unit | Vitest or Jest | Standard |
|
|
201
|
+
| Integration | Supertest | HTTP testing |
|
|
202
|
+
| E2E | Playwright or Cypress | Full flow |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## What to Test (Priority Order)
|
|
207
|
+
|
|
208
|
+
### Must Test (Critical Path)
|
|
209
|
+
|
|
210
|
+
1. **Authentication** — Login, logout, session handling
|
|
211
|
+
2. **Core user action** — The main thing users do
|
|
212
|
+
3. **Payment flows** — If you charge money
|
|
213
|
+
4. **Data integrity** — Critical calculations, financial data
|
|
214
|
+
|
|
215
|
+
### Should Test (Important)
|
|
216
|
+
|
|
217
|
+
5. **Form validation** — Error states, edge cases
|
|
218
|
+
6. **API error handling** — What happens when things fail
|
|
219
|
+
7. **Permissions** — Users can only access their data
|
|
220
|
+
|
|
221
|
+
### Nice to Test (Polish)
|
|
222
|
+
|
|
223
|
+
8. **UI states** — Loading, empty, error states
|
|
224
|
+
9. **Edge cases** — Empty inputs, long strings, special characters
|
|
225
|
+
10. **Accessibility** — Screen reader, keyboard nav
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Session Testing Protocol
|
|
230
|
+
|
|
231
|
+
### Before Ending Session
|
|
232
|
+
|
|
233
|
+
1. **Run build** — Must pass
|
|
234
|
+
2. **Run existing tests** — All must pass
|
|
235
|
+
3. **Manual smoke test** — Core flows work
|
|
236
|
+
4. **Document test status** — Note in PROGRESS.md
|
|
237
|
+
|
|
238
|
+
### Test Status in PROGRESS.md
|
|
239
|
+
|
|
240
|
+
```markdown
|
|
241
|
+
### Session N - Testing
|
|
242
|
+
|
|
243
|
+
**Build:** ✅ Passes
|
|
244
|
+
**Existing Tests:** ✅ 12/12 passing
|
|
245
|
+
**New Tests Added:** 2 (item creation, validation)
|
|
246
|
+
**Manual Smoke Test:** ✅ Completed
|
|
247
|
+
|
|
248
|
+
**Coverage Notes:**
|
|
249
|
+
- Added tests for createItem action
|
|
250
|
+
- Auth flow manually verified
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## When Tests Fail
|
|
256
|
+
|
|
257
|
+
### In CI/Build
|
|
258
|
+
|
|
259
|
+
1. Stop deployment
|
|
260
|
+
2. Fix the failing test
|
|
261
|
+
3. Verify fix locally
|
|
262
|
+
4. Push and verify CI passes
|
|
263
|
+
|
|
264
|
+
### Flaky Tests
|
|
265
|
+
|
|
266
|
+
A test that sometimes passes and sometimes fails is **worse than no test**.
|
|
267
|
+
|
|
268
|
+
- Fix immediately or delete
|
|
269
|
+
- Never ignore flaky tests
|
|
270
|
+
- Usually caused by: timing issues, shared state, network dependencies
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Testing Debt
|
|
275
|
+
|
|
276
|
+
Track testing gaps in BACKLOG.md:
|
|
277
|
+
|
|
278
|
+
```markdown
|
|
279
|
+
## Testing Debt
|
|
280
|
+
|
|
281
|
+
- [ ] Add E2E tests for checkout flow (Session 8)
|
|
282
|
+
- [ ] Add unit tests for currency conversion (Session 5)
|
|
283
|
+
- [ ] Fix flaky auth test (Session 7)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Address testing debt before adding more features.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Quick Checklist
|
|
291
|
+
|
|
292
|
+
Every session:
|
|
293
|
+
- [ ] Build passes
|
|
294
|
+
- [ ] Existing tests pass
|
|
295
|
+
- [ ] New critical features have tests
|
|
296
|
+
- [ ] Manual smoke test completed
|
|
297
|
+
- [ ] Test status documented
|
|
298
|
+
|
|
299
|
+
Before launch:
|
|
300
|
+
- [ ] Critical path has automated tests
|
|
301
|
+
- [ ] No flaky tests
|
|
302
|
+
- [ ] Test coverage documented
|
|
303
|
+
- [ ] CI/CD runs tests on every push
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
*Last updated: Baton Protocol v3.1*
|