@torus-engineering/tas-kit 1.10.0 → 1.12.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/.tas/README.md +70 -70
- package/{.claude → .tas/_platform/claude-code}/settings.json +0 -12
- package/{.claude → .tas/_platform}/hooks/code-quality.js +1 -1
- package/{.claude → .tas/_platform}/hooks/session-end.js +20 -25
- package/.tas/commands/ado-create.md +28 -0
- package/.tas/commands/ado-delete.md +22 -0
- package/.tas/commands/ado-get.md +20 -0
- package/.tas/commands/ado-status.md +18 -0
- package/.tas/commands/ado-update.md +27 -0
- package/.tas/commands/tas-adr.md +33 -0
- package/.tas/commands/tas-apitest-plan.md +173 -0
- package/.tas/commands/tas-apitest.md +143 -0
- package/.tas/commands/tas-brainstorm.md +19 -0
- package/.tas/commands/tas-bug.md +113 -0
- package/.tas/commands/tas-design.md +37 -0
- package/.tas/commands/tas-dev.md +125 -0
- package/{.claude → .tas}/commands/tas-e2e-mobile.md +155 -155
- package/{.claude → .tas}/commands/tas-e2e-web.md +163 -163
- package/.tas/commands/tas-e2e.md +102 -0
- package/.tas/commands/tas-epic.md +35 -0
- package/.tas/commands/tas-feature.md +47 -0
- package/.tas/commands/tas-fix.md +51 -0
- package/.tas/commands/tas-functest-mobile.md +144 -0
- package/{.claude → .tas}/commands/tas-functest-web.md +192 -192
- package/.tas/commands/tas-functest.md +76 -0
- package/.tas/commands/tas-init.md +17 -0
- package/.tas/commands/tas-plan.md +198 -0
- package/.tas/commands/tas-prd.md +37 -0
- package/.tas/commands/tas-review.md +113 -0
- package/.tas/commands/tas-sad.md +43 -0
- package/.tas/commands/tas-security.md +87 -0
- package/.tas/commands/tas-spec.md +50 -0
- package/.tas/commands/tas-status.md +16 -0
- package/.tas/commands/tas-story.md +91 -0
- package/.tas/platforms.json +5 -0
- package/.tas/project-status-example.yaml +17 -17
- package/.tas/rules/ado-integration.md +65 -0
- package/{.claude/skills/api-design/SKILL.md → .tas/rules/common/api-design.md} +517 -530
- package/{.claude → .tas}/rules/common/code-review.md +30 -6
- package/.tas/rules/common/post-implementation-review.md +51 -0
- package/{.claude → .tas}/rules/common/project-status.md +80 -80
- package/.tas/rules/common/stack-detection.md +29 -0
- package/.tas/rules/common/story-done.md +30 -0
- package/.tas/rules/common/tdd.md +89 -0
- package/{.claude → .tas}/rules/common/testing.md +3 -8
- package/.tas/rules/common/token-logging.md +36 -0
- package/{.claude → .tas}/rules/csharp/api-testing.md +20 -20
- package/{.claude → .tas}/rules/csharp/coding-style.md +0 -2
- package/{.claude → .tas}/rules/csharp/security.md +10 -0
- package/{.claude → .tas}/rules/python/coding-style.md +0 -2
- package/{.claude → .tas}/rules/typescript/coding-style.md +0 -2
- package/.tas/rules/typescript/patterns.md +142 -0
- package/.tas/rules/typescript/security.md +88 -0
- package/{.claude → .tas}/rules/typescript/testing.md +0 -4
- package/{.claude → .tas}/rules/web/coding-style.md +0 -2
- package/.tas/tas-example.yaml +10 -11
- package/.tas/templates/ADR.md +47 -47
- package/.tas/templates/AGENTS.md +37 -0
- package/.tas/templates/API-Test-Spec.md +3 -3
- package/.tas/templates/Bug.md +67 -67
- package/.tas/templates/Design-Spec.md +36 -36
- package/.tas/templates/E2E-Execution-Report.md +1 -1
- package/.tas/templates/Epic.md +46 -46
- package/.tas/templates/Feature.md +10 -10
- package/.tas/templates/Func-Test-Spec.md +3 -3
- package/.tas/templates/SAD.md +106 -106
- package/.tas/templates/Security-Report.md +27 -27
- package/.tas/templates/Story.md +9 -9
- package/.tas/tools/tas-ado-readme.md +68 -68
- package/.tas/tools/tas-ado.py +621 -621
- package/README.md +78 -78
- package/bin/cli.js +91 -73
- package/lib/adapters/antigravity.js +137 -0
- package/lib/adapters/claude-code.js +35 -0
- package/lib/adapters/codex.js +163 -0
- package/lib/adapters/cursor.js +80 -0
- package/lib/adapters/index.js +20 -0
- package/lib/adapters/utils.js +81 -0
- package/lib/deleted-files.json +99 -0
- package/lib/install.js +403 -327
- package/package.json +4 -3
- package/.claude/agents/code-reviewer.md +0 -41
- package/.claude/agents/e2e-runner.md +0 -61
- package/.claude/agents/planner.md +0 -82
- package/.claude/agents/tdd-guide.md +0 -84
- package/.claude/commands/ado-create.md +0 -27
- package/.claude/commands/ado-delete.md +0 -21
- package/.claude/commands/ado-get.md +0 -20
- package/.claude/commands/ado-status.md +0 -18
- package/.claude/commands/ado-update.md +0 -26
- package/.claude/commands/tas-adr.md +0 -33
- package/.claude/commands/tas-apitest-plan.md +0 -173
- package/.claude/commands/tas-apitest.md +0 -143
- package/.claude/commands/tas-brainstorm.md +0 -19
- package/.claude/commands/tas-bug.md +0 -113
- package/.claude/commands/tas-design.md +0 -37
- package/.claude/commands/tas-dev.md +0 -128
- package/.claude/commands/tas-e2e.md +0 -102
- package/.claude/commands/tas-epic.md +0 -35
- package/.claude/commands/tas-feature.md +0 -47
- package/.claude/commands/tas-fix.md +0 -51
- package/.claude/commands/tas-functest-mobile.md +0 -144
- package/.claude/commands/tas-functest.md +0 -76
- package/.claude/commands/tas-init.md +0 -17
- package/.claude/commands/tas-plan.md +0 -200
- package/.claude/commands/tas-prd.md +0 -37
- package/.claude/commands/tas-review.md +0 -111
- package/.claude/commands/tas-sad.md +0 -43
- package/.claude/commands/tas-security.md +0 -87
- package/.claude/commands/tas-spec.md +0 -50
- package/.claude/commands/tas-status.md +0 -16
- package/.claude/commands/tas-story.md +0 -91
- package/.claude/commands/tas-verify.md +0 -51
- package/.claude/rules/common/post-review-agent.md +0 -49
- package/.claude/rules/common/stack-detection.md +0 -29
- package/.claude/rules/common/token-logging.md +0 -27
- package/.claude/rules/typescript/patterns.md +0 -62
- package/.claude/rules/typescript/security.md +0 -28
- package/.claude/settings.local.json +0 -38
- package/.claude/skills/ado-integration/SKILL.md +0 -75
- package/.claude/skills/ai-regression-testing/SKILL.md +0 -364
- package/.claude/skills/architecture-decision-records/SKILL.md +0 -184
- package/.claude/skills/benchmark/SKILL.md +0 -98
- package/.claude/skills/browser-qa/SKILL.md +0 -92
- package/.claude/skills/canary-watch/SKILL.md +0 -104
- package/.claude/skills/js-backend-patterns/SKILL.md +0 -603
- package/.claude/skills/tas-conventions/SKILL.md +0 -65
- package/.claude/skills/tas-implementation-complete/SKILL.md +0 -99
- package/.claude/skills/tas-tdd/SKILL.md +0 -123
- package/.claude/skills/token-logger/SKILL.md +0 -19
- package/.tas/checklists/code-review.md +0 -29
- package/.tas/checklists/security.md +0 -21
- package/.tas/checklists/story-done.md +0 -23
- package/CLAUDE-Example.md +0 -61
- /package/{.claude → .tas}/agents/architect.md +0 -0
- /package/{.claude → .tas}/agents/aws-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/build-resolver.md +0 -0
- /package/{.claude → .tas}/agents/code-explorer.md +0 -0
- /package/{.claude → .tas}/agents/csharp-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/database-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/doc-updater.md +0 -0
- /package/{.claude → .tas}/agents/python-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/security-reviewer.md +0 -0
- /package/{.claude → .tas}/agents/typescript-reviewer.md +0 -0
- /package/{.claude → .tas}/rules/.gitkeep +0 -0
- /package/{.claude → .tas}/rules/common/hooks.md +0 -0
- /package/{.claude → .tas}/rules/common/patterns.md +0 -0
- /package/{.claude → .tas}/rules/common/security.md +0 -0
- /package/{.claude → .tas}/rules/csharp/hooks.md +0 -0
- /package/{.claude → .tas}/rules/csharp/patterns.md +0 -0
- /package/{.claude → .tas}/rules/csharp/testing.md +0 -0
- /package/{.claude → .tas}/rules/python/hooks.md +0 -0
- /package/{.claude → .tas}/rules/python/patterns.md +0 -0
- /package/{.claude → .tas}/rules/python/security.md +0 -0
- /package/{.claude → .tas}/rules/python/testing.md +0 -0
- /package/{.claude → .tas}/rules/typescript/hooks.md +0 -0
- /package/{.claude → .tas}/rules/web/design-quality.md +0 -0
- /package/{.claude → .tas}/rules/web/hooks.md +0 -0
- /package/{.claude → .tas}/rules/web/patterns.md +0 -0
- /package/{.claude → .tas}/rules/web/performance.md +0 -0
- /package/{.claude → .tas}/rules/web/security.md +0 -0
- /package/{.claude → .tas}/rules/web/testing.md +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ts"
|
|
4
|
+
- "**/*.tsx"
|
|
5
|
+
- "**/*.js"
|
|
6
|
+
- "**/*.jsx"
|
|
7
|
+
---
|
|
8
|
+
# TypeScript/JavaScript Patterns
|
|
9
|
+
|
|
10
|
+
> This file extends [common/patterns.md](../common/patterns.md) with TypeScript/JavaScript specific content.
|
|
11
|
+
|
|
12
|
+
## API Response Format
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
interface ApiResponse<T> {
|
|
16
|
+
success: boolean
|
|
17
|
+
data?: T
|
|
18
|
+
error?: string
|
|
19
|
+
meta?: {
|
|
20
|
+
total: number
|
|
21
|
+
page: number
|
|
22
|
+
limit: number
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Custom Hooks Pattern
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
export function useDebounce<T>(value: T, delay: number): T {
|
|
31
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay)
|
|
35
|
+
return () => clearTimeout(handler)
|
|
36
|
+
}, [value, delay])
|
|
37
|
+
|
|
38
|
+
return debouncedValue
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Repository Pattern
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
interface Repository<T> {
|
|
46
|
+
findAll(filters?: Filters): Promise<T[]>
|
|
47
|
+
findById(id: string): Promise<T | null>
|
|
48
|
+
create(data: CreateDto): Promise<T>
|
|
49
|
+
update(id: string, data: UpdateDto): Promise<T>
|
|
50
|
+
delete(id: string): Promise<void>
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Performance Anti-Patterns
|
|
55
|
+
|
|
56
|
+
Avoid these in Node.js backends:
|
|
57
|
+
|
|
58
|
+
- **Sequential awaits that could be parallel**: use `Promise.all()` when calls are independent
|
|
59
|
+
- **CPU-blocking on event loop**: offload heavy computation to worker threads
|
|
60
|
+
- **Missing connection pooling**: never create a new DB connection per request — use pooled clients
|
|
61
|
+
- **ORM N+1**: missing `include`/`select` in Prisma/Sequelize — use eager loading or DataLoader for GraphQL
|
|
62
|
+
- **Large file reads without streaming**: avoid `fs.readFile` on large files — use streams instead
|
|
63
|
+
|
|
64
|
+
## N+1 Query Prevention (Batch Fetch)
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// BAD: N+1 queries
|
|
68
|
+
const markets = await getMarkets()
|
|
69
|
+
for (const market of markets) {
|
|
70
|
+
market.creator = await getUser(market.creator_id) // N queries
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// GOOD: Batch fetch — 2 queries total
|
|
74
|
+
const markets = await getMarkets()
|
|
75
|
+
const creatorIds = markets.map(m => m.creator_id)
|
|
76
|
+
const creators = await getUsers(creatorIds)
|
|
77
|
+
const creatorMap = new Map(creators.map(c => [c.id, c]))
|
|
78
|
+
markets.forEach(m => { m.creator = creatorMap.get(m.creator_id) })
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Centralized Error Handler
|
|
82
|
+
|
|
83
|
+
Custom `ApiError` class + single error mapper for API routes.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
class ApiError extends Error {
|
|
87
|
+
constructor(public statusCode: number, message: string, public isOperational = true) {
|
|
88
|
+
super(message)
|
|
89
|
+
Object.setPrototypeOf(this, ApiError.prototype)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function errorHandler(error: unknown): Response {
|
|
94
|
+
if (error instanceof ApiError) {
|
|
95
|
+
return NextResponse.json({ error: error.message }, { status: error.statusCode })
|
|
96
|
+
}
|
|
97
|
+
if (error instanceof z.ZodError) {
|
|
98
|
+
return NextResponse.json({ error: 'Validation failed', details: error.errors }, { status: 400 })
|
|
99
|
+
}
|
|
100
|
+
console.error('Unexpected error:', error)
|
|
101
|
+
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Cache-Aside Pattern
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
async function getMarketWithCache(id: string): Promise<Market> {
|
|
109
|
+
const cacheKey = `market:${id}`
|
|
110
|
+
const cached = await redis.get(cacheKey)
|
|
111
|
+
if (cached) return JSON.parse(cached)
|
|
112
|
+
|
|
113
|
+
const market = await db.markets.findUnique({ where: { id } })
|
|
114
|
+
if (!market) throw new ApiError(404, 'Market not found')
|
|
115
|
+
|
|
116
|
+
await redis.setex(cacheKey, 300, JSON.stringify(market)) // 5 min TTL
|
|
117
|
+
return market
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Invalidate on writes: `await redis.del(\`market:\${id}\`)` after update/delete.
|
|
122
|
+
|
|
123
|
+
## Retry with Exponential Backoff
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
|
|
127
|
+
let lastError: Error
|
|
128
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
129
|
+
try {
|
|
130
|
+
return await fn()
|
|
131
|
+
} catch (error) {
|
|
132
|
+
lastError = error as Error
|
|
133
|
+
if (i < maxRetries - 1) {
|
|
134
|
+
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000)) // 1s, 2s, 4s
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw lastError!
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Use for transient failures (network, upstream API). Do NOT retry on 4xx client errors.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.ts"
|
|
4
|
+
- "**/*.tsx"
|
|
5
|
+
- "**/*.js"
|
|
6
|
+
- "**/*.jsx"
|
|
7
|
+
---
|
|
8
|
+
# TypeScript/JavaScript Security
|
|
9
|
+
|
|
10
|
+
> This file extends [common/security.md](../common/security.md) with TypeScript/JavaScript specific content.
|
|
11
|
+
|
|
12
|
+
## Secret Management
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// NEVER: Hardcoded secrets
|
|
16
|
+
const apiKey = "sk-proj-xxxxx"
|
|
17
|
+
|
|
18
|
+
// ALWAYS: Environment variables
|
|
19
|
+
const apiKey = process.env.OPENAI_API_KEY
|
|
20
|
+
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
throw new Error('OPENAI_API_KEY not configured')
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## JWT Token Validation
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import jwt from 'jsonwebtoken'
|
|
30
|
+
|
|
31
|
+
interface JWTPayload {
|
|
32
|
+
userId: string
|
|
33
|
+
email: string
|
|
34
|
+
role: 'admin' | 'user'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function verifyToken(token: string): JWTPayload {
|
|
38
|
+
try {
|
|
39
|
+
return jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload
|
|
40
|
+
} catch {
|
|
41
|
+
throw new ApiError(401, 'Invalid token')
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function requireAuth(request: Request): Promise<JWTPayload> {
|
|
46
|
+
const token = request.headers.get('authorization')?.replace('Bearer ', '')
|
|
47
|
+
if (!token) throw new ApiError(401, 'Missing authorization token')
|
|
48
|
+
return verifyToken(token)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Always verify `JWT_SECRET` is set at boot. Never log tokens. Use short TTL (15min) + refresh tokens.
|
|
53
|
+
|
|
54
|
+
## Role-Based Access Control (RBAC)
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
type Permission = 'read' | 'write' | 'delete' | 'admin'
|
|
58
|
+
|
|
59
|
+
const rolePermissions: Record<User['role'], Permission[]> = {
|
|
60
|
+
admin: ['read', 'write', 'delete', 'admin'],
|
|
61
|
+
moderator: ['read', 'write', 'delete'],
|
|
62
|
+
user: ['read', 'write'],
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function hasPermission(user: User, permission: Permission): boolean {
|
|
66
|
+
return rolePermissions[user.role].includes(permission)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function requirePermission(permission: Permission) {
|
|
70
|
+
return (handler: (req: Request, user: User) => Promise<Response>) =>
|
|
71
|
+
async (req: Request) => {
|
|
72
|
+
const user = await requireAuth(req)
|
|
73
|
+
if (!hasPermission(user, permission)) throw new ApiError(403, 'Insufficient permissions')
|
|
74
|
+
return handler(req, user)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Usage
|
|
79
|
+
export const DELETE = requirePermission('delete')(async (req, user) => {
|
|
80
|
+
// handler with verified permission
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Check authorization at the route level (not inside business logic). Resource-level ownership checks (e.g., `if (resource.userId !== user.id)`) belong in service layer.
|
|
85
|
+
|
|
86
|
+
## Agent Support
|
|
87
|
+
|
|
88
|
+
- Use **security-reviewer** skill for comprehensive security audits
|
package/.tas/tas-example.yaml
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
# .tas/tas-example.yaml - Reference template
|
|
2
|
-
# Copy file
|
|
3
|
-
#
|
|
4
|
-
# Tech stack, coding conventions, build commands
|
|
1
|
+
# .tas/tas-example.yaml - Reference template for tas.yaml at root
|
|
2
|
+
# Copy this file to root (tas.yaml) and fill in project information.
|
|
3
|
+
# This file ONLY contains TAS flow and logic.
|
|
4
|
+
# Tech stack, coding conventions, build commands belong in CLAUDE.md.
|
|
5
5
|
|
|
6
6
|
project:
|
|
7
7
|
name: "My Project"
|
|
8
8
|
code: "PROJ" # Prefix for file naming: PROJ-Epic-001, PROJ-Feature-001, etc.
|
|
9
9
|
type: greenfield # greenfield | brownfield
|
|
10
|
-
description: "
|
|
10
|
+
description: "Brief project description"
|
|
11
11
|
|
|
12
12
|
# Azure DevOps integration
|
|
13
13
|
ado:
|
|
14
|
-
enabled: true # false
|
|
15
|
-
organization: "https://dev.azure.com/torus-
|
|
16
|
-
project_id: "
|
|
14
|
+
enabled: true # false if project doesn't use ADO
|
|
15
|
+
organization: "https://dev.azure.com/torus-engineering"
|
|
16
|
+
project_id: "f80dac23-9fa5-4b8e-a1db-da4d5aea7b31"
|
|
17
17
|
|
|
18
18
|
team:
|
|
19
19
|
- name: "Nguyen Van A"
|
|
@@ -118,9 +118,8 @@ models:
|
|
|
118
118
|
tas-feature: sonnet
|
|
119
119
|
tas-story: sonnet
|
|
120
120
|
tas-dev: sonnet
|
|
121
|
-
tas-review
|
|
121
|
+
tas-review: opus
|
|
122
122
|
tas-brainstorm: opus
|
|
123
123
|
tas-bug: sonnet
|
|
124
|
-
tas-verify: haiku
|
|
125
124
|
tas-status: haiku
|
|
126
|
-
tas-security
|
|
125
|
+
tas-security: opus
|
package/.tas/templates/ADR.md
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
# ADR-{NNN}: {Title}
|
|
2
|
-
|
|
3
|
-
> **Status:** Proposed | Accepted | Deprecated | Superseded
|
|
4
|
-
> **Date:** [Date]
|
|
5
|
-
> **Author:** [SE name]
|
|
6
|
-
> **Supersedes:** [ADR-NNN
|
|
7
|
-
> **Related:** [ADR-NNN
|
|
8
|
-
|
|
9
|
-
## Context
|
|
10
|
-
[
|
|
11
|
-
|
|
12
|
-
## Decision
|
|
13
|
-
[
|
|
14
|
-
|
|
15
|
-
## Rationale
|
|
16
|
-
[
|
|
17
|
-
|
|
18
|
-
## Alternatives Considered
|
|
19
|
-
|
|
20
|
-
### Alternative 1: [
|
|
21
|
-
- **Pros:** [
|
|
22
|
-
- **Cons:** [
|
|
23
|
-
- **
|
|
24
|
-
|
|
25
|
-
### Alternative 2: [
|
|
26
|
-
- **Pros:** [
|
|
27
|
-
- **Cons:** [
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
## Consequences
|
|
31
|
-
|
|
32
|
-
### Positive
|
|
33
|
-
- [consequence 1]
|
|
34
|
-
- [consequence 2]
|
|
35
|
-
|
|
36
|
-
### Negative
|
|
37
|
-
- [consequence 1]
|
|
38
|
-
- [consequence 2]
|
|
39
|
-
|
|
40
|
-
### SAD Updates
|
|
41
|
-
*(
|
|
42
|
-
- [ ] [
|
|
43
|
-
- [ ] [
|
|
44
|
-
|
|
45
|
-
## Changelog
|
|
46
|
-
| Date | Changes | Author |
|
|
47
|
-
|------|---------|--------|
|
|
1
|
+
# ADR-{NNN}: {Title}
|
|
2
|
+
|
|
3
|
+
> **Status:** Proposed | Accepted | Deprecated | Superseded
|
|
4
|
+
> **Date:** [Date]
|
|
5
|
+
> **Author:** [SE name]
|
|
6
|
+
> **Supersedes:** [ADR-NNN if any]
|
|
7
|
+
> **Related:** [ADR-NNN if any]
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
[Describe context leading to this decision. What problem needs solving?]
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
[Describe the chosen architectural decision.]
|
|
14
|
+
|
|
15
|
+
## Rationale
|
|
16
|
+
[Why choose this approach? Technical and business reasons.]
|
|
17
|
+
|
|
18
|
+
## Alternatives Considered
|
|
19
|
+
|
|
20
|
+
### Alternative 1: [Name]
|
|
21
|
+
- **Pros:** [advantages]
|
|
22
|
+
- **Cons:** [disadvantages]
|
|
23
|
+
- **Why not chosen:** [explanation]
|
|
24
|
+
|
|
25
|
+
### Alternative 2: [Name]
|
|
26
|
+
- **Pros:** [advantages]
|
|
27
|
+
- **Cons:** [disadvantages]
|
|
28
|
+
- **Why not chosen:** [explanation]
|
|
29
|
+
|
|
30
|
+
## Consequences
|
|
31
|
+
|
|
32
|
+
### Positive
|
|
33
|
+
- [consequence 1]
|
|
34
|
+
- [consequence 2]
|
|
35
|
+
|
|
36
|
+
### Negative
|
|
37
|
+
- [consequence 1]
|
|
38
|
+
- [consequence 2]
|
|
39
|
+
|
|
40
|
+
### SAD Updates
|
|
41
|
+
*(List changes needed to update docs/sad.md - only add when ADR affects overall architecture)*
|
|
42
|
+
- [ ] [change 1]
|
|
43
|
+
- [ ] [change 2]
|
|
44
|
+
|
|
45
|
+
## Changelog
|
|
46
|
+
| Date | Changes | Author |
|
|
47
|
+
|------|---------|--------|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Project Context
|
|
2
|
+
|
|
3
|
+
## Tech Stack
|
|
4
|
+
<!-- Specify your backend, frontend, database, infrastructure, and CI/CD -->
|
|
5
|
+
- Backend: [e.g., .NET 8, Node.js, Python]
|
|
6
|
+
- Frontend: [e.g., ReactJS, Vue, Angular]
|
|
7
|
+
- Database: [e.g., PostgreSQL, MySQL, MongoDB]
|
|
8
|
+
- Infrastructure: [e.g., AWS, Azure, GCP]
|
|
9
|
+
- CI/CD: [e.g., GitHub Actions, Azure DevOps, Jenkins]
|
|
10
|
+
|
|
11
|
+
## Conventions
|
|
12
|
+
<!-- Define coding standards and patterns used in this project -->
|
|
13
|
+
- Branching: [e.g., git-flow, trunk-based, GitHub flow]
|
|
14
|
+
- Commit: [e.g., conventional commits, custom format]
|
|
15
|
+
- Naming: [e.g., PascalCase for classes, camelCase for variables]
|
|
16
|
+
- Test framework: [e.g., xUnit, Jest, pytest]
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
<!-- Reference key architecture documents -->
|
|
20
|
+
- System design: see [docs/sad.md](docs/sad.md)
|
|
21
|
+
- Architecture decisions: see [docs/adr/](docs/adr/)
|
|
22
|
+
|
|
23
|
+
## Build & Test
|
|
24
|
+
<!-- Commands for building, testing, and linting -->
|
|
25
|
+
- Build: [e.g., dotnet build, npm run build]
|
|
26
|
+
- Test: [e.g., dotnet test, npm test]
|
|
27
|
+
- Lint: [e.g., dotnet format, npm run lint]
|
|
28
|
+
|
|
29
|
+
## Environment Setup
|
|
30
|
+
<!-- Prerequisites for running this project -->
|
|
31
|
+
- [e.g., Node.js 20+, .NET 8 SDK, Python 3.11+]
|
|
32
|
+
- [e.g., Azure CLI with specific extensions]
|
|
33
|
+
- [e.g., Required environment variables in .env file]
|
|
34
|
+
|
|
35
|
+
## Key Workflows
|
|
36
|
+
<!-- Common commands for this project -->
|
|
37
|
+
Type /[command-name] to [describe what it does].
|
|
@@ -28,7 +28,7 @@ framework: xUnit
|
|
|
28
28
|
|
|
29
29
|
## Version History
|
|
30
30
|
|
|
31
|
-
>
|
|
31
|
+
> Each API version has separate section. APPEND-ONLY: don't modify old versions.
|
|
32
32
|
|
|
33
33
|
| Version | Status | Created | Description |
|
|
34
34
|
|---------|--------|---------|-------------|
|
|
@@ -354,7 +354,7 @@ framework: xUnit
|
|
|
354
354
|
|
|
355
355
|
## Story-Specific Test Cases (Optional)
|
|
356
356
|
|
|
357
|
-
>
|
|
357
|
+
> If spec generated from Story, add AC mapping here.
|
|
358
358
|
|
|
359
359
|
| AC ID | AC Description | Test Case IDs |
|
|
360
360
|
|-------|----------------|---------------|
|
|
@@ -365,7 +365,7 @@ framework: xUnit
|
|
|
365
365
|
|
|
366
366
|
## Regression Tests (Optional)
|
|
367
367
|
|
|
368
|
-
> Test cases
|
|
368
|
+
> Test cases for bugs that were found and fixed.
|
|
369
369
|
|
|
370
370
|
| Bug ID | Description | Test Case ID | Date Added |
|
|
371
371
|
|--------|-------------|--------------|------------|
|
package/.tas/templates/Bug.md
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
---
|
|
2
|
-
ado_id:
|
|
3
|
-
ado_type: Bug
|
|
4
|
-
ado_title: "{Title}"
|
|
5
|
-
ado_state: New
|
|
6
|
-
ado_assigned_to:
|
|
7
|
-
ado_created:
|
|
8
|
-
last_ado_sync:
|
|
9
|
-
parent_ado_id:
|
|
10
|
-
---
|
|
11
|
-
# Bug-{NNN}: {Title}
|
|
12
|
-
|
|
13
|
-
> **Status:** New | Committed | In Progress | Deploy Test | Verify Test | Deploy Stag | Verify Stag | Deploy Prod | Verify Prod | Done
|
|
14
|
-
> **Feature:** Feature-{NNN}
|
|
15
|
-
> **Severity:** Critical | High | Medium | Low
|
|
16
|
-
> **Found in:** Test | Staging | Production
|
|
17
|
-
> **Found by:** {PE/SE name}
|
|
18
|
-
> **Assigned to:** {SE name}
|
|
19
|
-
> **Created:** {Date}
|
|
20
|
-
|
|
21
|
-
## Description
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
## Steps to Reproduce
|
|
25
|
-
1. {Step 1}
|
|
26
|
-
2. {Step 2}
|
|
27
|
-
3. {Step 3}
|
|
28
|
-
|
|
29
|
-
## Expected Behavior
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
## Actual Behavior
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
## Evidence
|
|
36
|
-
{Screenshots, logs, error messages}
|
|
37
|
-
|
|
38
|
-
## Root Cause Analysis
|
|
39
|
-
*SE
|
|
40
|
-
- **Root Cause:** {
|
|
41
|
-
- **Affected Files:** {
|
|
42
|
-
- **Impact Scope:** {
|
|
43
|
-
|
|
44
|
-
## Regression Test Cases
|
|
45
|
-
*SE
|
|
46
|
-
|
|
47
|
-
| ID | Description | Input | Expected | Status |
|
|
48
|
-
|----|-------------|-------|----------|--------|
|
|
49
|
-
| RT-1 | Reproduce bug case | {input} | {expected} | - |
|
|
50
|
-
| RT-2 | Related regression | {input} | {expected} | - |
|
|
51
|
-
|
|
52
|
-
## Fix Notes
|
|
53
|
-
*SE
|
|
54
|
-
- **Fix Description:** {
|
|
55
|
-
- **Files Changed:** {
|
|
56
|
-
- **Commit:** {commit hash}
|
|
57
|
-
|
|
58
|
-
## Verify Notes
|
|
59
|
-
*PE
|
|
60
|
-
|
|
61
|
-
| Date | Environment | Result | Verified by | Notes |
|
|
62
|
-
|------|-------------|--------|-------------|-------|
|
|
63
|
-
| {Date} | {env} | Pass/Fail | {PE name} | {notes} |
|
|
64
|
-
|
|
65
|
-
## Changelog
|
|
66
|
-
| Date | Changes | Author |
|
|
67
|
-
|------|---------|--------|
|
|
1
|
+
---
|
|
2
|
+
ado_id:
|
|
3
|
+
ado_type: Bug
|
|
4
|
+
ado_title: "{Title}"
|
|
5
|
+
ado_state: New
|
|
6
|
+
ado_assigned_to:
|
|
7
|
+
ado_created:
|
|
8
|
+
last_ado_sync:
|
|
9
|
+
parent_ado_id:
|
|
10
|
+
---
|
|
11
|
+
# Bug-{NNN}: {Title}
|
|
12
|
+
|
|
13
|
+
> **Status:** New | Committed | In Progress | Deploy Test | Verify Test | Deploy Stag | Verify Stag | Deploy Prod | Verify Prod | Done
|
|
14
|
+
> **Feature:** Feature-{NNN}
|
|
15
|
+
> **Severity:** Critical | High | Medium | Low
|
|
16
|
+
> **Found in:** Test | Staging | Production
|
|
17
|
+
> **Found by:** {PE/SE name}
|
|
18
|
+
> **Assigned to:** {SE name}
|
|
19
|
+
> **Created:** {Date}
|
|
20
|
+
|
|
21
|
+
## Description
|
|
22
|
+
{Brief bug description}
|
|
23
|
+
|
|
24
|
+
## Steps to Reproduce
|
|
25
|
+
1. {Step 1}
|
|
26
|
+
2. {Step 2}
|
|
27
|
+
3. {Step 3}
|
|
28
|
+
|
|
29
|
+
## Expected Behavior
|
|
30
|
+
{Expected result}
|
|
31
|
+
|
|
32
|
+
## Actual Behavior
|
|
33
|
+
{Actual result}
|
|
34
|
+
|
|
35
|
+
## Evidence
|
|
36
|
+
{Screenshots, logs, error messages}
|
|
37
|
+
|
|
38
|
+
## Root Cause Analysis
|
|
39
|
+
*SE fills when analyzing*
|
|
40
|
+
- **Root Cause:** {Root cause description}
|
|
41
|
+
- **Affected Files:** {List of related files}
|
|
42
|
+
- **Impact Scope:** {Affected functionality}
|
|
43
|
+
|
|
44
|
+
## Regression Test Cases
|
|
45
|
+
*SE designs before fixing*
|
|
46
|
+
|
|
47
|
+
| ID | Description | Input | Expected | Status |
|
|
48
|
+
|----|-------------|-------|----------|--------|
|
|
49
|
+
| RT-1 | Reproduce bug case | {input} | {expected} | - |
|
|
50
|
+
| RT-2 | Related regression | {input} | {expected} | - |
|
|
51
|
+
|
|
52
|
+
## Fix Notes
|
|
53
|
+
*SE fills after fixing*
|
|
54
|
+
- **Fix Description:** {Fix description}
|
|
55
|
+
- **Files Changed:** {List of changed files}
|
|
56
|
+
- **Commit:** {commit hash}
|
|
57
|
+
|
|
58
|
+
## Verify Notes
|
|
59
|
+
*PE fills when verifying*
|
|
60
|
+
|
|
61
|
+
| Date | Environment | Result | Verified by | Notes |
|
|
62
|
+
|------|-------------|--------|-------------|-------|
|
|
63
|
+
| {Date} | {env} | Pass/Fail | {PE name} | {notes} |
|
|
64
|
+
|
|
65
|
+
## Changelog
|
|
66
|
+
| Date | Changes | Author |
|
|
67
|
+
|------|---------|--------|
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# Design Specification
|
|
2
|
-
|
|
3
|
-
> **Status:** Draft | Approved
|
|
4
|
-
> **Last Updated:** [Date]
|
|
5
|
-
> **Author:** [PE name]
|
|
6
|
-
> **PRD Reference:** docs/prd.md
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 1. Overview
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
## 2. User Flows
|
|
14
|
-
<!--
|
|
15
|
-
|
|
16
|
-
## 3. Screen Descriptions
|
|
17
|
-
|
|
18
|
-
### Screen 1: {Name}
|
|
19
|
-
- **Purpose:** {
|
|
20
|
-
- **Key Elements:** {
|
|
21
|
-
- **Actions Available:** {
|
|
22
|
-
|
|
23
|
-
## 4. Navigation Structure
|
|
24
|
-
<!--
|
|
25
|
-
|
|
26
|
-
## 5. Interaction Patterns
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
## 6. Responsive Behavior
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Changelog
|
|
35
|
-
| Date | Changes | Author |
|
|
36
|
-
|------|---------|--------|
|
|
1
|
+
# Design Specification
|
|
2
|
+
|
|
3
|
+
> **Status:** Draft | Approved
|
|
4
|
+
> **Last Updated:** [Date]
|
|
5
|
+
> **Author:** [PE name]
|
|
6
|
+
> **PRD Reference:** docs/prd.md
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Overview
|
|
11
|
+
{Design overview}
|
|
12
|
+
|
|
13
|
+
## 2. User Flows
|
|
14
|
+
<!-- Use Mermaid flowchart, :::mermaid wrapper, no () -->
|
|
15
|
+
|
|
16
|
+
## 3. Screen Descriptions
|
|
17
|
+
|
|
18
|
+
### Screen 1: {Name}
|
|
19
|
+
- **Purpose:** {purpose}
|
|
20
|
+
- **Key Elements:** {key elements}
|
|
21
|
+
- **Actions Available:** {user actions available}
|
|
22
|
+
|
|
23
|
+
## 4. Navigation Structure
|
|
24
|
+
<!-- Use Mermaid flowchart -->
|
|
25
|
+
|
|
26
|
+
## 5. Interaction Patterns
|
|
27
|
+
{Describe patterns: form submission, search, pagination...}
|
|
28
|
+
|
|
29
|
+
## 6. Responsive Behavior
|
|
30
|
+
{Describe breakpoints and behavior changes}
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Changelog
|
|
35
|
+
| Date | Changes | Author |
|
|
36
|
+
|------|---------|--------|
|
|
@@ -51,7 +51,7 @@ environment: # dev | staging | prod
|
|
|
51
51
|
### {Test ID}: {Test Description}
|
|
52
52
|
|
|
53
53
|
**AC Reference**: AC-{N}
|
|
54
|
-
**Failure Reason**: {
|
|
54
|
+
**Failure Reason**: {Brief description of WHY it failed — e.g.: "Button 'Submit' not visible after entering valid email", "API returns 401 instead of 200", "Timeout after 5s waiting for Home screen to load"}
|
|
55
55
|
**Error Type**: {Assertion Failure | Timeout | Crash | Element Not Found}
|
|
56
56
|
**Error Message**:
|
|
57
57
|
```
|