package store import ( "context" "fmt" "strings" "github.com/google/uuid" "github.com/jackc/pgx/v5" thoughttypes "git.warky.dev/wdevs/amcs/internal/types" ) func (db *DB) CreateProject(ctx context.Context, name, description string) (thoughttypes.Project, error) { row := db.pool.QueryRow(ctx, ` insert into projects (name, description) values ($1, $2) returning id, name, description, created_at, last_active_at `, name, description) var project thoughttypes.Project if err := row.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt); err != nil { return thoughttypes.Project{}, fmt.Errorf("create project: %w", err) } return project, nil } func (db *DB) GetProject(ctx context.Context, nameOrID string) (thoughttypes.Project, error) { var row pgx.Row if parsedID, err := uuid.Parse(strings.TrimSpace(nameOrID)); err == nil { row = db.pool.QueryRow(ctx, ` select id, name, description, created_at, last_active_at from projects where id = $1 `, parsedID) } else { row = db.pool.QueryRow(ctx, ` select id, name, description, created_at, last_active_at from projects where name = $1 `, strings.TrimSpace(nameOrID)) } var project thoughttypes.Project if err := row.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt); err != nil { if err == pgx.ErrNoRows { return thoughttypes.Project{}, err } return thoughttypes.Project{}, fmt.Errorf("get project: %w", err) } return project, nil } func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary, error) { rows, err := db.pool.Query(ctx, ` select p.id, p.name, p.description, p.created_at, p.last_active_at, count(t.id) as thought_count from projects p left join thoughts t on t.project_id = p.id and t.archived_at is null group by p.id order by p.last_active_at desc, p.created_at desc `) if err != nil { return nil, fmt.Errorf("list projects: %w", err) } defer rows.Close() projects := make([]thoughttypes.ProjectSummary, 0) for rows.Next() { var project thoughttypes.ProjectSummary if err := rows.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt, &project.ThoughtCount); err != nil { return nil, fmt.Errorf("scan project summary: %w", err) } projects = append(projects, project) } if err := rows.Err(); err != nil { return nil, fmt.Errorf("iterate projects: %w", err) } return projects, nil } func (db *DB) TouchProject(ctx context.Context, id uuid.UUID) error { tag, err := db.pool.Exec(ctx, `update projects set last_active_at = now() where id = $1`, id) if err != nil { return fmt.Errorf("touch project: %w", err) } if tag.RowsAffected() == 0 { return pgx.ErrNoRows } return nil }