f3-data-models 0.4.1__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/PKG-INFO +2 -1
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/f3_data_models/models.py +162 -148
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/pyproject.toml +25 -1
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/README.md +0 -0
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/f3_data_models/__init__.py +0 -0
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/f3_data_models/testing.py +0 -0
- {f3_data_models-0.4.1 → f3_data_models-0.4.3}/f3_data_models/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: f3-data-models
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.3
|
4
4
|
Summary: The data schema and models for F3 Nation applications.
|
5
5
|
License: MIT
|
6
6
|
Author: Evan Petzoldt
|
@@ -21,6 +21,7 @@ Requires-Dist: sphinx-autodoc-typehints (>=2.5.0,<3.0.0)
|
|
21
21
|
Requires-Dist: sphinx-multiversion (>=0.2.4,<0.3.0)
|
22
22
|
Requires-Dist: sphinx-rtd-theme (>=3.0.2,<4.0.0)
|
23
23
|
Requires-Dist: sqlalchemy (>=2.0.36,<3.0.0)
|
24
|
+
Requires-Dist: sqlalchemy-citext (>=1.8.0,<2.0.0)
|
24
25
|
Requires-Dist: sqlalchemy-schemadisplay (>=2.0,<3.0)
|
25
26
|
Requires-Dist: sqlmodel (>=0.0.22,<0.0.23)
|
26
27
|
Project-URL: Documentation, https://github.io/F3-Nation/f3-data-models
|
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
import enum
|
2
|
+
from datetime import date, datetime, time
|
2
3
|
from typing import Any, Dict, List, Optional
|
4
|
+
|
5
|
+
from citext import CIText
|
3
6
|
from sqlalchemy import (
|
4
7
|
ARRAY,
|
5
8
|
JSON,
|
@@ -9,24 +12,24 @@ from sqlalchemy import (
|
|
9
12
|
VARCHAR,
|
10
13
|
Boolean,
|
11
14
|
DateTime,
|
15
|
+
Enum,
|
12
16
|
Float,
|
13
17
|
ForeignKey,
|
18
|
+
Index,
|
14
19
|
Integer,
|
15
|
-
func,
|
16
20
|
UniqueConstraint,
|
17
|
-
Enum,
|
18
21
|
Uuid,
|
22
|
+
func,
|
19
23
|
inspect,
|
20
24
|
)
|
21
|
-
from typing_extensions import Annotated
|
22
25
|
from sqlalchemy.orm import (
|
23
26
|
DeclarativeBase,
|
24
|
-
mapped_column,
|
25
27
|
Mapped,
|
28
|
+
mapped_column,
|
26
29
|
relationship,
|
27
30
|
)
|
28
31
|
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
29
|
-
import
|
32
|
+
from typing_extensions import Annotated
|
30
33
|
|
31
34
|
# Custom Annotations
|
32
35
|
time_notz = Annotated[time, TIME(timezone=False)]
|
@@ -34,9 +37,7 @@ time_with_tz = Annotated[time, TIME(timezone=True)]
|
|
34
37
|
ts_notz = Annotated[datetime, DateTime(timezone=False)]
|
35
38
|
text = Annotated[str, TEXT]
|
36
39
|
intpk = Annotated[int, mapped_column(Integer, primary_key=True, autoincrement=True)]
|
37
|
-
dt_create = Annotated[
|
38
|
-
datetime, mapped_column(DateTime, server_default=func.timezone("utc", func.now()))
|
39
|
-
]
|
40
|
+
dt_create = Annotated[datetime, mapped_column(DateTime, server_default=func.timezone("utc", func.now()))]
|
40
41
|
dt_update = Annotated[
|
41
42
|
datetime,
|
42
43
|
mapped_column(
|
@@ -48,30 +49,70 @@ dt_update = Annotated[
|
|
48
49
|
|
49
50
|
|
50
51
|
class User_Status(enum.Enum):
|
52
|
+
"""
|
53
|
+
Enum representing the status of a user.
|
54
|
+
|
55
|
+
Attributes:
|
56
|
+
active
|
57
|
+
inactive
|
58
|
+
deleted
|
59
|
+
"""
|
60
|
+
|
51
61
|
active = 1
|
52
62
|
inactive = 2
|
53
63
|
deleted = 3
|
54
64
|
|
55
65
|
|
56
66
|
class Region_Role(enum.Enum):
|
67
|
+
"""
|
68
|
+
Enum representing the roles within a region.
|
69
|
+
|
70
|
+
Attributes:
|
71
|
+
user
|
72
|
+
editor
|
73
|
+
admin
|
74
|
+
"""
|
75
|
+
|
57
76
|
user = 1
|
58
77
|
editor = 2
|
59
78
|
admin = 3
|
60
79
|
|
61
80
|
|
62
81
|
class User_Role(enum.Enum):
|
82
|
+
"""
|
83
|
+
Enum representing the roles of a user.
|
84
|
+
|
85
|
+
Attributes:
|
86
|
+
user
|
87
|
+
editor
|
88
|
+
admin
|
89
|
+
"""
|
90
|
+
|
63
91
|
user = 1
|
64
92
|
editor = 2
|
65
93
|
admin = 3
|
66
94
|
|
67
95
|
|
68
96
|
class Update_Request_Status(enum.Enum):
|
97
|
+
"""
|
98
|
+
Enum representing the status of an update request.
|
99
|
+
|
100
|
+
Attributes:
|
101
|
+
pending
|
102
|
+
approved
|
103
|
+
rejected
|
104
|
+
"""
|
105
|
+
|
69
106
|
pending = 1
|
70
107
|
approved = 2
|
71
108
|
rejected = 3
|
72
109
|
|
73
110
|
|
74
111
|
class Day_Of_Week(enum.Enum):
|
112
|
+
"""
|
113
|
+
Enum representing the days of the week.
|
114
|
+
"""
|
115
|
+
|
75
116
|
monday = 0
|
76
117
|
tuesday = 1
|
77
118
|
wednesday = 2
|
@@ -82,11 +123,30 @@ class Day_Of_Week(enum.Enum):
|
|
82
123
|
|
83
124
|
|
84
125
|
class Event_Cadence(enum.Enum):
|
126
|
+
"""
|
127
|
+
Enum representing the cadence of an event.
|
128
|
+
|
129
|
+
Attributes:
|
130
|
+
weekly
|
131
|
+
monthly
|
132
|
+
"""
|
133
|
+
|
85
134
|
weekly = 1
|
86
135
|
monthly = 2
|
87
136
|
|
88
137
|
|
89
138
|
class Org_Type(enum.Enum):
|
139
|
+
"""
|
140
|
+
Enum representing the type of organization.
|
141
|
+
|
142
|
+
Attributes:
|
143
|
+
ao
|
144
|
+
region
|
145
|
+
area
|
146
|
+
sector
|
147
|
+
nation
|
148
|
+
"""
|
149
|
+
|
90
150
|
ao = 1
|
91
151
|
region = 2
|
92
152
|
area = 3
|
@@ -95,12 +155,31 @@ class Org_Type(enum.Enum):
|
|
95
155
|
|
96
156
|
|
97
157
|
class Event_Category(enum.Enum):
|
158
|
+
"""
|
159
|
+
Enum representing the category of an event.
|
160
|
+
|
161
|
+
Attributes:
|
162
|
+
first_f
|
163
|
+
second_f
|
164
|
+
third_f
|
165
|
+
"""
|
166
|
+
|
98
167
|
first_f = 1
|
99
168
|
second_f = 2
|
100
169
|
third_f = 3
|
101
170
|
|
102
171
|
|
103
172
|
class Request_Type(enum.Enum):
|
173
|
+
"""
|
174
|
+
Enum representing the type of request.
|
175
|
+
|
176
|
+
Attributes:
|
177
|
+
create_location
|
178
|
+
create_event
|
179
|
+
edit
|
180
|
+
delete_event
|
181
|
+
"""
|
182
|
+
|
104
183
|
create_location = 1
|
105
184
|
create_event = 2
|
106
185
|
edit = 3
|
@@ -153,11 +232,7 @@ class Base(DeclarativeBase):
|
|
153
232
|
Returns:
|
154
233
|
dict: A dictionary representation of the model instance.
|
155
234
|
"""
|
156
|
-
return {
|
157
|
-
c.key: self.get(c.key)
|
158
|
-
for c in self.__table__.columns
|
159
|
-
if c.key not in ["created", "updated"]
|
160
|
-
}
|
235
|
+
return {c.key: self.get(c.key) for c in self.__table__.columns if c.key not in ["created", "updated"]}
|
161
236
|
|
162
237
|
def to_update_dict(self) -> Dict[InstrumentedAttribute, Any]:
|
163
238
|
update_dict = {}
|
@@ -173,7 +248,7 @@ class Base(DeclarativeBase):
|
|
173
248
|
related_value = getattr(self, rel.key)
|
174
249
|
if related_value is not None:
|
175
250
|
if rel.uselist:
|
176
|
-
update_dict[rel] =
|
251
|
+
update_dict[rel] = list(related_value)
|
177
252
|
print(rel, update_dict[rel])
|
178
253
|
else:
|
179
254
|
update_dict[rel] = related_value
|
@@ -283,9 +358,7 @@ class Role_x_Permission(Base):
|
|
283
358
|
__tablename__ = "roles_x_permissions"
|
284
359
|
|
285
360
|
role_id: Mapped[int] = mapped_column(ForeignKey("roles.id"), primary_key=True)
|
286
|
-
permission_id: Mapped[int] = mapped_column(
|
287
|
-
ForeignKey("permissions.id"), primary_key=True
|
288
|
-
)
|
361
|
+
permission_id: Mapped[int] = mapped_column(ForeignKey("permissions.id"), primary_key=True)
|
289
362
|
|
290
363
|
|
291
364
|
class Role_x_User_x_Org(Base):
|
@@ -334,7 +407,7 @@ class Org(Base):
|
|
334
407
|
achievements (Optional[List[Achievement]]): The achievements available within the organization.
|
335
408
|
parent_org (Optional[Org]): The parent organization.
|
336
409
|
slack_space (Optional[SlackSpace]): The associated Slack workspace.
|
337
|
-
"""
|
410
|
+
""" # noqa: E501
|
338
411
|
|
339
412
|
__tablename__ = "orgs"
|
340
413
|
|
@@ -356,9 +429,13 @@ class Org(Base):
|
|
356
429
|
created: Mapped[dt_create]
|
357
430
|
updated: Mapped[dt_update]
|
358
431
|
|
359
|
-
|
360
|
-
"
|
432
|
+
__table_args__ = (
|
433
|
+
Index("idx_orgs_parent_id", "parent_id"),
|
434
|
+
Index("idx_orgs_org_type", "org_type"),
|
435
|
+
Index("idx_orgs_is_active", "is_active"),
|
361
436
|
)
|
437
|
+
|
438
|
+
locations: Mapped[Optional[List["Location"]]] = relationship("Location", cascade="expunge")
|
362
439
|
event_types: Mapped[Optional[List["EventType"]]] = relationship(
|
363
440
|
"EventType",
|
364
441
|
primaryjoin="or_(EventType.specific_org_id == Org.id, EventType.specific_org_id.is_(None))",
|
@@ -376,9 +453,7 @@ class Org(Base):
|
|
376
453
|
cascade="expunge",
|
377
454
|
primaryjoin="or_(Achievement.specific_org_id == Org.id, Achievement.specific_org_id.is_(None))",
|
378
455
|
)
|
379
|
-
parent_org: Mapped[Optional["Org"]] = relationship(
|
380
|
-
"Org", remote_side=[id], cascade="expunge"
|
381
|
-
)
|
456
|
+
parent_org: Mapped[Optional["Org"]] = relationship("Org", remote_side=[id], cascade="expunge")
|
382
457
|
slack_space: Mapped[Optional["SlackSpace"]] = relationship(
|
383
458
|
"SlackSpace", secondary="orgs_x_slack_spaces", cascade="expunge"
|
384
459
|
)
|
@@ -397,7 +472,7 @@ class EventType(Base):
|
|
397
472
|
specific_org_id (Optional[int]): The ID of the specific organization.
|
398
473
|
created (datetime): The timestamp when the record was created.
|
399
474
|
updated (datetime): The timestamp when the record was last updated.
|
400
|
-
"""
|
475
|
+
""" # noqa: E501
|
401
476
|
|
402
477
|
__tablename__ = "event_types"
|
403
478
|
|
@@ -420,37 +495,20 @@ class EventType_x_Event(Base):
|
|
420
495
|
event_type_id (int): The ID of the associated event type.
|
421
496
|
|
422
497
|
event (Event): The associated event.
|
423
|
-
"""
|
498
|
+
""" # noqa: E501
|
424
499
|
|
425
500
|
__tablename__ = "events_x_event_types"
|
426
501
|
|
427
502
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), primary_key=True)
|
428
|
-
event_type_id: Mapped[int] = mapped_column(
|
429
|
-
|
503
|
+
event_type_id: Mapped[int] = mapped_column(ForeignKey("event_types.id"), primary_key=True)
|
504
|
+
__table_args__ = (
|
505
|
+
Index("idx_events_x_event_types_event_id", "event_id"),
|
506
|
+
Index("idx_events_x_event_types_event_type_id", "event_type_id"),
|
430
507
|
)
|
431
508
|
|
432
509
|
event: Mapped["Event"] = relationship(back_populates="event_x_event_types")
|
433
510
|
|
434
511
|
|
435
|
-
# class EventType_x_Org(Base):
|
436
|
-
# """
|
437
|
-
# Model representing the association between event types and organizations. This controls which event types are available for selection at the region level, as well as default types for each AO.
|
438
|
-
|
439
|
-
# Attributes:
|
440
|
-
# event_type_id (int): The ID of the associated event type.
|
441
|
-
# org_id (int): The ID of the associated organization.
|
442
|
-
# is_default (bool): Whether this is the default event type for the organization. Default is False.
|
443
|
-
# """
|
444
|
-
|
445
|
-
# __tablename__ = "event_types_x_org"
|
446
|
-
|
447
|
-
# event_type_id: Mapped[int] = mapped_column(
|
448
|
-
# ForeignKey("event_types.id"), primary_key=True
|
449
|
-
# )
|
450
|
-
# org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"), primary_key=True)
|
451
|
-
# is_default: Mapped[bool] = mapped_column(Boolean, default=False)
|
452
|
-
|
453
|
-
|
454
512
|
class EventTag(Base):
|
455
513
|
"""
|
456
514
|
Model representing an event tag. These are used to mark special events, such as anniversaries or special workouts.
|
@@ -485,37 +543,16 @@ class EventTag_x_Event(Base):
|
|
485
543
|
event_tag_id (int): The ID of the associated event tag.
|
486
544
|
|
487
545
|
event (Event): The associated event.
|
488
|
-
"""
|
546
|
+
""" # noqa: E501
|
489
547
|
|
490
548
|
__tablename__ = "event_tags_x_events"
|
491
549
|
|
492
550
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), primary_key=True)
|
493
|
-
event_tag_id: Mapped[int] = mapped_column(
|
494
|
-
ForeignKey("event_tags.id"), primary_key=True
|
495
|
-
)
|
551
|
+
event_tag_id: Mapped[int] = mapped_column(ForeignKey("event_tags.id"), primary_key=True)
|
496
552
|
|
497
553
|
event: Mapped["Event"] = relationship(back_populates="event_x_event_tags")
|
498
554
|
|
499
555
|
|
500
|
-
# class EventTag_x_Org(Base):
|
501
|
-
# """
|
502
|
-
# Model representing the association between event tags and organizations. Controls which event tags are available for selection at the region level.
|
503
|
-
|
504
|
-
# Attributes:
|
505
|
-
# event_tag_id (int): The ID of the associated event tag.
|
506
|
-
# org_id (int): The ID of the associated organization.
|
507
|
-
# color_override (Optional[str]): The calendar color override for the event tag (if the region wants to use something other than the default).
|
508
|
-
# """
|
509
|
-
|
510
|
-
# __tablename__ = "event_tags_x_org"
|
511
|
-
|
512
|
-
# event_tag_id: Mapped[int] = mapped_column(
|
513
|
-
# ForeignKey("event_tags.id"), primary_key=True
|
514
|
-
# )
|
515
|
-
# org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"), primary_key=True)
|
516
|
-
# color_override: Mapped[Optional[str]]
|
517
|
-
|
518
|
-
|
519
556
|
class Org_x_SlackSpace(Base):
|
520
557
|
"""
|
521
558
|
Model representing the association between organizations and Slack workspaces. This is currently meant to be one to one, but theoretically could support multiple workspaces per organization.
|
@@ -523,14 +560,12 @@ class Org_x_SlackSpace(Base):
|
|
523
560
|
Attributes:
|
524
561
|
org_id (int): The ID of the associated organization.
|
525
562
|
slack_space_id (str): The ID of the associated Slack workspace.
|
526
|
-
"""
|
563
|
+
""" # noqa: E501
|
527
564
|
|
528
565
|
__tablename__ = "orgs_x_slack_spaces"
|
529
566
|
|
530
567
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"), primary_key=True)
|
531
|
-
slack_space_id: Mapped[int] = mapped_column(
|
532
|
-
ForeignKey("slack_spaces.id"), primary_key=True
|
533
|
-
)
|
568
|
+
slack_space_id: Mapped[int] = mapped_column(ForeignKey("slack_spaces.id"), primary_key=True)
|
534
569
|
|
535
570
|
|
536
571
|
class Location(Base):
|
@@ -554,7 +589,7 @@ class Location(Base):
|
|
554
589
|
meta (Optional[Dict[str, Any]]): Additional metadata for the location.
|
555
590
|
created (datetime): The timestamp when the record was created.
|
556
591
|
updated (datetime): The timestamp when the record was last updated.
|
557
|
-
"""
|
592
|
+
""" # noqa: E501
|
558
593
|
|
559
594
|
__tablename__ = "locations"
|
560
595
|
|
@@ -564,12 +599,8 @@ class Location(Base):
|
|
564
599
|
description: Mapped[Optional[text]]
|
565
600
|
is_active: Mapped[bool]
|
566
601
|
email: Mapped[Optional[str]]
|
567
|
-
latitude: Mapped[Optional[float]] = mapped_column(
|
568
|
-
|
569
|
-
)
|
570
|
-
longitude: Mapped[Optional[float]] = mapped_column(
|
571
|
-
Float(precision=8, decimal_return_scale=5)
|
572
|
-
)
|
602
|
+
latitude: Mapped[Optional[float]] = mapped_column(Float(precision=8, decimal_return_scale=5))
|
603
|
+
longitude: Mapped[Optional[float]] = mapped_column(Float(precision=8, decimal_return_scale=5))
|
573
604
|
address_street: Mapped[Optional[str]]
|
574
605
|
address_street2: Mapped[Optional[str]]
|
575
606
|
address_city: Mapped[Optional[str]]
|
@@ -580,6 +611,12 @@ class Location(Base):
|
|
580
611
|
created: Mapped[dt_create]
|
581
612
|
updated: Mapped[dt_update]
|
582
613
|
|
614
|
+
__table_args__ = (
|
615
|
+
Index("idx_locations_org_id", "org_id"),
|
616
|
+
Index("idx_locations_name", "name"),
|
617
|
+
Index("idx_locations_is_active", "is_active"),
|
618
|
+
)
|
619
|
+
|
583
620
|
|
584
621
|
class Event(Base):
|
585
622
|
"""
|
@@ -622,7 +659,7 @@ class Event(Base):
|
|
622
659
|
event_tags (Optional[List[EventTag]]): The associated event tags.
|
623
660
|
event_x_event_types (List[EventType_x_Event]): The association between the event and event types.
|
624
661
|
event_x_event_tags (Optional[List[EventTag_x_Event]]): The association between the event and event tags.
|
625
|
-
"""
|
662
|
+
""" # noqa: E501
|
626
663
|
|
627
664
|
__tablename__ = "events"
|
628
665
|
|
@@ -656,10 +693,14 @@ class Event(Base):
|
|
656
693
|
created: Mapped[dt_create]
|
657
694
|
updated: Mapped[dt_update]
|
658
695
|
|
659
|
-
|
660
|
-
|
661
|
-
|
696
|
+
__table_args__ = (
|
697
|
+
Index("idx_events_org_id", "org_id"),
|
698
|
+
Index("idx_events_location_id", "location_id"),
|
699
|
+
Index("idx_events_is_active", "is_active"),
|
662
700
|
)
|
701
|
+
|
702
|
+
org: Mapped[Org] = relationship(innerjoin=True, cascade="expunge", viewonly=True)
|
703
|
+
location: Mapped[Location] = relationship(innerjoin=True, cascade="expunge", viewonly=True)
|
663
704
|
event_types: Mapped[List[EventType]] = relationship(
|
664
705
|
secondary="events_x_event_types",
|
665
706
|
innerjoin=True,
|
@@ -675,9 +716,7 @@ class Event(Base):
|
|
675
716
|
event_x_event_tags: Mapped[Optional[List[EventTag_x_Event]]] = relationship(
|
676
717
|
back_populates="event", cascade="save-update, merge, delete"
|
677
718
|
)
|
678
|
-
attendance: Mapped[List["Attendance"]] = relationship(
|
679
|
-
back_populates="event", cascade="expunge, delete"
|
680
|
-
)
|
719
|
+
attendance: Mapped[List["Attendance"]] = relationship(back_populates="event", cascade="expunge, delete")
|
681
720
|
|
682
721
|
|
683
722
|
class AttendanceType(Base):
|
@@ -687,7 +726,7 @@ class AttendanceType(Base):
|
|
687
726
|
Attributes:
|
688
727
|
type (str): The type of attendance.
|
689
728
|
description (Optional[str]): A description of the attendance type.
|
690
|
-
"""
|
729
|
+
""" # noqa: E501
|
691
730
|
|
692
731
|
__tablename__ = "attendance_types"
|
693
732
|
|
@@ -707,20 +746,14 @@ class Attendance_x_AttendanceType(Base):
|
|
707
746
|
attendance_type_id (int): The ID of the associated attendance type.
|
708
747
|
|
709
748
|
attendance (Attendance): The associated attendance.
|
710
|
-
"""
|
749
|
+
""" # noqa: E501
|
711
750
|
|
712
751
|
__tablename__ = "attendance_x_attendance_types"
|
713
752
|
|
714
|
-
attendance_id: Mapped[int] = mapped_column(
|
715
|
-
|
716
|
-
)
|
717
|
-
attendance_type_id: Mapped[int] = mapped_column(
|
718
|
-
ForeignKey("attendance_types.id"), primary_key=True
|
719
|
-
)
|
753
|
+
attendance_id: Mapped[int] = mapped_column(ForeignKey("attendance.id"), primary_key=True)
|
754
|
+
attendance_type_id: Mapped[int] = mapped_column(ForeignKey("attendance_types.id"), primary_key=True)
|
720
755
|
|
721
|
-
attendance: Mapped["Attendance"] = relationship(
|
722
|
-
back_populates="attendance_x_attendance_types"
|
723
|
-
)
|
756
|
+
attendance: Mapped["Attendance"] = relationship(back_populates="attendance_x_attendance_types")
|
724
757
|
|
725
758
|
|
726
759
|
class User(Base):
|
@@ -741,15 +774,16 @@ class User(Base):
|
|
741
774
|
status (UserStatus): The status of the user. Default is 'active'.
|
742
775
|
created (datetime): The timestamp when the record was created.
|
743
776
|
updated (datetime): The timestamp when the record was last updated.
|
744
|
-
"""
|
777
|
+
""" # noqa: E501
|
745
778
|
|
746
779
|
__tablename__ = "users"
|
780
|
+
__table_args__ = (Index("idx_users_email", func.lower("email"), unique=True),)
|
747
781
|
|
748
782
|
id: Mapped[intpk]
|
749
783
|
f3_name: Mapped[Optional[str]]
|
750
784
|
first_name: Mapped[Optional[str]]
|
751
785
|
last_name: Mapped[Optional[str]]
|
752
|
-
email: Mapped[str] = mapped_column(
|
786
|
+
email: Mapped[str] = mapped_column(CIText)
|
753
787
|
phone: Mapped[Optional[str]]
|
754
788
|
emergency_contact: Mapped[Optional[str]]
|
755
789
|
emergency_phone: Mapped[Optional[str]]
|
@@ -758,9 +792,7 @@ class User(Base):
|
|
758
792
|
avatar_url: Mapped[Optional[str]]
|
759
793
|
meta: Mapped[Optional[Dict[str, Any]]]
|
760
794
|
email_verified: Mapped[Optional[datetime]]
|
761
|
-
status: Mapped[User_Status] = mapped_column(
|
762
|
-
Enum(User_Status), default=User_Status.active
|
763
|
-
)
|
795
|
+
status: Mapped[User_Status] = mapped_column(Enum(User_Status), default=User_Status.active)
|
764
796
|
created: Mapped[dt_create]
|
765
797
|
updated: Mapped[dt_update]
|
766
798
|
|
@@ -788,7 +820,7 @@ class SlackUser(Base):
|
|
788
820
|
slack_updated (Optional[datetime]): The last update time of the Slack user.
|
789
821
|
created (datetime): The timestamp when the record was created.
|
790
822
|
updated (datetime): The timestamp when the record was last updated.
|
791
|
-
"""
|
823
|
+
""" # noqa: E501
|
792
824
|
|
793
825
|
__tablename__ = "slack_users"
|
794
826
|
|
@@ -830,7 +862,7 @@ class Attendance(Base):
|
|
830
862
|
slack_user (Optional[SlackUser]): The associated Slack user.
|
831
863
|
attendance_x_attendance_types (List[Attendance_x_AttendanceType]): The association between the attendance and attendance types.
|
832
864
|
attendance_types (List[AttendanceType]): The associated attendance types.
|
833
|
-
"""
|
865
|
+
""" # noqa: E501
|
834
866
|
|
835
867
|
__tablename__ = "attendance"
|
836
868
|
__table_args__ = (UniqueConstraint("event_id", "user_id", "is_planned"),)
|
@@ -843,15 +875,13 @@ class Attendance(Base):
|
|
843
875
|
created: Mapped[dt_create]
|
844
876
|
updated: Mapped[dt_update]
|
845
877
|
|
846
|
-
event: Mapped[Event] = relationship(
|
847
|
-
innerjoin=True, cascade="expunge", viewonly=True
|
848
|
-
)
|
878
|
+
event: Mapped[Event] = relationship(innerjoin=True, cascade="expunge", viewonly=True)
|
849
879
|
user: Mapped[User] = relationship(innerjoin=True, cascade="expunge", viewonly=True)
|
850
880
|
slack_user: Mapped[Optional[SlackUser]] = relationship(
|
851
881
|
innerjoin=False, cascade="expunge", secondary="users", viewonly=True
|
852
882
|
)
|
853
|
-
attendance_x_attendance_types: Mapped[List[Attendance_x_AttendanceType]] = (
|
854
|
-
|
883
|
+
attendance_x_attendance_types: Mapped[List[Attendance_x_AttendanceType]] = relationship(
|
884
|
+
back_populates="attendance", cascade="save-update, merge, delete"
|
855
885
|
)
|
856
886
|
attendance_types: Mapped[List[AttendanceType]] = relationship(
|
857
887
|
secondary="attendance_x_attendance_types",
|
@@ -874,7 +904,7 @@ class Achievement(Base):
|
|
874
904
|
specific_org_id (Optional[int]): The ID of the specific region if a custom achievement. If null, the achievement is available to all regions.
|
875
905
|
created (datetime): The timestamp when the record was created.
|
876
906
|
updated (datetime): The timestamp when the record was last updated.
|
877
|
-
"""
|
907
|
+
""" # noqa: E501
|
878
908
|
|
879
909
|
__tablename__ = "achievements"
|
880
910
|
|
@@ -896,17 +926,13 @@ class Achievement_x_User(Base):
|
|
896
926
|
achievement_id (int): The ID of the associated achievement.
|
897
927
|
user_id (int): The ID of the associated user.
|
898
928
|
date_awarded (date): The date the achievement was awarded. Default is the current date.
|
899
|
-
"""
|
929
|
+
""" # noqa: E501
|
900
930
|
|
901
931
|
__tablename__ = "achievements_x_users"
|
902
932
|
|
903
|
-
achievement_id: Mapped[int] = mapped_column(
|
904
|
-
ForeignKey("achievements.id"), primary_key=True
|
905
|
-
)
|
933
|
+
achievement_id: Mapped[int] = mapped_column(ForeignKey("achievements.id"), primary_key=True)
|
906
934
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), primary_key=True)
|
907
|
-
date_awarded: Mapped[date] = mapped_column(
|
908
|
-
DateTime, server_default=func.timezone("utc", func.now())
|
909
|
-
)
|
935
|
+
date_awarded: Mapped[date] = mapped_column(DateTime, server_default=func.timezone("utc", func.now()))
|
910
936
|
|
911
937
|
|
912
938
|
class Position(Base):
|
@@ -918,7 +944,7 @@ class Position(Base):
|
|
918
944
|
description (Optional[str]): A description of the position.
|
919
945
|
org_type (Optional[Org_Type]): The associated organization type. This is used to limit the positions available to certain types of organizations. If null, the position is available to all organization types.
|
920
946
|
org_id (Optional[int]): The ID of the associated organization. This is used to limit the positions available to certain organizations. If null, the position is available to all organizations.
|
921
|
-
"""
|
947
|
+
""" # noqa: E501
|
922
948
|
|
923
949
|
__tablename__ = "positions"
|
924
950
|
|
@@ -939,13 +965,11 @@ class Position_x_Org_x_User(Base):
|
|
939
965
|
position_id (int): The ID of the associated position.
|
940
966
|
org_id (int): The ID of the associated organization.
|
941
967
|
user_id (int): The ID of the associated user.
|
942
|
-
"""
|
968
|
+
""" # noqa: E501
|
943
969
|
|
944
970
|
__tablename__ = "positions_x_orgs_x_users"
|
945
971
|
|
946
|
-
position_id: Mapped[int] = mapped_column(
|
947
|
-
ForeignKey("positions.id"), primary_key=True
|
948
|
-
)
|
972
|
+
position_id: Mapped[int] = mapped_column(ForeignKey("positions.id"), primary_key=True)
|
949
973
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"), primary_key=True)
|
950
974
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), primary_key=True)
|
951
975
|
|
@@ -964,7 +988,7 @@ class Expansion(Base):
|
|
964
988
|
interested_in_organizing (bool): Whether the user is interested in organizing.
|
965
989
|
created (datetime): The timestamp when the record was created.
|
966
990
|
updated (datetime): The timestamp when the record was last updated.
|
967
|
-
"""
|
991
|
+
""" # noqa: E501
|
968
992
|
|
969
993
|
__tablename__ = "expansions"
|
970
994
|
|
@@ -988,17 +1012,13 @@ class Expansion_x_User(Base):
|
|
988
1012
|
user_id (int): The ID of the associated user.
|
989
1013
|
requst_date (date): The date of the request. Default is the current date.
|
990
1014
|
notes (Optional[text]): Additional notes for the association.
|
991
|
-
"""
|
1015
|
+
""" # noqa: E501
|
992
1016
|
|
993
1017
|
__tablename__ = "expansions_x_users"
|
994
1018
|
|
995
|
-
expansion_id: Mapped[int] = mapped_column(
|
996
|
-
ForeignKey("expansions.id"), primary_key=True
|
997
|
-
)
|
1019
|
+
expansion_id: Mapped[int] = mapped_column(ForeignKey("expansions.id"), primary_key=True)
|
998
1020
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), primary_key=True)
|
999
|
-
request_date: Mapped[date] = mapped_column(
|
1000
|
-
DateTime, server_default=func.timezone("utc", func.now())
|
1001
|
-
)
|
1021
|
+
request_date: Mapped[date] = mapped_column(DateTime, server_default=func.timezone("utc", func.now()))
|
1002
1022
|
notes: Mapped[Optional[text]]
|
1003
1023
|
|
1004
1024
|
|
@@ -1020,7 +1040,7 @@ class NextAuthAccount(Base):
|
|
1020
1040
|
session_state (Optional[text]): The session state.
|
1021
1041
|
created (datetime): The timestamp when the record was created.
|
1022
1042
|
updated (datetime): The timestamp when the record was last updated.
|
1023
|
-
"""
|
1043
|
+
""" # noqa: E501
|
1024
1044
|
|
1025
1045
|
__tablename__ = "auth_accounts"
|
1026
1046
|
|
@@ -1049,7 +1069,7 @@ class NextAuthSession(Base):
|
|
1049
1069
|
expires (ts_notz): The expiration time of the session.
|
1050
1070
|
created (datetime): The timestamp when the record was created.
|
1051
1071
|
updated (datetime): The timestamp when the record was last updated.
|
1052
|
-
"""
|
1072
|
+
""" # noqa: E501
|
1053
1073
|
|
1054
1074
|
__tablename__ = "auth_sessions"
|
1055
1075
|
|
@@ -1070,7 +1090,7 @@ class NextAuthVerificationToken(Base):
|
|
1070
1090
|
expires (ts_notz): The expiration time of the token.
|
1071
1091
|
created (datetime): The timestamp when the record was created.
|
1072
1092
|
updated (datetime): The timestamp when the record was last updated.
|
1073
|
-
"""
|
1093
|
+
""" # noqa: E501
|
1074
1094
|
|
1075
1095
|
__tablename__ = "auth_verification_tokens"
|
1076
1096
|
|
@@ -1120,6 +1140,7 @@ class UpdateRequest(Base):
|
|
1120
1140
|
location_lng (Optional[float]): The longitude of the location.
|
1121
1141
|
location_id (Optional[int]): The ID of the location.
|
1122
1142
|
location_contact_email (Optional[str]): The contact email of the location.
|
1143
|
+
ao_name (Optional[text]): The name of the AO.
|
1123
1144
|
ao_logo (Optional[text]): The URL of the AO logo.
|
1124
1145
|
submitted_by (str): The user who submitted the request.
|
1125
1146
|
submitter_validated (Optional[bool]): Whether the submitter has validated the request. Default is False.
|
@@ -1130,16 +1151,12 @@ class UpdateRequest(Base):
|
|
1130
1151
|
request_type (Request_Type): The type of the request.
|
1131
1152
|
created (datetime): The timestamp when the record was created.
|
1132
1153
|
updated (datetime): The timestamp when the record was last updated.
|
1133
|
-
"""
|
1154
|
+
""" # noqa: E501
|
1134
1155
|
|
1135
1156
|
__tablename__ = "update_requests"
|
1136
1157
|
|
1137
|
-
id: Mapped[Uuid] = mapped_column(
|
1138
|
-
|
1139
|
-
)
|
1140
|
-
token: Mapped[Uuid] = mapped_column(
|
1141
|
-
UUID(as_uuid=True), server_default=func.gen_random_uuid()
|
1142
|
-
)
|
1158
|
+
id: Mapped[Uuid] = mapped_column(UUID(as_uuid=True), primary_key=True, server_default=func.gen_random_uuid())
|
1159
|
+
token: Mapped[Uuid] = mapped_column(UUID(as_uuid=True), server_default=func.gen_random_uuid())
|
1143
1160
|
region_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
1144
1161
|
event_id: Mapped[Optional[int]] = mapped_column(ForeignKey("events.id"))
|
1145
1162
|
event_type_ids: Mapped[Optional[List[int]]] = mapped_column(ARRAY(Integer))
|
@@ -1169,15 +1186,12 @@ class UpdateRequest(Base):
|
|
1169
1186
|
location_state: Mapped[Optional[str]]
|
1170
1187
|
location_zip: Mapped[Optional[str]]
|
1171
1188
|
location_country: Mapped[Optional[str]]
|
1172
|
-
location_lat: Mapped[Optional[float]] = mapped_column(
|
1173
|
-
|
1174
|
-
)
|
1175
|
-
location_lng: Mapped[Optional[float]] = mapped_column(
|
1176
|
-
Float(precision=8, decimal_return_scale=5)
|
1177
|
-
)
|
1189
|
+
location_lat: Mapped[Optional[float]] = mapped_column(Float(precision=8, decimal_return_scale=5))
|
1190
|
+
location_lng: Mapped[Optional[float]] = mapped_column(Float(precision=8, decimal_return_scale=5))
|
1178
1191
|
location_id: Mapped[Optional[int]] = mapped_column(ForeignKey("locations.id"))
|
1179
1192
|
location_contact_email: Mapped[Optional[str]]
|
1180
1193
|
|
1194
|
+
ao_name: Mapped[Optional[text]]
|
1181
1195
|
ao_logo: Mapped[Optional[text]]
|
1182
1196
|
|
1183
1197
|
submitted_by: Mapped[text]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "f3-data-models"
|
3
|
-
version = "0.4.
|
3
|
+
version = "0.4.3"
|
4
4
|
description = "The data schema and models for F3 Nation applications."
|
5
5
|
authors = ["Evan Petzoldt <evan.petzoldt@protonmail.com>"]
|
6
6
|
readme = "README.md"
|
@@ -10,6 +10,29 @@ license = "MIT"
|
|
10
10
|
repository = "https://github.com/F3-Nation/f3-data-models"
|
11
11
|
documentation = "https://github.io/F3-Nation/f3-data-models"
|
12
12
|
|
13
|
+
[tool.ruff]
|
14
|
+
line-length = 120
|
15
|
+
|
16
|
+
select = [
|
17
|
+
"E", # pycodestyle errors (settings from FastAPI, thanks, @tiangolo!)
|
18
|
+
"W", # pycodestyle warnings
|
19
|
+
"F", # pyflakes
|
20
|
+
"I", # isort
|
21
|
+
"C", # flake8-comprehensions
|
22
|
+
"B", # flake8-bugbear
|
23
|
+
]
|
24
|
+
ignore = [
|
25
|
+
"C901", # too complex
|
26
|
+
]
|
27
|
+
|
28
|
+
[tool.ruff.isort]
|
29
|
+
order-by-type = true
|
30
|
+
relative-imports-order = "closest-to-furthest"
|
31
|
+
extra-standard-library = ["typing"]
|
32
|
+
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
33
|
+
known-first-party = []
|
34
|
+
|
35
|
+
|
13
36
|
[tool.poetry.dependencies]
|
14
37
|
python = "^3.12"
|
15
38
|
sqlalchemy = "^2.0.36"
|
@@ -25,6 +48,7 @@ sphinx-multiversion = "^0.2.4"
|
|
25
48
|
psycopg2-binary = "^2.9.10"
|
26
49
|
sqlmodel = "^0.0.22"
|
27
50
|
alembic-postgresql-enum = "^1.6.1"
|
51
|
+
sqlalchemy-citext = "^1.8.0"
|
28
52
|
|
29
53
|
|
30
54
|
[build-system]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|