feat(repository): refactor query/mutation ports with capability-safe
interfaces - refactor: split UserRepository into AuthUserRepository and AdminUserRepository capabilities - refactor: split SessionRepository into AuthSessionRepository and repository-owned CLI/admin methods - refactor: replace generic Repository Update/Delete with operation-specific params and ownership predicates - refactor: replace CredentialRepository generic CRUD with passkey-specific methods - refactor: replace FileRepository generic Create/Update/Delete with UploadedFileParams, DirectoryParams, and owned soft-delete - refactor: remove repository fields from WebApp struct; repositories are now composition-time wiring only - feat: add domain error kinds ErrParentNotFound, ErrParentNotDir, ErrDirectoryNotEmpty, ErrInvalidMove - feat: add CredentialTypeAppPasskey constant - feat: add testutil.SetUserAdmin for test fixture setup that bypasses production service ports - test: add architecture test banning GORM Save in repository package - test: add capability interface contract tests ensuring each service receives the minimal interface - test: add blockingStorage helper for concurrent promotion tests - test: add preserved DSN parameter test for sqliteImmediateDSN - docs: update architecture decisions with repository write rules and capability separation - docs: update roadmap to clarify atomic single-use refresh sessions - docs: add -race test target to development docs
This commit is contained in:
+19
-35
@@ -17,15 +17,11 @@ type WebApp struct {
|
||||
Config *config.Config
|
||||
Version string
|
||||
|
||||
DB *gorm.DB
|
||||
UserRepo repository.UserRepository
|
||||
SessionRepo repository.SessionRepository
|
||||
FileRepo repository.FileRepository
|
||||
CredentialRepo repository.CredentialRepository
|
||||
AuthService *service.AuthService
|
||||
AdminService *service.AdminService
|
||||
FileService *service.FileService
|
||||
Storage storage.StorageBackend
|
||||
DB *gorm.DB
|
||||
AuthService *service.AuthService
|
||||
AdminService *service.AdminService
|
||||
FileService *service.FileService
|
||||
Storage storage.StorageBackend
|
||||
}
|
||||
|
||||
// Bootstrap creates a fully initialized WebApp from config.
|
||||
@@ -62,43 +58,31 @@ func Bootstrap(cfg *config.Config) (*WebApp, error) {
|
||||
adminService := service.NewAdminService(userRepo)
|
||||
|
||||
return &WebApp{
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
UserRepo: userRepo,
|
||||
SessionRepo: sessionRepo,
|
||||
FileRepo: fileRepo,
|
||||
CredentialRepo: credentialRepo,
|
||||
AuthService: authService,
|
||||
AdminService: adminService,
|
||||
FileService: fileService,
|
||||
Storage: store,
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
AuthService: authService,
|
||||
AdminService: adminService,
|
||||
FileService: fileService,
|
||||
Storage: store,
|
||||
}, 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,
|
||||
credentialRepo repository.CredentialRepository,
|
||||
authService *service.AuthService,
|
||||
adminService *service.AdminService,
|
||||
fileService *service.FileService,
|
||||
store storage.StorageBackend,
|
||||
) *WebApp {
|
||||
return &WebApp{
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
UserRepo: userRepo,
|
||||
SessionRepo: sessionRepo,
|
||||
FileRepo: fileRepo,
|
||||
CredentialRepo: credentialRepo,
|
||||
AuthService: authService,
|
||||
AdminService: adminService,
|
||||
FileService: fileService,
|
||||
Storage: store,
|
||||
Config: cfg,
|
||||
Version: AppVersion,
|
||||
DB: db,
|
||||
AuthService: authService,
|
||||
AdminService: adminService,
|
||||
FileService: fileService,
|
||||
Storage: store,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func TestNewWebApp(t *testing.T) {
|
||||
cfg := &config.Config{}
|
||||
|
||||
webApp := NewWebApp(cfg, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
webApp := NewWebApp(cfg, nil, nil, nil, nil, nil)
|
||||
|
||||
if webApp.Config != cfg {
|
||||
t.Fatal("Config was not assigned")
|
||||
@@ -20,7 +20,7 @@ func TestNewWebApp(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCloseNilDB(t *testing.T) {
|
||||
webApp := NewWebApp(&config.Config{}, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
webApp := NewWebApp(&config.Config{}, nil, 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