Coverage for src / tarefas / schemas / tarefa_schema.py: 94%

50 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-18 14:29 -0300

1"""Schemas pydantic do modulo tarefas.""" 

2 

3from datetime import datetime 

4 

5from pydantic import BaseModel, ConfigDict, Field, model_validator 

6 

7from src.tarefas.models import EscopoPrivacidadeTarefa 

8from src.tarefas.models import PrioridadeTarefa 

9from src.tarefas.models import TipoTarefa, VisibilidadeTarefa 

10 

11 

12class TarefaBaseSchema(BaseModel): 

13 """Campos compartilhados de tarefa.""" 

14 

15 titulo: str = Field(min_length=1, max_length=140) 

16 descricao: str | None = Field(default=None, max_length=500) 

17 tipo: TipoTarefa = TipoTarefa.PESSOAL 

18 prioridade: PrioridadeTarefa = PrioridadeTarefa.MEDIA 

19 visibilidade: VisibilidadeTarefa = VisibilidadeTarefa.PUBLICA 

20 escopo_privacidade: EscopoPrivacidadeTarefa | None = None 

21 criador_id: str = Field(min_length=1, max_length=64) 

22 grupo_nome: str | None = Field(default=None, min_length=1, max_length=64) 

23 

24 @model_validator(mode="after") 

25 def validate_visibilidade_privada(self): 

26 """Aplica regras de consistencia para acesso publico/privado.""" 

27 if self.visibilidade == VisibilidadeTarefa.PUBLICA: 

28 if self.escopo_privacidade is not None or self.grupo_nome is not None: 

29 raise ValueError( 

30 "Tarefa publica nao pode ter escopo_privacidade nem grupo_nome." 

31 ) 

32 return self 

33 

34 if self.escopo_privacidade is None: 

35 raise ValueError( 

36 "Tarefa privada exige escopo_privacidade definido." 

37 ) 

38 

39 if self.escopo_privacidade == EscopoPrivacidadeTarefa.CRIADOR: 

40 if self.grupo_nome is not None: 

41 raise ValueError( 

42 "Tarefa privada por criador nao pode ter grupo_nome." 

43 ) 

44 return self 

45 

46 if self.grupo_nome is None: 

47 raise ValueError("Tarefa privada por grupo exige grupo_nome.") 

48 

49 return self 

50 

51 

52class TarefaCreateSchema(TarefaBaseSchema): 

53 """Payload para criacao de tarefa.""" 

54 

55 

56class TarefaUpdateSchema(BaseModel): 

57 """Payload para atualizacao parcial (PATCH).""" 

58 

59 titulo: str | None = Field(default=None, min_length=1, max_length=140) 

60 descricao: str | None = Field(default=None, max_length=500) 

61 concluida: bool | None = None 

62 tipo: TipoTarefa | None = None 

63 prioridade: PrioridadeTarefa | None = None 

64 visibilidade: VisibilidadeTarefa | None = None 

65 escopo_privacidade: EscopoPrivacidadeTarefa | None = None 

66 criador_id: str | None = Field(default=None, min_length=1, max_length=64) 

67 grupo_nome: str | None = Field(default=None, min_length=1, max_length=64) 

68 

69 

70class TarefaConcluirSchema(BaseModel): 

71 """Payload para marcar tarefa como concluida.""" 

72 

73 concluida: bool = True 

74 

75 

76class TarefaResponseSchema(TarefaBaseSchema): 

77 """Payload de saida de tarefa.""" 

78 

79 model_config = ConfigDict(from_attributes=True) 

80 

81 id: int 

82 concluida: bool 

83 criado_em: datetime 

84 atualizado_em: datetime 

85 

86 

87class TarefasResponseSchema(BaseModel): 

88 """Payload da rota de listagem de tarefas.""" 

89 

90 tarefas: list[TarefaResponseSchema]