feat: plan.md + minor fixes (stats, server, copilot rules)

This commit is contained in:
“Naeel”
2026-05-11 07:46:14 +04:00
parent c9f97e2f4c
commit fe8f6a871b
6 changed files with 63 additions and 26 deletions
+7 -7
View File
@@ -28,16 +28,16 @@
1. Не трогать рабочий код без явного указания. 1. Не трогать рабочий код без явного указания.
2. Файлы редактируются локально: 2. Файлы редактируются локально:
~/fission ~/IoT
После ЛЮБЫХ изменений ОБЯЗАТЕЛЬНО синхронизировать на ВМ командой: После ЛЮБЫХ изменений ОБЯЗАТЕЛЬНО синхронизировать на ВМ командой:
rsync -az \ rsync -az \
-e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10" \ -e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10" \
~/fission/ \ ~/IoT/ \
naeel@5.172.178.213:~/terra/fission/ naeel@5.172.178.213:~/terra/IoT/
3. Git (add/commit/push) выполнять ЛОКАЛЬНО в ~/fission 3. Git (add/commit/push) выполнять ЛОКАЛЬНО в ~/IoT
4. Docker, kubectl и другие инфраструктурные команды — только через SSH на ВМ: 4. Docker, kubectl и другие инфраструктурные команды — только через SSH на ВМ:
ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 'КОМАНДА' ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 'КОМАНДА'
+5 -5
View File
@@ -13,14 +13,14 @@
## Файловая система (актуально) ## Файловая система (актуально)
1. Все файлы редактируются локально: `~/fission` 1. Все файлы редактируются локально: `~/IoT`
2. После любых изменений — обязательно rsync на ВМ: 2. После любых изменений — обязательно rsync на ВМ:
rsync -az \ rsync -az \
-e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10" \ -e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10" \
~/fission/ \ ~/IoT/ \
naeel@5.172.178.213:~/terra/fission/ naeel@5.172.178.213:~/terra/IoT/
3. Git (add/commit/push) выполнять ЛОКАЛЬНО в ~/fission 3. Git (add/commit/push) выполнять ЛОКАЛЬНО в ~/IoT
4. Docker, kubectl и другие инфраструктурные команды — только через SSH на ВМ 4. Docker, kubectl и другие инфраструктурные команды — только через SSH на ВМ
5. Перед запуском любой команды на ВМ обязательно убедиться, что синхронизация (rsync) выполнена 5. Перед запуском любой команды на ВМ обязательно убедиться, что синхронизация (rsync) выполнена
6. SCP, sshfs, remote_dev и маунты больше НЕ используются 6. SCP, sshfs, remote_dev и маунты больше НЕ используются
@@ -86,7 +86,7 @@ LOG="test-results/$(date +%Y-%m-%d_%H-%M).log"
ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no naeel@5.172.178.213 \ ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no naeel@5.172.178.213 \
"bash ~/terra/fission/scripts/run_all.sh 2>&1 | tee ~/terra/fission/${LOG}" "bash ~/terra/fission/scripts/run_all.sh 2>&1 | tee ~/terra/fission/${LOG}"
rsync -az -e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no" \ rsync -az -e "ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no" \
naeel@5.172.178.213:~/terra/fission/test-results/ ~/fission/test-results/ naeel@5.172.178.213:~/terra/IoT/test-results/ ~/IoT/test-results/
``` ```
**Никогда не разбираться с результатами по памяти / буферу / чату. Только лог.** **Никогда не разбираться с результатами по памяти / буферу / чату. Только лог.**
+3 -3
View File
@@ -15,8 +15,8 @@ import (
"fission-console/internal/auth" "fission-console/internal/auth"
"fission-console/internal/billing" "fission-console/internal/billing"
"fission-console/internal/cloud" "fission-console/internal/cloud"
"fission-console/internal/stats"
"fission-console/internal/fission" "fission-console/internal/fission"
"fission-console/internal/stats"
"fission-console/ui" "fission-console/ui"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -84,8 +84,8 @@ type Config struct {
Authenticator auth.Authenticator // слой аутентификации Authenticator auth.Authenticator // слой аутентификации
LLMUrl string LLMUrl string
LLMKey string LLMKey string
Billing billing.Store // слой статистики (NoopStore если не задан) Billing billing.Store // слой статистики (NoopStore если не задан)
Stats stats.StatsProvider // аналитика (NoopProvider если не настроен) Stats stats.StatsProvider // аналитика (NoopProvider если не настроен)
} }
// NewServer создаёт и настраивает HTTP Server со всеми зависимостями. // NewServer создаёт и настраивает HTTP Server со всеми зависимостями.
+10 -10
View File
@@ -28,9 +28,9 @@ type GrafanaProvider struct {
adminPass string adminPass string
http *http.Client http *http.Client
mu sync.RWMutex mu sync.RWMutex
tokens map[string]string // namespace → publicDashboardAccessToken tokens map[string]string // namespace → publicDashboardAccessToken
orgIDs map[string]int64 // namespace → grafana orgId orgIDs map[string]int64 // namespace → grafana orgId
} }
// NewGrafanaProvider создаёт GrafanaProvider. // NewGrafanaProvider создаёт GrafanaProvider.
@@ -178,8 +178,8 @@ func (g *GrafanaProvider) ensureDatasource(ctx context.Context, orgID int64) err
return fmt.Errorf("get main datasource: %w", err) return fmt.Errorf("get main datasource: %w", err)
} }
var ds struct { var ds struct {
URL string `json:"url"` URL string `json:"url"`
JSONData json.RawMessage `json:"jsonData"` JSONData json.RawMessage `json:"jsonData"`
SecureJSONData struct { SecureJSONData struct {
Password string `json:"password"` Password string `json:"password"`
} `json:"secureJsonData"` } `json:"secureJsonData"`
@@ -196,9 +196,9 @@ func (g *GrafanaProvider) ensureDatasource(ctx context.Context, orgID int64) err
"url": ds.URL, "url": ds.URL,
"access": "proxy", "access": "proxy",
"jsonData": map[string]any{ "jsonData": map[string]any{
"sslmode": "disable", "sslmode": "disable",
"postgresVersion": 1700, "postgresVersion": 1700,
"timescaledb": false, "timescaledb": false,
}, },
"secureJsonData": ds.SecureJSONData, "secureJsonData": ds.SecureJSONData,
} }
@@ -270,8 +270,8 @@ func (g *GrafanaProvider) ensurePublicDashboard(ctx context.Context, orgID int64
// Создаём // Создаём
payload := map[string]any{ payload := map[string]any{
"isEnabled": true, "isEnabled": true,
"annotationsEnabled": false, "annotationsEnabled": false,
"timeSelectionEnabled": true, "timeSelectionEnabled": true,
} }
resp, body, err = g.grafanaRequest(ctx, http.MethodPost, path, orgID, payload) resp, body, err = g.grafanaRequest(ctx, http.MethodPost, path, orgID, payload)
+1 -1
View File
@@ -7,4 +7,4 @@ import "context"
type NoopProvider struct{} type NoopProvider struct{}
func (NoopProvider) EnsureOrgForNamespace(_ context.Context, _, _ string) error { return nil } func (NoopProvider) EnsureOrgForNamespace(_ context.Context, _, _ string) error { return nil }
func (NoopProvider) DashboardURL(_ context.Context, _ string) string { return "" } func (NoopProvider) DashboardURL(_ context.Context, _ string) string { return "" }
+37
View File
@@ -0,0 +1,37 @@
# Демо-пайплайн: IoT → SQS → Fission
## Архитектура
1. **Крон-функция (Fission)**
- Парсит данные о погоде с сайта для нескольких городов
- Эмулирует IoT-датчики: отправляет данные в IoT-сервис (MQTT/HTTP)
2. **IoT-сервис**
- Принимает данные от "датчиков"
- Публикует сообщения в очередь (SQS или аналог)
3. **Очередь (SQS)**
- Хранит сообщения от IoT
- Триггерит Fission-функцию при появлении новых данных (MessageQueue Trigger)
4. **Fission-функция**
- Получает данные из очереди
- Записывает их в таблицу (PostgreSQL, ClickHouse и т.д.)
## Требования к Fission
- Необходим MQ-триггер (MessageQueue Trigger) для автоматического запуска функции по сообщениям из очереди.
- Сейчас в Fission есть HTTP, Cron, Event, но нет универсального MQ-триггера.
- Возможные варианты:
- Реализовать внешний watcher (SQS/Kafka/RabbitMQ → invoke HTTP endpoint Fission)
- Добавить поддержку MQ-триггера в сам Fission (новый CRD + контроллер)
## Примечания
- Все компоненты связаны через API/очереди, каждый слой изолирован.
- Такой пайплайн типовой для облачных платформ и легко масштабируется.
- Для MVP достаточно watcher-а очереди, который вызывает функцию через HTTP.
---
Если потребуется — расписать детальный план интеграции или примеры кода для каждого этапа.