package postgres import ( "time" "github.com/google/uuid" "github.com/jmoiron/sqlx" "github.com/ajaxray/geek-life/model" ) // ProjectRepository implements the project repository interface for PostgreSQL type ProjectRepository struct { db *sqlx.DB } // NewProjectRepository creates a new project repository func NewProjectRepository(db *sqlx.DB) *ProjectRepository { return &ProjectRepository{db: db} } // GetAll retrieves all projects for a user func (r *ProjectRepository) GetAll(ctx *model.UserContext) ([]model.Project, error) { var projects []model.Project query := `SELECT id, tenant_id, user_id, title, uuid, created_at, updated_at FROM projects WHERE tenant_id = $1 AND user_id = $2 ORDER BY created_at DESC` err := r.db.Select(&projects, query, ctx.Tenant.ID, ctx.User.ID) return projects, err } // GetByID retrieves a project by ID func (r *ProjectRepository) GetByID(ctx *model.UserContext, id int64) (model.Project, error) { var project model.Project query := `SELECT id, tenant_id, user_id, title, uuid, created_at, updated_at FROM projects WHERE id = $1 AND tenant_id = $2 AND user_id = $3` err := r.db.Get(&project, query, id, ctx.Tenant.ID, ctx.User.ID) return project, err } // GetByTitle retrieves a project by title func (r *ProjectRepository) GetByTitle(ctx *model.UserContext, title string) (model.Project, error) { var project model.Project query := `SELECT id, tenant_id, user_id, title, uuid, created_at, updated_at FROM projects WHERE title = $1 AND tenant_id = $2 AND user_id = $3` err := r.db.Get(&project, query, title, ctx.Tenant.ID, ctx.User.ID) return project, err } // GetByUUID retrieves a project by UUID func (r *ProjectRepository) GetByUUID(ctx *model.UserContext, UUID string) (model.Project, error) { var project model.Project query := `SELECT id, tenant_id, user_id, title, uuid, created_at, updated_at FROM projects WHERE uuid = $1 AND tenant_id = $2 AND user_id = $3` err := r.db.Get(&project, query, UUID, ctx.Tenant.ID, ctx.User.ID) return project, err } // Create creates a new project func (r *ProjectRepository) Create(ctx *model.UserContext, title, UUID string) (model.Project, error) { if UUID == "" { UUID = uuid.New().String() } project := model.Project{ TenantID: ctx.Tenant.ID, UserID: ctx.User.ID, Title: title, UUID: UUID, CreatedAt: time.Now(), UpdatedAt: time.Now(), } query := `INSERT INTO projects (tenant_id, user_id, title, uuid, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id` err := r.db.QueryRow(query, project.TenantID, project.UserID, project.Title, project.UUID, project.CreatedAt, project.UpdatedAt).Scan(&project.ID) if err != nil { return model.Project{}, err } return project, nil } // Update updates an existing project func (r *ProjectRepository) Update(ctx *model.UserContext, p *model.Project) error { p.UpdatedAt = time.Now() query := `UPDATE projects SET title = $1, updated_at = $2 WHERE id = $3 AND tenant_id = $4 AND user_id = $5` _, err := r.db.Exec(query, p.Title, p.UpdatedAt, p.ID, ctx.Tenant.ID, ctx.User.ID) return err } // UpdateField updates a specific field of a project func (r *ProjectRepository) UpdateField(ctx *model.UserContext, p *model.Project, field string, value interface{}) error { p.UpdatedAt = time.Now() query := `UPDATE projects SET ` + field + ` = $1, updated_at = $2 WHERE id = $3 AND tenant_id = $4 AND user_id = $5` _, err := r.db.Exec(query, value, p.UpdatedAt, p.ID, ctx.Tenant.ID, ctx.User.ID) return err } // Delete deletes a project func (r *ProjectRepository) Delete(ctx *model.UserContext, p *model.Project) error { query := `DELETE FROM projects WHERE id = $1 AND tenant_id = $2 AND user_id = $3` _, err := r.db.Exec(query, p.ID, ctx.Tenant.ID, ctx.User.ID) return err }