Documentation
¶
Overview ¶
Package projects provides project management functionality for the Corporate Task Tracker. Projects serve as containers for tasks and are linked to external BitBucket repositories.
The projects module follows a clean architecture pattern with clear separation between domain logic, data access, and HTTP presentation.
Domain Layer:
- Project: Core business entity
- ProjectInput: Data for creating projects
- ProjectUpdate: Data for updating projects
Repository Layer:
- Handles all database operations
- Uses Bun ORM for type-safe queries
Service Layer:
- Implements business rules and validation
- Validates repository URLs
- Ensures name uniqueness
HTTP Layer:
- RESTful API endpoints
- Admin-only write operations
- Authenticated read operations
Usage:
app := fx.New(
projects.Module(),
// other modules...
)
Index ¶
- Constants
- Variables
- func Module() fx.Option
- type Config
- type Pagination
- type Project
- type ProjectInput
- type ProjectUpdate
- type Repository
- func (r *Repository) Create(ctx context.Context, input ProjectInput, slug string) (*Project, error)
- func (r *Repository) Delete(ctx context.Context, slug string) error
- func (r *Repository) Exists(ctx context.Context, slug string) (bool, error)
- func (r *Repository) GetBySlug(ctx context.Context, slug string) (*Project, error)
- func (r *Repository) List(ctx context.Context, pagination *Pagination) ([]Project, int, error)
- func (r *Repository) Update(ctx context.Context, slug string, update ProjectUpdate) error
- type Service
- func (s *Service) Create(ctx context.Context, input ProjectInput) (*Project, error)
- func (s *Service) Delete(ctx context.Context, slug string) error
- func (s *Service) Exists(ctx context.Context, slug string) (bool, error)
- func (s *Service) GetBySlug(ctx context.Context, slug string) (*Project, error)
- func (s *Service) List(ctx context.Context, pagination *Pagination) ([]Project, int, error)
- func (s *Service) Update(ctx context.Context, slug string, update ProjectUpdate) (*Project, error)
Constants ¶
const ( DefaultLimit = 20 MaxLimit = 100 )
Variables ¶
var ( // ErrValidationFailed is returned when input data fails validation. ErrValidationFailed = errors.New("validation failed") // ErrNotFound is returned when a project with the given ID does not exist. ErrNotFound = errors.New("project not found") // ErrNameAlreadyUsed is returned when attempting to create or update // a project with a name that is already in use by another project. ErrNameAlreadyUsed = errors.New("project name already in use") // ErrInvalidURL is returned when the repository URL is not in a valid // format. ErrInvalidURL = errors.New("invalid repository URL") )
Functions ¶
func Module ¶
Module creates and returns an FX module for the projects package. This module wires up all dependencies for the projects functionality:
- Repository (private): Data access layer, only used within this module
- Service (public): Business logic layer, can be injected into other modules
The module also registers a named logger for structured logging.
Types ¶
type Config ¶
type Config struct {
}
Config holds configuration for the projects module. Currently empty as no module-specific configuration is needed for MVP. This struct can be extended in the future for feature flags or other configurable aspects.
type Pagination ¶
type Pagination = db.Pagination[*pagination]
func NewPagination ¶
func NewPagination(limit, offset int) *Pagination
type Project ¶
type Project struct {
ID string // Primary key
Name string // Unique project name
RepoURL string // BitBucket repository URL
CreatedAt time.Time // Creation timestamp
UpdatedAt time.Time // Last update timestamp
}
Project represents the core business entity for a project. A project is a container for tasks and is linked to a BitBucket repository.
type ProjectInput ¶
type ProjectInput struct {
Name string // Unique project name, required
RepoURL string // BitBucket repository URL, required
}
ProjectInput represents the data required to create a new project. All fields are required and must be validated before creation.
func (ProjectInput) Validate ¶
func (i ProjectInput) Validate() error
Validate checks if the input data is valid for creating a new project.
type ProjectUpdate ¶
type ProjectUpdate struct {
Name *string // Optional new name, must be unique if provided
RepoURL *string // Optional new repository URL, must be valid if provided
}
ProjectUpdate represents the data that can be updated for a project. All fields are optional (pointers) to support partial updates.
func (ProjectUpdate) IsEmpty ¶
func (u ProjectUpdate) IsEmpty() bool
IsEmpty returns true if no update fields are set. This prevents unnecessary database operations when no data is provided.
func (ProjectUpdate) Validate ¶
func (u ProjectUpdate) Validate() error
type Repository ¶
type Repository struct {
// contains filtered or unexported fields
}
Repository is the concrete implementation of Repository using Bun ORM.
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 ProjectInput, slug string) (*Project, error)
Create inserts a new project into the database. Returns the created project, or an error if creation fails. Expected errors:
- ErrNameAlreadyUsed if a project with the same name already exists
- Other database errors
func (*Repository) Delete ¶
func (r *Repository) Delete(ctx context.Context, slug string) error
Delete removes a project from the database by its slug. Due to foreign key constraints with ON DELETE CASCADE, all associated tasks, comments, and attachments will be automatically deleted. Returns ErrNotFound if the project does not exist.
func (*Repository) Exists ¶
Exists checks whether a project with the given slug exists. Returns true if found, false otherwise.
func (*Repository) GetBySlug ¶
GetBySlug retrieves a project by its unique slug identifier. Returns ErrNotFound if the project does not exist.
func (*Repository) List ¶
func (r *Repository) List(ctx context.Context, pagination *Pagination) ([]Project, int, error)
List retrieves a paginated list of projects, ordered by name ascending. Returns the list of projects and no error if successful.
func (*Repository) Update ¶
func (r *Repository) Update(ctx context.Context, slug string, update ProjectUpdate) error
Update modifies an existing project with the provided update data. Only the fields specified in the update struct will be changed. Returns ErrNotFound if the project does not exist. Returns ErrNameAlreadyUsed if the new name conflicts with another project.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service implements the business logic for project management. It coordinates between the repository layer and validation rules.
func NewService ¶
func NewService(repo *Repository) *Service
NewService creates a new Service instance with the given repository.
func (*Service) Create ¶
Create creates a new project after validating the input. Validation includes:
- Name must be non-empty after trimming whitespace
- Repository URL must be in valid format (HTTPS)
- Project name must be unique (case-sensitive)
Returns the created project or an error if validation fails.
func (*Service) Delete ¶
Delete removes a project by its slug. All associated tasks, comments, and attachments will be cascade-deleted due to foreign key constraints in the database. Returns ErrNotFound if the project does not exist.
func (*Service) Exists ¶
Exists checks whether a project with the given slug exists. Returns true if found, false otherwise.
func (*Service) GetBySlug ¶
GetBySlug retrieves a project by its slug. Returns ErrNotFound if the project does not exist.
func (*Service) List ¶
List retrieves a paginated list of projects. Projects are ordered by name ascending.
func (*Service) Update ¶
Update modifies an existing project with the provided update data. Validation includes:
- At least one field must be provided
- If name is provided, it must be non-empty and unique
- If repoURL is provided, it must be in valid format
Returns the updated project or an error if validation fails.