dflow-sdd-ddd 0.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/LICENSE +21 -0
- package/README.md +209 -0
- package/bin/dflow.js +72 -0
- package/lib/init.js +1206 -0
- package/package.json +42 -0
- package/templates/core/scaffolding/CLAUDE-md-snippet.md +168 -0
- package/templates/core/scaffolding/Git-principles-gitflow.md +350 -0
- package/templates/core/scaffolding/Git-principles-trunk.md +375 -0
- package/templates/core/scaffolding/_conventions.md +175 -0
- package/templates/core/scaffolding/_overview.md +165 -0
- package/templates/core/scaffolding/architecture-decisions-README.md +34 -0
- package/templates/core/templates/CLAUDE.md +172 -0
- package/templates/core/templates/_index.md +118 -0
- package/templates/core/templates/aggregate-design.md +58 -0
- package/templates/core/templates/behavior.md +62 -0
- package/templates/core/templates/context-definition.md +64 -0
- package/templates/core/templates/context-map.md +25 -0
- package/templates/core/templates/events.md +19 -0
- package/templates/core/templates/glossary.md +15 -0
- package/templates/core/templates/lightweight-spec.md +82 -0
- package/templates/core/templates/models.md +47 -0
- package/templates/core/templates/phase-spec.md +195 -0
- package/templates/core/templates/rules.md +24 -0
- package/templates/core/templates/tech-debt.md +15 -0
- package/templates/webforms/scaffolding/CLAUDE-md-snippet.md +167 -0
- package/templates/webforms/scaffolding/Git-principles-gitflow.md +333 -0
- package/templates/webforms/scaffolding/Git-principles-trunk.md +316 -0
- package/templates/webforms/scaffolding/_conventions.md +139 -0
- package/templates/webforms/scaffolding/_overview.md +109 -0
- package/templates/webforms/templates/CLAUDE.md +157 -0
- package/templates/webforms/templates/_index.md +110 -0
- package/templates/webforms/templates/behavior.md +58 -0
- package/templates/webforms/templates/context-definition.md +57 -0
- package/templates/webforms/templates/context-map.md +25 -0
- package/templates/webforms/templates/glossary.md +15 -0
- package/templates/webforms/templates/lightweight-spec.md +82 -0
- package/templates/webforms/templates/models.md +39 -0
- package/templates/webforms/templates/phase-spec.md +187 -0
- package/templates/webforms/templates/rules.md +24 -0
- package/templates/webforms/templates/tech-debt.md +15 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<!-- Scaffolding template maintained alongside Dflow skill. See proposals/PROPOSAL-010 for origin. -->
|
|
2
|
+
|
|
3
|
+
# System Overview — {System Name}
|
|
4
|
+
|
|
5
|
+
> Created: {YYYY-MM-DD}
|
|
6
|
+
> Scope: architectural overview and long-term direction of {System Name}.
|
|
7
|
+
> Audience: team members onboarding to the system + AI assistants reading
|
|
8
|
+
> `dflow/specs/` for context.
|
|
9
|
+
|
|
10
|
+
This file is a **project-level starting point**. It does not duplicate
|
|
11
|
+
Dflow's workflow rules (see `CLAUDE.md` and the Dflow skill for those) —
|
|
12
|
+
it captures the unique context of *this* system so that new engineers (or
|
|
13
|
+
AI) can quickly understand what they are working on.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## System Summary
|
|
18
|
+
|
|
19
|
+
{One paragraph: what this system does, who uses it, what business value it
|
|
20
|
+
delivers. Keep it non-technical enough that a new hire can skim it in
|
|
21
|
+
30 seconds.}
|
|
22
|
+
|
|
23
|
+
### Business Domain
|
|
24
|
+
|
|
25
|
+
- **Primary domain**: {e.g. expense management, HR, order processing}
|
|
26
|
+
- **Key stakeholders**: {e.g. finance team, HR admins, end-user employees}
|
|
27
|
+
- **User scale**: {e.g. ~200 internal users, 5 countries}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Technical Architecture
|
|
32
|
+
|
|
33
|
+
This project is an ASP.NET Core application built with **Clean
|
|
34
|
+
Architecture** and **Domain-Driven Design (DDD)**. Dependencies flow
|
|
35
|
+
inward only — the Domain layer is the core and depends on nothing.
|
|
36
|
+
|
|
37
|
+
### Stack
|
|
38
|
+
|
|
39
|
+
| Item | Choice |
|
|
40
|
+
|------|--------|
|
|
41
|
+
| Runtime | .NET {version, e.g. 8} |
|
|
42
|
+
| Language | C# {version, e.g. 12} |
|
|
43
|
+
| Web framework | ASP.NET Core (Web API / Minimal API — {which}) |
|
|
44
|
+
| ORM | Entity Framework Core {version} |
|
|
45
|
+
| Mediator | {e.g. MediatR, internal CQRS dispatcher, or none} |
|
|
46
|
+
| Validation | {e.g. FluentValidation} |
|
|
47
|
+
| Database | {e.g. PostgreSQL 16, SQL Server 2022} |
|
|
48
|
+
| Auth | {e.g. JWT bearer, OIDC via Azure AD, cookie auth} |
|
|
49
|
+
| Hosting | {e.g. Azure App Service, Kubernetes, Docker compose} |
|
|
50
|
+
| Testing | {e.g. xUnit + FluentAssertions + NSubstitute} |
|
|
51
|
+
|
|
52
|
+
### Clean Architecture Layers
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Presentation → Application → Domain ← Infrastructure
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Layer | Responsibilities | Must NOT |
|
|
59
|
+
|-------|------------------|----------|
|
|
60
|
+
| Domain | Aggregates, Entities, Value Objects, Domain Events, Domain Services, repository interfaces | Depend on any NuGet package outside allowed list; know about EF Core, HTTP, DI containers |
|
|
61
|
+
| Application | Commands / Queries (CQRS), Validators, DTOs, Event Handlers, orchestration | Contain business logic; access database directly |
|
|
62
|
+
| Infrastructure | EF Core `DbContext` + configurations, repository implementations, external API clients | Contain business logic |
|
|
63
|
+
| Presentation | HTTP endpoints, Request / Response mapping, auth + middleware | Contain business logic; expose Domain objects directly |
|
|
64
|
+
|
|
65
|
+
### Project Layout
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
src/
|
|
69
|
+
├── {Project}.Domain/
|
|
70
|
+
│ ├── Common/ # Entity, AggregateRoot, ValueObject base classes
|
|
71
|
+
│ ├── {BoundedContext}/
|
|
72
|
+
│ │ ├── Entities/
|
|
73
|
+
│ │ ├── ValueObjects/
|
|
74
|
+
│ │ ├── Events/
|
|
75
|
+
│ │ ├── Services/
|
|
76
|
+
│ │ ├── Specifications/
|
|
77
|
+
│ │ └── Interfaces/ # Repository / external service interfaces
|
|
78
|
+
│ └── SharedKernel/
|
|
79
|
+
├── {Project}.Application/
|
|
80
|
+
│ ├── Common/ # Pipeline behaviors, interfaces (IUnitOfWork, ...)
|
|
81
|
+
│ └── {BoundedContext}/
|
|
82
|
+
│ ├── Commands/
|
|
83
|
+
│ ├── Queries/
|
|
84
|
+
│ ├── DTOs/
|
|
85
|
+
│ └── EventHandlers/
|
|
86
|
+
├── {Project}.Infrastructure/
|
|
87
|
+
│ ├── Persistence/ # DbContext + EF Core configurations
|
|
88
|
+
│ ├── Repositories/
|
|
89
|
+
│ └── ExternalServices/
|
|
90
|
+
└── {Project}.WebAPI/ # Presentation layer
|
|
91
|
+
|
|
92
|
+
tests/
|
|
93
|
+
├── {Project}.Domain.UnitTests/
|
|
94
|
+
├── {Project}.Application.UnitTests/
|
|
95
|
+
└── {Project}.Integration.Tests/
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Bounded Contexts (Current Map)
|
|
101
|
+
|
|
102
|
+
{List the current Bounded Contexts in this system. Each entry: name +
|
|
103
|
+
one-line responsibility + link to its `dflow/specs/domain/{context}/` folder.
|
|
104
|
+
If only one BC exists at adoption time, that is fine — the map grows.}
|
|
105
|
+
|
|
106
|
+
- **{Context A}** — {responsibility}. See
|
|
107
|
+
[`dflow/specs/domain/{context-a}/`](../domain/{context-a}/).
|
|
108
|
+
- **{Context B}** — {responsibility}. See
|
|
109
|
+
[`dflow/specs/domain/{context-b}/`](../domain/{context-b}/).
|
|
110
|
+
|
|
111
|
+
Full context relationships (upstream / downstream, shared kernel,
|
|
112
|
+
anti-corruption layer) are documented in
|
|
113
|
+
[`dflow/specs/domain/context-map.md`](../domain/context-map.md).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Principles This Project Adopts
|
|
118
|
+
|
|
119
|
+
Clean Architecture + DDD is more than a folder layout; the team commits
|
|
120
|
+
to the following design habits. Expand / adapt each to this project:
|
|
121
|
+
|
|
122
|
+
- **Domain at the Center** — Business rules live in `*.Domain`. If you
|
|
123
|
+
find business logic in `*.Application` handlers or (worse) in
|
|
124
|
+
controllers, raise a tech-debt entry.
|
|
125
|
+
- **Aggregate Boundaries** — Each transaction modifies exactly one
|
|
126
|
+
Aggregate. Cross-aggregate workflows go through Domain Events.
|
|
127
|
+
- **Dependency Inversion** — The Domain declares interfaces; the
|
|
128
|
+
Infrastructure layer implements them. No Domain code imports
|
|
129
|
+
`Microsoft.EntityFrameworkCore`.
|
|
130
|
+
- **Ubiquitous Language** — Class / method / variable names come from
|
|
131
|
+
`dflow/specs/domain/glossary.md`. When business language evolves, the
|
|
132
|
+
glossary moves first, code follows.
|
|
133
|
+
- **Pragmatic First** — We do not gold-plate. If a feature needs a
|
|
134
|
+
quick fix, record the debt in `dflow/specs/architecture/tech-debt.md` and
|
|
135
|
+
ship.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Architecture Decision Records (ADRs)
|
|
140
|
+
|
|
141
|
+
Significant architectural choices are recorded as ADRs under
|
|
142
|
+
`dflow/specs/architecture/decisions/`. Each ADR captures: decision, context,
|
|
143
|
+
alternatives considered, consequences. See the `decisions/` folder's
|
|
144
|
+
README (if present) or the ADR convention in {Michael Nygard's ADR
|
|
145
|
+
format / MADR / other}.
|
|
146
|
+
|
|
147
|
+
Initial ADRs that typically exist:
|
|
148
|
+
|
|
149
|
+
- **ADR-0001** — Choice of ORM / persistence approach
|
|
150
|
+
- **ADR-0002** — CQRS + MediatR vs direct handlers
|
|
151
|
+
- **ADR-0003** — Auth strategy
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Related Documents
|
|
156
|
+
|
|
157
|
+
- [Spec conventions](_conventions.md)
|
|
158
|
+
- [Git principles](Git-principles-{gitflow|trunk}.md) — choose the
|
|
159
|
+
branching-strategy-specific file that matches this project
|
|
160
|
+
- [Context map](../domain/context-map.md)
|
|
161
|
+
- [Glossary](../domain/glossary.md)
|
|
162
|
+
- [Tech debt backlog](../architecture/tech-debt.md)
|
|
163
|
+
- [Architecture decisions](../architecture/decisions/)
|
|
164
|
+
- Dflow skill: see `CLAUDE.md` and the `sdd-ddd-core-skill/` bundle
|
|
165
|
+
for the full AI workflow guidance.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- Template maintained by Dflow. See proposals/PROPOSAL-013 for origin. -->
|
|
2
|
+
|
|
3
|
+
# Architecture Decisions
|
|
4
|
+
|
|
5
|
+
This directory stores Architecture Decision Records (ADRs) for decisions that affect architecture, bounded contexts, cross-cutting policies, integrations, or long-term maintainability.
|
|
6
|
+
|
|
7
|
+
## ADR Naming Convention
|
|
8
|
+
|
|
9
|
+
Use a stable numeric prefix and a short kebab-case title:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
ADR-0001-short-decision-title.md
|
|
13
|
+
ADR-0002-another-decision.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## When To Write An ADR
|
|
17
|
+
|
|
18
|
+
Write an ADR when a decision:
|
|
19
|
+
|
|
20
|
+
- Changes architectural boundaries, dependency direction, or layer responsibilities.
|
|
21
|
+
- Introduces or rejects a major technology, integration pattern, persistence strategy, or deployment approach.
|
|
22
|
+
- Creates a trade-off that future maintainers need to understand.
|
|
23
|
+
- Resolves a recurring design debate that should not be reopened without new evidence.
|
|
24
|
+
|
|
25
|
+
## Minimal ADR Fields
|
|
26
|
+
|
|
27
|
+
Each ADR should include:
|
|
28
|
+
|
|
29
|
+
- **Status**: proposed / accepted / superseded / deprecated
|
|
30
|
+
- **Date**: YYYY-MM-DD
|
|
31
|
+
- **Context**: the forces, constraints, and problem being addressed
|
|
32
|
+
- **Decision**: the chosen approach
|
|
33
|
+
- **Consequences**: expected benefits, trade-offs, and follow-up work
|
|
34
|
+
- **Related Specs / BR-IDs**: links to relevant specs, rules, or implementation references
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Project: {系統名稱} — ASP.NET Core + DDD
|
|
2
|
+
|
|
3
|
+
**重要:所有開發工作都必須遵循本文件定義的流程。**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## System Context
|
|
8
|
+
|
|
9
|
+
> 技術棧、架構、業務領域、目錄結構
|
|
10
|
+
|
|
11
|
+
### Background
|
|
12
|
+
|
|
13
|
+
這是一個使用 Clean Architecture 和 Domain-Driven Design 的 ASP.NET Core 系統。
|
|
14
|
+
採用 SDD 流程,所有開發工作必須遵循本文件定義的流程。
|
|
15
|
+
|
|
16
|
+
### Architecture (Clean Architecture)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Presentation → Application → Domain ← Infrastructure
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
依賴方向永遠朝內。Domain 層是核心,不依賴任何外部套件。
|
|
23
|
+
|
|
24
|
+
**各層職責**
|
|
25
|
+
|
|
26
|
+
| 層 | 職責 | 不可以做的事 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Domain | 業務規則、Aggregate、Value Object、Domain Event | 依賴外部套件、存取資料庫、處理 HTTP |
|
|
29
|
+
| Application | 編排領域操作、CQRS、驗證、DTO | 包含業務邏輯、直接存取資料庫 |
|
|
30
|
+
| Infrastructure | EF Core、外部 API、檔案存取 | 包含業務邏輯 |
|
|
31
|
+
| Presentation | HTTP 端點、Request/Response | 包含業務邏輯、直接操作 Domain 物件 |
|
|
32
|
+
|
|
33
|
+
### Project Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
dflow/specs/
|
|
37
|
+
├── shared/ # 專案級治理文件(由 npx dflow-sdd-ddd init 寫入)
|
|
38
|
+
│ ├── _overview.md # 系統現況與遷移策略
|
|
39
|
+
│ └── _conventions.md # 規格撰寫慣例
|
|
40
|
+
├── domain/
|
|
41
|
+
│ ├── glossary.md
|
|
42
|
+
│ ├── context-map.md
|
|
43
|
+
│ └── {context}/
|
|
44
|
+
│ ├── context.md
|
|
45
|
+
│ ├── models.md
|
|
46
|
+
│ ├── rules.md
|
|
47
|
+
│ └── events.md # Domain Events 目錄
|
|
48
|
+
├── features/
|
|
49
|
+
│ ├── active/ # 進行中的 feature
|
|
50
|
+
│ │ └── {SPEC-ID}-{slug}/ # 一個 feature 一個目錄
|
|
51
|
+
│ │ ├── _index.md # Feature dashboard:Goals & Scope / Phase Specs / Current BR Snapshot / Lightweight Changes / Resume Pointer
|
|
52
|
+
│ │ ├── phase-spec-YYYY-MM-DD-{slug}.md # T1 Heavy:每 phase 一份
|
|
53
|
+
│ │ └── lightweight-YYYY-MM-DD-{slug}.md # T2 Light(或 BUG-NNN-{slug}.md)
|
|
54
|
+
│ ├── completed/ # 整個 feature 目錄 git mv 到這裡
|
|
55
|
+
│ └── backlog/
|
|
56
|
+
│ # SPEC-ID 格式:SPEC-YYYYMMDD-NNN;slug 跟隨討論語言(中文/英文皆可)
|
|
57
|
+
│ # T3 無獨立檔,只在 _index.md Lightweight Changes 寫一列
|
|
58
|
+
└── architecture/
|
|
59
|
+
├── decisions/ # ADR
|
|
60
|
+
└── tech-debt.md
|
|
61
|
+
|
|
62
|
+
src/
|
|
63
|
+
├── {Project}.Domain/
|
|
64
|
+
├── {Project}.Application/
|
|
65
|
+
├── {Project}.Infrastructure/
|
|
66
|
+
└── {Project}.WebAPI/
|
|
67
|
+
|
|
68
|
+
tests/
|
|
69
|
+
├── Domain.UnitTests/
|
|
70
|
+
├── Application.UnitTests/
|
|
71
|
+
└── Integration.Tests/
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Development Workflow
|
|
77
|
+
|
|
78
|
+
> SDD 流程、Git 整合、Domain 層規範、AI 協作
|
|
79
|
+
|
|
80
|
+
### Core Principles
|
|
81
|
+
1. **Spec Before Code** — 沒有規格就不寫實作
|
|
82
|
+
2. **Domain at the Center** — 業務邏輯只存在於 Domain 層
|
|
83
|
+
3. **Ubiquitous Language** — 使用 `dflow/specs/domain/glossary.md` 中定義的術語
|
|
84
|
+
4. **One Aggregate per Transaction** — 單一操作只修改一個 Aggregate
|
|
85
|
+
5. **Dependency Inversion** — Domain 定義介面,Infrastructure 實作
|
|
86
|
+
|
|
87
|
+
### Three Ceremony Tiers
|
|
88
|
+
|
|
89
|
+
不是每次修改都要跑完整流程。AI 依下列判準選 tier:
|
|
90
|
+
|
|
91
|
+
- **T1 Heavy** — 新功能、新 phase、新 Aggregate / BC、新增 BR、新 Domain Event →
|
|
92
|
+
建獨立 phase-spec,走 `/dflow:new-feature` 或 `/dflow:new-phase`
|
|
93
|
+
- **T2 Light** — bug fix(邏輯錯誤)、UI 輸入驗證、流程分支修改(有 BR Delta
|
|
94
|
+
但無 Aggregate / 資料結構動)→ 建獨立 lightweight spec 置於 feature 目錄內
|
|
95
|
+
- **T3 Trivial** — 按鈕顏色、文案修正、typo、排版、純註解(無 BR 變動、
|
|
96
|
+
無 Domain 概念動、無資料結構動、只改 UI 表層 / 註解 / 格式化)→
|
|
97
|
+
只在 `_index.md` Lightweight Changes inline 寫一列
|
|
98
|
+
|
|
99
|
+
純 typo / 純格式化 commit(`dotnet format` / `prettier` 自動整理)**低於 T3**:
|
|
100
|
+
直接 `git commit`,不走 Dflow。
|
|
101
|
+
|
|
102
|
+
### New Feature
|
|
103
|
+
1. 建 feature 目錄 `dflow/specs/features/active/{SPEC-ID}-{slug}/`
|
|
104
|
+
2. 建 `_index.md`(feature dashboard)+ 第一份 `phase-spec-YYYY-MM-DD-{slug}.md`
|
|
105
|
+
3. 設計 Aggregate(不變條件、狀態變更方法、Domain Events)
|
|
106
|
+
4. 實作順序:Domain → Application → Infrastructure → Presentation
|
|
107
|
+
5. 撰寫測試:Domain 單元測試 → Application 測試 → 整合測試
|
|
108
|
+
|
|
109
|
+
### New Phase
|
|
110
|
+
1. 在已啟動的 active feature 上新增一份 phase-spec(含 Delta-from-prior-phases)
|
|
111
|
+
2. 更新 `_index.md` 的 Phase Specs 表 + regenerate Current BR Snapshot
|
|
112
|
+
3. 嚴格只適用於 active feature;completed 的 feature 不接受新 phase
|
|
113
|
+
|
|
114
|
+
### Modify Existing
|
|
115
|
+
1. AI 依 T1 / T2 / T3 判準分流
|
|
116
|
+
2. 若偵測到改動與 completed feature 相關,主動詢問是否為 follow-up
|
|
117
|
+
(follow-up 走新建 feature + `follow-up-of` 鏈回原 feature;不把 T2/T3
|
|
118
|
+
寫回 completed 目錄)
|
|
119
|
+
3. 確認 fix 在正確的 Clean Architecture 層
|
|
120
|
+
|
|
121
|
+
### Bug Fix
|
|
122
|
+
1. 建立輕量規格
|
|
123
|
+
2. 若 bug 不附掛既有 feature,先建最小 feature 目錄再放 lightweight-spec
|
|
124
|
+
3. 找到問題所在的層
|
|
125
|
+
4. 在正確的層修復
|
|
126
|
+
|
|
127
|
+
### Feature Closeout
|
|
128
|
+
1. 驗證 feature 目錄內所有 phase-spec `status: completed`
|
|
129
|
+
2. 把 `_index.md` Current BR Snapshot 同步到 BC 層 `rules.md` /
|
|
130
|
+
`behavior.md` / `events.md` / `context-map.md`
|
|
131
|
+
3. `git mv` 整個 feature 目錄從 `active/` 搬到 `completed/`
|
|
132
|
+
4. 產出 Integration Summary(Git-strategy-neutral;不自動 merge)
|
|
133
|
+
|
|
134
|
+
### Git Integration
|
|
135
|
+
|
|
136
|
+
> 本流程只規定 SDD 必要的最小 Git 耦合(feature branch per feature、
|
|
137
|
+
> `git mv`、commit 對應 SPEC-ID)。實際採用的分支策略(Git Flow /
|
|
138
|
+
> GitHub Flow / trunk-based / 單一 main)由專案決定,不在此強制。
|
|
139
|
+
> 若採用 Git Flow,可參考 `scaffolding/Git-principles-gitflow.md` 範本。
|
|
140
|
+
|
|
141
|
+
**分支命名**
|
|
142
|
+
```
|
|
143
|
+
feature/{SPEC-ID}-{short-description} # 新功能(SDD 必須)
|
|
144
|
+
bugfix/{BUG-ID}-{short-description} # Bug 修復(SDD 必須)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Commit Message**
|
|
148
|
+
```
|
|
149
|
+
[SPEC-ID] 簡述變更
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
> `/dflow:bug-fix` 不綁定任何分支策略;採 Git Flow 的專案可選擇把緊急修復
|
|
153
|
+
> 放在 `hotfix/` 分支,但這是專案決策,Dflow 不代為規定。
|
|
154
|
+
|
|
155
|
+
### Domain Layer Rules
|
|
156
|
+
|
|
157
|
+
- ❌ 不可有任何 NuGet 套件依賴(純 .NET 類型)
|
|
158
|
+
- ❌ 不可有 ORM 屬性([Table], [Column] 等)
|
|
159
|
+
- ❌ 不可有序列化屬性([JsonProperty] 等)
|
|
160
|
+
- ❌ 不可有 DbContext、IConfiguration、HttpClient
|
|
161
|
+
- ✅ Entity 使用 private setter,透過方法改變狀態
|
|
162
|
+
- ✅ Value Object 使用 record,建構式驗證
|
|
163
|
+
- ✅ Aggregate Root 管理 DomainEvents 集合
|
|
164
|
+
- ✅ 其他 Aggregate 只透過 ID 引用
|
|
165
|
+
|
|
166
|
+
### AI Collaboration Notes
|
|
167
|
+
|
|
168
|
+
- 開發者提出任何需求時,先引導建立 spec 和 Aggregate 設計
|
|
169
|
+
- 確認實作順序:Domain → Application → Infrastructure → Presentation
|
|
170
|
+
- 發現業務邏輯在錯誤的層時,指出並建議搬移
|
|
171
|
+
- 每次開發循環結束時,提醒更新術語表、models.md、events.md
|
|
172
|
+
- Review 時檢查 Domain 層的純淨度(零外部依賴)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
spec-id: SPEC-{YYYYMMDD}-{NNN}
|
|
3
|
+
slug: {slug-following-discussion-language}
|
|
4
|
+
status: in-progress # in-progress | completed
|
|
5
|
+
created: {YYYY-MM-DD}
|
|
6
|
+
branch: feature/{SPEC-ID}-{slug}
|
|
7
|
+
# follow-up-of: {原 SPEC-ID} # 選用:本 feature 為某個已 completed feature 的 follow-up 時填入
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!--
|
|
11
|
+
Template note (for AI):
|
|
12
|
+
This is the **feature-level dashboard** (`_index.md`) for a feature
|
|
13
|
+
directory. Place at `dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`.
|
|
14
|
+
|
|
15
|
+
Six required sections (see below):
|
|
16
|
+
1. Metadata (YAML front matter above)
|
|
17
|
+
2. Goals & Scope (prose)
|
|
18
|
+
3. Phase Specs (T1 list)
|
|
19
|
+
4. Current BR Snapshot (feature-level cumulative state)
|
|
20
|
+
5. Lightweight Changes (T2 outbound link + T3 inline)
|
|
21
|
+
6. Resume Pointer
|
|
22
|
+
|
|
23
|
+
Optional section (append at end if applicable):
|
|
24
|
+
- Follow-up Tracking (when this feature has follow-up features derived)
|
|
25
|
+
|
|
26
|
+
Refresh discipline for "Current BR Snapshot":
|
|
27
|
+
- Regenerate when /dflow:new-phase enters
|
|
28
|
+
- Regenerate when a phase-spec is finalized (completed)
|
|
29
|
+
- Regenerate when a T2 lightweight-spec is finalized
|
|
30
|
+
- This table is the feature-level CURRENT STATE (not history).
|
|
31
|
+
History lives in each phase-spec's "Delta from prior phases" section.
|
|
32
|
+
|
|
33
|
+
Sync to BC layer:
|
|
34
|
+
- At /dflow:finish-feature, BR Snapshot is reconciled with the bounded
|
|
35
|
+
context's `dflow/specs/domain/{context}/rules.md` and `behavior.md`
|
|
36
|
+
(continues the existing Step 8.3 / Step 5.3 sync mechanism — no new
|
|
37
|
+
flow is introduced).
|
|
38
|
+
- rules.md is the SYSTEM-LEVEL truth across features; _index.md is the
|
|
39
|
+
FEATURE-LEVEL aggregation. Both can co-exist; on conflict, finish-feature
|
|
40
|
+
reconciles them and rules.md wins as the system truth.
|
|
41
|
+
|
|
42
|
+
Minimal usage:
|
|
43
|
+
For a 1-commit / 1-phase feature this template can be ~30 lines —
|
|
44
|
+
fill metadata + a short Goals & Scope + one row in Phase Specs +
|
|
45
|
+
initial BR Snapshot + Resume Pointer. The other sections can stay empty.
|
|
46
|
+
-->
|
|
47
|
+
|
|
48
|
+
# {Feature Title}
|
|
49
|
+
|
|
50
|
+
## Goals & Scope
|
|
51
|
+
|
|
52
|
+
> 1-3 段:本 feature 解決什麼問題?為誰解決?邊界在哪?涉及哪些 Bounded
|
|
53
|
+
> Context / Aggregate?
|
|
54
|
+
>
|
|
55
|
+
> 若是 follow-up feature,AI 會在頂部自動加註:
|
|
56
|
+
> 「本 feature 為 `{原 SPEC-ID}-{原 slug}` 的 follow-up,原 feature 完成於
|
|
57
|
+
> `{date}`,詳見 `completed/{原 SPEC-ID}-{原 slug}/_index.md`」
|
|
58
|
+
|
|
59
|
+
## Phase Specs
|
|
60
|
+
|
|
61
|
+
> T1 Heavy ceremony 產出的 phase-spec 列表(一份 phase-spec ≈ 一次完整
|
|
62
|
+
> Kickoff → Domain → Design → Build → Verify 循環)。
|
|
63
|
+
|
|
64
|
+
| Phase | Date | Slug | Status | File Link |
|
|
65
|
+
|---|---|---|---|---|
|
|
66
|
+
| 1 | {YYYY-MM-DD} | {phase-slug} | in-progress / completed | [phase-spec-{date}-{phase-slug}.md](./phase-spec-{date}-{phase-slug}.md) |
|
|
67
|
+
|
|
68
|
+
<!-- dflow:section current-br-snapshot -->
|
|
69
|
+
## Current BR Snapshot
|
|
70
|
+
|
|
71
|
+
> Feature 層的 BR 當前狀態(不是歷史)。AI 在以下時機 regenerate 本表:
|
|
72
|
+
> - `/dflow:new-phase` 進入時
|
|
73
|
+
> - 完成一份 phase-spec 時
|
|
74
|
+
> - T2 lightweight spec 定稿時
|
|
75
|
+
>
|
|
76
|
+
> 歷史由各 phase-spec 的「Delta from prior phases」段串接閱讀;feature
|
|
77
|
+
> 完成時 `/dflow:finish-feature` 把本表推進到對應 BC 的 `rules.md` /
|
|
78
|
+
> `behavior.md`(延續 Step 5.3 既有 sync 機制)。
|
|
79
|
+
|
|
80
|
+
| BR-ID | Current Rule | First Seen (phase) | Last Updated (phase) | Status |
|
|
81
|
+
|---|---|---|---|---|
|
|
82
|
+
| BR-01 | {規則描述} | phase-1 / inherited from rules.md | phase-N | active / removed |
|
|
83
|
+
|
|
84
|
+
<!-- dflow:section lightweight-changes -->
|
|
85
|
+
## Lightweight Changes
|
|
86
|
+
|
|
87
|
+
> T2 行:描述含「見 `lightweight-{date}-{slug}.md`」外連
|
|
88
|
+
> T3 行:inline 完整描述一句話 + 標籤(如 `[cosmetic]` / `[text]` /
|
|
89
|
+
> `[format]`);T3 不產獨立 spec 檔
|
|
90
|
+
>
|
|
91
|
+
> Tier 判準見 SKILL.md § Ceremony Scaling 三層表。
|
|
92
|
+
|
|
93
|
+
| Date | Tier | Description | Commit |
|
|
94
|
+
|---|---|---|---|
|
|
95
|
+
| {YYYY-MM-DD} | T2 | bug fix XYZ — 見 [`lightweight-{date}-{slug}.md`](./lightweight-{date}-{slug}.md) | {hash} |
|
|
96
|
+
| {YYYY-MM-DD} | T3 | 按鈕顏色從藍改綠 `[cosmetic]` | {hash} |
|
|
97
|
+
|
|
98
|
+
## Resume Pointer
|
|
99
|
+
|
|
100
|
+
> 一句話:目前進展到哪?下一個動作是什麼?
|
|
101
|
+
> 開新對話接續工作時,從這裡讀起。
|
|
102
|
+
|
|
103
|
+
**Current Progress**: {one-line summary}
|
|
104
|
+
|
|
105
|
+
**Next Action**: {suggested next action}
|
|
106
|
+
|
|
107
|
+
<!--
|
|
108
|
+
## Follow-up Tracking
|
|
109
|
+
>(選用段;只有當本 feature 衍生出 follow-up feature 時才填)
|
|
110
|
+
> 由 `/dflow:new-feature` / `/dflow:modify-existing` 在新建 follow-up
|
|
111
|
+
> feature 時自動更新;新 feature 完成時 `/dflow:finish-feature` 反向更新
|
|
112
|
+
> 該列 Status 欄為 `completed`。
|
|
113
|
+
> 連結權威是新 feature 的 `follow-up-of` 欄;本表為衍生索引。
|
|
114
|
+
|
|
115
|
+
| SPEC-ID | slug | Created | Status |
|
|
116
|
+
|---|---|---|---|
|
|
117
|
+
| SPEC-{YYYYMMDD}-{NNN} | {slug} | {YYYY-MM-DD} | in-progress / completed |
|
|
118
|
+
-->
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
aggregate: {AggregateName}
|
|
3
|
+
bounded-context: {ContextName}
|
|
4
|
+
created: {YYYY-MM-DD}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# {AggregateName} Aggregate
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
> 這個 Aggregate 代表什麼業務概念?一句話描述。
|
|
12
|
+
|
|
13
|
+
## Invariants
|
|
14
|
+
|
|
15
|
+
> 必須永遠為真的規則。這是 Aggregate 存在的理由。
|
|
16
|
+
|
|
17
|
+
| ID | Invariant | Behavior on Violation |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| INV-01 | {必須為真的條件} | 拋出 DomainException |
|
|
20
|
+
| INV-02 | {必須為真的條件} | 拋出 DomainException |
|
|
21
|
+
|
|
22
|
+
## Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
{AggregateName} (Aggregate Root)
|
|
26
|
+
├── {ChildEntity} (Entity)
|
|
27
|
+
├── {ValueObject1} (Value Object)
|
|
28
|
+
└── {ValueObject2} (Value Object)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Aggregate Root
|
|
32
|
+
|
|
33
|
+
| Property | Type | Description |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| Id | {AggregateName}Id | 唯一識別 |
|
|
36
|
+
| {Property} | {Type} | {說明} |
|
|
37
|
+
|
|
38
|
+
## State Transition Methods
|
|
39
|
+
|
|
40
|
+
| Method | Preconditions | Postconditions | Domain Event |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| {MethodName}() | {必須滿足什麼} | {狀態如何改變} | {EventName} |
|
|
43
|
+
|
|
44
|
+
## Domain Events
|
|
45
|
+
|
|
46
|
+
| Event | Trigger | Consumer |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| {EventName} | {觸發條件} | {處理者或 Context} |
|
|
49
|
+
|
|
50
|
+
## Referenced Aggregates (ID only)
|
|
51
|
+
|
|
52
|
+
| Aggregate | Reference Type | Purpose |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| {OtherAggregate} | {OtherAggregate}Id | {為什麼需要引用} |
|
|
55
|
+
|
|
56
|
+
## Design Decisions
|
|
57
|
+
|
|
58
|
+
> 為什麼 Aggregate 的邊界劃在這裡?有沒有考慮過其他方案?
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# {Bounded Context} — Behavior Specification
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Consolidated source of truth for this context's current behavior.
|
|
4
|
+
> Unlike `dflow/specs/features/completed/` (historical archive), this file always reflects
|
|
5
|
+
> the **current** system behavior — what the system does right now.
|
|
6
|
+
>
|
|
7
|
+
> **Maintenance**: AI updates this file during the completion flow (Step 8.3 / Step 5.3).
|
|
8
|
+
> When a feature is completed, merge its Given/When/Then scenarios here.
|
|
9
|
+
> When behavior is modified, update the corresponding section using the Delta result
|
|
10
|
+
> (not the Delta markup — merge the final state).
|
|
11
|
+
>
|
|
12
|
+
> **Relationship to rules.md**: `rules.md` is the declarative index (BR-ID + one-line summary).
|
|
13
|
+
> This file is the scenario-level detail. Each BR-ID in `rules.md` should have a
|
|
14
|
+
> corresponding section here. If they drift, `/dflow:verify` will catch it.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<!-- dflow:section behavior-scenarios -->
|
|
19
|
+
## {Feature Area 1}
|
|
20
|
+
|
|
21
|
+
### BR-001: {Rule Name}
|
|
22
|
+
|
|
23
|
+
Given {Aggregate in initial state}
|
|
24
|
+
When {Command is issued / Aggregate method is called}
|
|
25
|
+
Then {Aggregate transitions to new state}
|
|
26
|
+
And {Domain Event is raised}
|
|
27
|
+
|
|
28
|
+
### BR-002: {Rule Name}
|
|
29
|
+
|
|
30
|
+
Given {Aggregate in initial state}
|
|
31
|
+
When {Command is issued}
|
|
32
|
+
Then {expected result}
|
|
33
|
+
|
|
34
|
+
#### Edge cases
|
|
35
|
+
|
|
36
|
+
- EC-001: Given {edge case state} When {action} Then {handling}
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## {Feature Area 2}
|
|
41
|
+
|
|
42
|
+
### BR-003: {Rule Name}
|
|
43
|
+
|
|
44
|
+
Given {Aggregate state}
|
|
45
|
+
When {Command}
|
|
46
|
+
Then {new state}
|
|
47
|
+
And {Domain Event}
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
<!--
|
|
52
|
+
Maintenance notes:
|
|
53
|
+
- Organize by feature area, not by spec ID (specs are transient; behavior areas are stable)
|
|
54
|
+
- When merging a completed spec, place its scenarios under the matching feature area
|
|
55
|
+
- When a MODIFIED delta changes a rule, update the scenario here to reflect the NEW behavior
|
|
56
|
+
(git history preserves the old version — don't keep "原本/改為" pairs here)
|
|
57
|
+
- When a REMOVED delta drops a rule, delete the corresponding section
|
|
58
|
+
- When a RENAMED delta renames a concept, update all references in this file
|
|
59
|
+
- Keep BR-IDs in sync with rules.md
|
|
60
|
+
- Include Aggregate state transitions and Domain Events in each scenario
|
|
61
|
+
(this is what /dflow:pr-review Step 0 reads to understand intent)
|
|
62
|
+
-->
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
context: {ContextName}
|
|
3
|
+
chinese-name: {中文名稱}
|
|
4
|
+
owner: {負責的開發者或團隊}
|
|
5
|
+
created: {YYYY-MM-DD}
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# {ContextName} Bounded Context
|
|
9
|
+
|
|
10
|
+
## Responsibilities
|
|
11
|
+
|
|
12
|
+
> 這個 Context 負責什麼?用 2-3 句話描述。
|
|
13
|
+
|
|
14
|
+
## Boundaries
|
|
15
|
+
|
|
16
|
+
### In Scope
|
|
17
|
+
- {職責 1}
|
|
18
|
+
- {職責 2}
|
|
19
|
+
|
|
20
|
+
### Out of Scope
|
|
21
|
+
- {排除項 1} → 由 {OtherContext} 處理
|
|
22
|
+
- {排除項 2} → 由 {OtherContext} 處理
|
|
23
|
+
|
|
24
|
+
## Core Domain Models
|
|
25
|
+
|
|
26
|
+
> 詳細定義在 `models.md`,這裡只列出概覽。
|
|
27
|
+
|
|
28
|
+
### Aggregates
|
|
29
|
+
- **{AggregateName}** — {一句話描述}
|
|
30
|
+
|
|
31
|
+
### Entities
|
|
32
|
+
- **{EntityName}** — {一句話描述}
|
|
33
|
+
|
|
34
|
+
### Value Objects
|
|
35
|
+
- **{VOName}** — {一句話描述}
|
|
36
|
+
|
|
37
|
+
### Domain Services
|
|
38
|
+
- **{ServiceName}** — {一句話描述}
|
|
39
|
+
|
|
40
|
+
### Repository Interfaces
|
|
41
|
+
- **{RepositoryName}** — {一句話描述}
|
|
42
|
+
|
|
43
|
+
## Interactions with Other Contexts
|
|
44
|
+
|
|
45
|
+
| Other Context | Interaction Type | Description |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| {OtherContext} | 呼叫 / 事件 / 共享資料 | {描述} |
|
|
48
|
+
|
|
49
|
+
## Key Business Rules
|
|
50
|
+
|
|
51
|
+
> 規則索引在 `rules.md`(BR-ID + 一行摘要),完整 Behavior Scenarios 在 `behavior.md`(Given/When/Then)。這裡只列最重要的幾條。
|
|
52
|
+
|
|
53
|
+
1. {最重要的規則}
|
|
54
|
+
2. {第二重要的規則}
|
|
55
|
+
|
|
56
|
+
## Code Mapping
|
|
57
|
+
|
|
58
|
+
### Current Implementation
|
|
59
|
+
- Domain: `src/{Project}.Domain/{Context}/`
|
|
60
|
+
- Application: `src/{Project}.Application/{Context}/`
|
|
61
|
+
- Infrastructure: `src/{Project}.Infrastructure/`
|
|
62
|
+
|
|
63
|
+
### Architecture Notes
|
|
64
|
+
- 依 Clean Architecture dependency direction 維持 Domain 純淨。
|