tasks

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

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

View Source
const (
	DefaultLimit = 20
	MaxLimit     = 100
)
View Source
const MaxTitleLength = 255

Variables

View Source
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

func Module

func Module() fx.Option

Module creates and returns an FX module for the tasks package.

The module provides:

  • tasks.Service (public) - for use by HTTP handlers and other modules
  • tasks.Repository (private) - internal data access layer
  • Named logger "tasks" for structured logging

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.

func (Kind) IsValid

func (k Kind) IsValid() bool

IsValid checks if the kind value is one of the allowed constants.

func (Kind) String

func (k Kind) String() string

String returns the string representation of Kind.

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.

const (
	PriorityTrivial  Priority = "Trivial"
	PriorityMinor    Priority = "Minor"
	PriorityMajor    Priority = "Major"
	PriorityCritical Priority = "Critical"
	PriorityBlocker  Priority = "Blocker"
)

Priority constants.

func (Priority) IsValid

func (p Priority) IsValid() bool

IsValid checks if the priority value is one of the allowed constants.

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

func (r *Repository) Create(ctx context.Context, input TaskInput) (*Task, error)

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) Exists

func (r *Repository) Exists(ctx context.Context, id int64) (bool, error)

func (*Repository) GetByID

func (r *Repository) GetByID(ctx context.Context, id int64) (*Task, error)

GetByID retrieves a task by its global database ID.

func (*Repository) Import

func (r *Repository) Import(
	ctx context.Context,
	input Task,
) (*Task, error)

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

func NewService(repo *Repository, projects *projects.Service, logger *zap.Logger) *Service

NewService creates a new Service instance with the given dependencies.

func (*Service) Create

func (s *Service) Create(ctx context.Context, input TaskInput) (*Task, error)

Create validates input and creates a new task with auto-generated number.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id int64) error

Delete soft-deletes a task.

func (*Service) Exists

func (s *Service) Exists(ctx context.Context, id int64) (bool, error)

Exists checks if a task with the given ID exists.

func (*Service) GetByID

func (s *Service) GetByID(ctx context.Context, id int64) (*Task, error)

GetByID retrieves a task by its global ID.

func (*Service) Import

func (s *Service) Import(
	ctx context.Context,
	input Task,
) (*Task, error)

Import creates a task with explicit number, timestamps, and kind for import. Bypasses auto-number generation and allows preserving original metadata.

func (*Service) List

func (s *Service) List(
	ctx context.Context,
	filter TaskFilter,
	sort string,
	pagination *Pagination,
) ([]Task, int, error)

List retrieves tasks with filtering, sorting, and pagination. Returns the list of tasks and the total count matching the filter.

func (*Service) Update

func (s *Service) Update(ctx context.Context, id int64, update TaskUpdate) (*Task, error)

Update modifies an existing task with the provided data. Returns the updated task or an error if not found or validation fails.

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"
)

Status constants.

func (Status) IsValid

func (s Status) IsValid() bool

IsValid checks if the status value is one of the allowed 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.

func (TaskInput) Validate

func (i TaskInput) Validate() error

Validate checks that the input data is valid for task creation.

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL