projects

package
v0.2.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 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

View Source
const (
	DefaultLimit = 20
	MaxLimit     = 100
)

Variables

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

func Module() fx.Option

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

func (r *Repository) Exists(ctx context.Context, slug string) (bool, error)

Exists checks whether a project with the given slug exists. Returns true if found, false otherwise.

func (*Repository) GetBySlug

func (r *Repository) GetBySlug(ctx context.Context, slug string) (*Project, error)

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

func (s *Service) Create(ctx context.Context, input ProjectInput) (*Project, error)

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

func (s *Service) Delete(ctx context.Context, slug string) error

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

func (s *Service) Exists(ctx context.Context, slug string) (bool, error)

Exists checks whether a project with the given slug exists. Returns true if found, false otherwise.

func (*Service) GetBySlug

func (s *Service) GetBySlug(ctx context.Context, slug string) (*Project, error)

GetBySlug retrieves a project by its slug. Returns ErrNotFound if the project does not exist.

func (*Service) List

func (s *Service) List(ctx context.Context, pagination *Pagination) ([]Project, int, error)

List retrieves a paginated list of projects. Projects are ordered by name ascending.

func (*Service) Update

func (s *Service) Update(ctx context.Context, slug string, update ProjectUpdate) (*Project, error)

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.

Jump to

Keyboard shortcuts

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