diff --git a/gateway/router/nokia.go b/gateway/router/nokia.go index f200bc3..d0fec7e 100644 --- a/gateway/router/nokia.go +++ b/gateway/router/nokia.go @@ -126,7 +126,7 @@ func (d *NokiaDriver) Reboot(ctx context.Context) error { if err != nil { return fmt.Errorf("router: reboot request: %w", err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("router: read reboot response: %w", err) @@ -167,7 +167,7 @@ func (d *NokiaDriver) fetchCSRFToken(ctx context.Context) (string, error) { if err != nil { return "", fmt.Errorf("fetch reboot page: %w", err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() body, err := io.ReadAll(resp.Body) if err != nil { @@ -231,7 +231,7 @@ func (d *NokiaDriver) login(ctx context.Context) error { if err != nil { return fmt.Errorf("router: login request: %w", err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if _, err := io.Copy(io.Discard, resp.Body); err != nil { return fmt.Errorf("router: drain login response: %w", err) } diff --git a/gateway/router/nokia_test.go b/gateway/router/nokia_test.go index 55cec8b..4229412 100644 --- a/gateway/router/nokia_test.go +++ b/gateway/router/nokia_test.go @@ -392,10 +392,10 @@ func newRouterServer(t *testing.T, cfg routerServerConfig) (*httptest.Server, *r return } if cfg.noTokenPage { - fmt.Fprint(w, "
no token here") + _, _ = fmt.Fprint(w, "no token here") return } - fmt.Fprintf(w, ``, token) + _, _ = fmt.Fprintf(w, ``, token) case http.MethodPost: obs.rebootCalled = true obs.rebootCT = r.Header.Get("Content-Type") @@ -416,7 +416,7 @@ func newRouterServer(t *testing.T, cfg routerServerConfig) (*httptest.Server, *r } w.WriteHeader(http.StatusOK) if !cfg.emptyRebootBody { - fmt.Fprint(w, dto.RebootDoneMarker) // confirmed reboot marker + _, _ = fmt.Fprint(w, dto.RebootDoneMarker) // confirmed reboot marker } default: w.WriteHeader(http.StatusMethodNotAllowed) @@ -444,11 +444,11 @@ func newRouterServerRecordingPaths(t *testing.T, paths *[]string) *httptest.Serv mux.HandleFunc("/reboot.cgi", func(w http.ResponseWriter, r *http.Request) { *paths = append(*paths, r.URL.Path) if r.Method == http.MethodGet { - fmt.Fprintf(w, ``, defaultTestCSRF) + _, _ = fmt.Fprintf(w, ``, defaultTestCSRF) return } w.WriteHeader(http.StatusOK) - fmt.Fprint(w, dto.RebootDoneMarker) + _, _ = fmt.Fprint(w, dto.RebootDoneMarker) }) srv := httptest.NewServer(mux) diff --git a/gateway/telegram/telegram.go b/gateway/telegram/telegram.go index a26b377..779713a 100644 --- a/gateway/telegram/telegram.go +++ b/gateway/telegram/telegram.go @@ -126,7 +126,7 @@ func (c *Client) sendMessage(ctx context.Context, text string) error { if err != nil { return fmt.Errorf("telegram: send request: %w", err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { respBody, readErr := io.ReadAll(io.LimitReader(resp.Body, 1024)) diff --git a/infrastructure/check.go b/infrastructure/check.go index bb88902..09527dc 100644 --- a/infrastructure/check.go +++ b/infrastructure/check.go @@ -116,7 +116,7 @@ func (c *Checker) probeHTTP(ctx context.Context, target string) domain.TargetRes if err != nil { return domain.TargetResult{Target: target, Kind: domain.CheckKindDomain, OK: false, Latency: latency, Error: stage.annotate(err)} } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode < 200 || resp.StatusCode >= 300 { return domain.TargetResult{ @@ -143,7 +143,7 @@ func (c *Checker) probeTCP(ctx context.Context, target, kind string) domain.Targ if err != nil { return domain.TargetResult{Target: target, Kind: kind, OK: false, Latency: latency, Error: err.Error()} } - defer conn.Close() + defer func() { _ = conn.Close() }() return domain.TargetResult{Target: target, Kind: kind, OK: true, Latency: latency} } diff --git a/infrastructure/env.go b/infrastructure/env.go index 2bad9fc..5e96c02 100644 --- a/infrastructure/env.go +++ b/infrastructure/env.go @@ -22,7 +22,7 @@ func loadEnvFile(path string) (map[string]string, error) { if err != nil { return nil, fmt.Errorf("open env file %q: %w", path, err) } - defer f.Close() + defer func() { _ = f.Close() }() values := map[string]string{} scanner := bufio.NewScanner(f) diff --git a/infrastructure/store.go b/infrastructure/store.go index 3efa9a5..e7237de 100644 --- a/infrastructure/store.go +++ b/infrastructure/store.go @@ -369,7 +369,7 @@ func (s *Store) LatestMetrics(ctx context.Context) ([]domain.MetricRecord, error if err != nil { return nil, fmt.Errorf("latest metrics: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() out, err := scanMetricRecords(rows) if err != nil { @@ -403,7 +403,7 @@ func (s *Store) ListChecksByRun(ctx context.Context, runID string) ([]domain.Che if err != nil { return nil, fmt.Errorf("list checks for run %s: %w", runID, err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.Check for rows.Next() { @@ -476,7 +476,7 @@ func (s *Store) ListMetrics(ctx context.Context, f services.MetricsFilter) ([]do if err != nil { return nil, fmt.Errorf("list metrics: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() out, err := scanMetricRecords(rows) if err != nil { @@ -498,7 +498,7 @@ func (s *Store) ListMetricsByRun(ctx context.Context, runID string) ([]domain.Me if err != nil { return nil, fmt.Errorf("list metrics for run %s: %w", runID, err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.MetricSample for rows.Next() { @@ -563,7 +563,7 @@ func (s *Store) ListPings(ctx context.Context, f services.PingFilter) ([]domain. if err != nil { return nil, fmt.Errorf("list pings: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() out, err := scanPingRecords(rows) if err != nil { @@ -585,7 +585,7 @@ func (s *Store) ListPingsByRun(ctx context.Context, runID string) ([]domain.Ping if err != nil { return nil, fmt.Errorf("list pings for run %s: %w", runID, err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.PingResult for rows.Next() { @@ -624,7 +624,7 @@ func (s *Store) ListRuns(ctx context.Context, limit int) ([]domain.Run, error) { if err != nil { return nil, fmt.Errorf("list runs: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.Run for rows.Next() { @@ -653,7 +653,7 @@ func (s *Store) ListUnsentOutboxMessages(ctx context.Context) ([]domain.OutboxMe if err != nil { return nil, fmt.Errorf("list unsent outbox messages: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.OutboxMessage for rows.Next() { @@ -795,7 +795,7 @@ func (s *Store) OverviewMetrics(ctx context.Context, since time.Time, bucket tim if err != nil { return nil, fmt.Errorf("overview metrics: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.MetricSeries var cur *domain.MetricSeries @@ -863,7 +863,7 @@ func (s *Store) OverviewPings(ctx context.Context, since time.Time, bucket time. if err != nil { return nil, fmt.Errorf("overview pings: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.PingSeries var cur *domain.PingSeries @@ -921,7 +921,7 @@ func (s *Store) PingSamples(ctx context.Context, since time.Time) ([]domain.Ping if err != nil { return nil, fmt.Errorf("ping samples: %w", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() out, err := scanPingRecords(rows) if err != nil { @@ -1005,7 +1005,7 @@ func (s *Store) RecentRuns(ctx context.Context, beforeID string, limit int) ([]d if err != nil { return nil, fmt.Errorf("recent runs before %s: %w", beforeID, err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var out []domain.RunSummary for rows.Next() { diff --git a/infrastructure/store_test.go b/infrastructure/store_test.go index 802706e..adddd8d 100644 --- a/infrastructure/store_test.go +++ b/infrastructure/store_test.go @@ -1405,7 +1405,7 @@ func TestStore_ListMetrics(t *testing.T) { if err != nil { t.Fatalf("EXPLAIN QUERY PLAN: %v", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var plan strings.Builder for rows.Next() { @@ -1596,7 +1596,7 @@ func TestStore_ListPings(t *testing.T) { if err != nil { t.Fatalf("EXPLAIN QUERY PLAN: %v", err) } - defer rows.Close() + defer func() { _ = rows.Close() }() var plan strings.Builder for rows.Next() { diff --git a/plans/plan_review_20260718.txt b/plans/plan_review_20260718.txt new file mode 100644 index 0000000..c6091da --- /dev/null +++ b/plans/plan_review_20260718.txt @@ -0,0 +1,28 @@ +Все задачи надо прочитать и спланировать планы по каждой таске. Планы можно сгруппировать так, чтобы можно было запустить их параллельно, если такая возможность присутствует. +NOTE: Тут в задачах, есть ключевые моменты, которые важны для любого моего проекта. Так что добавь в CLAUDE правило что надо вычленять мои паттерны работы и требования к коду и записывать в rules нового агента (агент глобальный уже должен быть создан надо расширить). То есть тебе нужно создать нового суб агента которые будет хранить список требований к коду мы будем его запускать в ручную по требованию и проверять кода на этим ключевые моменты. + + + +"Ower" замечания: + +- проект должен быть стиле DDD, можешь глянуть структуру проекта ~/projects/developments/com_lingocrm_api. +Там я старался придерживаться концепций DDD, тут я бы тоже все положил в internal пакет а не держал все к корне. + + +- логирование надо делать через мою библиотеку - loginjector +запись в файл с ротированием логов за 7 дней думаю будет нормально + + +- infrastructure/testdata для кого это создано? если для тестов то надо перенести данные в тесты. +тесты не должны портить структуру проекта. если это проблема давай сделаем пакет ./test для глобальных тестов. +там будем собирать итоговые решения скажем сервисы или репозитории и тестировать и работу + + +- infrastructure/uuid.go - это страное расположение, давай сделаем tools и туда перенесем подобные решения. +а лучшее вообще удалить и заменить на готовую библиотеку github.com/twinj/uuid или гугловую. + + +- infrastructure - давай разделим на подгруппы, скажем тут много связанно с "os" или "system" + + +- gateway/httpapi/web давай вынесем это в root проекта я думаю это будет более канонично. \ No newline at end of file