向宁 3a18ca0579 feat: add directory structure and file sharing support
- PostgreSQL metadata overlay layer on top of existing S3 storage
- 3 new tables: folders, files, share_links
- Folder CRUD: create, get with children, tree, rename, delete (cascade)
- File operations: upload to folder, move between folders
- Share links: create with optional password/expiry/download limit, public access
- S3 compensation on PG write failure
- Existing 14 endpoints untouched
2026-05-20 20:26:19 +08:00

61 lines
1.6 KiB
Go

package common
import (
"fmt"
"os"
)
type Config struct {
RustFSEndpoint string
RustFSAccessKeyID string
RustFSSecretAccessKey string
RustFSRegion string
ServerPort string
AuthAPIKey string
RequestTimeout int
GRPCAuthAddr string
OTelEndpoint string
DatabaseURL string
}
func LoadConfig() *Config {
return &Config{
RustFSEndpoint: getEnv("RUSTFS_ENDPOINT_URL", "http://192.168.1.154:9000"),
RustFSAccessKeyID: getEnv("RUSTFS_ACCESS_KEY_ID", ""),
RustFSSecretAccessKey: getEnv("RUSTFS_SECRET_ACCESS_KEY", ""),
RustFSRegion: getEnv("RUSTFS_REGION", "us-east-1"),
ServerPort: getEnv("SERVER_PORT", "8080"),
AuthAPIKey: getEnv("AUTH_API_KEY", ""),
RequestTimeout: 30,
GRPCAuthAddr: getEnv("GRPC_AUTH_ADDR", ""),
OTelEndpoint: getEnv("OTEL_ENDPOINT", "192.168.1.154:4316"),
DatabaseURL: getEnv("DATABASE_URL", ""),
}
}
func (c *Config) Validate() error {
if c.AuthAPIKey == "" && c.GRPCAuthAddr == "" {
return fmt.Errorf("AUTH_API_KEY or GRPC_AUTH_ADDR is required")
}
if c.RustFSAccessKeyID == "" {
return fmt.Errorf("RUSTFS_ACCESS_KEY_ID is required")
}
if c.RustFSSecretAccessKey == "" {
return fmt.Errorf("RUSTFS_SECRET_ACCESS_KEY is required")
}
if c.RustFSEndpoint == "" {
return fmt.Errorf("RUSTFS_ENDPOINT_URL is required")
}
if c.DatabaseURL == "" {
return fmt.Errorf("DATABASE_URL is required")
}
return nil
}
func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}