gohorsejobs/backend/internal/infrastructure/persistence/postgres/company_repository.go
Tiago Yamamoto 7d99e77468 refactor: unify schema - eliminate core_* tables
BREAKING CHANGE: Removed core_companies, core_users, core_user_roles tables

Migrations:
- Create 020_unify_schema.sql: adds tenant_id, email, name to users table
- Create user_roles table (replaces core_user_roles)
- Disable 009_create_core_tables.sql (renamed to .disabled)
- Update 010_seed_super_admin.sql to use unified tables

Backend Repositories:
- company_repository.go: use companies table with INT id
- user_repository.go: use users/user_roles with INT id conversion

Seeders:
- All seeders now use companies/users/user_roles tables
- Removed all core_* table insertions
- Query companies by slug to get SERIAL id

This eliminates the redundancy between core_* and legacy tables.
2025-12-24 11:06:31 -03:00

131 lines
3.2 KiB
Go

package postgres
import (
"context"
"database/sql"
"errors"
"fmt"
"strconv"
"time"
"github.com/rede5/gohorsejobs/backend/internal/core/domain/entity"
)
type CompanyRepository struct {
db *sql.DB
}
func NewCompanyRepository(db *sql.DB) *CompanyRepository {
return &CompanyRepository{db: db}
}
func (r *CompanyRepository) Save(ctx context.Context, company *entity.Company) (*entity.Company, error) {
// companies table uses SERIAL id, we let DB generate it
query := `
INSERT INTO companies (name, slug, type, document, email, description, verified, active, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id
`
slug := company.Name // TODO: slugify function
var id int
err := r.db.QueryRowContext(ctx, query,
company.Name,
slug,
"company",
company.Document,
company.Contact, // mapped to email
"{}", // description as JSON
true, // verified
company.Status == "ACTIVE",
company.CreatedAt,
company.UpdatedAt,
).Scan(&id)
if err != nil {
return nil, err
}
company.ID = strconv.Itoa(id)
return company, nil
}
func (r *CompanyRepository) FindByID(ctx context.Context, id string) (*entity.Company, error) {
query := `SELECT id, name, document, email,
CASE WHEN active THEN 'ACTIVE' ELSE 'INACTIVE' END as status,
created_at, updated_at
FROM companies WHERE id = $1`
numID, err := strconv.Atoi(id)
if err != nil {
return nil, fmt.Errorf("invalid company id: %s", id)
}
row := r.db.QueryRowContext(ctx, query, numID)
c := &entity.Company{}
var dbID int
err = row.Scan(&dbID, &c.Name, &c.Document, &c.Contact, &c.Status, &c.CreatedAt, &c.UpdatedAt)
if err == sql.ErrNoRows {
return nil, errors.New("company not found")
}
c.ID = strconv.Itoa(dbID)
return c, err
}
func (r *CompanyRepository) Update(ctx context.Context, company *entity.Company) (*entity.Company, error) {
company.UpdatedAt = time.Now()
numID, err := strconv.Atoi(company.ID)
if err != nil {
return nil, fmt.Errorf("invalid company id: %s", company.ID)
}
query := `
UPDATE companies
SET name=$1, document=$2, email=$3, active=$4, updated_at=$5
WHERE id=$6
`
_, err = r.db.ExecContext(ctx, query,
company.Name,
company.Document,
company.Contact,
company.Status == "ACTIVE",
company.UpdatedAt,
numID,
)
return company, err
}
func (r *CompanyRepository) Delete(ctx context.Context, id string) error {
numID, err := strconv.Atoi(id)
if err != nil {
return fmt.Errorf("invalid company id: %s", id)
}
query := `DELETE FROM companies WHERE id = $1`
_, err = r.db.ExecContext(ctx, query, numID)
return err
}
func (r *CompanyRepository) FindAll(ctx context.Context) ([]*entity.Company, error) {
query := `SELECT id, name, document, email,
CASE WHEN active THEN 'ACTIVE' ELSE 'INACTIVE' END as status,
created_at, updated_at
FROM companies`
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
defer rows.Close()
var companies []*entity.Company
for rows.Next() {
c := &entity.Company{}
var dbID int
if err := rows.Scan(&dbID, &c.Name, &c.Document, &c.Contact, &c.Status, &c.CreatedAt, &c.UpdatedAt); err != nil {
return nil, err
}
c.ID = strconv.Itoa(dbID)
companies = append(companies, c)
}
return companies, nil
}