package registry import ( "context" "database/sql" "reanimator/internal/domain" "reanimator/internal/idgen" ) type ProjectRepository struct { db *sql.DB idgen *idgen.Generator } func NewProjectRepository(db *sql.DB) *ProjectRepository { return &ProjectRepository{ db: db, idgen: idgen.NewGenerator(db), } } func (r *ProjectRepository) Create(ctx context.Context, customerID string, name string) (domain.Project, error) { // Generate string ID id, err := r.idgen.Generate(ctx, idgen.Project) if err != nil { return domain.Project{}, err } _, err = r.db.ExecContext(ctx, `INSERT INTO projects (id, customer_id, name) VALUES (?, ?, ?)`, id, customerID, name, ) if err != nil { return domain.Project{}, classifyError(err) } return r.Get(ctx, id) } func (r *ProjectRepository) Get(ctx context.Context, id string) (domain.Project, error) { var project domain.Project row := r.db.QueryRowContext(ctx, `SELECT id, customer_id, name, created_at, updated_at FROM projects WHERE id = ?`, id, ) if err := row.Scan(&project.ID, &project.CustomerID, &project.Name, &project.CreatedAt, &project.UpdatedAt); err != nil { if err == sql.ErrNoRows { return domain.Project{}, ErrNotFound } return domain.Project{}, err } return project, nil } func (r *ProjectRepository) List(ctx context.Context) ([]domain.Project, error) { rows, err := r.db.QueryContext(ctx, `SELECT id, customer_id, name, created_at, updated_at FROM projects ORDER BY created_at DESC`, ) if err != nil { return nil, err } defer rows.Close() projects := make([]domain.Project, 0) for rows.Next() { var project domain.Project if err := rows.Scan(&project.ID, &project.CustomerID, &project.Name, &project.CreatedAt, &project.UpdatedAt); err != nil { return nil, err } projects = append(projects, project) } if err := rows.Err(); err != nil { return nil, err } return projects, nil }