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.
@@ -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*