规范 UI 开发,ui-five-layer-architecture skill
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: ui-five-layer-architecture
|
||||
description: Define, review, and refactor UI modules using a strict five-layer architecture (UseCase, RawData, Controller, Context, View). Use when creating cross-project UI architecture standards, designing new UI modules, reviewing layer boundaries and event flow, converting ad-hoc UI code into layered structure, or validating UI test strategy for business-driven interfaces.
|
||||
---
|
||||
|
||||
# UI Five-Layer Architecture
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Read `./references/ui-five-layer-standard.md`.
|
||||
2. Classify the UI as `standard-five-layer` or `lightweight`.
|
||||
3. Apply boundary rules before editing code or writing design output.
|
||||
4. Use the checklists in this file to drive design, review, or refactor tasks.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Scope the task
|
||||
|
||||
Decide which mode the user needs:
|
||||
|
||||
- architecture-spec mode: create or revise a UI architecture standard
|
||||
- design mode: design one or more UI modules before coding
|
||||
- implementation mode: implement or refactor code to match the standard
|
||||
- review mode: audit existing code for boundary or dependency violations
|
||||
|
||||
### 2. Choose module level
|
||||
|
||||
Use `standard-five-layer` when UI owns business state transitions, validations, or branching behavior.
|
||||
|
||||
Use `lightweight` when UI only handles display/navigation and has no independent business rules.
|
||||
|
||||
### 3. Enforce non-negotiable boundaries
|
||||
|
||||
Apply these constraints in every mode:
|
||||
|
||||
- keep `UseCase` business-only and return only `RawData/Result`
|
||||
- build `Context` only inside `Controller`
|
||||
- keep `View` presentation-only and event-emitting only
|
||||
- keep `View` out of global business event subscriptions
|
||||
- route external UI open/close/refresh through `Controller`
|
||||
|
||||
### 4. Apply communication and dependency checks
|
||||
|
||||
Validate:
|
||||
|
||||
- dependency direction is valid for all touched files
|
||||
- UI-specific events stay UI-local in meaning
|
||||
- `Controller` filters sender and instance scope when needed
|
||||
- no `RawData` field uses `*Context` types
|
||||
|
||||
### 5. Produce mode-specific output
|
||||
|
||||
- architecture-spec mode:
|
||||
- output the final standard text
|
||||
- include strict rules, permitted exceptions, and checklists
|
||||
- design mode:
|
||||
- output layer map and flow diagram for each UI module
|
||||
- include type list and event list
|
||||
- implementation mode:
|
||||
- implement code changes matching the standard
|
||||
- update tests if `UseCase` behavior changes
|
||||
- review mode:
|
||||
- report findings first, ordered by severity
|
||||
- include concrete file and line references
|
||||
|
||||
## Architecture Checklist
|
||||
|
||||
Use this list before closing any task:
|
||||
|
||||
1. Classify each UI module correctly: `standard-five-layer` or `lightweight`.
|
||||
2. Ensure `UseCase` does not construct `Context` or touch view concerns.
|
||||
3. Ensure `RawData` does not include `*Context` or presentation types.
|
||||
4. Ensure `Controller` owns all `RawData/Result -> Context` transformation.
|
||||
5. Ensure `View` only consumes `Context` and emits UI-local events.
|
||||
6. Ensure external open/close/update operations enter through `Controller`.
|
||||
7. Ensure event ownership and sender filtering are explicit.
|
||||
8. Ensure test approach matches policy in the reference file.
|
||||
|
||||
## References
|
||||
|
||||
Read `./references/ui-five-layer-standard.md` for the full specification.
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "UI Five-Layer Architecture"
|
||||
short_description: "Cross-project UI five-layer architecture standards"
|
||||
default_prompt: "Use $ui-five-layer-architecture to define, review, or refactor a UI module with clear five-layer boundaries."
|
||||
@@ -0,0 +1,274 @@
|
||||
# UI Five-Layer Architecture Standard
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Scope and Intent](#scope-and-intent)
|
||||
2. [Core Model](#core-model)
|
||||
3. [Layer Definitions](#layer-definitions)
|
||||
4. [UI Module Levels](#ui-module-levels)
|
||||
5. [Dependency Rules](#dependency-rules)
|
||||
6. [Event Communication Rules](#event-communication-rules)
|
||||
7. [Interaction Flow](#interaction-flow)
|
||||
8. [Naming and Folder Conventions](#naming-and-folder-conventions)
|
||||
9. [Testing Policy](#testing-policy)
|
||||
10. [Anti-Patterns](#anti-patterns)
|
||||
11. [Delivery Checklist](#delivery-checklist)
|
||||
|
||||
## Scope and Intent
|
||||
|
||||
Use this standard to define and enforce a stable UI architecture that can be reused across projects.
|
||||
|
||||
Primary goals:
|
||||
|
||||
- keep business logic independent from UI rendering
|
||||
- keep UI rendering deterministic and testable
|
||||
- make reviews and refactors consistent
|
||||
- reduce coupling and regression risk
|
||||
|
||||
## Core Model
|
||||
|
||||
Base chain:
|
||||
|
||||
```text
|
||||
External Flow
|
||||
-> Controller
|
||||
-> UseCase
|
||||
-> RawData / Result
|
||||
-> BuildContext
|
||||
-> View
|
||||
|
||||
View
|
||||
--(UI-local event)--> Controller
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `UseCase` produces business outputs only.
|
||||
- `Controller` is the only layer that creates `Context`.
|
||||
- `View` only renders and emits interaction events.
|
||||
|
||||
## Layer Definitions
|
||||
|
||||
### UseCase
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- own business rules and state transitions
|
||||
- validate business actions
|
||||
- return `RawData` or result objects
|
||||
|
||||
Constraints:
|
||||
|
||||
- do not depend on `Context`, `View`, or rendering types
|
||||
- do not format display strings or map visual assets
|
||||
- do not publish UI-local events
|
||||
|
||||
### RawData
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- carry business data from `UseCase` to `Controller`
|
||||
|
||||
Constraints:
|
||||
|
||||
- keep data business-oriented
|
||||
- do not reference any `*Context` type
|
||||
- do not contain rendering objects (for example UI components)
|
||||
|
||||
### Controller
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- be the external entry point for open/close/refresh
|
||||
- bind and call `UseCase`
|
||||
- transform `RawData/Result` into `Context`
|
||||
- subscribe/unsubscribe UI-local events
|
||||
- coordinate full or partial refresh
|
||||
|
||||
Constraints:
|
||||
|
||||
- do not let `View` bypass controller orchestration
|
||||
- do not hide heavy business logic that belongs in `UseCase`
|
||||
|
||||
### Context
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- carry display-ready data for rendering
|
||||
|
||||
Constraints:
|
||||
|
||||
- construct/update only in `Controller`
|
||||
- do not enter `UseCase`
|
||||
- allow composition (`FormContext`, `ItemContext`, `AreaContext`)
|
||||
|
||||
### View
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- bind controls and render `Context`
|
||||
- emit UI-local interaction events
|
||||
|
||||
Constraints:
|
||||
|
||||
- do not call `UseCase`
|
||||
- do not mutate domain state
|
||||
- do not subscribe to global business events
|
||||
- do not become external entry points
|
||||
|
||||
## UI Module Levels
|
||||
|
||||
### Standard Five-Layer Module
|
||||
|
||||
Structure:
|
||||
|
||||
- `UseCase + RawData + Controller + Context + View`
|
||||
|
||||
Use when:
|
||||
|
||||
- module owns business rules, validations, or branching state transitions
|
||||
- user actions mutate domain state
|
||||
- behavior requires automated verification
|
||||
|
||||
### Lightweight Module
|
||||
|
||||
Structure:
|
||||
|
||||
- `Controller + Context + View`
|
||||
|
||||
Use when:
|
||||
|
||||
- module is display/navigation/confirmation only
|
||||
- no independent business rules are present
|
||||
|
||||
Rule:
|
||||
|
||||
- upgrade to standard five-layer as soon as business rules appear
|
||||
|
||||
## Dependency Rules
|
||||
|
||||
Allowed:
|
||||
|
||||
- `UseCase -> domain/services/RawData/Result`
|
||||
- `Controller -> UseCase/RawData/Result/Context/View/UI-local events`
|
||||
- `Context -> child context/value objects`
|
||||
- `View -> Context/UI-local events`
|
||||
|
||||
Forbidden:
|
||||
|
||||
- `UseCase -> Context/View/rendering types`
|
||||
- `RawData/Result -> Context/View`
|
||||
- `Context -> UseCase/View`
|
||||
- `View -> UseCase`
|
||||
- `View -> global business events`
|
||||
- `View -> domain state mutation`
|
||||
|
||||
## Event Communication Rules
|
||||
|
||||
### Event Ownership
|
||||
|
||||
- `View -> Controller` uses UI-local events only
|
||||
- UI-local events are not global business contracts
|
||||
- business/domain modules must not consume UI-local event semantics
|
||||
|
||||
### Safety Requirements
|
||||
|
||||
- validate sender ownership in `Controller`
|
||||
- scope handling to the active UI instance
|
||||
- keep subscribe/unsubscribe symmetric
|
||||
|
||||
## Interaction Flow
|
||||
|
||||
### Standard Module
|
||||
|
||||
```text
|
||||
External Flow
|
||||
-> create/bind UseCase
|
||||
-> open UI via Controller
|
||||
|
||||
Controller
|
||||
-> UseCase action
|
||||
-> RawData/Result
|
||||
-> BuildContext
|
||||
-> View refresh
|
||||
|
||||
View
|
||||
--(UI-local event)--> Controller
|
||||
```
|
||||
|
||||
### Lightweight Module
|
||||
|
||||
```text
|
||||
External Flow
|
||||
-> open UI via Controller(userData)
|
||||
|
||||
Controller
|
||||
-> BuildContext(userData)
|
||||
-> View refresh
|
||||
|
||||
View
|
||||
--(UI-local event)--> Controller
|
||||
```
|
||||
|
||||
## Naming and Folder Conventions
|
||||
|
||||
Recommended folders:
|
||||
|
||||
- `UI/<Domain>/UseCase`
|
||||
- `UI/<Domain>/RawData`
|
||||
- `UI/<Domain>/Controller`
|
||||
- `UI/<Domain>/Context`
|
||||
- `UI/<Domain>/View`
|
||||
|
||||
Recommended naming:
|
||||
|
||||
- `XXXFormUseCase`
|
||||
- `XXXFormRawData`
|
||||
- `XXXFormController`
|
||||
- `XXXFormContext`, `XXXItemContext`, `XXXAreaContext`
|
||||
- `XXXResult`, `XXXActionResult`
|
||||
|
||||
## Testing Policy
|
||||
|
||||
Policy:
|
||||
|
||||
- if a UI has a `UseCase` and automated tests are added, use EditMode tests for the `UseCase`
|
||||
|
||||
Priority coverage:
|
||||
|
||||
- initial model generation
|
||||
- business branch and validation behavior
|
||||
- action result correctness
|
||||
- boundary and invalid input handling
|
||||
|
||||
Manual verification focus:
|
||||
|
||||
- first open
|
||||
- interaction refresh
|
||||
- partial refresh
|
||||
- close and reopen
|
||||
- null/invalid userData behavior
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
Do not allow:
|
||||
|
||||
- `UseCase` returning `Context`
|
||||
- `RawData` carrying `*Context`
|
||||
- `View` subscribing global business events
|
||||
- direct domain mutation inside `View`
|
||||
- skipping `Controller` as module entry
|
||||
- module marked lightweight while carrying business state transitions
|
||||
|
||||
## Delivery Checklist
|
||||
|
||||
Use this checklist before marking work complete:
|
||||
|
||||
1. classify each module as standard or lightweight
|
||||
2. verify business rules sit in `UseCase` only
|
||||
3. verify `Context` is built only in `Controller`
|
||||
4. verify `RawData` has no presentation model leakage
|
||||
5. verify `View` is render-and-emit only
|
||||
6. verify UI-local events are scoped and sender-checked
|
||||
7. verify dependency direction constraints pass
|
||||
8. verify tests/manual checks match the testing policy
|
||||
Reference in New Issue
Block a user