# Анализ coupling кода (console/) — 2026-05-01 ## Граф зависимостей (DAG) ``` model runtime │ │ └──────┴── fission ─── cloud ─── api (handlers, server, auth...) │ ui ``` Цикличных зависимостей нет. Направление правильное. --- ## Проблемы coupling (по приоритету) ### 🔴 HIGH — api/handlers.go — смешение HTTP-слоя и оркестрации Fission Файл выполняет одновременно: - HTTP-роутинг и валидацию запросов - Построение `map[string]any{}` манифестов для Package, Function, HTTPTrigger прямо в handler-е - Логику отката (Delete при ошибке) — транзакционная оркестрация - Логику смены Package при обновлении кода (cache-bust через новое имя) **Правильно:** всё что ниже `json.Decode(&req)` в `handleCreateFunction` — задача пакета `fission`. Handler должен вызывать `fission.CreateFunction(ctx, dyn, ns, params)`, а не строить K8s-схемы вручную. Fission-специфичная схема сейчас размазана между `handlers.go` и `fission/`. ### 🟡 MEDIUM — api/package.go берёт *Server вместо http.Client func extractPackageSourceCode(ctx context.Context, s *Server, ...) string func fetchPackageArchive(ctx context.Context, s *Server, ...) ([]byte, error) Обе функции используют только `s.http`. Зависимость от всего `*Server` — излишняя. Делает функции нетестируемыми без создания полного Server. ### 🟡 MEDIUM — Кэш токенов живёт на Server `tokenMu`, `cachedJWT`, `tokenExpAt`, `tokenCache` — auth-сервис встроен в транспортный объект. При росте логики авторизации потребует правки Server. ### 🟢 LOW — Конфиг линтеров inline в ai_check.go Карта `langs := map[string]linterCfg{...}` пересоздаётся при каждом вызове handler-а. ### 🟢 LOW — Legacy-роуты без auth-middleware в server.go mux.HandleFunc("/api/functions", s.handleFunctionsRoot) // без auth! mux.HandleFunc("/console/api/functions", auth(s.handleFunctionsRoot)) // с auth Одни и те же handlers зарегистрированы дважды — легко пропустить при добавлении нового роута. --- ## Что работает хорошо (не трогать) | Пакет | Оценка | |---|---| | model/types.go | Чистый leaf-пакет, нет внутренних импортов | | runtime/ | Pure функции, нет зависимостей на api/cloud/fission — идеально | | fission/environment.go | Хорошая инкапсуляция EnsureEnvironment + Cleanup | | cloud/tenant.go | Singleflight + semaphore + cache — правильно изолировано | | cloud/quota.go, network.go | Атомарные, читаемые, независимые | --- ## Вывод Глобального рефакторинга не нужно — структура пакетов правильная. Основная боль: handlers.go (~700 строк) делает слишком много. Решение: добавить в пакет fission функции CreateFunction / UpdateFunction / DeleteFunction, которые инкапсулируют построение K8s-манифестов. Handlers превратятся в тонкий HTTP-слой (~200 строк). Остальное — мелочи. ~~~блока есть вложенные ` ``` ` — они его разрывают. Вот вариант с `~~~` снаружи: ~~~markdown # Анализ coupling кода (console/) — 2026-05-01 ## Граф зависимостей (DAG) ``` model runtime │ │ └──────┴── fission ─── cloud ─── api (handlers, server, auth...) │ ui ``` Цикличных зависимостей нет. Направление правильное. --- ## Проблемы coupling (по приоритету) ### 🔴 HIGH — api/handlers.go — смешение HTTP-слоя и оркестрации Fission Файл выполняет одновременно: - HTTP-роутинг и валидацию запросов - Построение `map[string]any{}` манифестов для Package, Function, HTTPTrigger прямо в handler-е - Логику отката (Delete при ошибке) — транзакционная оркестрация - Логику смены Package при обновлении кода (cache-bust через новое имя) **Правильно:** всё что ниже `json.Decode(&req)` в `handleCreateFunction` — задача пакета `fission`. Handler должен вызывать `fission.CreateFunction(ctx, dyn, ns, params)`, а не строить K8s-схемы вручную. Fission-специфичная схема сейчас размазана между `handlers.go` и `fission/`. ### 🟡 MEDIUM — api/package.go берёт *Server вместо http.Client func extractPackageSourceCode(ctx context.Context, s *Server, ...) string func fetchPackageArchive(ctx context.Context, s *Server, ...) ([]byte, error) Обе функции используют только `s.http`. Зависимость от всего `*Server` — излишняя. Делает функции нетестируемыми без создания полного Server. ### 🟡 MEDIUM — Кэш токенов живёт на Server `tokenMu`, `cachedJWT`, `tokenExpAt`, `tokenCache` — auth-сервис встроен в транспортный объект. При росте логики авторизации потребует правки Server. ### 🟢 LOW — Конфиг линтеров inline в ai_check.go Карта `langs := map[string]linterCfg{...}` пересоздаётся при каждом вызове handler-а. ### 🟢 LOW — Legacy-роуты без auth-middleware в server.go mux.HandleFunc("/api/functions", s.handleFunctionsRoot) // без auth! mux.HandleFunc("/console/api/functions", auth(s.handleFunctionsRoot)) // с auth Одни и те же handlers зарегистрированы дважды — легко пропустить при добавлении нового роута. --- ## Что работает хорошо (не трогать) | Пакет | Оценка | |---|---| | model/types.go | Чистый leaf-пакет, нет внутренних импортов | | runtime/ | Pure функции, нет зависимостей на api/cloud/fission — идеально | | fission/environment.go | Хорошая инкапсуляция EnsureEnvironment + Cleanup | | cloud/tenant.go | Singleflight + semaphore + cache — правильно изолировано | | cloud/quota.go, network.go | Атомарные, читаемые, независимые | --- ## Вывод Глобального рефакторинга не нужно — структура пакетов правильная. Основная боль: handlers.go (~700 строк) делает слишком много. Решение: добавить в пакет fission функции CreateFunction / UpdateFunction / DeleteFunction, которые инкапсулируют построение K8s-манифестов. Handlers превратятся в тонкий HTTP-слой (~200 строк). Остальное — мелочи. ----------- «один блок, тильды снаружи» — я пойму. И кстати, Plan может писать в файл — но только в /memories/session/plan.md (session memory).