Documentation
¶
Overview ¶
Package tasks provides task management functionality for the corporate issue tracker.
This module implements the core task lifecycle management including:
- Task creation with per-project auto-incrementing numbers
- Status and priority management (matching BitBucket enums)
- Assignment and due date tracking
- Soft delete support for audit trails
- Filtering and sorting for dashboards
The module follows clean architecture principles with clear separation between:
- Domain layer (domain.go): Business entities and validation
- Data layer (models.go, repository.go): Persistence and queries
- Service layer (service.go): Business logic and coordination
Integration:
- Depends on projects.Service for project existence validation
- Uses bun.DB for MySQL persistence
- Provides tasks.Service for HTTP handlers
Example usage:
// In your FX application setup:
app := fx.New(
tasks.Module(),
fx.Invoke(func(service *tasks.Service) {
// Use the service
}),
)
The module is production-ready and follows the established patterns from the internal/example, internal/users, and internal/projects modules.
Index ¶
- Constants
- Variables
- func Module() fx.Option
- type Config
- type Kind
- type Pagination
- type Priority
- type Repository
- func (r *Repository) Create(ctx context.Context, input TaskInput) (*Task, error)
- func (r *Repository) Delete(ctx context.Context, id int64) error
- func (r *Repository) Exists(ctx context.Context, id int64) (bool, error)
- func (r *Repository) GetByID(ctx context.Context, id int64) (*Task, error)
- func (r *Repository) Import(ctx context.Context, input Task) (*Task, error)
- func (r *Repository) List(ctx context.Context, filter TaskFilter, sort string, pagination *Pagination) ([]Task, int, error)
- func (r *Repository) Update(ctx context.Context, id int64, update TaskUpdate) error
- type Service
- func (s *Service) Create(ctx context.Context, input TaskInput) (*Task, error)
- func (s *Service) Delete(ctx context.Context, id int64) error
- func (s *Service) Exists(ctx context.Context, id int64) (bool, error)
- func (s *Service) GetByID(ctx context.Context, id int64) (*Task, error)
- func (s *Service) Import(ctx context.Context, input Task) (*Task, error)
- func (s *Service) List(ctx context.Context, filter TaskFilter, sort string, pagination *Pagination) ([]Task, int, error)
- func (s *Service) Update(ctx context.Context, id int64, update TaskUpdate) (*Task, error)
- type Status
- type Task
- type TaskFilter
- type TaskInput
- type TaskUpdate
Constants ¶
const ( DefaultLimit = 20 MaxLimit = 100 )
const MaxTitleLength = 255
Variables ¶
var ( // ErrNotFound indicates the requested task does not exist. ErrNotFound = errors.New("task not found") // ErrValidationFailed indicates input validation failed. ErrValidationFailed = errors.New("validation failed") // ErrProjectNotFound indicates the specified project does not exist. ErrProjectNotFound = errors.New("project not found") )
Module-specific error definitions. These errors can be checked using errors.Is(err, ErrXXX).
Functions ¶
Types ¶
type Config ¶
type Config struct {
}
Config holds configuration for the tasks module.
Currently, this module does not require any specific configuration. The struct is provided for consistency with other modules and future extensibility (e.g., default limits, feature flags).
type Kind ¶
type Kind string
Kind represents the type of task, matching BitBucket values.
const ( KindBug Kind = "Bug" KindEnhancement Kind = "Enhancement" KindTask Kind = "Task" KindProposal Kind = "Proposal" )
Kind constants.
type Pagination ¶
type Pagination = db.Pagination[*pagination]
func NewPagination ¶
func NewPagination(limit, offset int) *Pagination
type Priority ¶
type Priority string
Priority represents task priority levels, matching BitBucket values.
type Repository ¶
type Repository struct {
// contains filtered or unexported fields
}
Repository handles data access operations for tasks.
func NewRepository ¶
func NewRepository(db *bun.DB) *Repository
NewRepository creates a new Repository instance with the given database connection.
func (*Repository) Create ¶
Create inserts a new task with an auto-generated per-project number. The number generation happens within a transaction to ensure uniqueness.
func (*Repository) Delete ¶
func (r *Repository) Delete(ctx context.Context, id int64) error
Delete soft-deletes a task.
func (*Repository) Import ¶
Import creates a task with explicit number, timestamps, and kind for import. This bypasses auto-number generation and allows setting custom CreatedAt/UpdatedAt.
func (*Repository) List ¶
func (r *Repository) List( ctx context.Context, filter TaskFilter, sort string, pagination *Pagination, ) ([]Task, int, error)
List retrieves a paginated list of tasks with optional filtering and sorting. The filter parameter controls which tasks are returned. Empty fields mean no filter. The sort parameter is a field name, optionally prefixed with "-" for descending order.
func (*Repository) Update ¶
func (r *Repository) Update(ctx context.Context, id int64, update TaskUpdate) error
Update modifies an existing task with the provided update data. Only non-nil fields in the TaskUpdate struct will be changed.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service implements the business logic for task management.
func NewService ¶
NewService creates a new Service instance with the given dependencies.
func (*Service) Import ¶
Import creates a task with explicit number, timestamps, and kind for import. Bypasses auto-number generation and allows preserving original metadata.
type Status ¶
type Status string
Status represents task lifecycle states, matching BitBucket values.
const ( StatusNew Status = "New" StatusOpen Status = "Open" StatusInProgress Status = "In Progress" StatusResolved Status = "Resolved" StatusClosed Status = "Closed" StatusReopened Status = "Reopened" StatusInvalid Status = "Invalid" StatusDuplicate Status = "Duplicate" StatusWontfix Status = "Wontfix" StatusOnHold Status = "On Hold" )
Status constants.
type Task ¶
type Task struct {
ID int64
ProjectSlug string
Number int
Title string
Description string
Priority Priority
Status Status
Kind Kind
AuthorID int64
AssigneeID *int64
DueDate *string
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
Task represents a complete task entity with all fields.
type TaskFilter ¶
type TaskFilter struct {
ProjectSlug *string
AuthorID *int64
AssigneeID *int64
Statuses []Status
Priorities []Priority
DueFrom *time.Time
DueTo *time.Time
CreatedFrom *time.Time
CreatedTo *time.Time
IncludeDeleted bool
// Extended
UserID *int64 // AuthorID or AssigneeID
}
TaskFilter contains filtering criteria for querying tasks.
type TaskInput ¶
type TaskInput struct {
ProjectSlug string
Title string
Description string
Priority Priority
Status Status
Kind Kind
AuthorID int64
AssigneeID *int64
DueDate *string // YYYY-MM-DD format
}
TaskInput contains the data required to create a new task.
type TaskUpdate ¶
type TaskUpdate struct {
Title *string
Description *string
Priority *Priority
Status *Status
Kind *Kind
AssigneeID *int64 // nil=unchanged, 0=set to NULL, value=set to ID
DueDate *string // nil=unchanged, ""=set to NULL, value=set date string
}
TaskUpdate represents the data that can be updated for a task. All fields are optional. Pointers are used to distinguish between "set to zero value" and "not provided".
func (TaskUpdate) IsEmpty ¶
func (u TaskUpdate) IsEmpty() bool
IsEmpty returns true if no update fields are set.
func (TaskUpdate) Validate ¶
func (u TaskUpdate) Validate() error