Skip to content

Postgres Tables

erDiagram USERS 1 to zero or more FAVORITES : has FAVORITES zero or more to 1 BILLS : marks SPONSORS one or more to one or more BILLS : introduces BILLS 1 to one or more ACTIONS : has BILLS zero or more to zero or more TOPICS : has UPDATES 1 to 1 BILLS : has USER_NOTIFICATION_QUEUE 1 to 1 USERS : has MOST_RECENT_UPLOAD

Note: Django auto-creates an id primary key if one does not already exist in the table.

Users

Bases: AbstractBaseUser, PermissionsMixin

A modification of the built-in Django user that
  • switches first_name & last_name for username & full_name
  • keeps other admin-compliant options

Has connections from:

  • Favorites

Attributes:

Name Type Description
email (Email, unique)

This doubles as the username.

phone Varchar

User's phone number, used for notifications and dual authentication.

phone_verified Boolean

Indicates whether the user's phone number is verified.

username (Varchar, unique)

User's username, used for login and identification.

full_name Varchar

User's full name, used for display purposes.

is_staff Boolean

Indicates whether the user can log into the admin site.

is_active Boolean

Indicates whether the user is active. Unselect this instead of deleting accounts.

is_subscribed Boolean

Indicates whether the user is subscribed to notifications.

date_joined DateTime

The date and time when the user joined the platform.

Source code in apps\accounts\models.py
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class User(AbstractBaseUser, PermissionsMixin):
    """
    A modification of the built-in Django user that:
        - switches first_name & last_name for username & full_name
        - keeps other admin-compliant options

    Has connections from:

    - Favorites

    Attributes:
        email (Email, unique): This doubles as the username.
        phone (Varchar): User's phone number, used for notifications and dual authentication.
        phone_verified (Boolean): Indicates whether the user's phone number is verified.
        username (Varchar, unique): User's username, used for login and identification.
        full_name (Varchar): User's full name, used for display purposes.
        is_staff (Boolean): Indicates whether the user can log into the admin site.
        is_active (Boolean): Indicates whether the user is active. Unselect this instead of deleting accounts.
        is_subscribed (Boolean): Indicates whether the user is subscribed to notifications.
        date_joined (DateTime): The date and time when the user joined the platform.
    """

    username_validator = UnicodeUsernameValidator()

    email = models.EmailField(_("email address"), unique=EMAIL_REQUIRED, default="")
    phone = models.CharField(
        _("phone number"),
        max_length=20,
        blank=True,
        unique=True,
    )

    phone_verified = models.BooleanField(
        _("phone verified"),
        default=False,
        help_text=_("Designates whether this user's phone number is verified."),
    )

    username = models.CharField(
        max_length=255,
        unique=True,
        validators=[username_validator] if USERNAME_REQUIRED else [],
        default="",
    )
    full_name = models.CharField(_("full name"), max_length=150, blank=True)
    is_staff = models.BooleanField(
        _("staff status"),
        default=False,
        help_text=_("Designates whether the user can log into this admin site."),
    )
    is_active = models.BooleanField(
        _("active"),
        default=True,
        help_text=_(
            "Designates whether this user should be treated as active. "
            "Unselect this instead of deleting accounts."
        ),
    )

    is_subscribed = models.BooleanField(
        _("subscribed"),
        default=True,
        help_text=_("Designates whether the user is subscribed to notifications."),
    )

    date_joined = models.DateTimeField(_("date joined"), default=timezone.now)

    objects = OkUserManager()

    EMAIL_FIELD = "email"
    USERNAME_FIELD = "username" if USERNAME_REQUIRED else "email"
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = _("user")
        verbose_name_plural = _("users")

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def save(self, *args, **kwargs):
        if EMAIL_REQUIRED and not self.username:
            self.username = self.email
        super().save(*args, **kwargs)

    def get_short_name(self):
        return self.username

    def get_full_name(self):
        return self.full_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

Actions

Bases: Model

Stores each distinct action taken on a bill, e.g., ("First Reading"). Represented by a one-to-many relationship between bill and actions.

This table is queried by frontend views that show bill information, such as most recent action. Additionally, it will be queried by the notification system, which updates users about favorited bills that have had a significant action associated with them in the past 24 hours.

Connects to:

  • Bills (on bill_id ForeignKey)

Attributes:

Name Type Description
action_id (Varchar, PrimaryKey, unique)

Unique identifier for the action.

bill_id ForeignKey

bill_id from the bills table for the bill associated with this action.

description Varchar

Description of the action, e.g., ("First Reading").

date Timestamp

Date of the action.

category (Varchar, nullable)

Category of the action. Used to group actions into broader types for tracking bill status.

Source code in apps\core\models.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class ActionsTable(models.Model):
    """
    Stores each distinct action taken on a bill, e.g., ("First Reading").
    Represented by a one-to-many relationship between bill and actions.

    This table is queried by frontend views that show bill information, such
    as most recent action. Additionally, it will be queried by the
    notification system, which updates users about favorited bills that have
    had a significant action associated with them in the past 24 hours.

    Connects to:

    - Bills (on bill_id ForeignKey)

    Attributes:
        action_id (Varchar, PrimaryKey, unique):
            Unique identifier for the action.
        bill_id (ForeignKey):
            `bill_id` from the bills table for the bill associated with this action.
        description (Varchar): Description of the action, e.g., ("First Reading").
        date (Timestamp): Date of the action.
        category (Varchar, nullable):
            Category of the action. Used to group actions into broader types for
            tracking bill status.
    """

    action_id = models.CharField(unique=True, primary_key=True, db_column="action_id")
    bill_id = models.ForeignKey("BillsTable", on_delete=models.CASCADE, db_column="bill_id")
    description = models.CharField()
    date = models.DateTimeField()
    category = models.CharField(null=True)
    chamber = models.CharField(null=True, default=None)

    class Meta:
        db_table = "actions_table"
        unique_together = ("action_id", "bill_id")

Bills

Bases: Model

Stores data for each bill.

This table is queried by frontend views that show bill information, such as the search view and individual bill pages.

Has connections from:

  • Actions
  • Favorites
  • Sponsors
  • Topics

Attributes:

Name Type Description
bill_id (Varchar, PrimaryKey, unique)

Unique identifier for the bill, sourced from OpenStates.

number Varchar

Bill number used by the legislature.

title Varchar

Official title of the bill.

state Varchar

State where the bill is introduced.

session Varchar

Legislative session in which the bill is introduced.

summary Varchar

Bill summary as sourced from OpenStates API.

status Varchar

The latest action taken on the bill.

Source code in apps\core\models.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class BillsTable(models.Model):
    """
    Stores data for each bill.

    This table is queried by frontend views that show bill information, such
    as the search view and individual bill pages.

    Has connections from:

    - Actions
    - Favorites
    - Sponsors
    - Topics

    Attributes:
        bill_id (Varchar, PrimaryKey, unique):
            Unique identifier for the bill, sourced from OpenStates.
        number (Varchar): Bill number used by the legislature.
        title (Varchar): Official title of the bill.
        state (Varchar): State where the bill is introduced.
        session (Varchar): Legislative session in which the bill is introduced.
        summary (Varchar): Bill summary as sourced from OpenStates API.
        status (Varchar): The latest action taken on the bill.
    """

    bill_id = models.CharField(unique=True, primary_key=True)
    number = models.CharField()
    title = models.CharField()
    state = models.CharField()
    session = models.CharField()
    summary = models.CharField()
    status = models.CharField()

    class Meta:
        db_table = "bills_table"

Favorites

Bases: Model

Stores data for user favorites of bills. Represents a many-to-many relationship: one user can like many bills, one bill can be associated with many users.

This table will be queried by frontend views that show users which bills they have favorited. Additionally, this table will be used for the automatic notification system that notifies users about updates from bills they have favorited.

Connects to:

  • Bills (on bill_id ForeignKey)
  • Users (on user_id ForeignKey)

Attributes:

Name Type Description
id (Bigint, PrimaryKey)

Internal ID for a favorite.

bill_id (Varchar, ForeignKey)

bill_id from the bills table for the bill favorited.

user_id (Varchar, ForeignKey)

user_id from the users table for the user favoriting the bill.

