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:
2026-04-28 13:32:33 +08:00
parent f57f6c8f35
commit 901a769ee7
24 changed files with 1232 additions and 24 deletions

10
internal/model/errors.go Normal file
View File

@@ -0,0 +1,10 @@
package model
import "errors"
var (
ErrNotFound = errors.New("resource not found")
ErrDuplicate = errors.New("resource already exists")
ErrUnauthorized = errors.New("unauthorized")
ErrForbidden = errors.New("forbidden")
)

19
internal/model/file.go Normal file
View File

@@ -0,0 +1,19 @@
package model
import (
"time"
)
// File represents a file or directory entry in the virtual filesystem.
type File struct {
ID string `gorm:"primaryKey;type:varchar(36)" json:"id"`
UserID string `gorm:"index;type:varchar(36);not null" json:"user_id"`
ParentID *string `gorm:"index;type:varchar(36)" json:"parent_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Size int64 `gorm:"default:0" json:"size"`
MimeType string `gorm:"type:varchar(127)" json:"mime_type"`
StoragePath string `gorm:"type:varchar(512)" json:"storage_path"`
IsDir bool `gorm:"default:false" json:"is_dir"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

14
internal/model/session.go Normal file
View File

@@ -0,0 +1,14 @@
package model
import (
"time"
)
// Session stores a refresh token for a user session.
type Session struct {
ID string `gorm:"primaryKey;type:varchar(36)" json:"id"`
UserID string `gorm:"index;type:varchar(36);not null" json:"user_id"`
TokenHash string `gorm:"uniqueIndex;type:varchar(255);not null" json:"-"`
ExpiresAt time.Time `gorm:"not null" json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}

16
internal/model/user.go Normal file
View File

@@ -0,0 +1,16 @@
package model
import (
"time"
)
// User represents a registered account.
type User struct {
ID string `gorm:"primaryKey;type:varchar(36)" json:"id"`
Username string `gorm:"uniqueIndex;type:varchar(64);not null" json:"username"`
Email string `gorm:"uniqueIndex;type:varchar(255);not null" json:"email"`
PasswordHash string `gorm:"type:varchar(255);not null" json:"-"`
IsAdmin bool `gorm:"default:false" json:"is_admin"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}