Complete foundational data layer with repository implementation
- Add GORM dependencies for SQLite and PostgreSQL - Create domain models (User, Session, File) with common errors - Implement repository interfaces and database layer with migrations - Update WebApp to bootstrap with database and repositories - Add comprehensive unit tests for repository methods - Update config structure to support multiple database drivers - Extend AGENTS.md with debugging principles and dependency rules
This commit is contained in:
@@ -1,19 +1,67 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/dhao2001/mygo/internal/config"
|
||||
"github.com/dhao2001/mygo/internal/repository"
|
||||
)
|
||||
|
||||
// WebApp contains application-wide runtime dependencies and metadata.
|
||||
type WebApp struct {
|
||||
Config *config.Config
|
||||
Version string
|
||||
|
||||
DB *gorm.DB
|
||||
UserRepo repository.UserRepository
|
||||
SessionRepo repository.SessionRepository
|
||||
FileRepo repository.FileRepository
|
||||
}
|
||||
|
||||
// NewWebApp creates the application dependency container for the HTTP server.
|
||||
func NewWebApp(cfg *config.Config) *WebApp {
|
||||
// Bootstrap creates a fully initialized WebApp from config.
|
||||
// It opens the database, runs migrations, and wires all repositories.
|
||||
func Bootstrap(cfg *config.Config) (*WebApp, error) {
|
||||
db, err := repository.Open(cfg.Database)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open database: %w", err)
|
||||
}
|
||||
|
||||
if err := repository.AutoMigrate(db); err != nil {
|
||||
return nil, fmt.Errorf("migrate database: %w", err)
|
||||
}
|
||||
|
||||
return &WebApp{
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
UserRepo: repository.NewUserRepository(db),
|
||||
SessionRepo: repository.NewSessionRepository(db),
|
||||
FileRepo: repository.NewFileRepository(db),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewWebApp creates a WebApp with pre-built dependencies (useful for testing).
|
||||
func NewWebApp(cfg *config.Config, db *gorm.DB, userRepo repository.UserRepository, sessionRepo repository.SessionRepository, fileRepo repository.FileRepository) *WebApp {
|
||||
return &WebApp{
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
UserRepo: userRepo,
|
||||
SessionRepo: sessionRepo,
|
||||
FileRepo: fileRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// Close releases resources held by the application (e.g., database connections).
|
||||
func (w *WebApp) Close() error {
|
||||
if w.DB == nil {
|
||||
return nil
|
||||
}
|
||||
sqlDB, err := w.DB.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqlDB.Close()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func TestNewWebApp(t *testing.T) {
|
||||
cfg := &config.Config{}
|
||||
|
||||
webApp := NewWebApp(cfg)
|
||||
webApp := NewWebApp(cfg, nil, nil, nil, nil)
|
||||
|
||||
if webApp.Config != cfg {
|
||||
t.Fatal("Config was not assigned")
|
||||
@@ -18,3 +18,10 @@ func TestNewWebApp(t *testing.T) {
|
||||
t.Errorf("Version = %q, want %q", webApp.Version, AppVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloseNilDB(t *testing.T) {
|
||||
webApp := NewWebApp(&config.Config{}, nil, nil, nil, nil)
|
||||
if err := webApp.Close(); err != nil {
|
||||
t.Errorf("Close with nil DB should not error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user