From 20216116f126619f66ea79cf7269ec1796e9a8c8 Mon Sep 17 00:00:00 2001 From: Cecilentsama <Cecile.ntsama@student.reutlingen-university.de> Date: Tue, 27 May 2025 17:34:46 +0200 Subject: [PATCH] resolving path errors --- src/app/project/projects.go | 246 +++++++++++++++++++++++ src/app/project/repository/repository.go | 0 2 files changed, 246 insertions(+) create mode 100644 src/app/project/projects.go create mode 100644 src/app/project/repository/repository.go diff --git a/src/app/project/projects.go b/src/app/project/projects.go new file mode 100644 index 0000000..daa2d9b --- /dev/null +++ b/src/app/project/projects.go @@ -0,0 +1,246 @@ +package project + +import ( + "context" + "errors" + "time" + + "github.com/google/uuid" + "github.com/jackc/pgx/v5/pgxpool" + "github.com/org-harmony/harmony/src/core/trace" + "github.com/org-harmony/harmony/src/core/validation" +) + +// Errors that can be defined in the module +var ( + ErrProjectNotFound = errors.New("project not found") + ErrProjectAlreadyExists = errors.New("project already exists") + ErrInvalidProject = errors.New("invalid project data") + ErrProjectUpdateFailed = errors.New("failed to update project") + ErrProjectDeleteFailed = errors.New("failed to delete project") + ErrProjectCreationFailed = errors.New("failed to create project") +) + +// Project represents a project in the system +type Project struct { + ID uuid.UUID `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + OwnerID uuid.UUID `json:"owner_id"` + Status string `json:"status"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// NewProject creates a new instance of Project +func NewProject(name, description string, ownerID uuid.UUID, status string) *Project { + now := time.Now() + return &Project{ + ID: uuid.New(), + Name: name, + Description: description, + OwnerID: ownerID, + Status: status, + CreatedAt: now, + UpdatedAt: now, + } +} + +// Service defines operations available for projects +type Service interface { + Create(ctx context.Context, project *Project) error + GetByID(ctx context.Context, id uuid.UUID) (*Project, error) + Edit(ctx context.Context, project *Project) error + Delete(ctx context.Context, id uuid.UUID) error + List(ctx context.Context, ownerID uuid.UUID) ([]*Project, error) +} + +type service struct { + repo Repository + validator validation.V + logger trace.Logger +} + +func NewService(repo Repository, validator validation.V, logger trace.Logger) Service { + return &service{ + repo: repo, + validator: validator, + logger: logger, + } +} + +func (s *service) Create(ctx context.Context, project *Project) error { + if err := s.validator.Struct(project); err != nil { + s.logger.Error("Invalid project data", "error", err) + return ErrInvalidProject + } + if err := s.repo.Create(ctx, project); err != nil { + s.logger.Error("Failed to create project", "error", err) + return ErrProjectCreationFailed + } + return nil +} + +func (s *service) GetByID(ctx context.Context, id uuid.UUID) (*Project, error) { + project, err := s.repo.GetByID(ctx, id) + if err != nil { + s.logger.Error("Failed to get project", "error", err, "id", id) + return nil, ErrProjectNotFound + } + return project, nil +} + +func (s *service) Edit(ctx context.Context, project *Project) error { + return s.Update(ctx, project) +} + +func (s *service) Update(ctx context.Context, project *Project) error { + if err := s.validator.Struct(project); err != nil { + s.logger.Error("Invalid project data", "error", err) + return ErrInvalidProject + } + project.UpdatedAt = time.Now() + if err := s.repo.Update(ctx, project); err != nil { + s.logger.Error("Failed to update project", "error", err) + return ErrProjectUpdateFailed + } + return nil +} + +func (s *service) Delete(ctx context.Context, id uuid.UUID) error { + if err := s.repo.Delete(ctx, id); err != nil { + s.logger.Error("Failed to delete project", "error", err, "id", id) + return ErrProjectDeleteFailed + } + return nil +} + +func (s *service) List(ctx context.Context, ownerID uuid.UUID) ([]*Project, error) { + projects, err := s.repo.List(ctx, ownerID) + if err != nil { + s.logger.Error("Failed to list projects", "error", err, "ownerID", ownerID) + return nil, err + } + return projects, nil +} + +// Repository defines persistence operations for projects +type Repository interface { + Create(ctx context.Context, project *Project) error + GetByID(ctx context.Context, id uuid.UUID) (*Project, error) + Update(ctx context.Context, project *Project) error + Delete(ctx context.Context, id uuid.UUID) error + List(ctx context.Context, ownerID uuid.UUID) ([]*Project, error) + RepositoryName() string +} + +type repository struct { + db *pgxpool.Pool +} + +func NewRepository(db *pgxpool.Pool) Repository { + return &repository{db: db} +} + +func (r *repository) RepositoryName() string { + return "project" +} + +func (r *repository) Create(ctx context.Context, project *Project) error { + query := ` + INSERT INTO projects (id, name, description, owner_id, status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ` + _, err := r.db.Exec(ctx, query, + project.ID, + project.Name, + project.Description, + project.OwnerID, + project.Status, + project.CreatedAt, + project.UpdatedAt, + ) + return err +} + +func (r *repository) GetByID(ctx context.Context, id uuid.UUID) (*Project, error) { + query := ` + SELECT id, name, description, owner_id, status, created_at, updated_at + FROM projects + WHERE id = $1 + ` + var project Project + err := r.db.QueryRow(ctx, query, id).Scan( + &project.ID, + &project.Name, + &project.Description, + &project.OwnerID, + &project.Status, + &project.CreatedAt, + &project.UpdatedAt, + ) + if err != nil { + return nil, err + } + return &project, nil +} + +func (r *repository) Update(ctx context.Context, project *Project) error { + query := ` + UPDATE projects + SET name = $1, description = $2, status = $3, updated_at = $4 + WHERE id = $5 + ` + _, err := r.db.Exec(ctx, query, + project.Name, + project.Description, + project.Status, + project.UpdatedAt, + project.ID, + ) + return err +} + +func (r *repository) Delete(ctx context.Context, id uuid.UUID) error { + query := "DELETE FROM projects WHERE id = $1" + _, err := r.db.Exec(ctx, query, id) + return err +} + +func (r *repository) List(ctx context.Context, ownerID uuid.UUID) ([]*Project, error) { + query := ` + SELECT id, name, description, owner_id, status, created_at, updated_at + FROM projects + WHERE owner_id = $1 + ORDER BY created_at DESC + ` + rows, err := r.db.Query(ctx, query, ownerID) + if err != nil { + return nil, err + } + defer rows.Close() + + var projects []*Project + for rows.Next() { + var project Project + err := rows.Scan( + &project.ID, + &project.Name, + &project.Description, + &project.OwnerID, + &project.Status, + &project.CreatedAt, + &project.UpdatedAt, + ) + if err != nil { + return nil, err + } + projects = append(projects, &project) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return projects, nil +} diff --git a/src/app/project/repository/repository.go b/src/app/project/repository/repository.go new file mode 100644 index 0000000..e69de29 -- GitLab