# Types & Data Structures ## Go Types ### GlobalConfig Глобальный конфиг, хранится в `~/.config/aevs/config.yaml`. ```go package config // GlobalConfig represents ~/.config/aevs/config.yaml type GlobalConfig struct { Storage StorageConfig `yaml:"storage"` } // StorageConfig holds S3-compatible storage credentials type StorageConfig struct { Type string `yaml:"type"` // storage type: "s3" Endpoint string `yaml:"endpoint"` // S3 endpoint URL Region string `yaml:"region"` // AWS region (optional, default: us-east-1) Bucket string `yaml:"bucket"` // S3 bucket name AccessKey string `yaml:"access_key"` // AWS Access Key ID SecretKey string `yaml:"secret_key"` // AWS Secret Access Key } ``` **Валидация:** - `Type` — должен быть `"s3"` (в будущем: `"gcs"`, `"azure"`) - `Endpoint` — валидный URL - `Bucket` — непустая строка, валидное имя S3 bucket - `AccessKey`, `SecretKey` — непустые строки --- ### ProjectConfig Локальный конфиг проекта, хранится в `./aevs.yaml`. ```go package config // ProjectConfig represents ./aevs.yaml type ProjectConfig struct { Project string `yaml:"project"` // unique project identifier Files []string `yaml:"files"` // list of file paths to sync } ``` **Валидация:** - `Project` — непустая строка, только `[a-z0-9_-]` - `Files` — непустой массив, каждый элемент — валидный относительный путь --- ### Metadata Метаданные проекта, хранятся в storage как `{project}/metadata.json`. ```go package types import "time" // Metadata stored alongside the archive in S3 type Metadata struct { UpdatedAt time.Time `json:"updated_at"` // last push timestamp Files []string `json:"files"` // list of files in archive Machine string `json:"machine"` // hostname of machine that pushed SizeBytes int64 `json:"size_bytes"` // archive size in bytes } ``` --- ### ProjectInfo Информация о проекте для отображения в `aevs list`. ```go package types import "time" // ProjectInfo represents a project in storage (for listing) type ProjectInfo struct { Name string `json:"project"` FileCount int `json:"files"` UpdatedAt time.Time `json:"updated_at"` SizeBytes int64 `json:"size_bytes"` } ``` --- ### FileStatus Статус файла для `aevs status`. ```go package types // FileStatus represents the sync status of a single file type FileStatus struct { Path string `json:"path"` LocalSize int64 `json:"local_size"` // -1 if missing RemoteSize int64 `json:"remote_size"` // -1 if missing Status SyncStatus `json:"status"` LocalHash string `json:"local_hash"` // MD5 or SHA256 RemoteHash string `json:"remote_hash"` } // SyncStatus represents the synchronization state type SyncStatus string const ( StatusUpToDate SyncStatus = "up_to_date" StatusLocalModified SyncStatus = "local_modified" StatusRemoteModified SyncStatus = "remote_modified" StatusMissingLocal SyncStatus = "missing_local" StatusLocalOnly SyncStatus = "local_only" StatusConflict SyncStatus = "conflict" // both modified ) ``` --- ## Constants ```go package config const ( // DefaultConfigDir is the directory for global config DefaultConfigDir = ".config/aevs" // DefaultGlobalConfigFile is the global config filename DefaultGlobalConfigFile = "config.yaml" // DefaultProjectConfigFile is the project config filename DefaultProjectConfigFile = "aevs.yaml" // DefaultStorageType is the default storage backend DefaultStorageType = "s3" // DefaultRegion is the default AWS region DefaultRegion = "us-east-1" // DefaultEndpoint is the default S3 endpoint DefaultEndpoint = "https://s3.amazonaws.com" // ArchiveFileName is the name of the archive in storage ArchiveFileName = "envs.tar.gz" // MetadataFileName is the name of the metadata file in storage MetadataFileName = "metadata.json" ) ``` --- ## File Patterns ```go package scanner // IncludePatterns are glob patterns for env files var IncludePatterns = []string{ ".env", ".env.*", "*.env", } // ExcludePatterns are glob patterns to exclude var ExcludePatterns = []string{ ".env.example", ".env.sample", ".env.template", } // ExcludeDirs are directories to skip when scanning var ExcludeDirs = []string{ "node_modules", ".git", "vendor", "venv", ".venv", "__pycache__", ".idea", ".vscode", "dist", "build", } ``` --- ## Interfaces ### Storage ```go package storage import ( "context" "io" "aevs/types" ) // Storage interface for cloud storage operations type Storage interface { // Upload uploads data to the specified key Upload(ctx context.Context, key string, data io.Reader, size int64) error // Download downloads data from the specified key Download(ctx context.Context, key string) (io.ReadCloser, error) // Delete deletes the specified key Delete(ctx context.Context, key string) error // Exists checks if the key exists Exists(ctx context.Context, key string) (bool, error) // List lists all keys with the given prefix List(ctx context.Context, prefix string) ([]string, error) // ListProjects returns all project directories ListProjects(ctx context.Context) ([]string, error) } ``` ### Scanner ```go package scanner // Scanner interface for finding env files type Scanner interface { // Scan scans the directory for env files Scan(rootDir string) ([]string, error) } ``` ### Archiver ```go package archiver import "io" // Archiver interface for creating/extracting archives type Archiver interface { // Create creates a tar.gz archive from the given files Create(files []string, rootDir string) (io.Reader, int64, error) // Extract extracts a tar.gz archive to the given directory Extract(archive io.Reader, destDir string) ([]string, error) // List lists files in the archive without extracting List(archive io.Reader) ([]string, error) } ``` --- ## Error Types ```go package errors import "errors" var ( // Config errors ErrNoGlobalConfig = errors.New("no storage configured; run 'aevs config' first") ErrNoProjectConfig = errors.New("no aevs.yaml found; run 'aevs init' first") ErrConfigExists = errors.New("aevs.yaml already exists; use --force to overwrite") ErrInvalidProject = errors.New("invalid project name; use only a-z, 0-9, -, _") // Storage errors ErrProjectNotFound = errors.New("project not found in storage") ErrAccessDenied = errors.New("access denied; check your credentials") ErrBucketNotFound = errors.New("bucket not found") // File errors ErrFileNotFound = errors.New("file not found") ErrNoEnvFiles = errors.New("no env files found") ) ```