Coverage for app/db/models.py: 100%

144 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-02 23:27 +0000

1from sqlalchemy import ( 

2 Column, String, Integer, Boolean, ForeignKey, Text, DateTime, JSON, UniqueConstraint 

3) 

4from sqlalchemy.dialects.postgresql import UUID, JSONB 

5from sqlalchemy.orm import declarative_base, relationship 

6from datetime import datetime 

7from app.db.supabaseDB import Base 

8 

9class World(Base): 

10 __tablename__ = 'worlds' 

11 

12 id = Column(Integer, primary_key=True) 

13 name = Column(String(100), unique=True, nullable=False) 

14 description = Column(Text) 

15 created_at = Column(DateTime, default=datetime.now) 

16 created_by = Column(UUID, nullable=True) 

17 

18 campaigns = relationship("Campaign", back_populates="world", cascade="all, delete-orphan") 

19 regions = relationship("MapRegion", back_populates="world", cascade="all, delete-orphan") 

20 events = relationship("WorldEvent", back_populates="world", cascade="all, delete-orphan") 

21 markers = relationship("MapMarker", back_populates="world", cascade="all, delete-orphan") 

22 settings = relationship("WorldSettings", back_populates="world", uselist=False, cascade="all, delete-orphan") 

23 notifications = relationship("Notification", back_populates="world", cascade="all, delete-orphan") 

24 time = relationship("WorldTime", back_populates="world", uselist=False, cascade="all, delete-orphan") 

25 

26 

27class WorldSettings(Base): 

28 __tablename__ = 'world_settings' 

29 

30 id = Column(Integer, primary_key=True) 

31 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE'), unique=True) 

32 allow_public_visibility = Column(Boolean, default=False) 

33 join_method = Column(String(20)) 

34 max_campaigns = Column(Integer, default=5) 

35 allow_dm_invites = Column(Boolean, default=True) 

36 enable_fog_of_war = Column(Boolean, default=True) 

37 inter_party_visibility = Column(Boolean, default=False) 

38 spectator_map_visibility = Column(Boolean, default=True) 

39 show_party_position_globally = Column(Boolean, default=False) 

40 

41 world = relationship("World", back_populates="settings") 

42 

43 

44class Campaign(Base): 

45 __tablename__ = 'campaigns' 

46 

47 id = Column(Integer, primary_key=True) 

48 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE')) 

49 dm_id = Column(UUID, ForeignKey('auth.users.id', ondelete='SET NULL')) 

50 name = Column(String(100), nullable=False) 

51 current_session_number = Column(Integer, default=0) 

52 created_at = Column(DateTime, default=datetime.now) 

53 

54 world = relationship("World", back_populates="campaigns") 

55 sessions = relationship("Session", back_populates="campaign", cascade="all, delete-orphan") 

56 positions = relationship("PartyPosition", back_populates="campaign", cascade="all, delete-orphan") 

57 invites = relationship("CampaignInvite", back_populates="campaign", cascade="all, delete-orphan") 

58 notifications = relationship("Notification", back_populates="campaign", cascade="all, delete-orphan") 

59 roles = relationship("UserCampaignRole", back_populates="campaign", cascade="all, delete-orphan") 

60 

61 

62class MapRegion(Base): 

63 __tablename__ = 'map_regions' 

64 

65 id = Column(Integer, primary_key=True) 

66 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE')) 

67 name = Column(String(100), nullable=False) 

68 description = Column(Text) 

69 coordinates = Column(JSONB) 

70 is_revealed = Column(Boolean, default=False) 

71 revealed_at_session = Column(Integer, nullable=False) 

72 created_at = Column(DateTime, default=datetime.now) 

73 

74 world = relationship("World", back_populates="regions") 

75 lore_entries = relationship("LoreEntry", back_populates="region") 

76 

77 

78class Session(Base): 

79 __tablename__ = 'sessions' 

80 

81 id = Column(Integer, primary_key=True) 

82 campaign_id = Column(Integer, ForeignKey('campaigns.id', ondelete='CASCADE')) 

83 session_number = Column(Integer, nullable=False) 

84 path_data = Column(JSONB) 

85 summary = Column(Text) 

86 created_at = Column(DateTime, default=datetime.now) 

87 

88 campaign = relationship("Campaign", back_populates="sessions") 

89 positions = relationship("PartyPosition", back_populates="session") 

90 

91 

92class MapMarker(Base): 

93 __tablename__ = 'map_markers' 

