refactor: разделение кода на пакеты и улучшение архитектуры

- Создана новая структура проекта с разделением на пакеты
- Добавлены интерфейсы для всех сервисов (Git, Quartz, Files, Build)
- Реализован Dependency Injection для сервисов
- Добавлены middleware для логирования, Request ID и Response Time
- Создан пакет конфигурации с валидацией
- Улучшено логирование через интерфейс
- Добавлены обработчики HTTP в отдельных пакетах
- Создана структура для тестирования
- Добавлены конфигурационные файлы и документация
This commit is contained in:
Andrey Epifancev
2025-08-11 19:45:54 +04:00
parent 1b340362be
commit 04cea69d6e
16 changed files with 1293 additions and 0 deletions

101
internal/config/config.go Normal file
View File

@@ -0,0 +1,101 @@
package config
import (
"errors"
"os"
"strconv"
)
// Config содержит все настройки приложения
type Config struct {
Server ServerConfig `yaml:"server"`
Paths PathsConfig `yaml:"paths"`
Git GitConfig `yaml:"git"`
}
// ServerConfig содержит настройки HTTP сервера
type ServerConfig struct {
Port string `yaml:"port"`
Timeout int `yaml:"timeout"` // в секундах
}
// PathsConfig содержит пути к директориям
type PathsConfig struct {
Obsidian string `yaml:"obsidian"`
Quartz string `yaml:"quartz"`
Public string `yaml:"public"`
}
// GitConfig содержит настройки Git
type GitConfig struct {
Branch string `yaml:"branch"`
Remote string `yaml:"remote"`
}
// Load загружает конфигурацию из переменных окружения
func Load() *Config {
config := &Config{
Server: ServerConfig{
Port: getEnv("PORT", "3000"),
Timeout: getEnvAsInt("SERVER_TIMEOUT", 30),
},
Paths: PathsConfig{
Obsidian: getEnv("OBSIDIAN_PATH", "/obsidian"),
Quartz: getEnv("QUARTZ_PATH", "/quartz"),
Public: getEnv("PUBLIC_PATH", "/public"),
},
Git: GitConfig{
Branch: getEnv("GIT_BRANCH", "main"),
Remote: getEnv("GIT_REMOTE", "origin"),
},
}
return config
}
// Validate проверяет корректность конфигурации
func (c *Config) Validate() error {
if c.Server.Port == "" {
return errors.New("server port is required")
}
if c.Paths.Obsidian == "" {
return errors.New("obsidian path is required")
}
if c.Paths.Quartz == "" {
return errors.New("quartz path is required")
}
if c.Paths.Public == "" {
return errors.New("public path is required")
}
if c.Git.Branch == "" {
return errors.New("git branch is required")
}
if c.Git.Remote == "" {
return errors.New("git remote is required")
}
return nil
}
// getEnv получает значение переменной окружения или возвращает значение по умолчанию
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
// getEnvAsInt получает значение переменной окружения как int или возвращает значение по умолчанию
func getEnvAsInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}