mxrb 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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.de-DE.md +108 -0
- data/README.md +172 -0
- data/README.pt-BR.md +109 -0
- data/bin/mxrb +1613 -0
- data/docs/README.md +10 -0
- data/docs/de-DE/README.md +24 -0
- data/docs/de-DE/architectural-patterns.md +26 -0
- data/docs/de-DE/architectural-standard.md +48 -0
- data/docs/de-DE/architecture.md +76 -0
- data/docs/de-DE/compiler.md +162 -0
- data/docs/de-DE/conventions.md +19 -0
- data/docs/de-DE/design-system.md +52 -0
- data/docs/de-DE/entity-dsl.md +53 -0
- data/docs/de-DE/native-runtime-quality-report.md +74 -0
- data/docs/de-DE/oql-sql.md +211 -0
- data/docs/de-DE/platform-api-integration.md +36 -0
- data/docs/de-DE/platform-operations.md +243 -0
- data/docs/de-DE/project-structure.md +32 -0
- data/docs/de-DE/ruby-first-roadmap.md +116 -0
- data/docs/de-DE/scaffolds.md +59 -0
- data/docs/de-DE/semantic-refactoring.md +56 -0
- data/docs/de-DE/team-server.md +33 -0
- data/docs/de-DE/validation-matrix.md +64 -0
- data/docs/de-DE/vetclinic-acceptance.md +24 -0
- data/docs/de-DE/writing.md +138 -0
- data/docs/en-US/README.md +24 -0
- data/docs/en-US/architectural-patterns.md +151 -0
- data/docs/en-US/architectural-standard.md +89 -0
- data/docs/en-US/architecture.md +170 -0
- data/docs/en-US/compiler.md +157 -0
- data/docs/en-US/conventions.md +82 -0
- data/docs/en-US/design-system.md +163 -0
- data/docs/en-US/entity-dsl.md +53 -0
- data/docs/en-US/native-runtime-quality-report.md +73 -0
- data/docs/en-US/oql-sql.md +201 -0
- data/docs/en-US/platform-api-integration.md +36 -0
- data/docs/en-US/platform-operations.md +244 -0
- data/docs/en-US/project-structure.md +49 -0
- data/docs/en-US/ruby-first-roadmap.md +186 -0
- data/docs/en-US/scaffolds.md +57 -0
- data/docs/en-US/semantic-refactoring.md +198 -0
- data/docs/en-US/team-server.md +32 -0
- data/docs/en-US/validation-matrix.md +257 -0
- data/docs/en-US/vetclinic-acceptance.md +23 -0
- data/docs/en-US/writing.md +655 -0
- data/docs/pt-BR/README.md +24 -0
- data/docs/pt-BR/architectural-patterns.md +25 -0
- data/docs/pt-BR/architectural-standard.md +533 -0
- data/docs/pt-BR/architecture.md +300 -0
- data/docs/pt-BR/compiler.md +162 -0
- data/docs/pt-BR/conventions.md +19 -0
- data/docs/pt-BR/design-system.md +65 -0
- data/docs/pt-BR/entity-dsl.md +116 -0
- data/docs/pt-BR/native-runtime-quality-report.md +73 -0
- data/docs/pt-BR/oql-sql.md +208 -0
- data/docs/pt-BR/platform-api-integration.md +36 -0
- data/docs/pt-BR/platform-operations.md +260 -0
- data/docs/pt-BR/project-structure.md +32 -0
- data/docs/pt-BR/ruby-first-roadmap.md +239 -0
- data/docs/pt-BR/scaffolds.md +104 -0
- data/docs/pt-BR/semantic-refactoring.md +55 -0
- data/docs/pt-BR/team-server.md +59 -0
- data/docs/pt-BR/validation-matrix.md +86 -0
- data/docs/pt-BR/vetclinic-acceptance.md +50 -0
- data/docs/pt-BR/writing.md +177 -0
- data/examples/sudoku_evaluation.rb +14 -0
- data/examples/sudoku_functional_test.rb +28 -0
- data/lib/mxrb/architecture/graph.rb +124 -0
- data/lib/mxrb/architecture/validator.rb +98 -0
- data/lib/mxrb/benchmark.rb +33 -0
- data/lib/mxrb/compare.rb +390 -0
- data/lib/mxrb/compiler/adapter.rb +96 -0
- data/lib/mxrb/compiler/artifact_document_compiler.rb +102 -0
- data/lib/mxrb/compiler/artifact_materializer.rb +53 -0
- data/lib/mxrb/compiler/client_model_materializer.rb +42 -0
- data/lib/mxrb/compiler/code_action_document_compiler.rb +64 -0
- data/lib/mxrb/compiler/code_action_materializer.rb +35 -0
- data/lib/mxrb/compiler/code_action_type_compiler.rb +32 -0
- data/lib/mxrb/compiler/combo_box_bundle_compiler.rb +314 -0
- data/lib/mxrb/compiler/compatibility_analyzer.rb +169 -0
- data/lib/mxrb/compiler/constants_materializer.rb +111 -0
- data/lib/mxrb/compiler/data_grid_bundle_compiler.rb +290 -0
- data/lib/mxrb/compiler/database_connector_action_compiler.rb +280 -0
- data/lib/mxrb/compiler/deployment_asset_copier.rb +60 -0
- data/lib/mxrb/compiler/deployment_bootstrapper.rb +208 -0
- data/lib/mxrb/compiler/deployment_materializer.rb +43 -0
- data/lib/mxrb/compiler/deployment_metadata.rb +64 -0
- data/lib/mxrb/compiler/domain_document_compiler.rb +153 -0
- data/lib/mxrb/compiler/domain_model_materializer.rb +35 -0
- data/lib/mxrb/compiler/domain_security_compiler.rb +82 -0
- data/lib/mxrb/compiler/gallery_bundle_compiler.rb +190 -0
- data/lib/mxrb/compiler/generic_widget_bundle_compiler.rb +281 -0
- data/lib/mxrb/compiler/image_bundle_compiler.rb +216 -0
- data/lib/mxrb/compiler/java_proxy_generator.rb +509 -0
- data/lib/mxrb/compiler/legacy_data_grid_compiler.rb +267 -0
- data/lib/mxrb/compiler/legacy_page_builder.rb +287 -0
- data/lib/mxrb/compiler/mda.rb +99 -0
- data/lib/mxrb/compiler/microflow_document_compiler.rb +85 -0
- data/lib/mxrb/compiler/microflow_materializer.rb +48 -0
- data/lib/mxrb/compiler/microflow_node_compiler.rb +250 -0
- data/lib/mxrb/compiler/model_package.rb +116 -0
- data/lib/mxrb/compiler/model_values.rb +67 -0
- data/lib/mxrb/compiler/nanoflow_program_compiler.rb +483 -0
- data/lib/mxrb/compiler/navigation_document_compiler.rb +93 -0
- data/lib/mxrb/compiler/packager.rb +100 -0
- data/lib/mxrb/compiler/page_bundle_builder.rb +56 -0
- data/lib/mxrb/compiler/page_bundle_compiler.rb +2004 -0
- data/lib/mxrb/compiler/page_document_compiler.rb +77 -0
- data/lib/mxrb/compiler/portable_packager.rb +356 -0
- data/lib/mxrb/compiler/project_jar_archive.rb +84 -0
- data/lib/mxrb/compiler/project_jar_builder.rb +121 -0
- data/lib/mxrb/compiler/project_materializer.rb +139 -0
- data/lib/mxrb/compiler/project_model_orderer.rb +52 -0
- data/lib/mxrb/compiler/runtime_data_types.rb +31 -0
- data/lib/mxrb/compiler/runtime_model_schema.rb +90 -0
- data/lib/mxrb/compiler/schemas/runtime-10.24.0.73019.json +1052 -0
- data/lib/mxrb/compiler/schemas/runtime-11.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-6.10.8.json +1148 -0
- data/lib/mxrb/compiler/schemas/runtime-7.17.0.json +1144 -0
- data/lib/mxrb/compiler/schemas/runtime-7.5.0.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-9.6.1.29396.json +868 -0
- data/lib/mxrb/compiler/schemas/system-model-10.24.0.73019.b64 +1135 -0
- data/lib/mxrb/compiler/schemas/system-model-11.12.1.b64 +815 -0
- data/lib/mxrb/compiler/schemas/system-model-6.10.8.b64 +497 -0
- data/lib/mxrb/compiler/schemas/system-model-7.17.0.b64 +519 -0
- data/lib/mxrb/compiler/schemas/system-model-7.5.0.b64 +504 -0
- data/lib/mxrb/compiler/schemas/system-model-9.6.1.29396.b64 +816 -0
- data/lib/mxrb/compiler/security_materializer.rb +104 -0
- data/lib/mxrb/compiler/settings_document_compiler.rb +45 -0
- data/lib/mxrb/compiler/settings_materializer.rb +25 -0
- data/lib/mxrb/compiler/source_model.rb +128 -0
- data/lib/mxrb/compiler/system_model_seed.rb +88 -0
- data/lib/mxrb/compiler/system_queue_materializer.rb +54 -0
- data/lib/mxrb/compiler/system_text_materializer.rb +49 -0
- data/lib/mxrb/compiler/translation_materializer.rb +95 -0
- data/lib/mxrb/compiler/web_bundle_builder.rb +155 -0
- data/lib/mxrb/compiler/web_list_data_source.rb +139 -0
- data/lib/mxrb/compiler/web_operation_compiler.rb +614 -0
- data/lib/mxrb/compiler/web_shell_materializer.rb +194 -0
- data/lib/mxrb/compiler/widget_package_extractor.rb +63 -0
- data/lib/mxrb/doctor.rb +116 -0
- data/lib/mxrb/dsl/builder.rb +1636 -0
- data/lib/mxrb/errors.rb +18 -0
- data/lib/mxrb/evaluation.rb +131 -0
- data/lib/mxrb/exporter.rb +1716 -0
- data/lib/mxrb/frontend/migrator.rb +775 -0
- data/lib/mxrb/functional.rb +307 -0
- data/lib/mxrb/github/annotator.rb +161 -0
- data/lib/mxrb/initializer.rb +257 -0
- data/lib/mxrb/integrity/validator.rb +136 -0
- data/lib/mxrb/io/bson_codec.rb +145 -0
- data/lib/mxrb/io/mpr_file.rb +558 -0
- data/lib/mxrb/io/mxunit_codec.rb +42 -0
- data/lib/mxrb/marketplace.rb +380 -0
- data/lib/mxrb/model/association.rb +98 -0
- data/lib/mxrb/model/attribute.rb +100 -0
- data/lib/mxrb/model/connector.rb +17 -0
- data/lib/mxrb/model/design_materializer.rb +133 -0
- data/lib/mxrb/model/design_migration.rb +126 -0
- data/lib/mxrb/model/design_system.rb +111 -0
- data/lib/mxrb/model/domain_model.rb +51 -0
- data/lib/mxrb/model/entity.rb +180 -0
- data/lib/mxrb/model/menu.rb +38 -0
- data/lib/mxrb/model/microflow.rb +100 -0
- data/lib/mxrb/model/module.rb +142 -0
- data/lib/mxrb/model/navigation.rb +127 -0
- data/lib/mxrb/model/page.rb +410 -0
- data/lib/mxrb/model/project.rb +187 -0
- data/lib/mxrb/model/unit.rb +48 -0
- data/lib/mxrb/module_initializer.rb +75 -0
- data/lib/mxrb/official_marketplace/content_api.rb +292 -0
- data/lib/mxrb/official_marketplace/dependency_resolver.rb +329 -0
- data/lib/mxrb/official_marketplace/lifecycle.rb +367 -0
- data/lib/mxrb/official_marketplace/module_package_importer.rb +318 -0
- data/lib/mxrb/official_marketplace/widget_package_installer.rb +414 -0
- data/lib/mxrb/official_marketplace.rb +720 -0
- data/lib/mxrb/oql/analyzer.rb +155 -0
- data/lib/mxrb/oql/index_advisor.rb +85 -0
- data/lib/mxrb/oql/plan_analyzer.rb +185 -0
- data/lib/mxrb/oql/server.rb +132 -0
- data/lib/mxrb/oql/sql_server_plan_analyzer.rb +190 -0
- data/lib/mxrb/oql/sql_server_workload_analyzer.rb +80 -0
- data/lib/mxrb/oql/workload_analyzer.rb +175 -0
- data/lib/mxrb/oql/workload_baseline.rb +60 -0
- data/lib/mxrb/oql.rb +424 -0
- data/lib/mxrb/project_lifecycle.rb +76 -0
- data/lib/mxrb/protocols/plan.rb +86 -0
- data/lib/mxrb/protocols.rb +123 -0
- data/lib/mxrb/runtime/database_workspace.rb +677 -0
- data/lib/mxrb/runtime/docker_executor.rb +41 -0
- data/lib/mxrb/runtime/docker_workspace.rb +29 -0
- data/lib/mxrb/runtime/executor.rb +169 -0
- data/lib/mxrb/runtime/java_locator.rb +26 -0
- data/lib/mxrb/runtime/native.rb +474 -0
- data/lib/mxrb/runtime/sql_server_database.rb +146 -0
- data/lib/mxrb/runtime/toolchain.rb +82 -0
- data/lib/mxrb/scaffold/cli.rb +113 -0
- data/lib/mxrb/scaffold/generator.rb +246 -0
- data/lib/mxrb/scaffold/help.rb +80 -0
- data/lib/mxrb/scaffold/page_templates.rb +54 -0
- data/lib/mxrb/scaffold/recipes.rb +198 -0
- data/lib/mxrb/scaffold/registry.rb +82 -0
- data/lib/mxrb/scaffold/templates.rb +723 -0
- data/lib/mxrb/scaffold/transaction.rb +84 -0
- data/lib/mxrb/schema/tables.rb +55 -0
- data/lib/mxrb/semantic/analyzer.rb +473 -0
- data/lib/mxrb/semantic/batch_plan.rb +68 -0
- data/lib/mxrb/semantic/domain_mutator.rb +419 -0
- data/lib/mxrb/semantic/embedder.rb +51 -0
- data/lib/mxrb/semantic/extractor.rb +290 -0
- data/lib/mxrb/semantic/index.rb +623 -0
- data/lib/mxrb/semantic/inliner.rb +216 -0
- data/lib/mxrb/semantic/mover.rb +153 -0
- data/lib/mxrb/semantic/onnx_embedder.rb +34 -0
- data/lib/mxrb/semantic/remover.rb +70 -0
- data/lib/mxrb/semantic/renamer.rb +211 -0
- data/lib/mxrb/semantic/tfidf_embedder.rb +46 -0
- data/lib/mxrb/semantic/vec_store.rb +75 -0
- data/lib/mxrb/team_server.rb +390 -0
- data/lib/mxrb/templates/project/10.24.0.73019.json +32 -0
- data/lib/mxrb/templates/project/11.12.1.json +32 -0
- data/lib/mxrb/templates/project/6.10.8.json +50 -0
- data/lib/mxrb/templates/project/7.17.0.json +50 -0
- data/lib/mxrb/templates/project/7.5.0.json +50 -0
- data/lib/mxrb/templates/project/9.6.1.29396.json +50 -0
- data/lib/mxrb/version.rb +5 -0
- data/lib/mxrb/widget_package.rb +338 -0
- data/lib/mxrb/widget_synchronizer.rb +31 -0
- data/lib/mxrb/writer.rb +3775 -0
- data/lib/mxrb.rb +188 -0
- data/marketplace/catalog.json +10 -0
- data/marketplace/modules/shared-kernel/domain/README.md +4 -0
- data/marketplace/modules/shared-kernel/module.rb +5 -0
- data/marketplace/modules/shared-kernel/mxrb-module.json +9 -0
- metadata +447 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
# Padrão arquitetural do mxrb
|
|
2
|
+
|
|
3
|
+
**Português** · [English](../en-US/architectural-standard.md) · [Deutsch](../de-DE/architectural-standard.md)
|
|
4
|
+
|
|
5
|
+
Este documento é normativo. Ele define como conceitos Mendix são representados
|
|
6
|
+
em um projeto Ruby do `mxrb`, independentemente de como o Studio Pro agrupa os
|
|
7
|
+
documentos visualmente.
|
|
8
|
+
|
|
9
|
+
## 1. Princípio central
|
|
10
|
+
|
|
11
|
+
Tipos técnicos não são camadas arquiteturais.
|
|
12
|
+
|
|
13
|
+
- microflow é um mecanismo de execução no servidor;
|
|
14
|
+
- nanoflow é um mecanismo de execução no cliente/dispositivo;
|
|
15
|
+
- page é um documento de apresentação;
|
|
16
|
+
- entity é um elemento do Domain Model;
|
|
17
|
+
- navigation e security são políticas transversais.
|
|
18
|
+
|
|
19
|
+
Portanto, um microflow **não é automaticamente um service**. Sua pasta é
|
|
20
|
+
determinada pela responsabilidade exercida.
|
|
21
|
+
|
|
22
|
+
## 2. Estrutura completa
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
my_app/
|
|
26
|
+
├── project.rb
|
|
27
|
+
├── app/
|
|
28
|
+
│ ├── settings.rb
|
|
29
|
+
│ ├── security/
|
|
30
|
+
│ │ ├── security.rb
|
|
31
|
+
│ │ ├── user_roles.rb
|
|
32
|
+
│ │ └── role_mappings.rb
|
|
33
|
+
│ ├── navigation/
|
|
34
|
+
│ │ ├── navigation.rb
|
|
35
|
+
│ │ ├── responsive.rb
|
|
36
|
+
│ │ ├── phone.rb
|
|
37
|
+
│ │ ├── tablet.rb
|
|
38
|
+
│ │ └── native.rb
|
|
39
|
+
│ └── design_system/
|
|
40
|
+
│ ├── design_system.rb
|
|
41
|
+
│ ├── tokens.rb
|
|
42
|
+
│ ├── layouts.rb
|
|
43
|
+
│ └── components.rb
|
|
44
|
+
├── modules/
|
|
45
|
+
│ └── OrderManagement/
|
|
46
|
+
│ ├── module.rb
|
|
47
|
+
│ ├── domain/
|
|
48
|
+
│ │ ├── model.rb
|
|
49
|
+
│ │ ├── entities/
|
|
50
|
+
│ │ ├── enumerations/
|
|
51
|
+
│ │ ├── rules/
|
|
52
|
+
│ │ └── policies/
|
|
53
|
+
│ ├── application/
|
|
54
|
+
│ │ ├── application.rb
|
|
55
|
+
│ │ ├── use_cases/
|
|
56
|
+
│ │ ├── queries/
|
|
57
|
+
│ │ ├── validations/
|
|
58
|
+
│ │ ├── jobs/
|
|
59
|
+
│ │ └── ports/
|
|
60
|
+
│ ├── presentation/
|
|
61
|
+
│ │ ├── presentation.rb
|
|
62
|
+
│ │ ├── pages/
|
|
63
|
+
│ │ ├── client_actions/
|
|
64
|
+
│ │ ├── snippets/
|
|
65
|
+
│ │ └── view_models/
|
|
66
|
+
│ ├── infrastructure/
|
|
67
|
+
│ │ ├── infrastructure.rb
|
|
68
|
+
│ │ ├── integrations/
|
|
69
|
+
│ │ ├── persistence/
|
|
70
|
+
│ │ ├── mappings/
|
|
71
|
+
│ │ ├── actions/
|
|
72
|
+
│ │ └── endpoints/
|
|
73
|
+
│ └── security/
|
|
74
|
+
│ ├── security.rb
|
|
75
|
+
│ ├── module_roles.rb
|
|
76
|
+
│ ├── entity_access.rb
|
|
77
|
+
│ └── document_access.rb
|
|
78
|
+
├── themesource/
|
|
79
|
+
├── widgets/
|
|
80
|
+
├── javasource/
|
|
81
|
+
└── resources/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Nem toda aplicação precisa usar todas as pastas. Diretórios vazios podem ser
|
|
85
|
+
omitidos, mas um artefato existente deve respeitar esta classificação.
|
|
86
|
+
|
|
87
|
+
## 3. Mapeamento dos fluxos
|
|
88
|
+
|
|
89
|
+
### Organização por feature
|
|
90
|
+
|
|
91
|
+
As camadas controlam a direção das dependências, mas artefatos de uma mesma
|
|
92
|
+
tela devem permanecer próximos. A apresentação usa **vertical slices**:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
presentation/
|
|
96
|
+
├── presentation.rb
|
|
97
|
+
└── features/
|
|
98
|
+
└── order_editor/
|
|
99
|
+
├── feature.rb
|
|
100
|
+
├── order_edit_page.rb
|
|
101
|
+
├── view_model.rb
|
|
102
|
+
└── client_actions/
|
|
103
|
+
├── on_product_change.rb
|
|
104
|
+
├── on_quantity_change.rb
|
|
105
|
+
└── on_submit.rb
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`feature.rb` é o agregador da slice. A página e seus nanoflows ficam juntos
|
|
109
|
+
porque mudam pelos mesmos motivos. O caso de uso server-side chamado pela tela
|
|
110
|
+
continua em `application/use_cases/`; ele pode ser utilizado por outras páginas,
|
|
111
|
+
APIs ou jobs sem depender da UI.
|
|
112
|
+
|
|
113
|
+
Uma feature não é uma nova camada e não pode inverter dependências.
|
|
114
|
+
|
|
115
|
+
### Microflows
|
|
116
|
+
|
|
117
|
+
Microflows executam no servidor e podem usufruir de transação. Eles são
|
|
118
|
+
classificados pela responsabilidade:
|
|
119
|
+
|
|
120
|
+
| Responsabilidade | Pasta Ruby | Exemplo |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| Caso de uso | `application/use_cases/` | `place_order.rb` |
|
|
123
|
+
| Consulta/data source | `application/queries/` | `find_open_orders.rb` |
|
|
124
|
+
| Validação coordenada | `application/validations/` | `validate_checkout.rb` |
|
|
125
|
+
| Job/scheduled event | `application/jobs/` | `expire_reservations.rb` |
|
|
126
|
+
| Adapter de integração | `infrastructure/integrations/` | `send_order_to_erp.rb` |
|
|
127
|
+
| Endpoint publicado | `infrastructure/endpoints/` | `post_order.rb` |
|
|
128
|
+
| Operação técnica interna | `infrastructure/actions/` | `calculate_file_hash.rb` |
|
|
129
|
+
|
|
130
|
+
Não existe uma pasta genérica `services/`, pois ela normalmente mistura casos
|
|
131
|
+
de uso, domínio e infraestrutura.
|
|
132
|
+
|
|
133
|
+
### Nanoflows
|
|
134
|
+
|
|
135
|
+
Nanoflows executam no browser/dispositivo, não são transacionais e são
|
|
136
|
+
especialmente adequados a UI responsiva e offline-first. Eles ficam em:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
presentation/client_actions/
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Responsabilidades permitidas:
|
|
143
|
+
|
|
144
|
+
- coordenar estado temporário de tela;
|
|
145
|
+
- validação imediata de formulário;
|
|
146
|
+
- abrir/fechar páginas;
|
|
147
|
+
- mostrar mensagens;
|
|
148
|
+
- manipular dados locais/offline;
|
|
149
|
+
- chamar um caso de uso no servidor e tratar seu resultado na UI.
|
|
150
|
+
|
|
151
|
+
Nanoflows não devem conter regras de negócio autoritativas. Uma regra que
|
|
152
|
+
protege integridade, dinheiro, autorização ou persistência deve existir no
|
|
153
|
+
domínio/aplicação do servidor, mesmo que haja uma validação equivalente no
|
|
154
|
+
cliente para melhorar a experiência.
|
|
155
|
+
|
|
156
|
+
### Eventos e callbacks
|
|
157
|
+
|
|
158
|
+
O nome `on_change` sozinho é ambíguo. O `mxrb` distingue quatro categorias:
|
|
159
|
+
|
|
160
|
+
| Categoria | Origem | Destino típico | Exemplo |
|
|
161
|
+
|---|---|---|---|
|
|
162
|
+
| Evento de widget | page/widget | nanoflow | campo `Quantity` mudou |
|
|
163
|
+
| Ação de página | page/button | nano ou microflow | salvar pedido |
|
|
164
|
+
| Lifecycle de entidade | runtime/domain model | microflow | before commit |
|
|
165
|
+
| Evento de domínio | caso de uso | handler de application | pedido confirmado |
|
|
166
|
+
|
|
167
|
+
Eventos de widget ficam declarados junto ao widget/página e apontam para uma
|
|
168
|
+
ação nomeada:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
page :OrderEdit do
|
|
172
|
+
data_source query: :GetOrderForEdit
|
|
173
|
+
|
|
174
|
+
number_input :Quantity do
|
|
175
|
+
on_change nanoflow: :RecalculateOrderDraft
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
button :Save do
|
|
179
|
+
on_click microflow: :PlaceOrder
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Lifecycle de entidade não deve ser usado como substituto genérico de caso de
|
|
185
|
+
uso. Ele é apropriado para invariantes que devem ocorrer em toda criação,
|
|
186
|
+
alteração ou remoção, independentemente do ponto de entrada:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
entity :Order do
|
|
190
|
+
before_commit microflow: :ValidateOrderInvariant
|
|
191
|
+
after_commit microflow: :PublishOrderChanged
|
|
192
|
+
end
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Regras:
|
|
196
|
+
|
|
197
|
+
- `before_commit` pode validar e rejeitar a transação;
|
|
198
|
+
- `after_commit` não deve fingir atomicidade com a transação já concluída;
|
|
199
|
+
- callbacks não devem iniciar navegação ou manipular widgets;
|
|
200
|
+
- callbacks devem ser pequenos e delegar para regras/casos de uso;
|
|
201
|
+
- evitar cadeias ocultas de callbacks;
|
|
202
|
+
- cada ligação deve ser uma referência explícita, validada pelo `mxrb lint`;
|
|
203
|
+
- handlers precisam declarar parâmetros e retorno compatíveis com o evento.
|
|
204
|
+
|
|
205
|
+
### Grafo de relações
|
|
206
|
+
|
|
207
|
+
O `mxrb` deve construir um grafo tipado, não apenas procurar nomes:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
Page
|
|
211
|
+
├── data_source ──> Query
|
|
212
|
+
├── on_change ────> Nanoflow
|
|
213
|
+
└── on_submit ────> UseCase Microflow
|
|
214
|
+
|
|
215
|
+
UseCase
|
|
216
|
+
├── reads/writes ─> Repository Port
|
|
217
|
+
├── applies ──────> Domain Rule
|
|
218
|
+
└── emits ────────> Domain Event
|
|
219
|
+
|
|
220
|
+
Repository Port
|
|
221
|
+
└── implemented_by > Mendix/External Adapter
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Renomear um artefato deve atualizar referências pelo seu ID estável. Nome é
|
|
225
|
+
apenas a identidade legível e fallback para importação.
|
|
226
|
+
|
|
227
|
+
### Domain rules
|
|
228
|
+
|
|
229
|
+
Uma regra pura e reutilizável pertence a:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
domain/rules/
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Se a regra somente decide permissão de negócio, use:
|
|
236
|
+
|
|
237
|
+
```text
|
|
238
|
+
domain/policies/
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Se ela coordena repositórios, integrações ou múltiplas entidades, é um caso de
|
|
242
|
+
uso em `application/use_cases/`.
|
|
243
|
+
|
|
244
|
+
## 4. Dependências permitidas
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
presentation ───────> application ───────> domain
|
|
248
|
+
↑ ↑
|
|
249
|
+
infrastructure ────────────┘ │
|
|
250
|
+
security policies ───────────────────────────┘
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Regras:
|
|
254
|
+
|
|
255
|
+
1. `domain` não depende de presentation, application ou infrastructure.
|
|
256
|
+
2. `application` depende do domain e declara ports para necessidades externas.
|
|
257
|
+
3. `infrastructure` implementa ports; não define regras de negócio.
|
|
258
|
+
4. `presentation` chama application; não chama adapters diretamente.
|
|
259
|
+
5. nanoflow pode chamar um microflow público de application.
|
|
260
|
+
6. um módulo não acessa documentos internos de outro módulo; usa sua API.
|
|
261
|
+
7. dependência circular entre módulos é proibida.
|
|
262
|
+
|
|
263
|
+
Uma page pode referenciar nanoflows da própria feature e operações públicas de
|
|
264
|
+
application. Ela não acessa repository ou integração diretamente.
|
|
265
|
+
|
|
266
|
+
## 4.1 Queries, repositories e persistência Mendix
|
|
267
|
+
|
|
268
|
+
Consulta não é sinônimo de repository.
|
|
269
|
+
|
|
270
|
+
- **Query** representa intenção de leitura da aplicação, como
|
|
271
|
+
`FindOpenOrdersForCustomer`.
|
|
272
|
+
- **Repository port** representa um contrato de persistência necessário ao caso
|
|
273
|
+
de uso, como `OrderRepository`.
|
|
274
|
+
- **Adapter** implementa o port usando Mendix, REST, OData ou outra fonte.
|
|
275
|
+
- **Data source** adapta uma query para uma page/widget.
|
|
276
|
+
|
|
277
|
+
Estrutura:
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
application/
|
|
281
|
+
├── queries/
|
|
282
|
+
│ └── find_open_orders_for_customer.rb
|
|
283
|
+
└── ports/
|
|
284
|
+
└── repositories/
|
|
285
|
+
└── order_repository.rb
|
|
286
|
+
|
|
287
|
+
infrastructure/
|
|
288
|
+
└── persistence/
|
|
289
|
+
├── mendix/
|
|
290
|
+
│ └── order_repository.rb
|
|
291
|
+
└── external/
|
|
292
|
+
└── erp_order_repository.rb
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Para CRUD simples sobre entidades Mendix, não é obrigatório criar um repository
|
|
296
|
+
cerimonial. Um port deve existir quando há uma fronteira relevante: múltiplas
|
|
297
|
+
fontes, troca de implementação, integração externa, política de cache ou uma
|
|
298
|
+
necessidade real de desacoplamento.
|
|
299
|
+
|
|
300
|
+
Fluxo correto:
|
|
301
|
+
|
|
302
|
+
```text
|
|
303
|
+
Page -> DataSource/Query -> Repository Port -> Persistence Adapter
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Fluxo proibido:
|
|
307
|
+
|
|
308
|
+
```text
|
|
309
|
+
Page -> SQL/REST/Database Adapter
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## 5. API pública de módulo
|
|
313
|
+
|
|
314
|
+
Cada módulo deve poder ser tratado como componente substituível. Sua API pública
|
|
315
|
+
é composta por:
|
|
316
|
+
|
|
317
|
+
- microflows de application explicitamente exportados;
|
|
318
|
+
- entidades e associações cujo export level permite consumo;
|
|
319
|
+
- eventos/mensagens publicados;
|
|
320
|
+
- páginas deliberadamente reutilizáveis;
|
|
321
|
+
- contratos de integração.
|
|
322
|
+
|
|
323
|
+
Convenção:
|
|
324
|
+
|
|
325
|
+
```text
|
|
326
|
+
application/use_cases/public/
|
|
327
|
+
application/use_cases/internal/
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
O `mxrb lint` deverá impedir referência externa a documentos em `internal/`.
|
|
331
|
+
|
|
332
|
+
## 6. Security
|
|
333
|
+
|
|
334
|
+
Security possui dois níveis distintos.
|
|
335
|
+
|
|
336
|
+
### App security
|
|
337
|
+
|
|
338
|
+
Fica em `app/security/`:
|
|
339
|
+
|
|
340
|
+
- nível de segurança (`production` por padrão);
|
|
341
|
+
- user roles;
|
|
342
|
+
- mapeamento de user roles para module roles;
|
|
343
|
+
- usuário anônimo;
|
|
344
|
+
- política de senha;
|
|
345
|
+
- regras de administração de usuários.
|
|
346
|
+
|
|
347
|
+
Um user role representa a função do usuário no app. Cada user role deve mapear,
|
|
348
|
+
preferencialmente, para no máximo um module role de cada módulo.
|
|
349
|
+
|
|
350
|
+
### Module security
|
|
351
|
+
|
|
352
|
+
Fica em `modules/<Module>/security/`:
|
|
353
|
+
|
|
354
|
+
- module roles;
|
|
355
|
+
- acesso a entidades e membros;
|
|
356
|
+
- XPath constraints;
|
|
357
|
+
- acesso a páginas;
|
|
358
|
+
- acesso a microflows e nanoflows;
|
|
359
|
+
- acesso a REST/OData/GraphQL e datasets.
|
|
360
|
+
|
|
361
|
+
Princípios:
|
|
362
|
+
|
|
363
|
+
- deny by default;
|
|
364
|
+
- menor privilégio;
|
|
365
|
+
- regras explícitas para toda entidade persistente;
|
|
366
|
+
- segurança nunca depende apenas de ocultar menu ou botão;
|
|
367
|
+
- acesso de documento e acesso de entidade devem ser validados juntos;
|
|
368
|
+
- XPath de segurança deve ser testado por role;
|
|
369
|
+
- regras são aditivas no Mendix: conceder acesso em uma segunda regra amplia o
|
|
370
|
+
acesso efetivo.
|
|
371
|
+
|
|
372
|
+
O menu esconder uma página não impede acesso por URL ou chamada direta.
|
|
373
|
+
|
|
374
|
+
## 7. Navigation
|
|
375
|
+
|
|
376
|
+
Navigation é configuração de app e fica em `app/navigation/`, não dentro de um
|
|
377
|
+
módulo de negócio.
|
|
378
|
+
|
|
379
|
+
Cada profile possui arquivo próprio:
|
|
380
|
+
|
|
381
|
+
- responsive web;
|
|
382
|
+
- responsive offline;
|
|
383
|
+
- phone;
|
|
384
|
+
- tablet;
|
|
385
|
+
- native;
|
|
386
|
+
- embedded, quando aplicável.
|
|
387
|
+
|
|
388
|
+
Cada profile declara:
|
|
389
|
+
|
|
390
|
+
- home page padrão;
|
|
391
|
+
- home page por user role;
|
|
392
|
+
- sign-in page;
|
|
393
|
+
- menu;
|
|
394
|
+
- parâmetros de sincronização offline;
|
|
395
|
+
- pages/microflows usados como destinos.
|
|
396
|
+
|
|
397
|
+
Navigation depende das APIs públicas dos módulos. Um módulo pode oferecer
|
|
398
|
+
destinos navegáveis, mas não deve controlar o menu global do app.
|
|
399
|
+
|
|
400
|
+
## 8. Design system
|
|
401
|
+
|
|
402
|
+
O design system possui duas partes.
|
|
403
|
+
|
|
404
|
+
### Contrato Ruby
|
|
405
|
+
|
|
406
|
+
Fica em `app/design_system/`:
|
|
407
|
+
|
|
408
|
+
- tokens semânticos;
|
|
409
|
+
- layouts autorizados;
|
|
410
|
+
- componentes/padrões de página;
|
|
411
|
+
- variantes e estados;
|
|
412
|
+
- regras de acessibilidade;
|
|
413
|
+
- convenções responsivas.
|
|
414
|
+
|
|
415
|
+
Tokens devem expressar intenção:
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
color :surface_primary
|
|
419
|
+
color :text_danger
|
|
420
|
+
spacing :content_gap
|
|
421
|
+
radius :control
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Evite nomes acoplados a valores como `blue_500` na API de negócio.
|
|
425
|
+
|
|
426
|
+
### Recursos Mendix
|
|
427
|
+
|
|
428
|
+
Permanecem nos locais nativos:
|
|
429
|
+
|
|
430
|
+
- `themesource/`;
|
|
431
|
+
- UI resources package;
|
|
432
|
+
- layouts;
|
|
433
|
+
- snippets;
|
|
434
|
+
- building blocks;
|
|
435
|
+
- page templates;
|
|
436
|
+
- pluggable widgets.
|
|
437
|
+
|
|
438
|
+
Páginas de módulos consomem o design system; não criam estilos isolados sem
|
|
439
|
+
justificativa.
|
|
440
|
+
|
|
441
|
+
## 9. Padrões de design
|
|
442
|
+
|
|
443
|
+
Padrões adotados:
|
|
444
|
+
|
|
445
|
+
- **Use Case/Interactor**: microflow de `application/use_cases`;
|
|
446
|
+
- **Ports and Adapters**: contratos em `application/ports`, implementação em
|
|
447
|
+
`infrastructure`;
|
|
448
|
+
- **Repository**: somente quando uma abstração real de fonte de dados for
|
|
449
|
+
necessária; não envolver CRUD Mendix mecanicamente;
|
|
450
|
+
- **Policy**: decisão de negócio pura em `domain/policies`;
|
|
451
|
+
- **Specification**: critérios reutilizáveis de seleção/validação;
|
|
452
|
+
- **Presenter/View Model**: transformação de dados para páginas;
|
|
453
|
+
- **Facade**: API pública estável do módulo;
|
|
454
|
+
- **Domain Event**: desacoplamento entre módulos quando consistência imediata
|
|
455
|
+
não for necessária.
|
|
456
|
+
|
|
457
|
+
Não usar padrões apenas para reproduzir sintaxe de frameworks Ruby tradicionais.
|
|
458
|
+
O metamodelo e runtime Mendix continuam sendo a plataforma de execução.
|
|
459
|
+
|
|
460
|
+
## 10. Convenções de nomes
|
|
461
|
+
|
|
462
|
+
O nome Ruby do arquivo é `snake_case`; o nome Mendix permanece `PascalCase`.
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
PlaceOrder -> place_order.rb
|
|
466
|
+
OrderList -> order_list.rb
|
|
467
|
+
CustomerAddress -> customer_address.rb
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Prefixos Mendix podem ser reconhecidos na importação:
|
|
471
|
+
|
|
472
|
+
| Prefixo | Classificação padrão |
|
|
473
|
+
|---|---|
|
|
474
|
+
| `ACT_`, `IVK_` | `application/use_cases/` |
|
|
475
|
+
| `DS_`, `OQL_` | `application/queries/` |
|
|
476
|
+
| `VAL_` | `application/validations/` |
|
|
477
|
+
| `SUB_` | mesma camada do chamador; interno |
|
|
478
|
+
| `SE_` | `application/jobs/` |
|
|
479
|
+
| `API_` | `infrastructure/endpoints/` |
|
|
480
|
+
| `INT_` | `infrastructure/integrations/` |
|
|
481
|
+
|
|
482
|
+
Prefixos ajudam a importar projetos existentes, mas metadados explícitos devem
|
|
483
|
+
ter prioridade quando disponíveis.
|
|
484
|
+
|
|
485
|
+
## 11. Regras de qualidade automatizáveis
|
|
486
|
+
|
|
487
|
+
O futuro `mxrb lint` deve verificar:
|
|
488
|
+
|
|
489
|
+
- dependências entre camadas;
|
|
490
|
+
- ciclos entre módulos;
|
|
491
|
+
- documentos públicos sem documentação;
|
|
492
|
+
- entidade persistente sem access rules;
|
|
493
|
+
- página/microflow/nanoflow sem roles em security production;
|
|
494
|
+
- referência a documento interno de outro módulo;
|
|
495
|
+
- nanoflow contendo decisão autoritativa conhecida;
|
|
496
|
+
- endpoint chamando domínio sem passar por application;
|
|
497
|
+
- página fora do design system;
|
|
498
|
+
- navigation apontando para documento inexistente ou sem acesso;
|
|
499
|
+
- user role mapeado para múltiplos module roles do mesmo módulo;
|
|
500
|
+
- arquivos agregadores desatualizados.
|
|
501
|
+
- referência de evento inexistente ou com assinatura incompatível;
|
|
502
|
+
- page acessando repository/adapter diretamente;
|
|
503
|
+
- ciclo entre callbacks;
|
|
504
|
+
- lifecycle handler com efeito de apresentação;
|
|
505
|
+
- data source que executa comando/escrita sem declaração explícita;
|
|
506
|
+
|
|
507
|
+
## 12. Limite do suporte atual
|
|
508
|
+
|
|
509
|
+
Esta especificação define o formato-alvo. O writer/exporter atual cobre domínio,
|
|
510
|
+
microflows e nanoflows, páginas, menus, security e navigation nativa. Assets de
|
|
511
|
+
tema e código usam manifesto com checksum; tokens e políticas do design system
|
|
512
|
+
possuem contrato Ruby tipado. Workflows, integrações, APIs publicadas e widgets
|
|
513
|
+
sem API concisa continuam editáveis pelo Ruby profundo e pelo baseline nativo,
|
|
514
|
+
mas ainda precisam de DSLs tipadas específicas.
|
|
515
|
+
|
|
516
|
+
Até isso ocorrer, gere sobre uma cópia do MPR original para preservar units
|
|
517
|
+
desconhecidas.
|
|
518
|
+
|
|
519
|
+
O grafo tipado e a DSL dessas relações já validam referências ausentes,
|
|
520
|
+
dependências entre módulos, acesso direto indevido e ciclos de chamadas.
|
|
521
|
+
Nanoflows e entity lifecycle handlers possuem representação BSON. Conceitos sem
|
|
522
|
+
unit Mendix próprio, como repository ports, e eventos que ainda não possuem uma
|
|
523
|
+
árvore concreta de widgets são preservados na tabela `_MxrbArchitecture` dentro
|
|
524
|
+
do MPR. O exportador lê esse manifesto e recompõe a mesma DSL no round-trip.
|
|
525
|
+
|
|
526
|
+
Bindings ligados a widgets concretos de entrada e botões são serializados como
|
|
527
|
+
`Pages$TextBox`, `Pages$ActionButton`, `Pages$MicroflowClientAction` ou
|
|
528
|
+
`Pages$CallNanoflowClientAction`. Data sources de página são materializados em
|
|
529
|
+
um `Pages$DataView`.
|
|
530
|
+
|
|
531
|
+
Bindings abstratos sem widget concreto continuam preservados no manifesto. Eles
|
|
532
|
+
não devem ser apresentados como funcionalidade executável do app Mendix até
|
|
533
|
+
serem associados a um elemento `Pages$...`.
|