generated from VLADIMIR/template
148 lines
2.7 KiB
Go
148 lines
2.7 KiB
Go
// Package actions_repo provides database access for team actions.
|
|
package actions_repo
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
var (
|
|
// ErrActionsNotFound indicates that no actions were found.
|
|
ErrActionsNotFound = errors.New("ход не найден")
|
|
)
|
|
|
|
// ActionsRepo persists team actions.
|
|
type ActionsRepo struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
// Action describes a team action.
|
|
type Action struct {
|
|
Code string
|
|
ViaMCP bool
|
|
}
|
|
|
|
// NewActionsRepo creates an actions repository.
|
|
func NewActionsRepo(pool *pgxpool.Pool) *ActionsRepo {
|
|
return &ActionsRepo{
|
|
pool: pool,
|
|
}
|
|
}
|
|
|
|
// AddAction stores an action for a team.
|
|
func (r *ActionsRepo) AddAction(ctx context.Context, teamID string, code string, viaMCP bool) (int, error) {
|
|
id := 0
|
|
err := r.pool.QueryRow(
|
|
ctx,
|
|
`INSERT INTO actions (code, team_id, via_mcp)
|
|
VALUES ($1, $2, $3)
|
|
RETURNING id`,
|
|
code,
|
|
teamID,
|
|
viaMCP,
|
|
).Scan(&id)
|
|
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// GetActionsByTeamID returns actions for a team.
|
|
func (r *ActionsRepo) GetActionsByTeamID(ctx context.Context, teamID string) ([]Action, error) {
|
|
rows, err := r.pool.Query(
|
|
ctx,
|
|
`SELECT
|
|
code,
|
|
via_mcp
|
|
FROM actions
|
|
WHERE team_id = $1
|
|
ORDER BY created_at ASC`,
|
|
teamID,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var actions []Action
|
|
for rows.Next() {
|
|
action := Action{}
|
|
err := rows.Scan(
|
|
&action.Code,
|
|
&action.ViaMCP,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
actions = append(actions, action)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return actions, nil
|
|
}
|
|
|
|
// GetActionsCountByTeamIDs returns action counts for teams.
|
|
func (r *ActionsRepo) GetActionsCountByTeamIDs(ctx context.Context, teamIDs []string) (map[string]int, error) {
|
|
rows, err := r.pool.Query(
|
|
ctx,
|
|
`SELECT
|
|
team_id,
|
|
count(*)
|
|
FROM actions
|
|
WHERE team_id = ANY($1)
|
|
GROUP BY team_id`,
|
|
teamIDs,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
res := make(map[string]int, len(teamIDs))
|
|
for rows.Next() {
|
|
var id string
|
|
count := 0
|
|
err := rows.Scan(
|
|
&id,
|
|
&count,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res[id] = count
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// DeleteLastActionByTeamID removes the latest action for a team.
|
|
func (r *ActionsRepo) DeleteLastActionByTeamID(ctx context.Context, teamID string) error {
|
|
tag, err := r.pool.Exec(
|
|
ctx,
|
|
`DELETE FROM actions
|
|
WHERE id IN (
|
|
SELECT id
|
|
FROM actions
|
|
WHERE team_id = $1
|
|
ORDER BY created_at DESC
|
|
LIMIT 1
|
|
)`,
|
|
teamID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if tag.RowsAffected() == 0 {
|
|
return ErrActionsNotFound
|
|
}
|
|
return nil
|
|
}
|