Source code in apps\core\models.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
class FavoritesTable(models.Model):
    """
    Stores data for user favorites of bills. Represents a many-to-many
    relationship: one user can like many bills, one bill can be associated
    with many users.

    This table will be queried by frontend views that show users which bills
    they have favorited. Additionally, this table will be used for the
    automatic notification system that notifies users about updates from
    bills they have favorited.

    Connects to:

    - Bills (on bill_id ForeignKey)
    - Users (on user_id ForeignKey)

    Attributes:
        id (Bigint, PrimaryKey): Internal ID for a favorite.
        bill_id (Varchar, ForeignKey):
            `bill_id` from the bills table for the bill favorited.
        user_id (Varchar, ForeignKey):
            `user_id` from the users table for the user favoriting the bill.
    """

    user_id = models.ForeignKey(User, on_delete=models.CASCADE, db_column="user_id")
    bill_id = models.ForeignKey("BillsTable", on_delete=models.CASCADE, db_column="bill_id")

    class Meta:
        db_table = "favorites_table"
        unique_together = ("user_id", "bill_id")

Sponsors

Bases: Model

Stores data for sponsors of bills. Represents a many-to-many relationship: one bill may have many sponsors, and one sponsor may have many bills.

This table is queried by frontend views that show bill information, including sponsor information.

Connects to:

  • Bills (on bill_id ForeignKey)

Attributes:

Name Type Description
id (Varchar, PrimaryKey, unique)

Internal id of the sponsor. Separate from sponsor_id as sponsor_id comes from OpenStates and may be null.

sponsor_id Varchar

sponsor_id from OpenStates.

sponsor_name Varchar

Name of the bill sponsor.

bill_id (Varchar, ForeignKey)

bill_id from the bills table, the bill that the sponsor has sponsored.

position (Varchar, nullable)

The position (e.g., Member of the State House, Member of the State Senate) that the sponsor occupies.

party (Varchar, nullable)

The political party of the sponsor.

Source code in apps\core\models.py
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
class SponsorsTable(models.Model):
    """
    Stores data for sponsors of bills. Represents a many-to-many relationship:
    one bill may have many sponsors, and one sponsor may have many bills.

    This table is queried by frontend views that show bill information,
    including sponsor information.

    Connects to:

    - Bills (on bill_id ForeignKey)

    Attributes:
        id (Varchar, PrimaryKey, unique):
            Internal id of the sponsor. Separate from sponsor_id
            as sponsor_id comes from OpenStates and may be null.
        sponsor_id (Varchar): sponsor_id from OpenStates.
        sponsor_name (Varchar): Name of the bill sponsor.
        bill_id (Varchar, ForeignKey):
            `bill_id` from the bills table, the bill that the sponsor has sponsored.
        position (Varchar, nullable):
            The position (e.g., Member of the State House, Member
            of the State Senate) that the sponsor occupies.
        party (Varchar, nullable): The political party of the sponsor.
    """

    id = models.CharField(unique=True, primary_key=True)
    bill_id = models.ForeignKey("BillsTable", on_delete=models.CASCADE, db_column="bill_id")
    sponsor_id = models.CharField(null=True)
    sponsor_name = models.CharField()
    position = models.CharField(null=True)
    party = models.CharField(null=True)

    class Meta:
        db_table = "sponsors_table"

Topics

Bases: Model

Stores data for topics associated with each bill. Represents a many-to-many relationship: one bill may have many topics, one topic may have many bills associated with it.

This table is queried by frontend views that show bill information, including topic information.

Connects to:

  • Bills (on bill_id ForeignKey)

Attributes:

Name Type Description
id (Bigint, PrimaryKey)

ID of the topic.

topic Varchar

Topic name.

bill_id (Varchar, ForeignKey)

bill_id from the bills table, the bill the topic is associated with.

Source code in apps\core\models.py
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
class TopicsTable(models.Model):
    """
    Stores data for topics associated with each bill. Represents a many-to-many relationship:
    one bill may have many topics, one topic may have many bills associated with it.

    This table is queried by frontend views that show bill information,
    including topic information.

    Connects to:

    - Bills (on bill_id ForeignKey)

    Attributes:
        id (Bigint, PrimaryKey): ID of the topic.
        topic (Varchar): Topic name.
        bill_id (Varchar, ForeignKey):
            `bill_id` from the bills table, the bill the topic is associated with.
    """

    bill_id = models.ForeignKey("BillsTable", on_delete=models.CASCADE, db_column="bill_id")
    topic = models.CharField()

    class Meta:
        db_table = "topics_table"