94 

95 id = Column(Integer, primary_key=True) 

96 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE')) 

97 created_by = Column(UUID, ForeignKey('auth.users.id', ondelete='SET NULL')) 

98 name = Column(String(100)) 

99 description = Column(Text) 

100 coordinates = Column(JSONB) 

101 is_personal = Column(Boolean, default=False) 

102 created_at = Column(DateTime, default=datetime.now) 

103 

104 world = relationship("World", back_populates="markers") 

105 

106 

107class WorldEvent(Base): 

108 __tablename__ = 'world_events' 

109 

110 id = Column(Integer, primary_key=True) 

111 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE')) 

112 title = Column(String(150), nullable=False) 

113 description = Column(Text) 

114 visible_at_session = Column(Integer) 

115 created_at = Column(DateTime, default=datetime.now) 

116 

117 world = relationship("World", back_populates="events") 

118 

119 

120class LoreEntry(Base): 

121 __tablename__ = 'lore_entries' 

122 

123 id = Column(Integer, primary_key=True) 

124 region_id = Column(Integer, ForeignKey('map_regions.id', ondelete='CASCADE')) 

125 title = Column(String(150), nullable=False) 

126 content = Column(Text) 

127 created_by = Column(UUID, ForeignKey('auth.users.id', ondelete='SET NULL')) 

128 created_at = Column(DateTime, default=datetime.now) 

129 

130 region = relationship("MapRegion", back_populates="lore_entries") 

131 

132 

133class UserCampaignRole(Base): 

134 __tablename__ = 'user_campaign_roles' 

135 __table_args__ = (UniqueConstraint('user_id', 'campaign_id'),) 

136 

137 id = Column(Integer, primary_key=True) 

138 user_id = Column(UUID, ForeignKey('auth.users.id', ondelete='CASCADE'), nullable=False) 

139 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE'), nullable=False) 

140 campaign_id = Column(Integer, ForeignKey('campaigns.id', ondelete='CASCADE'), nullable=False) 

141 role = Column(String(32), nullable=False) 

142 joined_at = Column(DateTime, default=datetime.now) 

143 

144 campaign = relationship("Campaign", back_populates="roles") 

145 

146 

147class Notification(Base): 

148 __tablename__ = 'notifications' 

149 

150 id = Column(Integer, primary_key=True) 

151 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE')) 

152 campaign_id = Column(Integer, ForeignKey('campaigns.id', ondelete='CASCADE')) 

153 user_id = Column(UUID, ForeignKey('auth.users.id', ondelete='SET NULL')) 

154 title = Column(String(200)) 

155 message = Column(Text) 

156 type = Column(String(30)) 

157 created_at = Column(DateTime, default=datetime.now) 

158 

159 world = relationship("World", back_populates="notifications") 

160 campaign = relationship("Campaign", back_populates="notifications") 

161 

162 

163class PartyPosition(Base): 

164 __tablename__ = 'party_positions' 

165 

166 id = Column(Integer, primary_key=True) 

167 campaign_id = Column(Integer, ForeignKey('campaigns.id', ondelete='CASCADE')) 

168 session_id = Column(Integer, ForeignKey('sessions.id', ondelete='CASCADE')) 

169 position = Column(JSONB, nullable=False) 

170 created_at = Column(DateTime, default=datetime.now) 

171 

172 campaign = relationship("Campaign", back_populates="positions") 

173 session = relationship("Session", back_populates="positions") 

174 

175 

176class WorldTime(Base): 

177 __tablename__ = 'world_time' 

178 

179 id = Column(Integer, primary_key=True) 

180 world_id = Column(Integer, ForeignKey('worlds.id', ondelete='CASCADE'), unique=True, nullable=False) 

181 world_date = Column(String(100)) 

182 last_updated = Column(DateTime, default=datetime.now) 

183 

184 world = relationship("World", back_populates="time") 

185 

186 

187class CampaignInvite(Base): 

188 __tablename__ = 'campaign_invites' 

189 

190 id = Column(Integer, primary_key=True) 

191 campaign_id = Column(Integer, ForeignKey('campaigns.id', ondelete='CASCADE')) 

192 user_id = Column(UUID, ForeignKey('auth.users.id', ondelete='CASCADE')) 

193 invited_by = Column(UUID) 

194 status = Column(String(20), default='pending') 

195 created_at = Column(DateTime, default=datetime.now) 

196 

197 campaign = relationship("Campaign", back_populates="invites") 

198