Skip to content

Commit

Permalink
Merge pull request #23 from cs3216-a3-group-4/seeleng/add-more-models
Browse files Browse the repository at this point in the history
feat: add more models to match workflows
chloeelim authored Sep 22, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents d7fdd11 + a441921 commit 693695c
Showing 15 changed files with 533 additions and 10 deletions.
66 changes: 66 additions & 0 deletions backend/alembic/versions/04e02312343d_add_user_question_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Add user question models
Revision ID: 04e02312343d
Revises: d369cd69a23b
Create Date: 2024-09-22 21:35:48.778303
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "04e02312343d"
down_revision: Union[str, None] = "d369cd69a23b"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"user_question",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("question", sa.String(), nullable=False),
sa.Column("user_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"answer",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("user_question_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["user_question_id"],
["user_question.id"],
),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"point",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("title", sa.String(), nullable=False),
sa.Column("body", sa.String(), nullable=False),
sa.Column("answer_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["answer_id"],
["answer.id"],
),
sa.PrimaryKeyConstraint("id"),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("point")
op.drop_table("answer")
op.drop_table("user_question")
# ### end Alembic commands ###
40 changes: 40 additions & 0 deletions backend/alembic/versions/680d9bea2168_add_note_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Add note models
Revision ID: 680d9bea2168
Revises: 04e02312343d
Create Date: 2024-09-22 22:07:11.979617
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "680d9bea2168"
down_revision: Union[str, None] = "04e02312343d"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"note",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("content", sa.String(), nullable=False),
sa.Column("start_index", sa.Integer(), nullable=False),
sa.Column("end_index", sa.Integer(), nullable=False),
sa.Column("parent_id", sa.Integer(), nullable=False),
sa.Column("parent_type", sa.String(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("note")
# ### end Alembic commands ###
58 changes: 58 additions & 0 deletions backend/alembic/versions/8912e0e896bf_add_analysis_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Add Analysis table
Revision ID: 8912e0e896bf
Revises: ff5af4d7ce04
Create Date: 2024-09-22 18:29:26.096419
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "8912e0e896bf"
down_revision: Union[str, None] = "ff5af4d7ce04"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"analysis",
sa.Column("event_id", sa.Integer(), nullable=False),
sa.Column("category_id", sa.Integer(), nullable=False),
sa.Column("content", sa.String(), nullable=False),
sa.ForeignKeyConstraint(
["category_id"],
["category.id"],
),
sa.ForeignKeyConstraint(
["event_id"],
["event.id"],
),
sa.PrimaryKeyConstraint("event_id", "category_id"),
)
op.drop_table("event_category")
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"event_category",
sa.Column("event_id", sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column("category_id", sa.INTEGER(), autoincrement=False, nullable=False),
sa.ForeignKeyConstraint(
["category_id"], ["category.id"], name="event_category_category_id_fkey"
),
sa.ForeignKeyConstraint(
["event_id"], ["event.id"], name="event_category_event_id_fkey"
),
sa.PrimaryKeyConstraint("event_id", "category_id", name="event_category_pkey"),
)
op.drop_table("analysis")
# ### end Alembic commands ###
57 changes: 57 additions & 0 deletions backend/alembic/versions/8c458d0adb18_add_gp_questions_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Add GP Questions tables
Revision ID: 8c458d0adb18
Revises: 8912e0e896bf
Create Date: 2024-09-22 18:49:41.011371
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "8c458d0adb18"
down_revision: Union[str, None] = "8912e0e896bf"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"gp_question",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("question", sa.String(), nullable=False),
sa.Column("is_llm_generated", sa.Boolean(), nullable=False),
sa.Column("event_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["event_id"],
["event.id"],
),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"gp_question_categories",
sa.Column("gp_question_id", sa.Integer(), nullable=False),
sa.Column("category_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["category_id"],
["category.id"],
),
sa.ForeignKeyConstraint(
["gp_question_id"],
["gp_question.id"],
),
sa.PrimaryKeyConstraint("gp_question_id", "category_id"),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("gp_question_categories")
op.drop_table("gp_question")
# ### end Alembic commands ###
31 changes: 31 additions & 0 deletions backend/alembic/versions/b8f3f95c78b6_add_image_url_to_article.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Add image url to article
Revision ID: b8f3f95c78b6
Revises: 8c458d0adb18
Create Date: 2024-09-22 18:56:47.024304
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "b8f3f95c78b6"
down_revision: Union[str, None] = "8c458d0adb18"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("article", sa.Column("image_url", sa.String(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("article", "image_url")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Remove analysis field from event
Revision ID: bc5fcbe47713
Revises: f624d58d3f42
Create Date: 2024-09-22 22:33:38.823000
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "bc5fcbe47713"
down_revision: Union[str, None] = "f624d58d3f42"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("event", "analysis")
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"event",
sa.Column("analysis", sa.VARCHAR(), autoincrement=False, nullable=False),
)
# ### end Alembic commands ###
31 changes: 31 additions & 0 deletions backend/alembic/versions/d369cd69a23b_add_rating_to_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Add rating to event
Revision ID: d369cd69a23b
Revises: b8f3f95c78b6
Create Date: 2024-09-22 18:59:11.283743
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "d369cd69a23b"
down_revision: Union[str, None] = "b8f3f95c78b6"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("event", sa.Column("rating", sa.Integer(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("event", "rating")
# ### end Alembic commands ###
33 changes: 33 additions & 0 deletions backend/alembic/versions/f624d58d3f42_add_user_id_to_note.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Add user id to note
Revision ID: f624d58d3f42
Revises: 680d9bea2168
Create Date: 2024-09-22 22:29:21.220643
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "f624d58d3f42"
down_revision: Union[str, None] = "680d9bea2168"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("note", sa.Column("user_id", sa.Integer(), nullable=False))
op.create_foreign_key(None, "note", "user", ["user_id"], ["id"])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "note", type_="foreignkey")
op.drop_column("note", "user_id")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Add ArticleEvent join table
Revision ID: ff5af4d7ce04
Revises: a73902039c96
Create Date: 2024-09-22 18:24:05.699420
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "ff5af4d7ce04"
down_revision: Union[str, None] = "a73902039c96"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"article_event",
sa.Column("article_id", sa.Integer(), nullable=False),
sa.Column("event_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["article_id"],
["article.id"],
),
sa.ForeignKeyConstraint(
["event_id"],
["event.id"],
),
sa.PrimaryKeyConstraint("article_id", "event_id"),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("article_event")
# ### end Alembic commands ###
2 changes: 2 additions & 0 deletions backend/src/auth/models.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.common.base import Base
from src.events.models import Category
from src.notes.models import Note


class AccountType(str, Enum):
@@ -27,3 +28,4 @@ class User(Base):
account_type: Mapped[AccountType]

categories: Mapped[list[Category]] = relationship(secondary=user_category_table)
notes: Mapped[list[Note]] = relationship("Note", backref="user")
77 changes: 68 additions & 9 deletions backend/src/events/models.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
from enum import Enum
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship, foreign
from sqlalchemy import Column, ForeignKey, Table, and_
from datetime import datetime
from src.common.base import Base
from src.notes.models import Note


class ArticleSource(str, Enum):
CNA = "CNA"
GUARDIAN = "GUARDIAN"


article_event_table = Table(
"article_event",
Base.metadata,
Column("article_id", ForeignKey("article.id"), primary_key=True),
Column("event_id", ForeignKey("event.id"), primary_key=True),
)


class Article(Base):
__tablename__ = "article"

@@ -20,8 +29,21 @@ class Article(Base):
url: Mapped[str]
source: Mapped[ArticleSource]
date: Mapped[datetime]
image_url: Mapped[str]

original_events: Mapped[list["Event"]] = relationship(
back_populates="original_article"
)

events: Mapped[list["Event"]] = relationship(back_populates="original_article")
events: Mapped[list["Event"]] = relationship(
back_populates="articles", secondary=article_event_table
)

notes = relationship(
"Note",
primaryjoin=and_(id == foreign(Note.parent_id), Note.parent_type == "article"),
backref="article",
)


class Event(Base):
@@ -30,17 +52,27 @@ class Event(Base):
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
description: Mapped[str]
analysis: Mapped[str]
duplicate: Mapped[bool]
date: Mapped[datetime]
is_singapore: Mapped[bool]
original_article_id: Mapped[int] = mapped_column(ForeignKey("article.id"))
rating: Mapped[int]

categories: Mapped[list["Category"]] = relationship(
back_populates="events", secondary="event_category"
back_populates="events", secondary="analysis"
)

original_article: Mapped[Article] = relationship(back_populates="events")
original_article: Mapped[Article] = relationship(back_populates="original_events")
articles: Mapped[list[Article]] = relationship(
back_populates="events", secondary=article_event_table
)
gp_questions: Mapped["GPQuestion"] = relationship(back_populates="event")

notes = relationship(
"Note",
primaryjoin=and_(id == foreign(Note.parent_id), Note.parent_type == "note"),
backref="event",
)


class Category(Base):
@@ -50,14 +82,41 @@ class Category(Base):
name: Mapped[str]

events: Mapped[list[Event]] = relationship(
secondary="event_category", back_populates="categories"
secondary="analysis", back_populates="categories"
)


class EventCategory(Base):
__tablename__ = "event_category"
class Analysis(Base):
__tablename__ = "analysis"

event_id: Mapped[int] = mapped_column(ForeignKey("event.id"), primary_key=True)
category_id: Mapped[int] = mapped_column(
ForeignKey("category.id"), primary_key=True
)
content: Mapped[str]


class GPQuestion(Base):
__tablename__ = "gp_question"

id: Mapped[int] = mapped_column(primary_key=True)
question: Mapped[str]
is_llm_generated: Mapped[bool] = mapped_column(default=True)
event_id = mapped_column(ForeignKey("event.id"))

categories: Mapped[list["Category"]] = relationship(
secondary="gp_question_categories"
)

event: Mapped[Event] = relationship(back_populates="gp_questions")


class GPQuestionCategories(Base):
__tablename__ = "gp_question_categories"

gp_question_id: Mapped[int] = mapped_column(
ForeignKey("gp_question.id"), primary_key=True
)
category_id: Mapped[int] = mapped_column(
ForeignKey("category.id"), primary_key=True
)
26 changes: 26 additions & 0 deletions backend/src/notes/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from sqlalchemy import Enum, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column
from src.common.base import Base


class NoteType(str, Enum):
EVENT = "event"
ARTICLE = "article"
POINT = "point"


class Note(Base):
__tablename__ = "note"

id: Mapped[int] = mapped_column(primary_key=True)
content: Mapped[str]

start_index: Mapped[int]
end_index: Mapped[int]

parent_id: Mapped[int]
parent_type: Mapped[str]

user_id: Mapped[int] = mapped_column(ForeignKey("user.id"))

__mapper_args__ = {"polymorphic_on": "parent_type", "polymorphic_identity": "note"}
1 change: 0 additions & 1 deletion backend/src/scripts/seed.py
Original file line number Diff line number Diff line change
@@ -44,7 +44,6 @@ def test_associations():
event = Event(
title="test event 1",
description="x",
analysis="x",
duplicate=False,
date=datetime.now(),
is_singapore=False,
41 changes: 41 additions & 0 deletions backend/src/user_questions/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from sqlalchemy import ForeignKey, and_
from src.common.base import Base
from sqlalchemy.orm import Mapped, mapped_column, relationship, foreign
from src.notes.models import Note


class UserQuestion(Base):
__tablename__ = "user_question"

id: Mapped[int] = mapped_column(primary_key=True)
question: Mapped[str]

answer: Mapped["Answer"] = relationship(back_populates="user_question")

user_id: Mapped[int] = mapped_column(ForeignKey("user.id"))


class Answer(Base):
__tablename__ = "answer"
id: Mapped[int] = mapped_column(primary_key=True)
user_question_id: Mapped[int] = mapped_column(ForeignKey("user_question.id"))

user_question: Mapped[UserQuestion] = relationship(back_populates="answer")

points: Mapped[list["Point"]] = relationship(back_populates="answer")


class Point(Base):
__tablename__ = "point"
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
body: Mapped[str]
answer_id: Mapped[int] = mapped_column(ForeignKey("answer.id"))

answer: Mapped[Answer] = relationship(back_populates="points")

notes = relationship(
"Note",
primaryjoin=and_(id == foreign(Note.parent_id), Note.parent_type == "point"),
backref="point",
)
2 changes: 2 additions & 0 deletions backend/src/utils/models.py
Original file line number Diff line number Diff line change
@@ -2,3 +2,5 @@

from src.auth import models as auth_models # noqa: F401
from src.events import models as event_models # noqa: F401
from src.user_questions import models as user_question_models # noqa: F401
from src.notes import models as note_models # noqa: F401

0 comments on commit 693695c

Please sign in to comment.