This commit is contained in:
60
internal/domain/entities/counter.go
Normal file
60
internal/domain/entities/counter.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package entities
|
||||
|
||||
import "time"
|
||||
|
||||
// Counter represents a counter entity
|
||||
type Counter struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
UserID int `json:"user_id" db:"user_id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
Description string `json:"description" db:"description"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
// CounterEntry represents a single increment/decrement entry
|
||||
type CounterEntry struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
CounterID int `json:"counter_id" db:"counter_id"`
|
||||
Value int `json:"value" db:"value"` // +1 for increment, -1 for decrement
|
||||
Date time.Time `json:"date" db:"date"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
}
|
||||
|
||||
// CounterWithStats represents a counter with aggregated statistics
|
||||
type CounterWithStats struct {
|
||||
Counter
|
||||
TotalValue int `json:"total_value"`
|
||||
TodayValue int `json:"today_value"`
|
||||
WeekValue int `json:"week_value"`
|
||||
MonthValue int `json:"month_value"`
|
||||
EntryCount int `json:"entry_count"`
|
||||
}
|
||||
|
||||
// DailyStat represents daily statistics for a counter
|
||||
type DailyStat struct {
|
||||
Date time.Time `json:"date"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// Validate validates counter data
|
||||
func (c *Counter) Validate() error {
|
||||
if c.Name == "" {
|
||||
return ErrInvalidCounterName
|
||||
}
|
||||
if c.UserID <= 0 {
|
||||
return ErrInvalidUserID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates counter entry data
|
||||
func (ce *CounterEntry) Validate() error {
|
||||
if ce.CounterID <= 0 {
|
||||
return ErrInvalidCounterID
|
||||
}
|
||||
if ce.Value == 0 {
|
||||
return ErrInvalidEntryValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
19
internal/domain/entities/errors.go
Normal file
19
internal/domain/entities/errors.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package entities
|
||||
|
||||
import "errors"
|
||||
|
||||
// Domain errors
|
||||
var (
|
||||
ErrInvalidUsername = errors.New("username is required")
|
||||
ErrInvalidEmail = errors.New("email is required")
|
||||
ErrInvalidPassword = errors.New("password is required")
|
||||
ErrInvalidCounterName = errors.New("counter name is required")
|
||||
ErrInvalidUserID = errors.New("invalid user ID")
|
||||
ErrInvalidCounterID = errors.New("invalid counter ID")
|
||||
ErrInvalidEntryValue = errors.New("entry value cannot be zero")
|
||||
ErrUserNotFound = errors.New("user not found")
|
||||
ErrCounterNotFound = errors.New("counter not found")
|
||||
ErrCounterEntryNotFound = errors.New("counter entry not found")
|
||||
ErrUserAlreadyExists = errors.New("user already exists")
|
||||
ErrInvalidCredentials = errors.New("invalid credentials")
|
||||
)
|
||||
32
internal/domain/entities/user.go
Normal file
32
internal/domain/entities/user.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package entities
|
||||
|
||||
import "time"
|
||||
|
||||
// User represents a registered user
|
||||
type User struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
Username string `json:"username" db:"username"`
|
||||
Email string `json:"email" db:"email"`
|
||||
Password string `json:"-" db:"password"` // Hidden from JSON
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
// Validate validates user data
|
||||
func (u *User) Validate() error {
|
||||
if u.Username == "" {
|
||||
return ErrInvalidUsername
|
||||
}
|
||||
if u.Email == "" {
|
||||
return ErrInvalidEmail
|
||||
}
|
||||
if u.Password == "" {
|
||||
return ErrInvalidPassword
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearPassword removes password from user for safe serialization
|
||||
func (u *User) ClearPassword() {
|
||||
u.Password = ""
|
||||
}
|
||||
20
internal/domain/repositories/counter_repository.go
Normal file
20
internal/domain/repositories/counter_repository.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"counter/internal/domain/entities"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CounterRepository defines the interface for counter data operations
|
||||
type CounterRepository interface {
|
||||
Create(ctx context.Context, counter *entities.Counter) error
|
||||
FindByID(ctx context.Context, id, userID int) (*entities.CounterWithStats, error)
|
||||
FindByUserID(ctx context.Context, userID int, search string) ([]*entities.CounterWithStats, error)
|
||||
Update(ctx context.Context, counter *entities.Counter) error
|
||||
Delete(ctx context.Context, id, userID int) error
|
||||
AddEntry(ctx context.Context, entry *entities.CounterEntry) error
|
||||
GetEntries(ctx context.Context, counterID, userID int, startDate, endDate *time.Time) ([]*entities.CounterEntry, error)
|
||||
GetDailyStats(ctx context.Context, counterID, userID int, days int) ([]*entities.DailyStat, error)
|
||||
Exists(ctx context.Context, id, userID int) (bool, error)
|
||||
}
|
||||
16
internal/domain/repositories/user_repository.go
Normal file
16
internal/domain/repositories/user_repository.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"counter/internal/domain/entities"
|
||||
)
|
||||
|
||||
// UserRepository defines the interface for user data operations
|
||||
type UserRepository interface {
|
||||
Create(ctx context.Context, user *entities.User) error
|
||||
FindByID(ctx context.Context, id int) (*entities.User, error)
|
||||
FindByUsername(ctx context.Context, username string) (*entities.User, error)
|
||||
FindByEmail(ctx context.Context, email string) (*entities.User, error)
|
||||
Update(ctx context.Context, user *entities.User) error
|
||||
Delete(ctx context.Context, id int) error
|
||||
}
|
||||
Reference in New Issue
Block a user