@torus-engineering/tas-kit 1.13.0 → 2.1.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/_platform/claude-code/settings.json +58 -46
- package/.tas/_platform/hooks/code-quality.js +127 -127
- package/.tas/_platform/hooks/session-end.js +111 -111
- package/.tas/agents/architect.md +53 -53
- package/.tas/agents/aws-reviewer.md +71 -71
- package/.tas/agents/build-resolver.md +89 -59
- package/.tas/agents/code-explorer.md +63 -63
- package/.tas/agents/csharp-reviewer.md +62 -62
- package/.tas/agents/database-reviewer.md +73 -73
- package/.tas/agents/doc-updater.md +68 -66
- package/.tas/agents/python-reviewer.md +67 -67
- package/.tas/agents/security-reviewer.md +79 -79
- package/.tas/agents/software-engineer.md +53 -0
- package/.tas/agents/typescript-reviewer.md +65 -65
- package/.tas/commands/ado-create.md +33 -28
- package/.tas/commands/ado-delete.md +26 -22
- package/.tas/commands/ado-get.md +24 -20
- package/.tas/commands/ado-status.md +22 -18
- package/.tas/commands/ado-update.md +31 -27
- package/.tas/commands/tas-adr.md +37 -33
- package/.tas/commands/tas-apitest-plan.md +177 -173
- package/.tas/commands/tas-apitest.md +147 -143
- package/.tas/commands/tas-brainstorm.md +23 -19
- package/.tas/commands/tas-brd.md +50 -0
- package/.tas/commands/tas-bug.md +127 -113
- package/.tas/commands/tas-checklist.md +180 -0
- package/.tas/commands/tas-debug.md +103 -0
- package/.tas/commands/tas-design.md +41 -37
- package/.tas/commands/tas-dev.md +225 -125
- package/.tas/commands/tas-e2e-mobile.md +146 -155
- package/.tas/commands/tas-e2e-web.md +150 -163
- package/.tas/commands/tas-e2e.md +289 -102
- package/.tas/commands/tas-feature.md +181 -47
- package/.tas/commands/tas-fix.md +72 -51
- package/.tas/commands/tas-functest-mobile.md +138 -144
- package/.tas/commands/tas-functest-web.md +176 -192
- package/.tas/commands/tas-functest.md +225 -76
- package/.tas/commands/tas-init.md +22 -17
- package/.tas/commands/tas-master-plan.md +300 -0
- package/.tas/commands/tas-orchestrate.md +159 -0
- package/.tas/commands/tas-plan.md +152 -117
- package/.tas/commands/tas-prd.md +57 -37
- package/.tas/commands/tas-review-pr.md +174 -0
- package/.tas/commands/tas-review.md +115 -113
- package/.tas/commands/tas-sad.md +47 -43
- package/.tas/commands/tas-security.md +91 -87
- package/.tas/commands/tas-spec.md +54 -50
- package/.tas/commands/tas-status.md +25 -16
- package/.tas/project-status-example.yaml +3 -1
- package/.tas/rules/ado-integration.md +67 -65
- package/.tas/rules/common/api-design.md +517 -517
- package/.tas/rules/common/build-debug-loop.md +233 -0
- package/.tas/rules/common/code-review.md +4 -0
- package/.tas/rules/common/feature-done.md +42 -0
- package/.tas/rules/common/post-implementation-review.md +4 -0
- package/.tas/rules/common/project-status.md +33 -16
- package/.tas/rules/common/sad-impact.md +81 -0
- package/.tas/rules/common/tdd.md +104 -89
- package/.tas/rules/csharp/api-testing.md +2 -2
- package/.tas/rules/csharp/torus-core-framework.md +128 -0
- package/.tas/tas-example.yaml +9 -32
- package/.tas/templates/AGENTS.md +13 -0
- package/.tas/templates/API-Test-Spec.md +5 -4
- package/.tas/templates/BRD.md +133 -0
- package/.tas/templates/Bug.md +15 -0
- package/.tas/templates/E2E-Execution-Report.md +8 -8
- package/.tas/templates/E2E-Mobile-Spec.md +6 -8
- package/.tas/templates/E2E-Report.md +2 -2
- package/.tas/templates/E2E-Scenario.md +22 -22
- package/.tas/templates/E2E-Test-Spec.md +274 -0
- package/.tas/templates/E2E-Web-Spec.md +4 -4
- package/.tas/templates/Feature-Technical-Part.md +69 -0
- package/.tas/templates/Feature-Technical-Stack.md +74 -0
- package/.tas/templates/Feature-Technical.md +329 -0
- package/.tas/templates/Feature.md +50 -26
- package/.tas/templates/Func-Test-Script.md +29 -56
- package/.tas/templates/Func-Test-Spec.md +144 -142
- package/.tas/templates/PRD.md +173 -142
- package/.tas/templates/TestChecklist.md +96 -0
- package/.tas/templates/torus-dotnet-bootstrap.md +223 -0
- package/.tas/tools/tas-ado-readme.md +24 -27
- package/.tas/tools/tas-ado.py +328 -25
- package/.tas/tools/tas-github.py +339 -0
- package/README.md +142 -57
- package/bin/cli.js +90 -90
- package/lib/adapters/antigravity.js +131 -131
- package/lib/adapters/claude-code.js +71 -35
- package/lib/adapters/codex.js +157 -157
- package/lib/adapters/cursor.js +80 -80
- package/lib/adapters/index.js +20 -20
- package/lib/adapters/utils.js +81 -81
- package/lib/deleted-files.json +7 -0
- package/lib/install.js +546 -543
- package/package.json +2 -2
- package/.tas/README.md +0 -334
- package/.tas/commands/tas-epic.md +0 -35
- package/.tas/commands/tas-story.md +0 -91
- package/.tas/rules/common/story-done.md +0 -30
- package/.tas/templates/Epic.md +0 -46
- package/.tas/templates/Story.md +0 -90
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
---
|
|
2
|
+
feature_id: # e.g., Feature-001
|
|
3
|
+
feature_file: # relative path to Feature .md
|
|
4
|
+
plan_by: # SE name
|
|
5
|
+
plan_date:
|
|
6
|
+
status: Draft # Draft | Approved | Implemented
|
|
7
|
+
sad_impact: false # true if Feature changes/extends SAD
|
|
8
|
+
adr_needed: false # true if Feature needs new ADR
|
|
9
|
+
split_mode: single # single | stack-split | sub-feature-split
|
|
10
|
+
---
|
|
11
|
+
# Feature-{NNN}-Technical: {Title}
|
|
12
|
+
|
|
13
|
+
> Technical plan for `{feature_file}`. Generated by `/tas-plan`.
|
|
14
|
+
> Source of truth for SE during `/tas-dev`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Context Diagram
|
|
19
|
+
> All containers involved across all stacks. Who calls what, which DBs/external systems are touched.
|
|
20
|
+
|
|
21
|
+
:::mermaid
|
|
22
|
+
flowchart LR
|
|
23
|
+
user[User / Caller]
|
|
24
|
+
web[Web App]
|
|
25
|
+
service[API Service]
|
|
26
|
+
integration[Integration Adapter]
|
|
27
|
+
db[({DB})]
|
|
28
|
+
ext[{External API / Queue}]
|
|
29
|
+
|
|
30
|
+
user --> web
|
|
31
|
+
web --> service
|
|
32
|
+
service --> integration
|
|
33
|
+
integration --> ext
|
|
34
|
+
service --> db
|
|
35
|
+
:::
|
|
36
|
+
|
|
37
|
+
- **Stacks involved:** {list only stacks active in this feature — omit others}
|
|
38
|
+
- **Callers / Actors:** {users, internal services, schedulers}
|
|
39
|
+
- **Databases:** {names + tables touched}
|
|
40
|
+
- **External systems:** {third-party APIs, queues, message brokers}
|
|
41
|
+
|
|
42
|
+
## Data Flow
|
|
43
|
+
> End-to-end data journey across all stacks.
|
|
44
|
+
|
|
45
|
+
:::mermaid
|
|
46
|
+
graph LR
|
|
47
|
+
input["{Input: {source}}"]
|
|
48
|
+
validate["{Validate}"]
|
|
49
|
+
transform["{Transform}"]
|
|
50
|
+
persist["{Persist}"]
|
|
51
|
+
|
|
52
|
+
input --> validate
|
|
53
|
+
validate --> transform
|
|
54
|
+
transform --> persist
|
|
55
|
+
:::
|
|
56
|
+
|
|
57
|
+
| Step | Stack | Field(s) | Transformation | Destination |
|
|
58
|
+
|------|-------|----------|----------------|-------------|
|
|
59
|
+
| {step} | {stack} | {fields} | {mapping, validation} | {DB column / response / event} |
|
|
60
|
+
|
|
61
|
+
## API Spec
|
|
62
|
+
> Contracts between stacks (REST, event, queue). Only if feature exposes new/changed interfaces.
|
|
63
|
+
|
|
64
|
+
| Endpoint / Event | Stack | Method | Request | Response | Status |
|
|
65
|
+
|-----------------|-------|--------|---------|----------|--------|
|
|
66
|
+
| {path/topic} | {service/web} | {GET/POST/EVENT} | {schema} | {schema} | {codes} |
|
|
67
|
+
|
|
68
|
+
**Error Codes:**
|
|
69
|
+
- {code}: {description}
|
|
70
|
+
|
|
71
|
+
## ERD
|
|
72
|
+
> Tables involved. New tables, columns, indexes.
|
|
73
|
+
|
|
74
|
+
:::mermaid
|
|
75
|
+
erDiagram
|
|
76
|
+
TABLE_A ||--o{ TABLE_B : "1..N"
|
|
77
|
+
TABLE_A {
|
|
78
|
+
uuid id PK
|
|
79
|
+
string name
|
|
80
|
+
}
|
|
81
|
+
TABLE_B {
|
|
82
|
+
uuid id PK
|
|
83
|
+
uuid a_id FK
|
|
84
|
+
string status
|
|
85
|
+
}
|
|
86
|
+
:::
|
|
87
|
+
|
|
88
|
+
- **New tables:** {list — or "None"}
|
|
89
|
+
- **New columns:** {table.column — or "None"}
|
|
90
|
+
- **New indexes:** {table(column) — or "None"}
|
|
91
|
+
- **Migration script:** {path — or "None"}
|
|
92
|
+
|
|
93
|
+
## SAD Impact Matrix
|
|
94
|
+
> Fill per `.tas/rules/common/sad-impact.md`. Set frontmatter `sad_impact: true` if any row `Detected: Yes`. ADR Candidate marks decisions human will review for `/tas-adr`.
|
|
95
|
+
|
|
96
|
+
| # | Category | Detected | SAD Section | Change Summary | ADR Candidate |
|
|
97
|
+
|---|----------|----------|-------------|----------------|---------------|
|
|
98
|
+
| 1 | Tech Stack | No | — | — | No |
|
|
99
|
+
| 2 | System Boundary | No | — | — | No |
|
|
100
|
+
| 3 | Container / Topology | No | — | — | No |
|
|
101
|
+
| 4 | Data Architecture | No | — | — | No |
|
|
102
|
+
| 5 | API Contract | No | — | — | No |
|
|
103
|
+
| 6 | Security | No | — | — | No |
|
|
104
|
+
| 7 | NFR / Ops | No | — | — | No |
|
|
105
|
+
| 8 | Deployment | No | — | — | No |
|
|
106
|
+
|
|
107
|
+
## Architecture Decisions
|
|
108
|
+
> Significant design choices. Document decision + rationale. Flag candidates for ADR review (human decides).
|
|
109
|
+
|
|
110
|
+
| Decision | Rationale | ADR Candidate |
|
|
111
|
+
|----------|-----------|---------------|
|
|
112
|
+
| {what} | {why — trade-offs, constraints} | {Yes / No} |
|
|
113
|
+
|
|
114
|
+
## Execution Plan
|
|
115
|
+
> `tas-dev` reads this to orchestrate agents. `split_mode: single` → all stacks in this file. `stack-split` / `sub-feature-split` → each row is a child file.
|
|
116
|
+
> `Parallel Safe: Yes` = no dependency on other rows; can run as concurrent agent.
|
|
117
|
+
|
|
118
|
+
| # | Part / Stack | File | Depends On | Parallel Safe | Est. Time |
|
|
119
|
+
|---|---|---|---|---|---|
|
|
120
|
+
| 1 | {stack or part-title} | {`this file` or relative child path} | — | Yes / No | {e.g. 2h} |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Stack: Web
|
|
125
|
+
> *(omit this section entirely if Web stack not involved)*
|
|
126
|
+
|
|
127
|
+
### Logic Flow
|
|
128
|
+
1. {entry point — component/page/route}
|
|
129
|
+
2. {validation / UI state}
|
|
130
|
+
3. {API call / user interaction}
|
|
131
|
+
4. {response handling / state update}
|
|
132
|
+
|
|
133
|
+
### File Changes
|
|
134
|
+
|
|
135
|
+
#### Modify
|
|
136
|
+
| File | Change | Reason |
|
|
137
|
+
|------|--------|--------|
|
|
138
|
+
| {path} | {what} | {why} |
|
|
139
|
+
|
|
140
|
+
#### Create
|
|
141
|
+
| File | Purpose |
|
|
142
|
+
|------|---------|
|
|
143
|
+
| {path} | {what it does} |
|
|
144
|
+
|
|
145
|
+
#### Delete
|
|
146
|
+
| File | Reason |
|
|
147
|
+
|------|--------|
|
|
148
|
+
| {path} | {why removed} |
|
|
149
|
+
|
|
150
|
+
### Config
|
|
151
|
+
| Item | Type | Value / Source | Environment |
|
|
152
|
+
|------|------|----------------|-------------|
|
|
153
|
+
| {VAR_NAME} | env var | {description} | dev / staging / prod |
|
|
154
|
+
|
|
155
|
+
### Unit Test Cases
|
|
156
|
+
> Test ID: `{PROJECT}_F{FEATURE}_AC{N}_UT_NNN_{H|E|N}`
|
|
157
|
+
|
|
158
|
+
| ID | AC Ref | Type | Description | Input | Expected Output |
|
|
159
|
+
|----|--------|------|-------------|-------|-----------------|
|
|
160
|
+
| {PROJ}_F{NNN}_AC1_UT_001_H | AC-1 | Happy | {description} | {input} | {expected} |
|
|
161
|
+
| {PROJ}_F{NNN}_AC1_UT_001_E | AC-1 | Edge | {description} | {boundary} | {expected} |
|
|
162
|
+
| {PROJ}_F{NNN}_AC1_UT_001_N | AC-1 | Negative | {description} | {invalid} | {error} |
|
|
163
|
+
|
|
164
|
+
### Tasks
|
|
165
|
+
- [ ] W1: {file + change}
|
|
166
|
+
- [ ] W2: {file + change}
|
|
167
|
+
- [ ] W3: Unit tests for AC-1, AC-2
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Stack: Service
|
|
172
|
+
> *(omit this section entirely if Service stack not involved)*
|
|
173
|
+
|
|
174
|
+
### Logic Flow
|
|
175
|
+
1. {entry point — controller/handler}
|
|
176
|
+
2. {validation / authn-authz}
|
|
177
|
+
3. {business logic — service/use-case}
|
|
178
|
+
4. {persistence / external call}
|
|
179
|
+
5. {response / event emit}
|
|
180
|
+
|
|
181
|
+
Optional sequence diagram:
|
|
182
|
+
:::mermaid
|
|
183
|
+
sequenceDiagram
|
|
184
|
+
Caller->>Controller: request
|
|
185
|
+
Controller->>Service: invoke
|
|
186
|
+
Service->>Repository: read/write
|
|
187
|
+
Repository->>DB: query
|
|
188
|
+
DB-->>Service: rows
|
|
189
|
+
Service-->>Controller: result
|
|
190
|
+
Controller-->>Caller: response
|
|
191
|
+
:::
|
|
192
|
+
|
|
193
|
+
### File Changes
|
|
194
|
+
|
|
195
|
+
#### Modify
|
|
196
|
+
| File | Change | Reason |
|
|
197
|
+
|------|--------|--------|
|
|
198
|
+
| {path} | {what} | {why} |
|
|
199
|
+
|
|
200
|
+
#### Create
|
|
201
|
+
| File | Purpose |
|
|
202
|
+
|------|---------|
|
|
203
|
+
| {path} | {what it does} |
|
|
204
|
+
|
|
205
|
+
#### Delete
|
|
206
|
+
| File | Reason |
|
|
207
|
+
|------|--------|
|
|
208
|
+
| {path} | {why removed} |
|
|
209
|
+
|
|
210
|
+
### Config
|
|
211
|
+
| Item | Type | Value / Source | Environment |
|
|
212
|
+
|------|------|----------------|-------------|
|
|
213
|
+
| {VAR_NAME} | env var | {description} | dev / staging / prod |
|
|
214
|
+
|
|
215
|
+
### Unit Test Cases
|
|
216
|
+
> Test ID: `{PROJECT}_F{FEATURE}_AC{N}_UT_NNN_{H|E|N}`
|
|
217
|
+
|
|
218
|
+
| ID | AC Ref | Type | Description | Input | Expected Output |
|
|
219
|
+
|----|--------|------|-------------|-------|-----------------|
|
|
220
|
+
| {PROJ}_F{NNN}_AC1_UT_001_H | AC-1 | Happy | {description} | {input} | {expected} |
|
|
221
|
+
| {PROJ}_F{NNN}_AC1_UT_001_E | AC-1 | Edge | {description} | {boundary} | {expected} |
|
|
222
|
+
| {PROJ}_F{NNN}_AC1_UT_001_N | AC-1 | Negative | {description} | {invalid} | {error} |
|
|
223
|
+
|
|
224
|
+
### Tasks
|
|
225
|
+
- [ ] S1: {file + change}
|
|
226
|
+
- [ ] S2: {file + change}
|
|
227
|
+
- [ ] S3: Unit tests for AC-1, AC-2
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Stack: Integration
|
|
232
|
+
> *(omit this section entirely if Integration stack not involved)*
|
|
233
|
+
|
|
234
|
+
### Logic Flow
|
|
235
|
+
1. {entry point — adapter/client}
|
|
236
|
+
2. {authentication with external system}
|
|
237
|
+
3. {request transform + call}
|
|
238
|
+
4. {response transform + error handling}
|
|
239
|
+
5. {retry / circuit breaker logic}
|
|
240
|
+
|
|
241
|
+
### File Changes
|
|
242
|
+
|
|
243
|
+
#### Modify
|
|
244
|
+
| File | Change | Reason |
|
|
245
|
+
|------|--------|--------|
|
|
246
|
+
| {path} | {what} | {why} |
|
|
247
|
+
|
|
248
|
+
#### Create
|
|
249
|
+
| File | Purpose |
|
|
250
|
+
|------|---------|
|
|
251
|
+
| {path} | {what it does} |
|
|
252
|
+
|
|
253
|
+
#### Delete
|
|
254
|
+
| File | Reason |
|
|
255
|
+
|------|--------|
|
|
256
|
+
| {path} | {why removed} |
|
|
257
|
+
|
|
258
|
+
### Config
|
|
259
|
+
| Item | Type | Value / Source | Environment |
|
|
260
|
+
|------|------|----------------|-------------|
|
|
261
|
+
| {VAR_NAME} | env var | {description} | dev / staging / prod |
|
|
262
|
+
| {API_KEY} | secret | {external service name} | all |
|
|
263
|
+
|
|
264
|
+
### Unit Test Cases
|
|
265
|
+
> Test ID: `{PROJECT}_F{FEATURE}_AC{N}_UT_NNN_{H|E|N}`
|
|
266
|
+
|
|
267
|
+
| ID | AC Ref | Type | Description | Input | Expected Output |
|
|
268
|
+
|----|--------|------|-------------|-------|-----------------|
|
|
269
|
+
| {PROJ}_F{NNN}_AC1_UT_001_H | AC-1 | Happy | {description} | {input} | {expected} |
|
|
270
|
+
| {PROJ}_F{NNN}_AC1_UT_001_E | AC-1 | Edge | {description} | {boundary} | {expected} |
|
|
271
|
+
| {PROJ}_F{NNN}_AC1_UT_001_N | AC-1 | Negative | {description} | {invalid} | {error} |
|
|
272
|
+
|
|
273
|
+
### Tasks
|
|
274
|
+
- [ ] I1: {file + change}
|
|
275
|
+
- [ ] I2: {file + change}
|
|
276
|
+
- [ ] I3: Unit tests for AC-1, AC-2
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Stack: App
|
|
281
|
+
> *(omit this section entirely if App/mobile stack not involved)*
|
|
282
|
+
|
|
283
|
+
### Logic Flow
|
|
284
|
+
1. {entry point — screen/view}
|
|
285
|
+
2. {state management / local validation}
|
|
286
|
+
3. {API call / deep link}
|
|
287
|
+
4. {response handling / navigation}
|
|
288
|
+
|
|
289
|
+
### File Changes
|
|
290
|
+
|
|
291
|
+
#### Modify
|
|
292
|
+
| File | Change | Reason |
|
|
293
|
+
|------|--------|--------|
|
|
294
|
+
| {path} | {what} | {why} |
|
|
295
|
+
|
|
296
|
+
#### Create
|
|
297
|
+
| File | Purpose |
|
|
298
|
+
|------|---------|
|
|
299
|
+
| {path} | {what it does} |
|
|
300
|
+
|
|
301
|
+
#### Delete
|
|
302
|
+
| File | Reason |
|
|
303
|
+
|------|--------|
|
|
304
|
+
| {path} | {why removed} |
|
|
305
|
+
|
|
306
|
+
### Config
|
|
307
|
+
| Item | Type | Value / Source | Environment |
|
|
308
|
+
|------|------|----------------|-------------|
|
|
309
|
+
| {VAR_NAME} | env var | {description} | dev / staging / prod |
|
|
310
|
+
|
|
311
|
+
### Unit Test Cases
|
|
312
|
+
> Test ID: `{PROJECT}_F{FEATURE}_AC{N}_UT_NNN_{H|E|N}`
|
|
313
|
+
|
|
314
|
+
| ID | AC Ref | Type | Description | Input | Expected Output |
|
|
315
|
+
|----|--------|------|-------------|-------|-----------------|
|
|
316
|
+
| {PROJ}_F{NNN}_AC1_UT_001_H | AC-1 | Happy | {description} | {input} | {expected} |
|
|
317
|
+
| {PROJ}_F{NNN}_AC1_UT_001_E | AC-1 | Edge | {description} | {boundary} | {expected} |
|
|
318
|
+
| {PROJ}_F{NNN}_AC1_UT_001_N | AC-1 | Negative | {description} | {invalid} | {error} |
|
|
319
|
+
|
|
320
|
+
### Tasks
|
|
321
|
+
- [ ] A1: {file + change}
|
|
322
|
+
- [ ] A2: {file + change}
|
|
323
|
+
- [ ] A3: Unit tests for AC-1, AC-2
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Changelog
|
|
328
|
+
| Date | Changes | Author |
|
|
329
|
+
|------|---------|--------|
|
|
@@ -7,48 +7,72 @@ ado_assigned_to:
|
|
|
7
7
|
ado_created:
|
|
8
8
|
last_ado_sync:
|
|
9
9
|
parent_ado_id:
|
|
10
|
+
plan_status: pending # pending | completed (set by /tas-plan)
|
|
11
|
+
plan_date:
|
|
12
|
+
autonomous_run: false # true if any /tas-plan or /tas-dev step ran with --autonomous=true
|
|
13
|
+
autonomous_run_date:
|
|
10
14
|
---
|
|
15
|
+
<!-- BOUNDARY: BUSINESS SPEC ONLY. This file contains business requirements, user stories, and acceptance criteria. Schema, SQL, code, migrations, data models, API specs, and all other technical content → Feature-Technical.md. Any agent adding technical sections here is wrong. -->
|
|
11
16
|
# Feature-{NNN}: {Title}
|
|
12
17
|
|
|
13
|
-
> **Status:** New |
|
|
14
|
-
> **Epic:** Epic-{NNN}
|
|
18
|
+
> **Status:** New | In Design | In Development | Done | Removed
|
|
15
19
|
> **Owner:** {PE name}
|
|
16
20
|
> **Created:** {Date}
|
|
17
|
-
> **
|
|
21
|
+
> **Done Date:** {Date when status = Done}
|
|
18
22
|
|
|
19
23
|
## Description
|
|
20
|
-
{
|
|
24
|
+
{Short summary — what this feature does and the business value}
|
|
21
25
|
|
|
22
|
-
## User
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
## User Story
|
|
27
|
+
As a {role}, I want {goal}, so that {benefit}.
|
|
28
|
+
|
|
29
|
+
## Actor
|
|
30
|
+
{Who interacts with this feature — roles, personas, systems}
|
|
31
|
+
|
|
32
|
+
## Business Flow
|
|
33
|
+
{Step-by-step business flow / user journey}
|
|
34
|
+
|
|
35
|
+
## Business Rules
|
|
36
|
+
- BR-1: {rule}
|
|
37
|
+
- BR-2: {rule}
|
|
38
|
+
|
|
39
|
+
## UI/UX Rules
|
|
40
|
+
- {UI/UX rule or reference to design-spec.md — omit section if backend-only}
|
|
41
|
+
|
|
42
|
+
## Non-Functional Requirements
|
|
43
|
+
- {Performance, security, scalability, accessibility — measurable when applicable}
|
|
26
44
|
|
|
27
45
|
## Acceptance Criteria
|
|
28
|
-
- [ ] AC-1: {criteria}
|
|
29
|
-
- [ ] AC-2: {criteria}
|
|
30
46
|
|
|
31
|
-
|
|
32
|
-
{
|
|
47
|
+
> Each AC drives unit tests (generated by `/tas-plan`) and functional tests (generated by `/tas-functest`).
|
|
48
|
+
> Test ID format: `{PROJECT}_F{NNN}_AC{N}_UT_NNN_{H|E|N}` (unit) or `_FT_NNN_` (functional).
|
|
33
49
|
|
|
34
|
-
|
|
35
|
-
|
|
50
|
+
### AC-1: {title}
|
|
51
|
+
- **Given** {precondition}
|
|
52
|
+
- **When** {action}
|
|
53
|
+
- **Then** {expected result}
|
|
36
54
|
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
### AC-2: {title}
|
|
56
|
+
- **Given** {precondition}
|
|
57
|
+
- **When** {action}
|
|
58
|
+
- **Then** {expected result}
|
|
39
59
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
## Definition of Done
|
|
61
|
+
- [ ] Technical plan completed (`/tas-plan`)
|
|
62
|
+
- [ ] Code implemented per all AC
|
|
63
|
+
- [ ] Unit tests pass (happy + edge + negative)
|
|
64
|
+
- [ ] Functional tests pass (per `/tas-functest`)
|
|
65
|
+
- [ ] Code review passed (no Critical/High)
|
|
66
|
+
- [ ] No regression on existing tests
|
|
67
|
+
- [ ] Documentation updated (if API/schema changed)
|
|
68
|
+
- [ ] Acceptance criteria verified by PE
|
|
69
|
+
- [ ] Ready for production release
|
|
44
70
|
|
|
45
|
-
##
|
|
46
|
-
|
|
71
|
+
## Autonomous Decisions Log
|
|
72
|
+
> Populated only when `autonomous_run: true`. Each entry records a gate that was skipped or a decision auto-made by `/tas-plan` / `/tas-dev` in autonomous mode.
|
|
47
73
|
|
|
48
|
-
|
|
|
49
|
-
|
|
50
|
-
| E2E-1 | AC-1 | {Scenario} | {Execution steps} | {Expected result} | - | - |
|
|
51
|
-
| E2E-2 | AC-2 | {Scenario} | {Execution steps} | {Expected result} | - | - |
|
|
74
|
+
| Timestamp | Stage | Decision | Rationale |
|
|
75
|
+
|-----------|-------|----------|-----------|
|
|
52
76
|
|
|
53
77
|
## Changelog
|
|
54
78
|
| Date | Changes | Author |
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> This document defines the conventions for generated functional test scripts.
|
|
4
4
|
> Used by `/tas-functest-mobile` and `/tas-functest-web` commands.
|
|
5
|
+
> Kit v3 — anchored on Feature (no Epic / Story).
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
@@ -11,12 +12,10 @@
|
|
|
11
12
|
```
|
|
12
13
|
apps/mobile/e2e/
|
|
13
14
|
├── features/ # Layer 2: Functional test scripts
|
|
14
|
-
│ ├── {
|
|
15
|
-
│ │ ├── {feature-slug}
|
|
16
|
-
│ │
|
|
17
|
-
│ │
|
|
18
|
-
│ │ │ └── index.ts # Barrel export
|
|
19
|
-
│ │ └── ...
|
|
15
|
+
│ ├── {feature-slug}/
|
|
16
|
+
│ │ ├── {feature-slug}.func.e2e.ts # One file per Feature
|
|
17
|
+
│ │ ├── helpers.ts # Feature-specific helpers (reusable by E2E)
|
|
18
|
+
│ │ └── index.ts # Barrel export
|
|
20
19
|
│ └── ...
|
|
21
20
|
├── flows/ # Layer 3: E2E scripts (separate)
|
|
22
21
|
├── data/ # Test data per environment
|
|
@@ -33,12 +32,10 @@ apps/mobile/e2e/
|
|
|
33
32
|
```
|
|
34
33
|
apps/web/e2e/
|
|
35
34
|
├── features/ # Layer 2: Functional test scripts
|
|
36
|
-
│ ├── {
|
|
37
|
-
│ │ ├── {feature-slug}
|
|
38
|
-
│ │
|
|
39
|
-
│ │
|
|
40
|
-
│ │ │ └── index.ts
|
|
41
|
-
│ │ └── ...
|
|
35
|
+
│ ├── {feature-slug}/
|
|
36
|
+
│ │ ├── {feature-slug}.func.spec.ts # One file per Feature
|
|
37
|
+
│ │ ├── helpers.ts
|
|
38
|
+
│ │ └── index.ts
|
|
42
39
|
│ └── ...
|
|
43
40
|
├── flows/ # Layer 3: E2E scripts
|
|
44
41
|
├── data/
|
|
@@ -68,13 +65,12 @@ apps/web/e2e/
|
|
|
68
65
|
|
|
69
66
|
```typescript
|
|
70
67
|
/**
|
|
71
|
-
* Functional Tests: {
|
|
72
|
-
* Story: {Story_ID}
|
|
68
|
+
* Functional Tests: {Feature Name}
|
|
73
69
|
* Feature: {Feature_ID}
|
|
74
|
-
*
|
|
75
|
-
*
|
|
70
|
+
* Stack: app
|
|
71
|
+
*
|
|
76
72
|
* Generated by /tas-functest-mobile
|
|
77
|
-
* Spec: docs/
|
|
73
|
+
* Spec: docs/features/{feature-dir}/Func-Test-Spec.md
|
|
78
74
|
*/
|
|
79
75
|
|
|
80
76
|
import { device, element, expect, by, waitFor } from 'detox';
|
|
@@ -84,10 +80,9 @@ import { login, navigateTo } from '../../helpers/test-utils';
|
|
|
84
80
|
|
|
85
81
|
const testData = loadTestData();
|
|
86
82
|
|
|
87
|
-
describe('{Feature Name}
|
|
83
|
+
describe('{Feature Name}', () => {
|
|
88
84
|
beforeAll(async () => {
|
|
89
85
|
await device.launchApp({ newInstance: true });
|
|
90
|
-
// Setup: login, navigate to target screen, etc.
|
|
91
86
|
});
|
|
92
87
|
|
|
93
88
|
beforeEach(async () => {
|
|
@@ -95,7 +90,7 @@ describe('{Feature Name} - {Story Name}', () => {
|
|
|
95
90
|
});
|
|
96
91
|
|
|
97
92
|
// AC Reference: AC-1
|
|
98
|
-
describe('{PROJECT}
|
|
93
|
+
describe('{PROJECT}_F{FEATURE}_AC1_FT_001_H', () => {
|
|
99
94
|
it('should {happy path description}', async () => {
|
|
100
95
|
// Given: {precondition}
|
|
101
96
|
// When: {action}
|
|
@@ -106,13 +101,10 @@ describe('{Feature Name} - {Story Name}', () => {
|
|
|
106
101
|
});
|
|
107
102
|
|
|
108
103
|
// AC Reference: AC-1
|
|
109
|
-
describe('{PROJECT}
|
|
104
|
+
describe('{PROJECT}_F{FEATURE}_AC1_FT_002_N', () => {
|
|
110
105
|
it('should {negative scenario description}', async () => {
|
|
111
|
-
// Given: {precondition}
|
|
112
|
-
// When: {invalid action}
|
|
113
106
|
await element(by.id(TEST_IDS.FEATURE.INPUT)).typeText('invalid');
|
|
114
107
|
await element(by.id(TEST_IDS.FEATURE.SUBMIT)).tap();
|
|
115
|
-
// Then: {error handling}
|
|
116
108
|
await expect(element(by.id(TEST_IDS.FEATURE.ERROR))).toBeVisible();
|
|
117
109
|
});
|
|
118
110
|
});
|
|
@@ -125,13 +117,12 @@ describe('{Feature Name} - {Story Name}', () => {
|
|
|
125
117
|
|
|
126
118
|
```typescript
|
|
127
119
|
/**
|
|
128
|
-
* Functional Tests: {
|
|
129
|
-
* Story: {Story_ID}
|
|
120
|
+
* Functional Tests: {Feature Name}
|
|
130
121
|
* Feature: {Feature_ID}
|
|
131
|
-
*
|
|
132
|
-
*
|
|
122
|
+
* Stack: web
|
|
123
|
+
*
|
|
133
124
|
* Generated by /tas-functest-web
|
|
134
|
-
* Spec: docs/
|
|
125
|
+
* Spec: docs/features/{feature-dir}/Func-Test-Spec.md
|
|
135
126
|
*/
|
|
136
127
|
|
|
137
128
|
import { test, expect } from '@playwright/test';
|
|
@@ -139,23 +130,19 @@ import { loadTestData, getCredentials } from '../../helpers/data-loader';
|
|
|
139
130
|
|
|
140
131
|
const testData = loadTestData();
|
|
141
132
|
|
|
142
|
-
test.describe('{Feature Name}
|
|
133
|
+
test.describe('{Feature Name}', () => {
|
|
143
134
|
test.beforeEach(async ({ page }) => {
|
|
144
|
-
// Setup: login, navigate to target page, etc.
|
|
145
135
|
await page.goto('/target-page');
|
|
146
136
|
});
|
|
147
137
|
|
|
148
138
|
// AC Reference: AC-1
|
|
149
|
-
test.describe('{PROJECT}
|
|
139
|
+
test.describe('{PROJECT}_F{FEATURE}_AC1_FT_001_H', () => {
|
|
150
140
|
test('should {happy path description}', async ({ page }) => {
|
|
151
|
-
// Given: {precondition}
|
|
152
|
-
// When: {action}
|
|
153
141
|
await page.getByTestId('feature-element').click();
|
|
154
|
-
// Then: {expected}
|
|
155
142
|
await expect(page.getByTestId('feature-result')).toBeVisible();
|
|
156
143
|
});
|
|
157
144
|
|
|
158
|
-
// Cross-viewport
|
|
145
|
+
// Cross-viewport
|
|
159
146
|
for (const viewport of [
|
|
160
147
|
{ width: 375, height: 812, name: 'mobile' },
|
|
161
148
|
{ width: 768, height: 1024, name: 'tablet' },
|
|
@@ -163,19 +150,15 @@ test.describe('{Feature Name} - {Story Name}', () => {
|
|
|
163
150
|
]) {
|
|
164
151
|
test(`should work on ${viewport.name}`, async ({ page }) => {
|
|
165
152
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
166
|
-
// Test responsive behavior
|
|
167
153
|
});
|
|
168
154
|
}
|
|
169
155
|
});
|
|
170
156
|
|
|
171
157
|
// AC Reference: AC-1
|
|
172
|
-
test.describe('{PROJECT}
|
|
158
|
+
test.describe('{PROJECT}_F{FEATURE}_AC1_FT_002_N', () => {
|
|
173
159
|
test('should {negative scenario description}', async ({ page }) => {
|
|
174
|
-
// Given: {precondition}
|
|
175
|
-
// When: {invalid action}
|
|
176
160
|
await page.getByTestId('feature-input').fill('invalid');
|
|
177
161
|
await page.getByTestId('feature-submit').click();
|
|
178
|
-
// Then: {error handling}
|
|
179
162
|
await expect(page.getByTestId('feature-error')).toBeVisible();
|
|
180
163
|
});
|
|
181
164
|
});
|
|
@@ -187,17 +170,10 @@ test.describe('{Feature Name} - {Story Name}', () => {
|
|
|
187
170
|
## Data Loading Pattern
|
|
188
171
|
|
|
189
172
|
```typescript
|
|
190
|
-
// Import data loader
|
|
191
173
|
import { loadTestData, getCredentials } from '../../helpers/data-loader';
|
|
192
174
|
|
|
193
|
-
// Load environment-specific data (reads TEST_ENV env var)
|
|
194
175
|
const testData = loadTestData();
|
|
195
|
-
// testData.users.default.email -> "e2e-user@yopmail.com" (from JSON)
|
|
196
|
-
|
|
197
|
-
// Load credentials (passwords from .env, never from JSON)
|
|
198
176
|
const creds = getCredentials();
|
|
199
|
-
// creds.email -> from JSON
|
|
200
|
-
// creds.password -> from process.env.TEST_USER_PASSWORD
|
|
201
177
|
```
|
|
202
178
|
|
|
203
179
|
---
|
|
@@ -205,11 +181,8 @@ const creds = getCredentials();
|
|
|
205
181
|
## describe/it Block Naming Convention
|
|
206
182
|
|
|
207
183
|
```typescript
|
|
208
|
-
|
|
209
|
-
describe('{
|
|
210
|
-
// Mid-level: Full FT ID (enables grep by test ID)
|
|
211
|
-
describe('{PROJECT}_E{EPIC}_F{FEATURE}_S{STORY}_FT_001_H', () => {
|
|
212
|
-
// Leaf: Human-readable description
|
|
184
|
+
describe('{Feature Name}', () => {
|
|
185
|
+
describe('{PROJECT}_F{FEATURE}_AC1_FT_001_H', () => {
|
|
213
186
|
it('should {action} when {condition}', async () => { ... });
|
|
214
187
|
});
|
|
215
188
|
});
|
|
@@ -222,7 +195,7 @@ describe('{Feature Name} - {Story Name}', () => {
|
|
|
222
195
|
Feature-specific helpers should be exported for Layer 3 (E2E) reuse:
|
|
223
196
|
|
|
224
197
|
```typescript
|
|
225
|
-
// features/{
|
|
198
|
+
// features/{feature-slug}/helpers.ts
|
|
226
199
|
export async function fillLoginForm(email: string, password: string) {
|
|
227
200
|
await element(by.id(TEST_IDS.AUTH.LOGIN.EMAIL_INPUT)).typeText(email);
|
|
228
201
|
await element(by.id(TEST_IDS.AUTH.LOGIN.PASSWORD_INPUT)).typeText(password);
|
|
@@ -245,8 +218,8 @@ These helpers are imported by E2E flow scripts in `flows/` to avoid duplication.
|
|
|
245
218
|
```json
|
|
246
219
|
{
|
|
247
220
|
"scripts": {
|
|
248
|
-
"functest:mobile:{feature-slug}": "detox test --configuration ios.sim.debug --testPathPattern='features/{
|
|
249
|
-
"functest:web:{feature-slug}": "npx playwright test
|
|
221
|
+
"functest:mobile:{feature-slug}": "detox test --configuration ios.sim.debug --testPathPattern='features/{feature-slug}'",
|
|
222
|
+
"functest:web:{feature-slug}": "npx playwright test e2e/features/{feature-slug}",
|
|
250
223
|
"functest:mobile:all": "detox test --configuration ios.sim.debug --testPathPattern='features/'",
|
|
251
224
|
"functest:web:all": "npx playwright test e2e/features/"
|
|
252
225
|
}
|