Pushpendra Sharma commited on
Commit
b55355a
·
1 Parent(s): 6263792

db-models: Create core database models for issues and users

Browse files
Files changed (1) hide show
  1. Backend/database/models.py +174 -0
Backend/database/models.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+ from typing import Optional
3
+ from uuid import UUID, uuid4
4
+ from sqlalchemy import Boolean, DateTime, Float, ForeignKey, Integer, String, Text, func
5
+ from sqlalchemy.dialects.postgresql import UUID as PGUUID
6
+ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
7
+
8
+
9
+ class Base(DeclarativeBase):
10
+ pass
11
+
12
+
13
+ class Department(Base):
14
+ __tablename__ = "departments"
15
+
16
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
17
+ name: Mapped[str] = mapped_column(String(100), nullable=False, unique=True)
18
+ code: Mapped[str] = mapped_column(String(20), nullable=False, unique=True)
19
+ description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
20
+
21
+ categories: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
22
+
23
+ default_sla_hours: Mapped[int] = mapped_column(Integer, default=48)
24
+ escalation_email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
25
+
26
+ is_active: Mapped[bool] = mapped_column(Boolean, default=True)
27
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now())
28
+ updated_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now())
29
+
30
+ members: Mapped[list["Member"]] = relationship(back_populates="department", lazy="selectin")
31
+
32
+
33
+ class Member(Base):
34
+ __tablename__ = "members"
35
+
36
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
37
+ department_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("departments.id", ondelete="SET NULL"), nullable=True, index=True)
38
+
39
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
40
+ email: Mapped[str] = mapped_column(String(255), nullable=False, unique=True)
41
+ phone: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
42
+ password_hash: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
43
+
44
+ role: Mapped[str] = mapped_column(String(50), default="worker")
45
+ city: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True)
46
+ locality: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
47
+
48
+ is_active: Mapped[bool] = mapped_column(Boolean, default=True)
49
+ current_workload: Mapped[int] = mapped_column(Integer, default=0)
50
+ max_workload: Mapped[int] = mapped_column(Integer, default=10)
51
+
52
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now())
53
+ updated_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now())
54
+
55
+ department: Mapped[Optional["Department"]] = relationship(back_populates="members")
56
+
57
+
58
+
59
+
60
+ class Issue(Base):
61
+ __tablename__ = "issues"
62
+
63
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
64
+ user_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, index=True)
65
+ description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
66
+ latitude: Mapped[float] = mapped_column(Float, nullable=False, index=True)
67
+ longitude: Mapped[float] = mapped_column(Float, nullable=False, index=True)
68
+ accuracy_meters: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
69
+
70
+ state: Mapped[str] = mapped_column(String(20), default="reported", index=True)
71
+ priority: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True)
72
+ priority_reason: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
73
+
74
+ validation_source: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
75
+ validation_reason: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
76
+
77
+ is_duplicate: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
78
+ parent_issue_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("issues.id"), nullable=True)
79
+ geo_cluster_id: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, index=True)
80
+
81
+ platform: Mapped[str] = mapped_column(String(50), nullable=False)
82
+ device_model: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
83
+
84
+ department_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("departments.id"), nullable=True)
85
+ assigned_member_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("members.id"), nullable=True)
86
+ city: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True)
87
+ locality: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
88
+ full_address: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
89
+
90
+ sla_deadline: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
91
+ sla_hours: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
92
+ escalation_level: Mapped[int] = mapped_column(Integer, default=0)
93
+ escalated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
94
+
95
+ resolved_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, index=True)
96
+ resolution_notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
97
+ proof_image_path: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
98
+ completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
99
+
100
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), index=True)
101
+ updated_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now())
102
+
103
+
104
+ images: Mapped[list["IssueImage"]] = relationship(back_populates="issue", lazy="selectin", foreign_keys="IssueImage.issue_id")
105
+ classification: Mapped[Optional["Classification"]] = relationship(back_populates="issue", uselist=False, lazy="selectin")
106
+
107
+ department: Mapped[Optional["Department"]] = relationship("Department", lazy="selectin")
108
+ assigned_member: Mapped[Optional["Member"]] = relationship("Member", foreign_keys=[assigned_member_id], lazy="selectin")
109
+
110
+ events: Mapped[list["IssueEvent"]] = relationship(back_populates="issue", lazy="noload")
111
+ duplicates: Mapped[list["Issue"]] = relationship(back_populates="parent_issue", foreign_keys=[parent_issue_id])
112
+ parent_issue: Mapped[Optional["Issue"]] = relationship(back_populates="duplicates", remote_side=[id], foreign_keys=[parent_issue_id])
113
+
114
+
115
+ class IssueImage(Base):
116
+ __tablename__ = "issue_images"
117
+
118
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
119
+ issue_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("issues.id", ondelete="CASCADE"), index=True)
120
+ file_path: Mapped[str] = mapped_column(String(500), nullable=False)
121
+ annotated_path: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
122
+ original_filename: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
123
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now())
124
+
125
+ issue: Mapped["Issue"] = relationship(back_populates="images", foreign_keys=[issue_id])
126
+
127
+
128
+ class Classification(Base):
129
+ __tablename__ = "classifications"
130
+
131
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
132
+ issue_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("issues.id", ondelete="CASCADE"), unique=True)
133
+
134
+ primary_category: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True)
135
+ primary_confidence: Mapped[float] = mapped_column(Float, default=0.0)
136
+
137
+ detections_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
138
+ inference_time_ms: Mapped[float] = mapped_column(Float, default=0.0)
139
+ model_version: Mapped[str] = mapped_column(String(20), default="1.0")
140
+
141
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now())
142
+
143
+ issue: Mapped["Issue"] = relationship(back_populates="classification")
144
+
145
+
146
+ class IssueEvent(Base):
147
+ __tablename__ = "issue_events"
148
+
149
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
150
+ issue_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("issues.id", ondelete="CASCADE"), index=True)
151
+
152
+ event_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
153
+ agent_name: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
154
+ event_data: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
155
+
156
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now(), index=True)
157
+
158
+ issue: Mapped["Issue"] = relationship(back_populates="events")
159
+
160
+
161
+ class Escalation(Base):
162
+ __tablename__ = "escalations"
163
+
164
+ id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
165
+ issue_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("issues.id", ondelete="CASCADE"), index=True)
166
+
167
+ from_level: Mapped[int] = mapped_column(Integer, nullable=False)
168
+ to_level: Mapped[int] = mapped_column(Integer, nullable=False)
169
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
170
+
171
+ escalated_by: Mapped[str] = mapped_column(String(50), default="system")
172
+ notified_emails: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
173
+
174
+ created_at: Mapped[datetime] = mapped_column(DateTime, default=func.now())