Updates

Bases: Model

A table storing periodic updates for bills.

This table is included in addition to the ActionsTable to provide a simple way to to use the most recent action for notifications.

Connects to:

  • Actions (on action_id ForeignKey)
  • Bills (on bill_id ForeignKey)

Attributes:

Name Type Description
action_id (Varchar, ForeignKey)

action_id from the actions table, the bill the update is associated with.

topic Varchar

Topic name.

bill_id (Varchar, ForeignKey)

bill_id from the bills table, the bill the update is associated with.

description Varchar

Description of the update.

date DateTime

Date of the update.

category (Varchar, nullable)

Category of the update.

chamber Varchar

Chamber (House or Senate) associated with the update.

Source code in apps\core\models.py
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
class UpdatesTable(models.Model):
    """
    A table storing periodic updates for bills.

    This table is included in addition to the ActionsTable to provide a simple way to
    to use the most recent action for notifications.

    Connects to:

    - Actions (on action_id ForeignKey)
    - Bills (on bill_id ForeignKey)

    Attributes:
        action_id (Varchar, ForeignKey):
            `action_id` from the actions table, the bill the update is associated with.
        topic (Varchar): Topic name.
        bill_id (Varchar, ForeignKey):
            `bill_id` from the bills table, the bill the update is associated with.
        description (Varchar): Description of the update.
        date (DateTime): Date of the update.
        category (Varchar, nullable): Category of the update.
        chamber (Varchar): Chamber (House or Senate) associated with the update.
    """

    action_id = models.ForeignKey("ActionsTable", on_delete=models.CASCADE, db_column="action_id")
    bill_id = models.ForeignKey("BillsTable", on_delete=models.CASCADE, db_column="bill_id")
    description = models.CharField()
    date = models.DateTimeField()
    category = models.CharField(null=True)
    chamber = models.CharField()

    class Meta:
        db_table = "updates_table"
        unique_together = ("action_id", "bill_id")

Most Recent Upload

Bases: Model

A table that stores the most recent date that bills data were uploaded.

Used to determine whether or not a notification email should be sent, or if there was an error uploading the bills.

Connects to:

  • None

Attributes:

Name Type Description
id (Bigint, PrimaryKey)

ID of the upload.

last_upload_date Date

Date of the last successful bill upload.

Source code in apps\core\models.py
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
class MostRecentUpload(models.Model):
    """
    A table that stores the most recent date that bills data were uploaded.

    Used to determine whether or not a notification email should be sent, or
    if there was an error uploading the bills.

    Connects to:

    - None

    Attributes:
        id (Bigint, PrimaryKey): ID of the upload.
        last_upload_date (Date): Date of the last successful bill upload.
    """

    last_upload_date = models.DateField()

    class Meta:
        db_table = "most_recent_upload"

User Notification Queue

Bases: Model

A table to store user notifications in a queue, with all bills to update on bundled in a single notification.

Connects to:

  • Users (on user_id)

Attributes:

Name Type Description
id (Bigint, PrimaryKey)

ID of the queue entry.

user_id ForeignKey

The user_id of the user to be notified.

number_of_notifications Int

Number of notifications for a user on a given day.

bills_to_notify Array

A list of the bill ids that the user needs to be updated on.

is_notified Boolean

Whether or not a notification email has been sent to the user.

Source code in apps\core\models.py
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
class UserNotificationQueue(models.Model):
    """
    A table to store user notifications in a queue, with all bills to update on bundled in a single notification.

    Connects to:

    - Users (on user_id)

    Attributes:
        id (Bigint, PrimaryKey): ID of the queue entry.
        user_id (ForeignKey): The user_id of the user to be notified.
        number_of_notifications (Int): Number of notifications for a user on a given day.
        bills_to_notify (Array): A list of the bill ids that the user needs to be updated on.
        is_notified (Boolean): Whether or not a notification email has been sent to the user.
    """

    user_id = models.OneToOneField(User, on_delete=models.CASCADE, db_column="user_id")
    number_of_notifications = models.IntegerField()
    bills_to_notify = models.JSONField()
    is_notified = models.BooleanField(default=False)

    class Meta:
        db_table = "user_notification_queue"