atdd 0.1.0__py3-none-any.whl
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.
- atdd/__init__.py +0 -0
- atdd/cli.py +404 -0
- atdd/coach/__init__.py +0 -0
- atdd/coach/commands/__init__.py +0 -0
- atdd/coach/commands/add_persistence_metadata.py +215 -0
- atdd/coach/commands/analyze_migrations.py +188 -0
- atdd/coach/commands/consumers.py +720 -0
- atdd/coach/commands/infer_governance_status.py +149 -0
- atdd/coach/commands/initializer.py +177 -0
- atdd/coach/commands/interface.py +1078 -0
- atdd/coach/commands/inventory.py +565 -0
- atdd/coach/commands/migration.py +240 -0
- atdd/coach/commands/registry.py +1560 -0
- atdd/coach/commands/session.py +430 -0
- atdd/coach/commands/sync.py +405 -0
- atdd/coach/commands/test_interface.py +399 -0
- atdd/coach/commands/test_runner.py +141 -0
- atdd/coach/commands/tests/__init__.py +1 -0
- atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
- atdd/coach/commands/traceability.py +4264 -0
- atdd/coach/conventions/session.convention.yaml +754 -0
- atdd/coach/overlays/__init__.py +2 -0
- atdd/coach/overlays/claude.md +2 -0
- atdd/coach/schemas/config.schema.json +34 -0
- atdd/coach/schemas/manifest.schema.json +101 -0
- atdd/coach/templates/ATDD.md +282 -0
- atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
- atdd/coach/utils/__init__.py +0 -0
- atdd/coach/utils/graph/__init__.py +0 -0
- atdd/coach/utils/graph/urn.py +875 -0
- atdd/coach/validators/__init__.py +0 -0
- atdd/coach/validators/shared_fixtures.py +365 -0
- atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
- atdd/coach/validators/test_registry.py +575 -0
- atdd/coach/validators/test_session_validation.py +1183 -0
- atdd/coach/validators/test_traceability.py +448 -0
- atdd/coach/validators/test_update_feature_paths.py +108 -0
- atdd/coach/validators/test_validate_contract_consumers.py +297 -0
- atdd/coder/__init__.py +1 -0
- atdd/coder/conventions/adapter.recipe.yaml +88 -0
- atdd/coder/conventions/backend.convention.yaml +460 -0
- atdd/coder/conventions/boundaries.convention.yaml +666 -0
- atdd/coder/conventions/commons.convention.yaml +460 -0
- atdd/coder/conventions/complexity.recipe.yaml +109 -0
- atdd/coder/conventions/component-naming.convention.yaml +178 -0
- atdd/coder/conventions/design.convention.yaml +327 -0
- atdd/coder/conventions/design.recipe.yaml +273 -0
- atdd/coder/conventions/dto.convention.yaml +660 -0
- atdd/coder/conventions/frontend.convention.yaml +542 -0
- atdd/coder/conventions/green.convention.yaml +1012 -0
- atdd/coder/conventions/presentation.convention.yaml +587 -0
- atdd/coder/conventions/refactor.convention.yaml +535 -0
- atdd/coder/conventions/technology.convention.yaml +206 -0
- atdd/coder/conventions/tests/__init__.py +0 -0
- atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
- atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
- atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
- atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
- atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
- atdd/coder/conventions/thinness.recipe.yaml +82 -0
- atdd/coder/conventions/train.convention.yaml +325 -0
- atdd/coder/conventions/verification.protocol.yaml +53 -0
- atdd/coder/schemas/design_system.schema.json +361 -0
- atdd/coder/validators/__init__.py +0 -0
- atdd/coder/validators/test_commons_structure.py +485 -0
- atdd/coder/validators/test_complexity.py +416 -0
- atdd/coder/validators/test_cross_language_consistency.py +431 -0
- atdd/coder/validators/test_design_system_compliance.py +413 -0
- atdd/coder/validators/test_dto_testing_patterns.py +268 -0
- atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
- atdd/coder/validators/test_green_layer_dependencies.py +148 -0
- atdd/coder/validators/test_green_python_layer_structure.py +103 -0
- atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
- atdd/coder/validators/test_import_boundaries.py +396 -0
- atdd/coder/validators/test_init_file_urns.py +593 -0
- atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
- atdd/coder/validators/test_presentation_convention.py +260 -0
- atdd/coder/validators/test_python_architecture.py +674 -0
- atdd/coder/validators/test_quality_metrics.py +420 -0
- atdd/coder/validators/test_station_master_pattern.py +244 -0
- atdd/coder/validators/test_train_infrastructure.py +454 -0
- atdd/coder/validators/test_train_urns.py +293 -0
- atdd/coder/validators/test_typescript_architecture.py +616 -0
- atdd/coder/validators/test_usecase_structure.py +421 -0
- atdd/coder/validators/test_wagon_boundaries.py +586 -0
- atdd/conftest.py +126 -0
- atdd/planner/__init__.py +1 -0
- atdd/planner/conventions/acceptance.convention.yaml +538 -0
- atdd/planner/conventions/appendix.convention.yaml +187 -0
- atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
- atdd/planner/conventions/component.convention.yaml +670 -0
- atdd/planner/conventions/criteria.convention.yaml +141 -0
- atdd/planner/conventions/feature.convention.yaml +371 -0
- atdd/planner/conventions/interface.convention.yaml +382 -0
- atdd/planner/conventions/steps.convention.yaml +141 -0
- atdd/planner/conventions/train.convention.yaml +552 -0
- atdd/planner/conventions/wagon.convention.yaml +275 -0
- atdd/planner/conventions/wmbt.convention.yaml +258 -0
- atdd/planner/schemas/acceptance.schema.json +336 -0
- atdd/planner/schemas/appendix.schema.json +78 -0
- atdd/planner/schemas/component.schema.json +114 -0
- atdd/planner/schemas/feature.schema.json +197 -0
- atdd/planner/schemas/train.schema.json +192 -0
- atdd/planner/schemas/wagon.schema.json +281 -0
- atdd/planner/schemas/wmbt.schema.json +59 -0
- atdd/planner/validators/__init__.py +0 -0
- atdd/planner/validators/conftest.py +5 -0
- atdd/planner/validators/test_draft_wagon_registry.py +374 -0
- atdd/planner/validators/test_plan_cross_refs.py +240 -0
- atdd/planner/validators/test_plan_uniqueness.py +224 -0
- atdd/planner/validators/test_plan_urn_resolution.py +268 -0
- atdd/planner/validators/test_plan_wagons.py +174 -0
- atdd/planner/validators/test_train_validation.py +514 -0
- atdd/planner/validators/test_wagon_urn_chain.py +648 -0
- atdd/planner/validators/test_wmbt_consistency.py +327 -0
- atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
- atdd/tester/__init__.py +1 -0
- atdd/tester/conventions/artifact.convention.yaml +257 -0
- atdd/tester/conventions/contract.convention.yaml +1009 -0
- atdd/tester/conventions/filename.convention.yaml +555 -0
- atdd/tester/conventions/migration.convention.yaml +509 -0
- atdd/tester/conventions/red.convention.yaml +797 -0
- atdd/tester/conventions/routing.convention.yaml +51 -0
- atdd/tester/conventions/telemetry.convention.yaml +458 -0
- atdd/tester/schemas/a11y.tmpl.json +17 -0
- atdd/tester/schemas/artifact.schema.json +189 -0
- atdd/tester/schemas/contract.schema.json +591 -0
- atdd/tester/schemas/contract.tmpl.json +95 -0
- atdd/tester/schemas/db.tmpl.json +20 -0
- atdd/tester/schemas/e2e.tmpl.json +17 -0
- atdd/tester/schemas/edge_function.tmpl.json +17 -0
- atdd/tester/schemas/event.tmpl.json +17 -0
- atdd/tester/schemas/http.tmpl.json +19 -0
- atdd/tester/schemas/job.tmpl.json +18 -0
- atdd/tester/schemas/load.tmpl.json +21 -0
- atdd/tester/schemas/metric.tmpl.json +19 -0
- atdd/tester/schemas/pack.schema.json +139 -0
- atdd/tester/schemas/realtime.tmpl.json +20 -0
- atdd/tester/schemas/rls.tmpl.json +18 -0
- atdd/tester/schemas/script.tmpl.json +16 -0
- atdd/tester/schemas/sec.tmpl.json +18 -0
- atdd/tester/schemas/storage.tmpl.json +18 -0
- atdd/tester/schemas/telemetry.schema.json +128 -0
- atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
- atdd/tester/schemas/test_filename.schema.json +194 -0
- atdd/tester/schemas/test_intent.schema.json +179 -0
- atdd/tester/schemas/unit.tmpl.json +18 -0
- atdd/tester/schemas/visual.tmpl.json +18 -0
- atdd/tester/schemas/ws.tmpl.json +17 -0
- atdd/tester/utils/__init__.py +0 -0
- atdd/tester/utils/filename.py +300 -0
- atdd/tester/validators/__init__.py +0 -0
- atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
- atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
- atdd/tester/validators/conftest.py +5 -0
- atdd/tester/validators/coverage_gap_report.py +321 -0
- atdd/tester/validators/fix_dual_ac_references.py +179 -0
- atdd/tester/validators/remove_duplicate_lines.py +93 -0
- atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
- atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
- atdd/tester/validators/test_artifact_naming_category.py +307 -0
- atdd/tester/validators/test_contract_schema_compliance.py +706 -0
- atdd/tester/validators/test_contracts_structure.py +200 -0
- atdd/tester/validators/test_coverage_adequacy.py +797 -0
- atdd/tester/validators/test_dual_ac_reference.py +225 -0
- atdd/tester/validators/test_fixture_validity.py +372 -0
- atdd/tester/validators/test_isolation.py +487 -0
- atdd/tester/validators/test_migration_coverage.py +204 -0
- atdd/tester/validators/test_migration_criteria.py +276 -0
- atdd/tester/validators/test_migration_generation.py +116 -0
- atdd/tester/validators/test_python_test_naming.py +410 -0
- atdd/tester/validators/test_red_layer_validation.py +95 -0
- atdd/tester/validators/test_red_python_layer_structure.py +87 -0
- atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
- atdd/tester/validators/test_telemetry_structure.py +634 -0
- atdd/tester/validators/test_typescript_test_naming.py +301 -0
- atdd/tester/validators/test_typescript_test_structure.py +84 -0
- atdd-0.1.0.dist-info/METADATA +191 -0
- atdd-0.1.0.dist-info/RECORD +183 -0
- atdd-0.1.0.dist-info/WHEEL +5 -0
- atdd-0.1.0.dist-info/entry_points.txt +2 -0
- atdd-0.1.0.dist-info/licenses/LICENSE +674 -0
- atdd-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
name: "Frontend Component Convention"
|
|
3
|
+
description: "Layer catalog and component suffixes for frontend implementation."
|
|
4
|
+
|
|
5
|
+
frontend:
|
|
6
|
+
layers:
|
|
7
|
+
presentation:
|
|
8
|
+
description: "User interface components and visual elements"
|
|
9
|
+
component_types:
|
|
10
|
+
- name: views
|
|
11
|
+
description: "Full-screen views and pages"
|
|
12
|
+
suffix:
|
|
13
|
+
dart: "*_page.dart, *_screen.dart"
|
|
14
|
+
typescript: "*-page.tsx, *-view.tsx"
|
|
15
|
+
vue: "*-view.vue"
|
|
16
|
+
examples:
|
|
17
|
+
- "Home page, login screen, dashboard"
|
|
18
|
+
- "Product detail page, checkout flow"
|
|
19
|
+
- "Settings page, profile view"
|
|
20
|
+
|
|
21
|
+
- name: components
|
|
22
|
+
description: "Reusable UI components"
|
|
23
|
+
suffix:
|
|
24
|
+
dart: "*_widget.dart"
|
|
25
|
+
typescript: "*.tsx, *.vue"
|
|
26
|
+
vue: "*.vue"
|
|
27
|
+
examples:
|
|
28
|
+
- "Buttons, inputs, cards, modals"
|
|
29
|
+
- "Data tables, charts, forms"
|
|
30
|
+
- "Navigation bars, sidebars, menus"
|
|
31
|
+
- "Stateless display components"
|
|
32
|
+
- "Stateful interactive components"
|
|
33
|
+
|
|
34
|
+
- name: containers
|
|
35
|
+
description: "Smart components connected to state"
|
|
36
|
+
suffix:
|
|
37
|
+
typescript: "*-container.tsx"
|
|
38
|
+
vue: "*-container.vue"
|
|
39
|
+
examples:
|
|
40
|
+
- "Connected components (Redux, Vuex)"
|
|
41
|
+
- "Data-fetching wrappers"
|
|
42
|
+
- "State-injecting HOCs"
|
|
43
|
+
|
|
44
|
+
- name: controllers
|
|
45
|
+
description: "UI state management and business logic"
|
|
46
|
+
suffix:
|
|
47
|
+
dart: "*_bloc.dart, *_cubit.dart, *_controller.dart"
|
|
48
|
+
typescript: "*-store.ts, *-slice.ts"
|
|
49
|
+
vue: "*-store.ts"
|
|
50
|
+
examples:
|
|
51
|
+
- "BLoC/Cubit (Flutter)"
|
|
52
|
+
- "Redux slices/reducers"
|
|
53
|
+
- "Vuex modules"
|
|
54
|
+
- "MobX stores"
|
|
55
|
+
- "View models (MVVM)"
|
|
56
|
+
|
|
57
|
+
- name: routes
|
|
58
|
+
description: "Navigation and routing configuration"
|
|
59
|
+
suffix:
|
|
60
|
+
dart: "*_router.dart, *_routes.dart"
|
|
61
|
+
typescript: "*-routes.ts, router.ts"
|
|
62
|
+
examples:
|
|
63
|
+
- "Route definitions"
|
|
64
|
+
- "Navigation guards"
|
|
65
|
+
- "Deep linking"
|
|
66
|
+
- "Route parameters"
|
|
67
|
+
|
|
68
|
+
- name: layouts
|
|
69
|
+
description: "Page structure and composition templates"
|
|
70
|
+
suffix:
|
|
71
|
+
dart: "*_layout.dart"
|
|
72
|
+
typescript: "*-layout.tsx"
|
|
73
|
+
examples:
|
|
74
|
+
- "App shell, main layout"
|
|
75
|
+
- "Sidebar layout, grid layout"
|
|
76
|
+
- "Responsive layouts"
|
|
77
|
+
|
|
78
|
+
- name: styles
|
|
79
|
+
description: "Design tokens, themes, and styling"
|
|
80
|
+
suffix:
|
|
81
|
+
dart: "*_theme.dart, *_styles.dart"
|
|
82
|
+
typescript: "*.css, *.scss, *-theme.ts"
|
|
83
|
+
examples:
|
|
84
|
+
- "Color palettes, typography"
|
|
85
|
+
- "Spacing, shadows, borders"
|
|
86
|
+
- "Dark mode themes"
|
|
87
|
+
- "CSS-in-JS configurations"
|
|
88
|
+
|
|
89
|
+
- name: animations
|
|
90
|
+
description: "UI animations and transitions"
|
|
91
|
+
suffix:
|
|
92
|
+
dart: "*_animation.dart"
|
|
93
|
+
typescript: "*-animation.ts"
|
|
94
|
+
examples:
|
|
95
|
+
- "Page transitions"
|
|
96
|
+
- "Loading animations"
|
|
97
|
+
- "Gesture animations"
|
|
98
|
+
- "Spring physics"
|
|
99
|
+
|
|
100
|
+
- name: forms
|
|
101
|
+
description: "Form state management and validation"
|
|
102
|
+
suffix:
|
|
103
|
+
dart: "*_form.dart"
|
|
104
|
+
typescript: "*-form.ts, *-schema.ts"
|
|
105
|
+
examples:
|
|
106
|
+
- "Form builders"
|
|
107
|
+
- "Validation rules (Yup, Zod, FormBuilder)"
|
|
108
|
+
- "Form state (Formik, React Hook Form)"
|
|
109
|
+
|
|
110
|
+
- name: hooks
|
|
111
|
+
description: "Reusable stateful logic (React/Preact-style)"
|
|
112
|
+
suffix:
|
|
113
|
+
typescript: "use-*.ts, use-*.tsx"
|
|
114
|
+
preact: "use-*.ts"
|
|
115
|
+
dart: "use_*.dart"
|
|
116
|
+
examples:
|
|
117
|
+
- "useAuth, useQuery, useLocalStorage"
|
|
118
|
+
- "useFetch, useDebounce, useThrottle"
|
|
119
|
+
- "Custom business logic hooks"
|
|
120
|
+
layer_guidance:
|
|
121
|
+
presentation: "UI state hooks (useCarouselState, useModalState)"
|
|
122
|
+
application: "Business logic hooks (useDilemma, useTimebank)"
|
|
123
|
+
|
|
124
|
+
- name: directives
|
|
125
|
+
description: "Custom DOM/element behaviors (Vue/Angular)"
|
|
126
|
+
suffix:
|
|
127
|
+
typescript: "*-directive.ts"
|
|
128
|
+
vue: "v-*.ts"
|
|
129
|
+
examples:
|
|
130
|
+
- "v-tooltip, v-click-outside"
|
|
131
|
+
- "Custom attribute directives"
|
|
132
|
+
- "Structural directives"
|
|
133
|
+
|
|
134
|
+
- name: filters
|
|
135
|
+
description: "Data formatting pipes/filters"
|
|
136
|
+
suffix:
|
|
137
|
+
typescript: "*-filter.ts, *-pipe.ts"
|
|
138
|
+
vue: "*-filter.ts"
|
|
139
|
+
examples:
|
|
140
|
+
- "Date formatting"
|
|
141
|
+
- "Currency formatting"
|
|
142
|
+
- "Text truncation"
|
|
143
|
+
|
|
144
|
+
application:
|
|
145
|
+
description: "Frontend-specific business logic and orchestration"
|
|
146
|
+
component_types:
|
|
147
|
+
- name: use_cases
|
|
148
|
+
description: "Frontend-initiated workflows"
|
|
149
|
+
suffix:
|
|
150
|
+
dart: "*_use_case.dart"
|
|
151
|
+
typescript: "*-use-case.ts"
|
|
152
|
+
examples:
|
|
153
|
+
- "Submit order flow"
|
|
154
|
+
- "Load user profile"
|
|
155
|
+
- "Search products"
|
|
156
|
+
- "Upload file with progress"
|
|
157
|
+
|
|
158
|
+
- name: ports
|
|
159
|
+
description: "Interfaces for data access and external services"
|
|
160
|
+
suffix:
|
|
161
|
+
dart: "*_port.dart"
|
|
162
|
+
typescript: "*-port.ts, *-interface.ts"
|
|
163
|
+
examples:
|
|
164
|
+
- "Repository interfaces"
|
|
165
|
+
- "API client interfaces"
|
|
166
|
+
- "Storage interfaces"
|
|
167
|
+
- "Analytics interfaces"
|
|
168
|
+
|
|
169
|
+
- name: policies
|
|
170
|
+
description: "Frontend business policies and rules"
|
|
171
|
+
suffix:
|
|
172
|
+
dart: "*_policy.dart"
|
|
173
|
+
typescript: "*-policy.ts"
|
|
174
|
+
examples:
|
|
175
|
+
- "Authorization policies"
|
|
176
|
+
- "Feature flags"
|
|
177
|
+
- "A/B test logic"
|
|
178
|
+
- "Validation policies"
|
|
179
|
+
|
|
180
|
+
- name: dtos
|
|
181
|
+
description: "Application-internal data structures"
|
|
182
|
+
suffix:
|
|
183
|
+
dart: "*_dto.dart"
|
|
184
|
+
typescript: "*-dto.ts"
|
|
185
|
+
examples:
|
|
186
|
+
- "View models (different from API DTOs)"
|
|
187
|
+
- "Internal transfer objects"
|
|
188
|
+
- "Aggregated UI state"
|
|
189
|
+
|
|
190
|
+
domain:
|
|
191
|
+
description: "Frontend domain types and pure logic (UI-framework agnostic)"
|
|
192
|
+
component_types:
|
|
193
|
+
- name: entities
|
|
194
|
+
description: "Domain models used on the client"
|
|
195
|
+
suffix:
|
|
196
|
+
dart: "*.dart, *_entity.dart"
|
|
197
|
+
typescript: "*.ts, *-entity.ts"
|
|
198
|
+
examples:
|
|
199
|
+
- "User, Product, Order"
|
|
200
|
+
- "Domain entities mirrored from backend"
|
|
201
|
+
- "Client-specific entities"
|
|
202
|
+
|
|
203
|
+
- name: value_objects
|
|
204
|
+
description: "Immutable typed values"
|
|
205
|
+
suffix:
|
|
206
|
+
dart: "*_vo.dart"
|
|
207
|
+
typescript: "*-vo.ts, *.ts"
|
|
208
|
+
examples:
|
|
209
|
+
- "Email, Money, Coordinates"
|
|
210
|
+
- "DateRange, Color, Dimension"
|
|
211
|
+
|
|
212
|
+
- name: services
|
|
213
|
+
description: "Pure domain logic services"
|
|
214
|
+
suffix:
|
|
215
|
+
dart: "*_service.dart"
|
|
216
|
+
typescript: "*-service.ts"
|
|
217
|
+
examples:
|
|
218
|
+
- "Calculation services"
|
|
219
|
+
- "Formatting services (pure functions)"
|
|
220
|
+
- "Business rule evaluation"
|
|
221
|
+
|
|
222
|
+
- name: specifications
|
|
223
|
+
description: "Composable rules and predicates"
|
|
224
|
+
suffix:
|
|
225
|
+
dart: "*_spec.dart"
|
|
226
|
+
typescript: "*-spec.ts"
|
|
227
|
+
examples:
|
|
228
|
+
- "Validation specifications"
|
|
229
|
+
- "Filter specifications"
|
|
230
|
+
- "Eligibility checks"
|
|
231
|
+
|
|
232
|
+
- name: exceptions
|
|
233
|
+
description: "Domain-level errors"
|
|
234
|
+
suffix:
|
|
235
|
+
dart: "*_exception.dart"
|
|
236
|
+
typescript: "*-exception.ts, errors.ts"
|
|
237
|
+
examples:
|
|
238
|
+
- "ValidationError"
|
|
239
|
+
- "BusinessRuleViolation"
|
|
240
|
+
- "InvalidStateError"
|
|
241
|
+
|
|
242
|
+
integration:
|
|
243
|
+
description: "API clients, storage, and external service adapters"
|
|
244
|
+
component_types:
|
|
245
|
+
- name: repositories
|
|
246
|
+
description: "Data access implementations"
|
|
247
|
+
suffix:
|
|
248
|
+
dart: "*_repository.dart"
|
|
249
|
+
typescript: "*-repository.ts"
|
|
250
|
+
examples:
|
|
251
|
+
- "API-backed repositories"
|
|
252
|
+
- "Local storage repositories"
|
|
253
|
+
- "Hybrid online/offline repositories"
|
|
254
|
+
- "IndexedDB repositories"
|
|
255
|
+
|
|
256
|
+
- name: clients
|
|
257
|
+
description: "HTTP/WebSocket/GraphQL API clients"
|
|
258
|
+
suffix:
|
|
259
|
+
dart: "*_client.dart"
|
|
260
|
+
typescript: "*-client.ts, *-api.ts"
|
|
261
|
+
examples:
|
|
262
|
+
- "REST API clients (fetch, axios)"
|
|
263
|
+
- "GraphQL clients (Apollo, urql)"
|
|
264
|
+
- "WebSocket clients"
|
|
265
|
+
- "gRPC-web clients"
|
|
266
|
+
|
|
267
|
+
- name: stores
|
|
268
|
+
description: "Local persistence implementations"
|
|
269
|
+
suffix:
|
|
270
|
+
dart: "*_store.dart"
|
|
271
|
+
typescript: "*-store.ts"
|
|
272
|
+
examples:
|
|
273
|
+
- "LocalStorage adapters"
|
|
274
|
+
- "SessionStorage adapters"
|
|
275
|
+
- "IndexedDB wrappers"
|
|
276
|
+
- "Secure storage (mobile)"
|
|
277
|
+
- "SQLite (mobile)"
|
|
278
|
+
|
|
279
|
+
- name: serializers
|
|
280
|
+
description: "API data transformation"
|
|
281
|
+
suffix:
|
|
282
|
+
dart: "*_serializer.dart"
|
|
283
|
+
typescript: "*-serializer.ts"
|
|
284
|
+
examples:
|
|
285
|
+
- "JSON serialization/deserialization"
|
|
286
|
+
- "API DTO → Entity mapping"
|
|
287
|
+
- "Entity → API DTO mapping"
|
|
288
|
+
- "Date/time normalization"
|
|
289
|
+
|
|
290
|
+
- name: mappers
|
|
291
|
+
description: "Data transformation between layers"
|
|
292
|
+
suffix:
|
|
293
|
+
dart: "*_mapper.dart"
|
|
294
|
+
typescript: "*-mapper.ts"
|
|
295
|
+
examples:
|
|
296
|
+
- "API response → Domain entity"
|
|
297
|
+
- "Domain entity → View model"
|
|
298
|
+
- "Form data → Request DTO"
|
|
299
|
+
|
|
300
|
+
- name: interceptors
|
|
301
|
+
description: "HTTP request/response middleware"
|
|
302
|
+
suffix:
|
|
303
|
+
dart: "*_interceptor.dart"
|
|
304
|
+
typescript: "*-interceptor.ts"
|
|
305
|
+
examples:
|
|
306
|
+
- "Auth token injection"
|
|
307
|
+
- "Error handling"
|
|
308
|
+
- "Request/response logging"
|
|
309
|
+
- "Retry logic"
|
|
310
|
+
- "Cache headers"
|
|
311
|
+
|
|
312
|
+
- name: caches
|
|
313
|
+
description: "Client-side caching implementations"
|
|
314
|
+
suffix:
|
|
315
|
+
dart: "*_cache.dart"
|
|
316
|
+
typescript: "*-cache.ts"
|
|
317
|
+
examples:
|
|
318
|
+
- "In-memory caches (LRU)"
|
|
319
|
+
- "HTTP cache"
|
|
320
|
+
- "Query result caches (React Query, SWR)"
|
|
321
|
+
- "Persistent caches"
|
|
322
|
+
|
|
323
|
+
- name: synchronizers
|
|
324
|
+
description: "Offline sync and conflict resolution"
|
|
325
|
+
suffix:
|
|
326
|
+
dart: "*_sync.dart"
|
|
327
|
+
typescript: "*-sync.ts"
|
|
328
|
+
examples:
|
|
329
|
+
- "Offline queue managers"
|
|
330
|
+
- "Sync engines"
|
|
331
|
+
- "Conflict resolution strategies"
|
|
332
|
+
- "Background sync"
|
|
333
|
+
|
|
334
|
+
- name: monitors
|
|
335
|
+
description: "Client-side monitoring and telemetry"
|
|
336
|
+
suffix:
|
|
337
|
+
dart: "*_monitor.dart, *_tracker.dart"
|
|
338
|
+
typescript: "*-monitor.ts, *-tracker.ts"
|
|
339
|
+
examples:
|
|
340
|
+
- "Analytics trackers (GA, Mixpanel)"
|
|
341
|
+
- "Error tracking (Sentry, Bugsnag)"
|
|
342
|
+
- "Performance monitoring (Web Vitals)"
|
|
343
|
+
- "User session recording"
|
|
344
|
+
|
|
345
|
+
- name: validators
|
|
346
|
+
description: "Client-side validation engines"
|
|
347
|
+
suffix:
|
|
348
|
+
dart: "*_validator.dart"
|
|
349
|
+
typescript: "*-validator.ts"
|
|
350
|
+
examples:
|
|
351
|
+
- "Form validators"
|
|
352
|
+
- "Schema validators (Yup, Zod)"
|
|
353
|
+
- "Business rule validators"
|
|
354
|
+
|
|
355
|
+
- name: workers
|
|
356
|
+
description: "Background processing and web workers"
|
|
357
|
+
suffix:
|
|
358
|
+
typescript: "*.worker.ts"
|
|
359
|
+
dart: "*_worker.dart"
|
|
360
|
+
examples:
|
|
361
|
+
- "Web Workers for heavy computation"
|
|
362
|
+
- "Service Workers for PWA"
|
|
363
|
+
- "Background tasks"
|
|
364
|
+
|
|
365
|
+
- name: connectors
|
|
366
|
+
description: "Real-time and streaming connections"
|
|
367
|
+
suffix:
|
|
368
|
+
dart: "*_connector.dart"
|
|
369
|
+
typescript: "*-connector.ts"
|
|
370
|
+
examples:
|
|
371
|
+
- "WebSocket managers"
|
|
372
|
+
- "SSE (Server-Sent Events)"
|
|
373
|
+
- "Firebase real-time database"
|
|
374
|
+
- "SignalR connections"
|
|
375
|
+
|
|
376
|
+
structure:
|
|
377
|
+
dart:
|
|
378
|
+
src_path_pattern: "lib/{wagon}/{feature}/{layer}/"
|
|
379
|
+
layers: [presentation, application, domain, integration]
|
|
380
|
+
|
|
381
|
+
flutter:
|
|
382
|
+
src_path_pattern: "lib/{wagon}/{feature}/{layer}/"
|
|
383
|
+
layers: [presentation, application, domain, integration]
|
|
384
|
+
import_restrictions:
|
|
385
|
+
domain:
|
|
386
|
+
forbidden_imports: ["package:flutter", "flutter"]
|
|
387
|
+
disallowed: ["package:flutter", "flutter"]
|
|
388
|
+
application:
|
|
389
|
+
forbidden_imports: ["package:flutter"]
|
|
390
|
+
|
|
391
|
+
preact:
|
|
392
|
+
framework: "preact + vite + typescript"
|
|
393
|
+
src_path_pattern: "web/src/{wagon}/{feature}/{layer}/"
|
|
394
|
+
test_path_pattern: "web/tests/{wagon}/{feature}/{layer}/"
|
|
395
|
+
layers: [presentation, application, domain, integration]
|
|
396
|
+
contracts:
|
|
397
|
+
description: "Cross-wagon domain types and catalogs that mirror contract schemas"
|
|
398
|
+
path: "web/src/commons/domain/"
|
|
399
|
+
purpose: "Pure domain types/constants usable across wagons; UI extensions allowed only as additive metadata"
|
|
400
|
+
allowed_content: ["types", "interfaces", "constants", "enums", "pure functions"]
|
|
401
|
+
forbidden_content: ["hooks", "components", "side-effects"]
|
|
402
|
+
import_rule: "Any layer in any wagon may import from web/src/commons/domain"
|
|
403
|
+
traceability: "TypeScript files must include @contract {schema_id} JSDoc"
|
|
404
|
+
structure:
|
|
405
|
+
- "commons/domain/DomainCatalog.ts # core contract + UI metadata"
|
|
406
|
+
- "commons/domain/AttributeCatalog.ts"
|
|
407
|
+
- "commons/domain/MatchContext.ts"
|
|
408
|
+
file_extensions: [".ts", ".tsx"]
|
|
409
|
+
layer_mapping:
|
|
410
|
+
presentation: ["pages", "components", "hooks", "styles"]
|
|
411
|
+
application: ["use-cases", "hooks", "ports", "context"]
|
|
412
|
+
domain: ["entities", "value-objects", "services", "types", "constants"]
|
|
413
|
+
integration: ["api", "repositories", "mappers", "adapters", "stores"]
|
|
414
|
+
import_restrictions:
|
|
415
|
+
domain:
|
|
416
|
+
forbidden_imports: ["preact", "preact/hooks", "@maintain-ux", "react"]
|
|
417
|
+
rationale: "Domain must be framework-agnostic - no UI imports"
|
|
418
|
+
application:
|
|
419
|
+
forbidden_imports: ["preact", "@maintain-ux"]
|
|
420
|
+
allowed_imports: ["preact/hooks"]
|
|
421
|
+
rationale: "Application orchestrates with hooks but doesn't render UI (no JSX)"
|
|
422
|
+
presentation:
|
|
423
|
+
forbidden_imports: ["integration layer directly"]
|
|
424
|
+
allowed_imports: ["preact", "preact/hooks", "@maintain-ux", "application layer", "domain types"]
|
|
425
|
+
rationale: "Presentation uses application layer, never calls APIs directly"
|
|
426
|
+
integration:
|
|
427
|
+
forbidden_imports: ["preact", "presentation layer"]
|
|
428
|
+
allowed_imports: ["application ports", "domain types"]
|
|
429
|
+
rationale: "Integration implements ports, doesn't know about UI"
|
|
430
|
+
component_patterns:
|
|
431
|
+
presentation_component:
|
|
432
|
+
pattern: |
|
|
433
|
+
import { h } from 'preact';
|
|
434
|
+
import type { ComponentProps } from './types';
|
|
435
|
+
|
|
436
|
+
export function ComponentName(props: ComponentProps) {
|
|
437
|
+
return <div>{props.children}</div>;
|
|
438
|
+
}
|
|
439
|
+
application_hook:
|
|
440
|
+
pattern: |
|
|
441
|
+
import { useState } from 'preact/hooks';
|
|
442
|
+
import { UseCase } from '../use-cases/UseCase';
|
|
443
|
+
|
|
444
|
+
export function useFeature() {
|
|
445
|
+
const [state, setState] = useState();
|
|
446
|
+
return { state };
|
|
447
|
+
}
|
|
448
|
+
domain_entity:
|
|
449
|
+
pattern: |
|
|
450
|
+
// No framework imports allowed
|
|
451
|
+
export class EntityName {
|
|
452
|
+
constructor(public readonly id: string) {
|
|
453
|
+
this.validate();
|
|
454
|
+
}
|
|
455
|
+
private validate(): void {}
|
|
456
|
+
}
|
|
457
|
+
integration_repository:
|
|
458
|
+
pattern: |
|
|
459
|
+
import type { Port } from '../../application/ports/Port';
|
|
460
|
+
|
|
461
|
+
export class Repository implements Port {
|
|
462
|
+
async method(): Promise<Result> {
|
|
463
|
+
return Promise.resolve({} as Result);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
file_organization:
|
|
467
|
+
feature_index:
|
|
468
|
+
path: "src/{wagon}/{feature}/index.ts"
|
|
469
|
+
purpose: "Public API - exports only what's needed"
|
|
470
|
+
exports:
|
|
471
|
+
- "Presentation: pages, components"
|
|
472
|
+
- "Application: hooks, use cases"
|
|
473
|
+
- "Domain: types, entities (read-only)"
|
|
474
|
+
- "Integration: NEVER (internal only)"
|
|
475
|
+
layer_index:
|
|
476
|
+
path: "src/{wagon}/{feature}/{layer}/index.ts"
|
|
477
|
+
purpose: "Layer-level exports for internal use"
|
|
478
|
+
testing:
|
|
479
|
+
framework: "vitest + @testing-library/preact"
|
|
480
|
+
test_pattern: "{component}.test.tsx or {component}.test.ts"
|
|
481
|
+
test_location: "web/tests/{wagon}/{feature}/{layer}/"
|
|
482
|
+
harness_to_layer:
|
|
483
|
+
unit: ["domain", "application"]
|
|
484
|
+
widget: ["presentation"]
|
|
485
|
+
integration: ["integration"]
|
|
486
|
+
test_types:
|
|
487
|
+
unit:
|
|
488
|
+
layer: "domain, application"
|
|
489
|
+
pattern: "Pure logic tests, no DOM"
|
|
490
|
+
integration:
|
|
491
|
+
layer: "integration"
|
|
492
|
+
pattern: "API mocking, repository tests"
|
|
493
|
+
component:
|
|
494
|
+
layer: "presentation"
|
|
495
|
+
pattern: "Component rendering, user interactions"
|
|
496
|
+
design_system:
|
|
497
|
+
wagon: "maintain-ux"
|
|
498
|
+
special_layers: ["foundations", "primitives", "components", "templates"]
|
|
499
|
+
import_aliases:
|
|
500
|
+
primary: "@maintain-ux"
|
|
501
|
+
exception:
|
|
502
|
+
description: "maintain-ux uses flat design-system layout; traceability via URN headers"
|
|
503
|
+
|
|
504
|
+
dependency:
|
|
505
|
+
# Frontend-specific dependency rules (different from backend)
|
|
506
|
+
# Rationale: Frontend hooks naturally orchestrate both domain logic and integration
|
|
507
|
+
# services (API clients, repositories). This is pragmatic for React/Preact ecosystems
|
|
508
|
+
# where hooks serve as composition points.
|
|
509
|
+
allowed_edges:
|
|
510
|
+
- from: presentation
|
|
511
|
+
to: [application, domain]
|
|
512
|
+
- from: application
|
|
513
|
+
to: [domain, integration] # Frontend hooks CAN import integration (differs from backend)
|
|
514
|
+
- from: integration
|
|
515
|
+
to: [application, domain]
|
|
516
|
+
forbidden_examples:
|
|
517
|
+
- "domain → application (domain must be pure)"
|
|
518
|
+
- "domain → integration (domain must be pure)"
|
|
519
|
+
- "domain → presentation (domain must be pure)"
|
|
520
|
+
- "presentation → integration (must go through application hooks)"
|
|
521
|
+
note: |
|
|
522
|
+
Frontend application layer (hooks/use-cases) is allowed to import from integration
|
|
523
|
+
because hooks serve as natural composition points in React/Preact apps.
|
|
524
|
+
This differs from backend where application layer uses ports for strict decoupling.
|
|
525
|
+
Backend rule: application → domain only (use ports for integration)
|
|
526
|
+
Frontend rule: application → domain, integration (pragmatic for hooks)
|
|
527
|
+
|
|
528
|
+
ci_enforcement:
|
|
529
|
+
checks:
|
|
530
|
+
- name: "arch_import_rules"
|
|
531
|
+
description: "Verify imports follow dependency_rules."
|
|
532
|
+
- name: "suffix_placement"
|
|
533
|
+
description: "Verify files live in layer matching suffix."
|
|
534
|
+
- name: "no_cross_feature_imports"
|
|
535
|
+
description: "Features cannot import other features' internals."
|
|
536
|
+
- name: "dto_boundary"
|
|
537
|
+
description: "Ensure DTOs are not imported in domain."
|
|
538
|
+
- name: "test_coverage_threshold"
|
|
539
|
+
description: "Min coverage for layers (configurable)."
|
|
540
|
+
tools:
|
|
541
|
+
- "dart import lints + custom scripts (melos/workspaces)"
|
|
542
|
+
failure_policy: "block_on_violation"
|