Coverage for src / avisos / models / aviso_model.py: 100%

29 statements  

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

1"""Modelo SQLModel e enums do modulo avisos.""" 

2 

3from datetime import datetime 

4from enum import Enum 

5 

6from sqlalchemy import JSON, CheckConstraint, Column, DateTime, SmallInteger 

7from sqlalchemy import Enum as SAEnum 

8from sqlalchemy import String 

9 

10from src.database.base import Base 

11from sqlmodel import Field 

12 

13 

14class NivelAcesso(str, Enum): 

15 """Niveis de acesso disponiveis para o aviso.""" 

16 

17 PUBLICO = "publico" 

18 PRIVADO = "privado" 

19 

20 

21class CategoriaAcessoPrivado(str, Enum): 

22 """Categorias usadas quando o aviso e privado.""" 

23 

24 ADMINISTRATIVO = "administrativo" 

25 USUARIO = "usuario" 

26 ESPECIFICO = "especifico" 

27 

28 

29class EscopoGrupos(str, Enum): 

30 """Escopo de grupos para avisos privados.""" 

31 

32 TODOS = "todos" 

33 GRUPOS = "grupos" 

34 

35 

36class Aviso(Base, table=True): 

37 """Tabela de avisos exibidos pela API.""" 

38 

39 __tablename__ = "avisos" 

40 __table_args__ = ( 

41 CheckConstraint( 

42 "prioridade BETWEEN 0 AND 4", 

43 name="ck_avisos_prioridade", 

44 ), 

45 CheckConstraint( 

46 "data_fim >= data_inicio", 

47 name="ck_avisos_periodo_valido", 

48 ), 

49 CheckConstraint( 

50 "(" 

51 "nivel_acesso = 'publico' AND " 

52 "categoria_privada IS NULL AND " 

53 "escopo_grupos IS NULL AND " 

54 "grupos IS NULL" 

55 ") OR (" 

56 "nivel_acesso = 'privado' AND " 

57 "categoria_privada IS NOT NULL AND " 

58 "escopo_grupos IS NOT NULL" 

59 ")", 

60 name="ck_avisos_regras_acesso", 

61 ), 

62 CheckConstraint( 

63 "escopo_grupos IS NULL OR " 

64 "escopo_grupos = 'todos' OR " 

65 "(escopo_grupos = 'grupos' AND grupos IS NOT NULL)", 

66 name="ck_avisos_grupos_privados", 

67 ), 

68 ) 

69 

70 id: int | None = Field(default=None, primary_key=True, index=True) 

71 titulo: str = Field( 

72 sa_column=Column(String(120), nullable=False), 

73 ) 

74 data_inicio: datetime = Field( 

75 sa_column=Column(DateTime(timezone=True), nullable=False), 

76 ) 

77 data_fim: datetime = Field( 

78 sa_column=Column(DateTime(timezone=True), nullable=False), 

79 ) 

80 prioridade: int = Field( 

81 default=0, 

82 sa_column=Column( 

83 SmallInteger, 

84 nullable=False, 

85 default=0, 

86 server_default="0", 

87 ), 

88 ) 

89 nivel_acesso: NivelAcesso = Field( 

90 default=NivelAcesso.PUBLICO, 

91 sa_column=Column( 

92 SAEnum( 

93 NivelAcesso, 

94 native_enum=False, 

95 length=20, 

96 values_callable=lambda enum_cls: [ 

97 item.value for item in enum_cls 

98 ], 

99 ), 

100 nullable=False, 

101 default=NivelAcesso.PUBLICO.value, 

102 server_default=NivelAcesso.PUBLICO.value, 

103 ), 

104 ) 

105 categoria_privada: CategoriaAcessoPrivado | None = Field( 

106 default=None, 

107 sa_column=Column( 

108 SAEnum( 

109 CategoriaAcessoPrivado, 

110 native_enum=False, 

111 length=20, 

112 values_callable=lambda enum_cls: [ 

113 item.value for item in enum_cls 

114 ], 

115 ), 

116 nullable=True, 

117 ), 

118 ) 

119 escopo_grupos: EscopoGrupos | None = Field( 

120 default=None, 

121 sa_column=Column( 

122 SAEnum( 

123 EscopoGrupos, 

124 native_enum=False, 

125 length=20, 

126 values_callable=lambda enum_cls: [ 

127 item.value for item in enum_cls 

128 ], 

129 ), 

130 nullable=True, 

131 ), 

132 ) 

133 grupos: list[str] | None = Field( 

134 default=None, 

135 sa_column=Column( 

136 JSON(none_as_null=True), 

137 nullable=True, 

138 ), 

139 )