gohorsejobs/backend/internal/services/company_follower_service.go
2026-02-15 16:03:40 +00:00

137 lines
3.6 KiB
Go

package services
import (
"database/sql"
"time"
"github.com/rede5/gohorsejobs/backend/internal/models"
)
type CompanyFollowerService struct {
DB *sql.DB
}
func NewCompanyFollowerService(db *sql.DB) *CompanyFollowerService {
return &CompanyFollowerService{DB: db}
}
func (s *CompanyFollowerService) Follow(userID, companyID string) (*models.CompanyFollower, error) {
query := `
INSERT INTO company_followers (user_id, company_id, created_at)
VALUES ($1, $2, $3)
ON CONFLICT (user_id, company_id) DO NOTHING
RETURNING id, user_id, company_id, created_at
`
var follower models.CompanyFollower
err := s.DB.QueryRow(query, userID, companyID, time.Now()).Scan(
&follower.ID, &follower.UserID, &follower.CompanyID, &follower.CreatedAt,
)
if err == sql.ErrNoRows {
err = s.DB.QueryRow(
"SELECT id, user_id, company_id, created_at FROM company_followers WHERE user_id = $1 AND company_id = $2",
userID, companyID,
).Scan(&follower.ID, &follower.UserID, &follower.CompanyID, &follower.CreatedAt)
if err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
return &follower, nil
}
func (s *CompanyFollowerService) Unfollow(userID, companyID string) error {
_, err := s.DB.Exec("DELETE FROM company_followers WHERE user_id = $1 AND company_id = $2", userID, companyID)
return err
}
func (s *CompanyFollowerService) GetFollowing(userID string) ([]models.CompanyFollowerWithCompany, error) {
query := `
SELECT
cf.id, cf.user_id, cf.company_id, cf.created_at,
c.name, c.logo_url,
(SELECT COUNT(*) FROM jobs j WHERE j.company_id = c.id AND j.status = 'published') as jobs_count
FROM company_followers cf
JOIN companies c ON cf.company_id = c.id
WHERE cf.user_id = $1
ORDER BY cf.created_at DESC
`
rows, err := s.DB.Query(query, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var followers []models.CompanyFollowerWithCompany
for rows.Next() {
var f models.CompanyFollowerWithCompany
err := rows.Scan(
&f.ID, &f.UserID, &f.CompanyID, &f.CreatedAt,
&f.CompanyName, &f.CompanyLogoURL, &f.JobsCount,
)
if err != nil {
return nil, err
}
followers = append(followers, f)
}
return followers, nil
}
func (s *CompanyFollowerService) IsFollowing(userID, companyID string) (bool, error) {
var exists bool
err := s.DB.QueryRow(
"SELECT EXISTS(SELECT 1 FROM company_followers WHERE user_id = $1 AND company_id = $2)",
userID, companyID,
).Scan(&exists)
return exists, err
}
func (s *CompanyFollowerService) GetCompanyFollowersCount(companyID string) (int, error) {
var count int
err := s.DB.QueryRow(
"SELECT COUNT(*) FROM company_followers WHERE company_id = $1",
companyID,
).Scan(&count)
return count, err
}
func (s *CompanyFollowerService) GetCompaniesWithJobs(limit, offset int) ([]models.CompanyFollowerWithCompany, error) {
query := `
SELECT
cf.id, cf.user_id, cf.company_id, cf.created_at,
c.name, c.logo_url,
(SELECT COUNT(*) FROM jobs j WHERE j.company_id = c.id AND j.status = 'published') as jobs_count
FROM companies c
LEFT JOIN company_followers cf ON cf.company_id = c.id
WHERE c.active = true
GROUP BY c.id, cf.id
ORDER BY jobs_count DESC, c.name ASC
LIMIT $1 OFFSET $2
`
rows, err := s.DB.Query(query, limit, offset)
if err != nil {
return nil, err
}
defer rows.Close()
var companies []models.CompanyFollowerWithCompany
for rows.Next() {
var c models.CompanyFollowerWithCompany
err := rows.Scan(
&c.ID, &c.UserID, &c.CompanyID, &c.CreatedAt,
&c.CompanyName, &c.CompanyLogoURL, &c.JobsCount,
)
if err != nil {
return nil, err
}
companies = append(companies, c)
}
return companies, nil
}