package sqlite import ( "context" "encoding/json" "time" "chat-switchboard/models" "chat-switchboard/store" ) // RoutingPolicyStore implements store.RoutingPolicyStore for SQLite. type RoutingPolicyStore struct{} func NewRoutingPolicyStore() *RoutingPolicyStore { return &RoutingPolicyStore{} } func (s *RoutingPolicyStore) Create(ctx context.Context, p *models.RoutingPolicy) error { p.ID = store.NewID() configJSON, err := json.Marshal(p.Config) if err != nil { return err } now := time.Now().UTC() p.CreatedAt = now p.UpdatedAt = now _, err = DB.ExecContext(ctx, ` INSERT INTO routing_policies (id, name, scope, team_id, priority, policy_type, config, is_active, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, p.ID, p.Name, p.Scope, p.TeamID, p.Priority, p.Type, string(configJSON), boolToInt(p.IsActive), p.CreatedAt.Format(time.RFC3339), p.UpdatedAt.Format(time.RFC3339)) return err } func (s *RoutingPolicyStore) Update(ctx context.Context, p *models.RoutingPolicy) error { configJSON, err := json.Marshal(p.Config) if err != nil { return err } _, err = DB.ExecContext(ctx, ` UPDATE routing_policies SET name = ?, scope = ?, team_id = ?, priority = ?, policy_type = ?, config = ?, is_active = ?, updated_at = datetime('now') WHERE id = ? `, p.Name, p.Scope, p.TeamID, p.Priority, p.Type, string(configJSON), boolToInt(p.IsActive), p.ID) return err } func (s *RoutingPolicyStore) Delete(ctx context.Context, id string) error { _, err := DB.ExecContext(ctx, `DELETE FROM routing_policies WHERE id = ?`, id) return err } func (s *RoutingPolicyStore) GetByID(ctx context.Context, id string) (*models.RoutingPolicy, error) { var p models.RoutingPolicy var configJSON string var isActive int err := DB.QueryRowContext(ctx, ` SELECT id, name, scope, team_id, priority, policy_type, config, is_active, created_at, updated_at FROM routing_policies WHERE id = ? `, id).Scan(&p.ID, &p.Name, &p.Scope, &p.TeamID, &p.Priority, &p.Type, &configJSON, &isActive, st(&p.CreatedAt), st(&p.UpdatedAt)) if err != nil { return nil, err } p.IsActive = isActive != 0 json.Unmarshal([]byte(configJSON), &p.Config) return &p, nil } func (s *RoutingPolicyStore) ListActive(ctx context.Context) ([]models.RoutingPolicy, error) { return s.query(ctx, ` SELECT id, name, scope, team_id, priority, policy_type, config, is_active, created_at, updated_at FROM routing_policies WHERE is_active = 1 ORDER BY priority ASC, created_at ASC `) } func (s *RoutingPolicyStore) ListAll(ctx context.Context) ([]models.RoutingPolicy, error) { return s.query(ctx, ` SELECT id, name, scope, team_id, priority, policy_type, config, is_active, created_at, updated_at FROM routing_policies ORDER BY priority ASC, created_at ASC `) } func (s *RoutingPolicyStore) ListForTeam(ctx context.Context, teamID string) ([]models.RoutingPolicy, error) { return s.query(ctx, ` SELECT id, name, scope, team_id, priority, policy_type, config, is_active, created_at, updated_at FROM routing_policies WHERE is_active = 1 AND (scope = 'global' OR (scope = 'team' AND team_id = ?)) ORDER BY priority ASC, created_at ASC `, teamID) } func (s *RoutingPolicyStore) query(ctx context.Context, q string, args ...interface{}) ([]models.RoutingPolicy, error) { rows, err := DB.QueryContext(ctx, q, args...) if err != nil { return nil, err } defer rows.Close() var result []models.RoutingPolicy for rows.Next() { var p models.RoutingPolicy var configJSON string var isActive int if err := rows.Scan(&p.ID, &p.Name, &p.Scope, &p.TeamID, &p.Priority, &p.Type, &configJSON, &isActive, st(&p.CreatedAt), st(&p.UpdatedAt)); err != nil { return nil, err } p.IsActive = isActive != 0 json.Unmarshal([]byte(configJSON), &p.Config) result = append(result, p) } return result, rows.Err() } var _ store.RoutingPolicyStore = (*RoutingPolicyStore)(nil)