refactor: update architecture documentation and add commenting standards

This commit is contained in:
Илья Глазунов
2026-09-05 19:40:35 +03:00
parent a55ee10d2b
commit ead0eecbc5
8 changed files with 331 additions and 3 deletions
+83
View File
@@ -0,0 +1,83 @@
# Swift Implementation Patterns Mastermind
Этот документ описывает нормативные паттерны реализации кода на Swift.
## 1. Concurrency & State Ownership
**Problem**: Состояние гонки (race conditions) и неопределённое поведение при многопоточности.
**Rule**: Каждая stateful-возможность (Capability) или сервис принадлежат конкретному `actor`. Межмодульный обмен — только через `Sendable` неизменяемые типы (value types). `MainActor` используется исключительно для UI-проекций.
**Apply when**: При проектировании хранилищ, сервисов и вью-моделей.
**Avoid**: Использование `lock`, `DispatchQueue` для синхронизации состояния вручную; захват мутабельного состояния в замыканиях.
**Trade-offs**: Требует понимания Swift Concurrency и использования `await`.
**Verification**: Swift 6 Strict Concurrency не должен выдавать предупреждений и ошибок.
## 2. Bounded Async Streams
**Problem**: Неконтролируемое накопление событий в очередях (backpressure) приводит к утечкам памяти и задержкам.
**Rule**: Все `AsyncStream` должны иметь ограниченный буфер (bounded) и явную политику обработки переполнения (`dropOldest`, `dropNewest` или `coalesce`).
**Apply when**: Для потоков аудио-фреймов, скриншотов и событий UI.
**Avoid**: Создание неограниченных потоков событий.
**Verification**: Каждый стрим должен иметь тесты на поведение при переполнении.
## 3. Lightweight UDF (Unidirectional Data Flow)
**Problem**: Сложная двусторонняя синхронизация UI и бизнес-логики.
**Rule**: Использование однонаправленного потока данных: Immutable State → View → Intent (Action) → Service/Reducer → New State. Без обязательной зависимости от тяжелых фреймворков (TCA).
**Apply when**: В реализации Companion Island и экранов управления.
**Avoid**: Прямая мутация состояния из View; использование `Binding` для бизнес-логики.
**Verification**: View зависит только от `State` и отправляет `Intents`.
## 4. Boundary State Machines
**Problem**: Неявные переходы между состояниями (например, Collectors) приводят к трудновоспроизводимым багам.
**Rule**: Использование явных конечных автоматов (State Machines) для жизненного циклаCollectors, сессий и миграций. Недопустимые переходы должны быть невозможны на уровне типов.
**Apply when**: Управление жизненным циклом сложных компонентов.
**Avoid**: Большое количество разрозненных `Bool` флагов для описания состояния.
**Verification**: Unit-тесты покрывают матрицу переходов.
## 5. Validated Value Types
**Problem**: Проброс примитивов (String, Int) через все слои приводит к потере смысла и ошибкам валидации.
**Rule**: Использование отдельных типов-обёрток для доменных понятий (ID, Timestamp, Confidence). Проверка инвариантов происходит при создании типа.
**Apply when**: Все доменные сущности и параметры портов.
**Avoid**: Использование `String` для ID или `Double` для Confidence без обёртки.
**Verification**: Код компилируется только при передаче правильных типов; невозможны "пустые" или некорректные значения.
## 6. Manual Composition Root
**Problem**: Глобальные синглтоны и Service Locator делают зависимости неявными.
**Rule**: Использование ручного внедрения зависимостей (Constructor Injection) в единственной точке входа (Composition Root). Глобальные мутабельные синглтоны запрещены.
**Apply when**: Инициализация приложения в `AppShell`.
**Avoid**: Использование `shared` instance для бизнес-логики.
**Verification**: Все зависимости можно подменить (mock) в тестах без изменения кода модулей.
## 7. Workflow-Sized Services
**Problem**: Use cases, которые делают слишком мало (один метод) или слишком много (весь модуль).
**Rule**: Application Service должен отражать осмысленный пользовательский или системный воркфлоу (например, `AssistantSessionService`) и оркестровать несколько портов.
**Avoid**: Создание класса UseCase для каждой мелкой функции; "божественные" объекты-координаторы.
**Verification**: Сервис покрывает логически связанную группу действий.
## 8. Typed Failure States
**Problem**: Обобщённые ошибки `Swift.Error` не дают понимания, как на них реагировать.
**Rule**: Ожидаемые ошибки моделируются как типизированные состояния (Enum). Ошибки адаптеров переводятся в доменные ошибки на границе модуля.
**Apply when**: Возврат результатов из портов и сервисов.
**Avoid**: Проброс `NSError` или `URLError` в доменные слои.
**Verification**: UI может точно отобразить причину сбоя на основе типа ошибки.
## 9. Structured Task Ownership
**Problem**: Утечки задач (detached tasks) и сложности с отменой (cancellation).
**Rule**: Каждая долгоживущая `Task` принадлежит владельцу жизненного цикла и отменяется при его завершении. `Task.detached` запрещён, кроме системных воркеров.
**Apply when**: Запуск Collectors и фоновой обработки.
**Avoid**: "Fire-and-forget" задачи без сохранения ссылки на отмену.
**Verification**: Deinit объекта приводит к остановке всех запущенных им задач.
## 10. Dedicated Executors for Blocking Work
**Problem**: Блокировка потока актора или MainActor тяжелыми вычислениями.
**Rule**: Все блокирующие операции (SQLite, ML, PCM) выносятся на выделенные очереди или исполнители (Dedicated Executors/Queues). Оркестрация акторов не должна выполнять тяжелую работу.
**Apply when**: I/O, обработка медиа, криптография.
**Avoid**: Выполнение `Data(contentsOf:)` или сложных циклов на MainActor.
**Verification**: Профилирование в Instruments не показывает блокировок UI потока.