Initialize project scaffold and domain model
This commit is contained in:
@@ -0,0 +1,709 @@
|
||||
# Декомпозиция модулей
|
||||
|
||||
## 1. Цель документа
|
||||
|
||||
Этот документ фиксирует детальную структуру проекта до начала активной разработки. Его задача - заранее ограничить ответственность каждого компонента, избежать разрастания `mcpaas-core`, не допустить появления "универсальных" структур на все случаи жизни и сохранить понятные границы между доменной логикой, runtime, адаптерами, API и UI.
|
||||
|
||||
Основной принцип: каждый crate отвечает за один слой системы. Внутри crate модули должны быть маленькими, тематическими и с минимальным количеством публичных сущностей.
|
||||
|
||||
## 2. Общие архитектурные правила
|
||||
|
||||
### 2.1. Что считается правильной декомпозицией
|
||||
|
||||
- `core` содержит только базовую доменную модель, идентификаторы, типы ошибок и общие контракты.
|
||||
- `registry` отвечает только за хранение и загрузку конфигурации операций.
|
||||
- `runtime` исполняет операции, но не знает о способе их хранения.
|
||||
- адаптеры знают только свой протокол и общий контракт runtime.
|
||||
- `admin-api` оркестрирует use case для UI, но не содержит протокольной логики.
|
||||
- `mcp-server` публикует tools и вызывает runtime, но не содержит бизнес-логики конфигурирования.
|
||||
- `ui` не знает внутреннюю реализацию runtime и работает только через HTTP API.
|
||||
|
||||
### 2.2. Что запрещено
|
||||
|
||||
- помещать SQL, HTTP-клиенты или gRPC-клиенты в `mcpaas-core`;
|
||||
- хранить в `core` "общие утилиты", не относящиеся к доменной модели;
|
||||
- делать `runtime`, который напрямую читает БД;
|
||||
- писать mapping-логику внутри REST, GraphQL или gRPC адаптеров;
|
||||
- дублировать доменные типы в `admin-api`, `mcp-server` и адаптерах;
|
||||
- создавать большие структуры вида `AppState`, в которые складывается все подряд;
|
||||
- создавать большие enum или config-объекты, содержащие поля всех протоколов одновременно без выделенных вложенных типов.
|
||||
|
||||
### 2.3. Предпочтительный стиль
|
||||
|
||||
- узкие интерфейсы;
|
||||
- маленькие DTO;
|
||||
- отдельные типы для draft, published и runtime-view сущностей;
|
||||
- отдельные модули для чтения, записи, валидации и исполнения;
|
||||
- композиция из небольших сервисов вместо одного глобального сервиса.
|
||||
|
||||
## 3. Workspace-структура
|
||||
|
||||
Рекомендуемая структура:
|
||||
|
||||
```text
|
||||
mcpaas/
|
||||
apps/
|
||||
admin-api/
|
||||
mcp-server/
|
||||
ui/
|
||||
crates/
|
||||
mcpaas-core/
|
||||
mcpaas-registry/
|
||||
mcpaas-runtime/
|
||||
mcpaas-adapter-rest/
|
||||
mcpaas-adapter-graphql/
|
||||
mcpaas-adapter-grpc/
|
||||
mcpaas-mapping/
|
||||
mcpaas-schema/
|
||||
mcpaas-proto/
|
||||
```
|
||||
|
||||
Дополнительные crates `mcpaas-mapping`, `mcpaas-schema` и `mcpaas-proto` нужны затем, чтобы не перегружать `mcpaas-core`.
|
||||
|
||||
## 4. Детальная декомпозиция по crate
|
||||
|
||||
### 4.1. `mcpaas-core`
|
||||
|
||||
Назначение:
|
||||
|
||||
- базовые доменные типы;
|
||||
- идентификаторы;
|
||||
- метаданные операций;
|
||||
- общие контракты и ошибки верхнего уровня.
|
||||
|
||||
Что должно лежать в crate:
|
||||
|
||||
```text
|
||||
mcpaas-core/
|
||||
src/
|
||||
lib.rs
|
||||
ids.rs
|
||||
protocol.rs
|
||||
operation/
|
||||
mod.rs
|
||||
model.rs
|
||||
status.rs
|
||||
target.rs
|
||||
metadata.rs
|
||||
auth/
|
||||
mod.rs
|
||||
profile.rs
|
||||
secret_ref.rs
|
||||
errors/
|
||||
mod.rs
|
||||
domain.rs
|
||||
validation.rs
|
||||
runtime.rs
|
||||
```
|
||||
|
||||
Описание модулей:
|
||||
|
||||
- `ids.rs` - типы `OperationId`, `DescriptorId`, `ToolId` и другие идентификаторы.
|
||||
- `protocol.rs` - enum протоколов и общие protocol capability flags.
|
||||
- `operation/model.rs` - основная доменная модель операции без технических деталей хранения.
|
||||
- `operation/status.rs` - типы состояний операции.
|
||||
- `operation/target.rs` - базовые protocol-specific target structs.
|
||||
- `operation/metadata.rs` - описание tool, display name, version, tags.
|
||||
- `auth/profile.rs` - типы auth-профилей без привязки к конкретному клиенту.
|
||||
- `auth/secret_ref.rs` - ссылки на секреты, а не сами секреты.
|
||||
- `errors/*` - типизированные ошибки доменного слоя.
|
||||
|
||||
Что не должно лежать в crate:
|
||||
|
||||
- JSON Schema реализация;
|
||||
- mapping engine;
|
||||
- SQL-модели;
|
||||
- HTTP DTO;
|
||||
- protobuf parsing;
|
||||
- `reqwest`, `sqlx`, `tonic`, `axum`.
|
||||
|
||||
Причина:
|
||||
|
||||
`mcpaas-core` должен быть максимально стабильным и независимым. Если положить туда все подряд, он станет точкой связности всей системы.
|
||||
|
||||
### 4.2. `mcpaas-schema`
|
||||
|
||||
Назначение:
|
||||
|
||||
- внутренняя модель схем;
|
||||
- нормализация входа и выхода;
|
||||
- представление полей для UI и runtime;
|
||||
- преобразование схем из разных источников в единый вид.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-schema/
|
||||
src/
|
||||
lib.rs
|
||||
schema/
|
||||
mod.rs
|
||||
model.rs
|
||||
field.rs
|
||||
scalar.rs
|
||||
object.rs
|
||||
collection.rs
|
||||
oneof.rs
|
||||
enums.rs
|
||||
normalize/
|
||||
mod.rs
|
||||
json.rs
|
||||
graphql.rs
|
||||
protobuf.rs
|
||||
validate/
|
||||
mod.rs
|
||||
input.rs
|
||||
output.rs
|
||||
```
|
||||
|
||||
Описание:
|
||||
|
||||
- `schema/model.rs` - корневая структура схемы.
|
||||
- `field.rs` - описание поля, nullable, required, description.
|
||||
- `scalar.rs` - базовые scalar types.
|
||||
- `object.rs` - вложенные объекты.
|
||||
- `collection.rs` - массивы и map-подобные структуры.
|
||||
- `oneof.rs` - представление protobuf `oneof`.
|
||||
- `enums.rs` - enum-значения и метаданные.
|
||||
- `normalize/*` - преобразование GraphQL и protobuf моделей в единую схему.
|
||||
- `normalize/json.rs` - нормализация загруженных JSON-примеров во внутреннюю schema model.
|
||||
- `validate/*` - проверка JSON относительно внутренней схемы.
|
||||
|
||||
Почему отдельный crate:
|
||||
|
||||
Схемы будут использоваться почти везде, но это не повод тащить их в `core`. Иначе `core` станет тяжелым и начнет менять версию при каждом изменении схемной логики.
|
||||
|
||||
### 4.3. `mcpaas-mapping`
|
||||
|
||||
Назначение:
|
||||
|
||||
- описание mapping DSL;
|
||||
- компиляция mappings в runtime-представление;
|
||||
- применение mappings к входу и выходу;
|
||||
- автогенерация чернового mapping по загруженным примерам;
|
||||
- трассировка ошибок маппинга.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-mapping/
|
||||
src/
|
||||
lib.rs
|
||||
model/
|
||||
mod.rs
|
||||
mapping.rs
|
||||
source.rs
|
||||
target.rs
|
||||
transform.rs
|
||||
parser/
|
||||
mod.rs
|
||||
jsonpath.rs
|
||||
compile/
|
||||
mod.rs
|
||||
plan.rs
|
||||
infer/
|
||||
mod.rs
|
||||
from_samples.rs
|
||||
from_schema.rs
|
||||
execute/
|
||||
mod.rs
|
||||
input.rs
|
||||
output.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Описание:
|
||||
|
||||
- `model/mapping.rs` - описание одного правила mapping.
|
||||
- `model/source.rs` - откуда берем данные: `mcp`, `response`, `constant`.
|
||||
- `model/target.rs` - куда кладем данные: `request.path`, `request.query`, `request.body`, `output`.
|
||||
- `model/transform.rs` - ограниченный набор допустимых преобразований.
|
||||
- `parser/jsonpath.rs` - единый parser и validator для `JSONPath` выражений.
|
||||
- `compile/plan.rs` - предварительно скомпилированный план маппинга.
|
||||
- `infer/from_samples.rs` - генерация чернового mapping по загруженным примерам JSON.
|
||||
- `infer/from_schema.rs` - генерация чернового mapping по нормализованной схеме.
|
||||
- `execute/input.rs` - применение mappings к запросу.
|
||||
- `execute/output.rs` - применение mappings к ответу.
|
||||
|
||||
Антипаттерн, которого нужно избежать:
|
||||
|
||||
не помещать mapping-правила в строковые поля, которые потом интерпретируются каждым адаптером по-своему. Mapping должен быть единым движком.
|
||||
|
||||
### 4.4. `mcpaas-proto`
|
||||
|
||||
Назначение:
|
||||
|
||||
- работа с `.proto` и descriptor set;
|
||||
- извлечение services, methods и message schemas;
|
||||
- преобразование protobuf metadata во внутренние типы.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-proto/
|
||||
src/
|
||||
lib.rs
|
||||
descriptor/
|
||||
mod.rs
|
||||
loader.rs
|
||||
source.rs
|
||||
registry.rs
|
||||
reflect/
|
||||
mod.rs
|
||||
client.rs
|
||||
model/
|
||||
mod.rs
|
||||
service.rs
|
||||
method.rs
|
||||
message.rs
|
||||
field.rs
|
||||
convert/
|
||||
mod.rs
|
||||
to_schema.rs
|
||||
to_json.rs
|
||||
from_json.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Описание:
|
||||
|
||||
- `descriptor/loader.rs` - загрузка descriptor set.
|
||||
- `descriptor/source.rs` - типы источников: upload, file, reflection.
|
||||
- `descriptor/registry.rs` - индексирование описаний для поиска services/methods.
|
||||
- `reflect/client.rs` - клиент server reflection, если будет добавлен.
|
||||
- `model/*` - protobuf-ориентированная промежуточная модель.
|
||||
- `convert/to_schema.rs` - перевод protobuf message в `mcpaas-schema`.
|
||||
- `convert/to_json.rs` и `from_json.rs` - преобразование runtime payload.
|
||||
|
||||
Почему отдельный crate:
|
||||
|
||||
protobuf-логика объемная и быстро начнет загрязнять gRPC adapter, если не отделить ее сразу.
|
||||
|
||||
### 4.5. `mcpaas-registry`
|
||||
|
||||
Назначение:
|
||||
|
||||
- хранение операций, схем, descriptor links и статусов;
|
||||
- выдача draft/published представлений;
|
||||
- поиск активных операций для runtime и MCP server.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-registry/
|
||||
src/
|
||||
lib.rs
|
||||
model/
|
||||
mod.rs
|
||||
record.rs
|
||||
draft.rs
|
||||
published.rs
|
||||
repo/
|
||||
mod.rs
|
||||
operation_repo.rs
|
||||
descriptor_repo.rs
|
||||
service/
|
||||
mod.rs
|
||||
create_operation.rs
|
||||
update_operation.rs
|
||||
publish_operation.rs
|
||||
list_operations.rs
|
||||
get_runtime_view.rs
|
||||
storage/
|
||||
mod.rs
|
||||
sqlite.rs
|
||||
postgres.rs
|
||||
cache/
|
||||
mod.rs
|
||||
runtime_cache.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Описание:
|
||||
|
||||
- `model/record.rs` - DB-aligned record model.
|
||||
- `model/draft.rs` - модель черновика.
|
||||
- `model/published.rs` - модель опубликованной операции.
|
||||
- `repo/*` - контракты репозиториев.
|
||||
- `service/*` - use case операции над реестром.
|
||||
- `storage/*` - реализации репозиториев на `sqlx`.
|
||||
- `cache/runtime_cache.rs` - кэш активных операций.
|
||||
|
||||
Правило:
|
||||
|
||||
`registry` не выполняет операции и не знает о `reqwest`/`tonic`. Он только хранит и отдает согласованные представления.
|
||||
|
||||
### 4.6. `mcpaas-runtime`
|
||||
|
||||
Назначение:
|
||||
|
||||
- исполнение операций;
|
||||
- orchestration между схемой, mapping и адаптерами;
|
||||
- выдача нормализованного результата.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-runtime/
|
||||
src/
|
||||
lib.rs
|
||||
executor/
|
||||
mod.rs
|
||||
operation_executor.rs
|
||||
input_prepare.rs
|
||||
output_finalize.rs
|
||||
adapter/
|
||||
mod.rs
|
||||
traits.rs
|
||||
dispatch.rs
|
||||
context/
|
||||
mod.rs
|
||||
execution_context.rs
|
||||
model/
|
||||
mod.rs
|
||||
runtime_operation.rs
|
||||
prepared_request.rs
|
||||
adapter_response.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Описание:
|
||||
|
||||
- `executor/operation_executor.rs` - основной orchestration use case.
|
||||
- `executor/input_prepare.rs` - валидация входа и применение input mapping.
|
||||
- `executor/output_finalize.rs` - обработка adapter response и output mapping.
|
||||
- `adapter/traits.rs` - общий контракт для протокольных адаптеров.
|
||||
- `adapter/dispatch.rs` - выбор адаптера по протоколу.
|
||||
- `context/execution_context.rs` - correlation id, deadlines, tracing data.
|
||||
- `model/runtime_operation.rs` - runtime-ready представление операции.
|
||||
|
||||
Правило:
|
||||
|
||||
`runtime` не должен знать, где хранится операция. Он получает уже готовую `runtime_operation`.
|
||||
|
||||
### 4.7. `mcpaas-adapter-rest`
|
||||
|
||||
Назначение:
|
||||
|
||||
- построение и выполнение REST-вызовов.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-adapter-rest/
|
||||
src/
|
||||
lib.rs
|
||||
client.rs
|
||||
request/
|
||||
mod.rs
|
||||
build.rs
|
||||
path.rs
|
||||
query.rs
|
||||
headers.rs
|
||||
body.rs
|
||||
response/
|
||||
mod.rs
|
||||
decode.rs
|
||||
normalize.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Правило:
|
||||
|
||||
REST adapter не валидирует MCP input и не знает о registry. Он получает уже подготовленный request contract.
|
||||
|
||||
### 4.8. `mcpaas-adapter-graphql`
|
||||
|
||||
Назначение:
|
||||
|
||||
- построение и выполнение GraphQL-вызовов.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-adapter-graphql/
|
||||
src/
|
||||
lib.rs
|
||||
client.rs
|
||||
request/
|
||||
mod.rs
|
||||
build.rs
|
||||
variables.rs
|
||||
response/
|
||||
mod.rs
|
||||
decode.rs
|
||||
extract.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Правило:
|
||||
|
||||
GraphQL adapter не занимается introspection по умолчанию и не содержит редактор схем. Он только исполняет подготовленный operation template.
|
||||
|
||||
Дополнительное ограничение:
|
||||
|
||||
один GraphQL tool соответствует одному заранее определенному `query` или `mutation`. Адаптер не должен принимать от LLM произвольный GraphQL-документ, потому что в MCP-модели операция должна оставаться узкой, предсказуемой и валидируемой по фиксированной схеме.
|
||||
|
||||
### 4.9. `mcpaas-adapter-grpc`
|
||||
|
||||
Назначение:
|
||||
|
||||
- выполнение unary gRPC-вызовов на основе уже выбранного метода и descriptor metadata.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
mcpaas-adapter-grpc/
|
||||
src/
|
||||
lib.rs
|
||||
channel.rs
|
||||
invoke/
|
||||
mod.rs
|
||||
unary.rs
|
||||
request/
|
||||
mod.rs
|
||||
build.rs
|
||||
response/
|
||||
mod.rs
|
||||
decode.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Правило:
|
||||
|
||||
gRPC adapter не должен сам парсить `.proto`. Этим занимается `mcpaas-proto`. Иначе в адаптере смешаются discovery и execution.
|
||||
|
||||
Дополнительное ограничение:
|
||||
|
||||
adapter поддерживает только unary RPC. Streaming-вызовы не реализуются, потому что целевая модель MCP tool в проекте соответствует сценарию `запрос -> ответ`, а не долгоживущей сессии обмена сообщениями.
|
||||
|
||||
### 4.10. `admin-api`
|
||||
|
||||
Назначение:
|
||||
|
||||
- HTTP API для UI;
|
||||
- координация use case создания, редактирования, тестирования и публикации.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
apps/admin-api/
|
||||
src/
|
||||
main.rs
|
||||
app.rs
|
||||
state.rs
|
||||
router.rs
|
||||
http/
|
||||
mod.rs
|
||||
dto/
|
||||
mod.rs
|
||||
operation.rs
|
||||
mapping.rs
|
||||
test_run.rs
|
||||
handlers/
|
||||
mod.rs
|
||||
create_operation.rs
|
||||
update_operation.rs
|
||||
publish_operation.rs
|
||||
list_operations.rs
|
||||
test_operation.rs
|
||||
export_operation_yaml.rs
|
||||
import_operation_yaml.rs
|
||||
upload_json_samples.rs
|
||||
upload_proto.rs
|
||||
list_grpc_services.rs
|
||||
response.rs
|
||||
services/
|
||||
mod.rs
|
||||
operation_service.rs
|
||||
descriptor_service.rs
|
||||
config_portability_service.rs
|
||||
test_service.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Правила:
|
||||
|
||||
- HTTP DTO не должны протекать в доменный слой;
|
||||
- handlers должны быть тонкими;
|
||||
- orchestration должна жить в `services/*`;
|
||||
- `state.rs` не должен разрастаться в огромную структуру. Лучше использовать вложенные state-компоненты или отдельные service bundles.
|
||||
- import/export конфигурации в `YAML` должен быть отдельным use case, а не побочным эффектом обычного CRUD.
|
||||
|
||||
### 4.11. `mcp-server`
|
||||
|
||||
Назначение:
|
||||
|
||||
- публикация MCP tools;
|
||||
- вызов runtime по имени tool;
|
||||
- обновление активного списка tools.
|
||||
|
||||
Структура:
|
||||
|
||||
```text
|
||||
apps/mcp-server/
|
||||
src/
|
||||
main.rs
|
||||
app.rs
|
||||
state.rs
|
||||
tools/
|
||||
mod.rs
|
||||
list.rs
|
||||
call.rs
|
||||
cache.rs
|
||||
translate/
|
||||
mod.rs
|
||||
to_mcp_tool.rs
|
||||
from_mcp_input.rs
|
||||
to_mcp_output.rs
|
||||
errors.rs
|
||||
```
|
||||
|
||||
Правило:
|
||||
|
||||
`mcp-server` не должен реализовывать business rules публикации. Он читает уже опубликованные операции и транслирует их в MCP.
|
||||
|
||||
### 4.12. `ui`
|
||||
|
||||
Назначение:
|
||||
|
||||
- интерфейс оператора.
|
||||
|
||||
Предлагаемая frontend-структура:
|
||||
|
||||
```text
|
||||
apps/ui/
|
||||
src/
|
||||
main.tsx
|
||||
app/
|
||||
router.tsx
|
||||
providers.tsx
|
||||
pages/
|
||||
operation-list/
|
||||
operation-create/
|
||||
operation-edit/
|
||||
operation-test/
|
||||
grpc-browser/
|
||||
features/
|
||||
operation-form/
|
||||
mapping-editor/
|
||||
sample-upload/
|
||||
grpc-method-picker/
|
||||
schema-viewer/
|
||||
publish-operation/
|
||||
entities/
|
||||
operation/
|
||||
descriptor/
|
||||
shared/
|
||||
api/
|
||||
lib/
|
||||
ui/
|
||||
config/
|
||||
```
|
||||
|
||||
Правило:
|
||||
|
||||
UI должен декомпозироваться по пользовательским сценариям, а не по типам файлов уровня "все компоненты в одной папке".
|
||||
|
||||
## 5. Правила зависимостей между crate
|
||||
|
||||
Целевой граф зависимостей:
|
||||
|
||||
```text
|
||||
mcpaas-core
|
||||
mcpaas-schema -> mcpaas-core
|
||||
mcpaas-mapping -> mcpaas-core
|
||||
mcpaas-proto -> mcpaas-core, mcpaas-schema
|
||||
mcpaas-registry -> mcpaas-core, mcpaas-schema, mcpaas-mapping
|
||||
mcpaas-adapter-rest -> mcpaas-core
|
||||
mcpaas-adapter-graphql -> mcpaas-core
|
||||
mcpaas-adapter-grpc -> mcpaas-core, mcpaas-proto
|
||||
mcpaas-runtime -> mcpaas-core, mcpaas-schema, mcpaas-mapping, adapters
|
||||
admin-api -> mcpaas-core, mcpaas-schema, mcpaas-mapping, mcpaas-proto, mcpaas-registry, mcpaas-runtime
|
||||
mcp-server -> mcpaas-core, mcpaas-registry, mcpaas-runtime
|
||||
```
|
||||
|
||||
Критические ограничения:
|
||||
|
||||
- `mcpaas-core` ни от кого не зависит;
|
||||
- адаптеры не зависят от `registry`;
|
||||
- `runtime` не зависит от `admin-api` и `mcp-server`;
|
||||
- `registry` не зависит от адаптеров;
|
||||
- `ui` зависит только от HTTP API.
|
||||
|
||||
## 6. Границы публичных API модулей
|
||||
|
||||
Чтобы структура не разъехалась, нужно заранее ограничить публичность.
|
||||
|
||||
Рекомендуемое правило:
|
||||
|
||||
- наружу экспортируются только корневые доменные типы, service-интерфейсы и ошибки;
|
||||
- внутренние DTO, record-модели и промежуточные builder-структуры остаются `pub(crate)`;
|
||||
- не реэкспортировать целые деревья модулей без необходимости;
|
||||
- не делать `mod utils`, если можно назвать модуль по смыслу.
|
||||
|
||||
Пример плохого решения:
|
||||
|
||||
- `pub mod common;`
|
||||
- `pub mod helpers;`
|
||||
- `pub struct AppContext { ... 25 полей ... }`
|
||||
|
||||
Пример правильного решения:
|
||||
|
||||
- `pub struct OperationExecutor`
|
||||
- `pub trait OperationRepository`
|
||||
- `pub struct RuntimeOperation`
|
||||
|
||||
## 7. Какие большие структуры точно не нужны
|
||||
|
||||
Ниже список сущностей, которые легко превращаются в антипаттерн:
|
||||
|
||||
- одна гигантская `Operation`, содержащая сразу все REST, GraphQL и gRPC поля;
|
||||
- один `MappingConfig`, содержащий и input, и output, и transforms, и validation rules без разделения;
|
||||
- единый `AppState` со всеми репозиториями, клиентами, кэшами и конфигами;
|
||||
- один `ProtocolAdapter` с ветвлением `match protocol` внутри на сотни строк;
|
||||
- один `SchemaField` без выделения object/array/enum/oneof вариантов.
|
||||
|
||||
Правильный подход:
|
||||
|
||||
- отдельные target-типы по протоколам;
|
||||
- отдельные input/output mapping модели;
|
||||
- отдельные bounded state-наборы для каждого приложения;
|
||||
- отдельные adapter crates;
|
||||
- выделенная иерархия schema types.
|
||||
|
||||
## 8. Порядок реализации без архитектурного долга
|
||||
|
||||
Рекомендуемый порядок разработки:
|
||||
|
||||
1. `mcpaas-core`
|
||||
2. `mcpaas-schema`
|
||||
3. `mcpaas-mapping`
|
||||
4. `mcpaas-registry`
|
||||
5. `mcpaas-adapter-rest`
|
||||
6. `mcpaas-runtime`
|
||||
7. `admin-api`
|
||||
8. `ui`
|
||||
9. `mcpaas-proto`
|
||||
10. `mcpaas-adapter-grpc`
|
||||
11. `mcpaas-adapter-graphql`
|
||||
12. `mcp-server`
|
||||
|
||||
Причина такого порядка:
|
||||
|
||||
- сначала фиксируется доменная модель;
|
||||
- затем схема и mapping как самые чувствительные части;
|
||||
- затем реестр и базовое выполнение REST;
|
||||
- после этого можно собирать UI и только потом наращивать сложные протоколы.
|
||||
|
||||
## 9. Практический итог
|
||||
|
||||
Если придерживаться этой декомпозиции, то:
|
||||
|
||||
- `mcpaas-core` останется маленьким и стабильным;
|
||||
- schema и mapping не смешаются с transport-логикой;
|
||||
- protobuf discovery не загрязнит gRPC runtime;
|
||||
- `admin-api` и `mcp-server` останутся тонкими входными слоями;
|
||||
- добавление нового протокола не потребует переписывать половину проекта.
|
||||
|
||||
Это и есть целевая архитектурная дисциплина проекта: отдельные слои, отдельные модели, минимально необходимая публичность и отсутствие "универсальных" структур, в которые со временем начинает стекаться вся система.
|
||||
Reference in New Issue
Block a user