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
« 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
9class World(Base):
10 __tablename__ = 'worlds'
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)
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")
27class WorldSettings(Base):
28 __tablename__ = 'world_settings'
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)
41 world = relationship("World", back_populates="settings")
44class Campaign(Base):
45 __tablename__ = 'campaigns'
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)
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")
62class MapRegion(Base):
63 __tablename__ = 'map_regions'
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)
74 world = relationship("World", back_populates="regions")
75 lore_entries = relationship("LoreEntry", back_populates="region")
78class Session(Base):
79 __tablename__ = 'sessions'
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)
88 campaign = relationship("Campaign", back_populates="sessions")
89 positions = relationship("PartyPosition", back_populates="session")
92class MapMarker(Base):
93 __tablename__ = 'map_markers'
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)
104 world = relationship("World", back_populates="markers")
107class WorldEvent(Base):
108 __tablename__ = 'world_events'
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)
117 world = relationship("World", back_populates="events")
120class LoreEntry(Base):
121 __tablename__ = 'lore_entries'
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)
130 region = relationship("MapRegion", back_populates="lore_entries")
133class UserCampaignRole(Base):
134 __tablename__ = 'user_campaign_roles'
135 __table_args__ = (UniqueConstraint('user_id', 'campaign_id'),)
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)
144 campaign = relationship("Campaign", back_populates="roles")
147class Notification(Base):
148 __tablename__ = 'notifications'
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)
159 world = relationship("World", back_populates="notifications")
160 campaign = relationship("Campaign", back_populates="notifications")
163class PartyPosition(Base):
164 __tablename__ = 'party_positions'
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)
172 campaign = relationship("Campaign", back_populates="positions")
173 session = relationship("Session", back_populates="positions")
176class WorldTime(Base):
177 __tablename__ = 'world_time'
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)
184 world = relationship("World", back_populates="time")
187class CampaignInvite(Base):
188 __tablename__ = 'campaign_invites'
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)
197 campaign = relationship("Campaign", back_populates="invites")