photum/backend/internal/escalas/service.go
NANDO9322 804a566095 feat(ops): implementa modulo operacional completo (escala, logistica, equipe)
- Backend: Migrations para tabelas 'escalas' e 'logistica' (transporte)
- Backend: Handlers e Services completos para gestão de escalas e logística
- Backend: Suporte a auth vinculado a perfil profissional
- Frontend: Nova página de Detalhes Operacionais (/agenda/:id)
- Frontend: Componente EventScheduler com verificação robusta de conflitos
- Frontend: Componente EventLogistics para gestão de motoristas e caronas
- Frontend: Modal de Detalhes de Profissional unificado (Admin + Self-view)
- Frontend: Dashboard com modal de gestão de equipe e filtros avançados
- Fix: Correção crítica de timezone (UTC) em horários de agendamento
- Fix: Tratamento de URLs no campo de local do evento
- Fix: Filtros de profissional com carro na logística
2025-12-29 16:01:17 -03:00

126 lines
3.2 KiB
Go

package escalas
import (
"context"
"photum-backend/internal/db/generated"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
type Service struct {
queries *generated.Queries
}
func NewService(queries *generated.Queries) *Service {
return &Service{queries: queries}
}
type CreateEscalaInput struct {
AgendaID string `json:"agenda_id"`
ProfissionalID string `json:"profissional_id"`
DataHoraInicio string `json:"data_hora_inicio"` // RFC3339
DataHoraFim string `json:"data_hora_fim"` // RFC3339
FuncaoEspecifica string `json:"funcao_especifica"`
}
func (s *Service) Create(ctx context.Context, input CreateEscalaInput) (*generated.AgendaEscala, error) {
agendaID, err := uuid.Parse(input.AgendaID)
if err != nil {
return nil, err
}
profID, err := uuid.Parse(input.ProfissionalID)
if err != nil {
return nil, err
}
var start, end pgtype.Timestamptz
err = start.Scan(input.DataHoraInicio)
if err != nil {
return nil, err
}
err = end.Scan(input.DataHoraFim)
if err != nil {
return nil, err
}
var funcao pgtype.Text
if input.FuncaoEspecifica != "" {
funcao = pgtype.Text{String: input.FuncaoEspecifica, Valid: true}
}
escala, err := s.queries.CreateEscala(ctx, generated.CreateEscalaParams{
AgendaID: pgtype.UUID{Bytes: agendaID, Valid: true},
ProfissionalID: pgtype.UUID{Bytes: profID, Valid: true},
DataHoraInicio: start,
DataHoraFim: end,
FuncaoEspecifica: funcao,
})
if err != nil {
return nil, err
}
return &escala, nil
}
func (s *Service) ListByAgenda(ctx context.Context, agendaID string) ([]generated.ListEscalasByAgendaIDRow, error) {
parsedUUID, err := uuid.Parse(agendaID)
if err != nil {
return nil, err
}
return s.queries.ListEscalasByAgendaID(ctx, pgtype.UUID{Bytes: parsedUUID, Valid: true})
}
func (s *Service) Delete(ctx context.Context, id string) error {
parsedUUID, err := uuid.Parse(id)
if err != nil {
return err
}
return s.queries.DeleteEscala(ctx, pgtype.UUID{Bytes: parsedUUID, Valid: true})
}
type UpdateEscalaInput struct {
ProfissionalID *string `json:"profissional_id"`
DataHoraInicio *string `json:"data_hora_inicio"`
DataHoraFim *string `json:"data_hora_fim"`
FuncaoEspecifica *string `json:"funcao_especifica"`
}
func (s *Service) Update(ctx context.Context, id string, input UpdateEscalaInput) (*generated.AgendaEscala, error) {
parsedUUID, err := uuid.Parse(id)
if err != nil {
return nil, err
}
params := generated.UpdateEscalaParams{
ID: pgtype.UUID{Bytes: parsedUUID, Valid: true},
}
if input.ProfissionalID != nil {
parsedProfID, err := uuid.Parse(*input.ProfissionalID)
if err == nil {
params.ProfissionalID = pgtype.UUID{Bytes: parsedProfID, Valid: true}
}
}
if input.DataHoraInicio != nil {
var t pgtype.Timestamptz
if err := t.Scan(*input.DataHoraInicio); err == nil {
params.DataHoraInicio = t
}
}
if input.DataHoraFim != nil {
var t pgtype.Timestamptz
if err := t.Scan(*input.DataHoraFim); err == nil {
params.DataHoraFim = t
}
}
if input.FuncaoEspecifica != nil {
params.FuncaoEspecifica = pgtype.Text{String: *input.FuncaoEspecifica, Valid: true}
}
escala, err := s.queries.UpdateEscala(ctx, params)
if err != nil {
return nil, err
}
return &escala, nil
}