From a840351e35b57ee7621bb6886eefc6e80196e1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 17:47:24 +0100 Subject: [PATCH 1/7] Bump version to 1.4.0 in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2f1b486..e164057 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "welearn-database" -version = "1.3.0" +version = "1.4.0" description = "All stuff related to relationnal database from the WeLearn project" authors = [ {name = "Théo",email = "theo.nardin@cri-paris.org"} From 54c6ca7dc3bbde4ac591385ccaea3ad8052b874b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 17:47:46 +0100 Subject: [PATCH 2/7] Add old conversation_id column --- welearn_database/data/models/user_related.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/welearn_database/data/models/user_related.py b/welearn_database/data/models/user_related.py index 9c3af47..cbfdc2b 100644 --- a/welearn_database/data/models/user_related.py +++ b/welearn_database/data/models/user_related.py @@ -134,6 +134,8 @@ class ReturnedDocument(Base): nullable=False, ) is_clicked: Mapped[bool] = mapped_column(default=False) + conversation_id: Mapped[UUID] + welearn_document: Mapped["WeLearnDocument"] = relationship() chat_message: Mapped["ChatMessage"] = relationship() From 90a944b1dc8d879755a2503a2220233ef09a3453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 18:08:39 +0100 Subject: [PATCH 3/7] Add FilterType enumeration and FilterUsedInQuery model with tests --- tests/test_user_related.py | 30 ++++++++++++++++++++ welearn_database/data/enumeration.py | 5 ++++ welearn_database/data/models/user_related.py | 30 ++++++++++++++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/test_user_related.py b/tests/test_user_related.py index 4c911c9..5cfedef 100644 --- a/tests/test_user_related.py +++ b/tests/test_user_related.py @@ -6,6 +6,7 @@ from sqlalchemy.orm import sessionmaker from tests.helpers import handle_schema_with_sqlite +from welearn_database.data.enumeration import FilterType from welearn_database.data.models import Base from welearn_database.data.models.user_related import ( APIKeyManagement, @@ -13,6 +14,7 @@ ChatMessage, DataCollectionCampaignManagement, EndpointRequest, + FilterUsedInQuery, InferredUser, ReturnedDocument, ) @@ -120,6 +122,7 @@ def test_create_and_read_chat_message(self): result = self.session.query(ChatMessage).filter_by(role="user").first() self.assertIsNotNone(result) self.assertEqual(result.textual_content, "Bonjour") + self.assertFalse(result.is_retrieved_by_user) def test_create_and_read_bookmark(self): inferred_user = InferredUser(id=uuid.uuid4()) @@ -158,6 +161,7 @@ def test_create_and_read_returned_document(self): message_id=chat.id, document_id=uuid.uuid4(), is_clicked=True, + original_feature_name="chat", ) self.session.add(returned_doc) self.session.commit() @@ -193,3 +197,29 @@ def test_create_and_read_endpoint_request(self): ) self.assertIsNotNone(result) self.assertEqual(result.http_code, 200) + + def test_create_and_read_filter_used_in_query(self): + inferred_user = InferredUser(id=uuid.uuid4()) + self.session.add(inferred_user) + self.session.commit() + chat = ChatMessage( + id=uuid.uuid4(), + inferred_user_id=inferred_user.id, + conversation_id=uuid.uuid4(), + role="user", + textual_content="test", + ) + self.session.add(chat) + self.session.commit() + filter_used = FilterUsedInQuery( + id=uuid.uuid4(), + message_id=chat.id, + filter_type=FilterType.SDG.value, + filter_value="13", + ) + self.session.add(filter_used) + self.session.commit() + result = ( + self.session.query(FilterUsedInQuery).filter_by(filter_value="13").first() + ) + self.assertIsNotNone(result) diff --git a/welearn_database/data/enumeration.py b/welearn_database/data/enumeration.py index c64f07e..99b78e1 100644 --- a/welearn_database/data/enumeration.py +++ b/welearn_database/data/enumeration.py @@ -38,3 +38,8 @@ class ExternalIdType(StrEnum): HANDLE = auto() SLUG = auto() QID = auto() + + +class FilterType(StrEnum): + SDG = auto() + SOURCE = auto() diff --git a/welearn_database/data/models/user_related.py b/welearn_database/data/models/user_related.py index cbfdc2b..bd79904 100644 --- a/welearn_database/data/models/user_related.py +++ b/welearn_database/data/models/user_related.py @@ -2,10 +2,10 @@ from uuid import UUID from sqlalchemy import ForeignKey, func, types -from sqlalchemy.dialects.postgresql import TIMESTAMP +from sqlalchemy.dialects.postgresql import ENUM, TIMESTAMP from sqlalchemy.orm import Mapped, mapped_column, relationship -from welearn_database.data.enumeration import DbSchemaEnum +from welearn_database.data.enumeration import DbSchemaEnum, FilterType from welearn_database.data.models.document_related import WeLearnDocument from . import Base @@ -96,6 +96,7 @@ class ChatMessage(Base): ) role: Mapped[str] textual_content: Mapped[str] + is_retrieved_by_user: Mapped[bool] = mapped_column(default=False) created_at: Mapped[datetime] = mapped_column( TIMESTAMP(timezone=False), @@ -134,6 +135,7 @@ class ReturnedDocument(Base): nullable=False, ) is_clicked: Mapped[bool] = mapped_column(default=False) + original_feature_name: Mapped[str] conversation_id: Mapped[UUID] welearn_document: Mapped["WeLearnDocument"] = relationship() @@ -242,3 +244,27 @@ class EndpointRequest(Base): server_default="NOW()", ) session = relationship("Session", foreign_keys=[session_id]) + + +class FilterUsedInQuery(Base): + __tablename__ = "filter_used_in_query" + __table_args__ = {"schema": DbSchemaEnum.USER_RELATED.value} + + id: Mapped[UUID] = mapped_column( + types.Uuid, primary_key=True, nullable=False, server_default="gen_random_uuid()" + ) + message_id = mapped_column( + types.Uuid, + ForeignKey(f"{DbSchemaEnum.USER_RELATED.value}.chat_message.id"), + nullable=False, + ) + filter_type: Mapped[str] = mapped_column( + ENUM( + *(e.value.lower() for e in FilterType), + name="filter_type", + schema=DbSchemaEnum.USER_RELATED.value, + ), + ) + filter_value: Mapped[str] + + chat_message: Mapped["ChatMessage"] = relationship() From 24621dd6eaba22f1f70004328fac9e1e7541b3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 18:09:53 +0100 Subject: [PATCH 4/7] Bump version to 1.4.0.dev0 in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e164057..9c73871 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "welearn-database" -version = "1.4.0" +version = "1.4.0.dev0" description = "All stuff related to relationnal database from the WeLearn project" authors = [ {name = "Théo",email = "theo.nardin@cri-paris.org"} From aae9373fe8d1eca259b77387cde68ddfea3e18bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 18:14:57 +0100 Subject: [PATCH 5/7] Bump version to 1.4.0.dev0 in pyproject.toml --- welearn_database/data/models/user_related.py | 1 - 1 file changed, 1 deletion(-) diff --git a/welearn_database/data/models/user_related.py b/welearn_database/data/models/user_related.py index bd79904..f8c0579 100644 --- a/welearn_database/data/models/user_related.py +++ b/welearn_database/data/models/user_related.py @@ -136,7 +136,6 @@ class ReturnedDocument(Base): ) is_clicked: Mapped[bool] = mapped_column(default=False) original_feature_name: Mapped[str] - conversation_id: Mapped[UUID] welearn_document: Mapped["WeLearnDocument"] = relationship() chat_message: Mapped["ChatMessage"] = relationship() From 7946d1f394e03f85495fb17e60114d798baf4fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 18:44:53 +0100 Subject: [PATCH 6/7] Add columns to chat_message and create filter_used_in_query table --- ...da0c1f2_data_collection_for_focus_group.py | 76 +++++++++++++++++++ welearn_database/data/models/user_related.py | 6 +- 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 welearn_database/alembic/versions/9b4f1da0c1f2_data_collection_for_focus_group.py diff --git a/welearn_database/alembic/versions/9b4f1da0c1f2_data_collection_for_focus_group.py b/welearn_database/alembic/versions/9b4f1da0c1f2_data_collection_for_focus_group.py new file mode 100644 index 0000000..e0bcf07 --- /dev/null +++ b/welearn_database/alembic/versions/9b4f1da0c1f2_data_collection_for_focus_group.py @@ -0,0 +1,76 @@ +"""data collection for focus group + +Revision ID: 9b4f1da0c1f2 +Revises: 2ad4895b2674 +Create Date: 2026-02-23 18:11:55.857517 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision: str = "9b4f1da0c1f2" +down_revision: Union[str, None] = "2ad4895b2674" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.add_column( + "chat_message", + sa.Column( + "is_retrieved_by_user", + sa.Boolean(), + nullable=False, + default=False, + server_default="False", + ), + schema="user_related", + ) + op.add_column( + "chat_message", + sa.Column("original_feature_name", sa.String(), nullable=True), + schema="user_related", + ) + op.create_table( + "filter_used_in_query", + sa.Column( + "id", sa.Uuid(), server_default=sa.func.gen_random_uuid(), nullable=False + ), + sa.Column("message_id", sa.Uuid(), nullable=False), + sa.Column( + "filter_type", + postgresql.ENUM( + "sdg", + "source", + name="filter_type", + schema="user_related", + ), + nullable=False, + ), + sa.Column("filter_value", sa.String(), nullable=False), + sa.ForeignKeyConstraint( + ["message_id"], + ["user_related.chat_message.id"], + name="filter_used_in_query_message_id_fkey", + ), + sa.PrimaryKeyConstraint("id"), + schema="user_related", + ) + + +def downgrade() -> None: + op.drop_column("chat_message", "is_retrieved_by_user", schema="user_related") + op.drop_column("chat_message", "original_feature_name", schema="user_related") + op.drop_constraint( + "filter_used_in_query_message_id_fkey", + "filter_used_in_query", + schema="user_related", + type_="foreignkey", + ) + op.drop_table("filter_used_in_query", schema="user_related") + op.execute("DROP TYPE IF EXISTS user_related.filter_type") diff --git a/welearn_database/data/models/user_related.py b/welearn_database/data/models/user_related.py index f8c0579..149a407 100644 --- a/welearn_database/data/models/user_related.py +++ b/welearn_database/data/models/user_related.py @@ -96,7 +96,10 @@ class ChatMessage(Base): ) role: Mapped[str] textual_content: Mapped[str] - is_retrieved_by_user: Mapped[bool] = mapped_column(default=False) + is_retrieved_by_user: Mapped[bool] = mapped_column( + default=False, server_default="False" + ) + original_feature_name: Mapped[str | None] created_at: Mapped[datetime] = mapped_column( TIMESTAMP(timezone=False), @@ -135,7 +138,6 @@ class ReturnedDocument(Base): nullable=False, ) is_clicked: Mapped[bool] = mapped_column(default=False) - original_feature_name: Mapped[str] welearn_document: Mapped["WeLearnDocument"] = relationship() chat_message: Mapped["ChatMessage"] = relationship() From 751b3d8c40920e1dc2af58e893808de2565012dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= Date: Mon, 23 Feb 2026 18:46:31 +0100 Subject: [PATCH 7/7] Add columns to chat_message and create filter_used_in_query table --- tests/test_user_related.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_user_related.py b/tests/test_user_related.py index 5cfedef..1a02eee 100644 --- a/tests/test_user_related.py +++ b/tests/test_user_related.py @@ -116,6 +116,7 @@ def test_create_and_read_chat_message(self): conversation_id=uuid.uuid4(), role="user", textual_content="Bonjour", + original_feature_name="chat", ) self.session.add(chat) self.session.commit() @@ -152,6 +153,7 @@ def test_create_and_read_returned_document(self): inferred_user_id=inferred_user.id, conversation_id=uuid.uuid4(), role="user", + original_feature_name="chat", textual_content="test", ) self.session.add(chat) @@ -161,7 +163,6 @@ def test_create_and_read_returned_document(self): message_id=chat.id, document_id=uuid.uuid4(), is_clicked=True, - original_feature_name="chat", ) self.session.add(returned_doc) self.session.commit() @@ -207,6 +208,7 @@ def test_create_and_read_filter_used_in_query(self): inferred_user_id=inferred_user.id, conversation_id=uuid.uuid4(), role="user", + original_feature_name="chat", textual_content="test", ) self.session.add(chat)