diff --git a/adapters/storage/json_file.py b/adapters/storage/json_file.py index 670112a..41a32b9 100644 --- a/adapters/storage/json_file.py +++ b/adapters/storage/json_file.py @@ -56,6 +56,8 @@ class JsonFileRoomStorage: due_date_ts=b.get("due_date_ts"), created_at=b["created_at"], created_by_user_id=b["created_by_user_id"], + deleted_at=b.get("deleted_at"), + created_by_username=b.get("created_by_username"), ) for b in data.get("bounties", []) ] @@ -64,6 +66,8 @@ class JsonFileRoomStorage: room_id=data["room_id"], bounties=bounties, next_id=data["next_id"], + timezone=data.get("timezone"), + admin_user_ids=data.get("admin_user_ids", []), ) def save(self, room_data: RoomData) -> None: @@ -71,6 +75,8 @@ class JsonFileRoomStorage: data = { "room_id": room_data.room_id, "next_id": room_data.next_id, + "timezone": room_data.timezone, + "admin_user_ids": room_data.admin_user_ids or [], "bounties": [ { "id": b.id, @@ -79,6 +85,8 @@ class JsonFileRoomStorage: "due_date_ts": b.due_date_ts, "created_at": b.created_at, "created_by_user_id": b.created_by_user_id, + "deleted_at": b.deleted_at, + "created_by_username": b.created_by_username, } for b in room_data.bounties ], diff --git a/core/models.py b/core/models.py index fe57645..e2109e5 100644 --- a/core/models.py +++ b/core/models.py @@ -9,6 +9,9 @@ class Bounty: The created_by_user_id field always refers to the user who created the bounty. It does NOT indicate whether the bounty is a group or personal bounty. + + The deleted_at field indicates soft-delete: None means not deleted, + a value means deleted at that Unix timestamp. """ id: int @@ -17,6 +20,8 @@ class Bounty: due_date_ts: int | None created_at: int created_by_user_id: int + deleted_at: int | None = None + created_by_username: str | None = None @dataclass @@ -37,11 +42,20 @@ class RoomData: The room_id can be negative for Telegram groups or positive for DMs. The next_id field is used to generate unique bounty IDs within this room. + + The timezone field stores the room's timezone (e.g., "Asia/Jakarta"), default UTC+0. + The admin_user_ids field lists users who have admin privileges in this room. """ room_id: int bounties: list[Bounty] next_id: int + timezone: str | None = None + admin_user_ids: list[int] | None = None + + def __post_init__(self): + if self.admin_user_ids is None: + self.admin_user_ids = [] @dataclass diff --git a/tests/test_models.py b/tests/test_models.py index ca45860..355d255 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -28,6 +28,22 @@ class TestBounty: assert b.due_date_ts == 1735689600 assert b.created_at == 1735603200 assert b.created_by_user_id == 123 + assert b.deleted_at is None + assert b.created_by_username is None + + def test_bounty_with_new_fields(self): + b = Bounty( + id=1, + text="Fix the bug", + link="https://github.com/example/repo/issues/1", + due_date_ts=1735689600, + created_at=1735603200, + created_by_user_id=123, + deleted_at=1736200000, + created_by_username="johndoe", + ) + assert b.deleted_at == 1736200000 + assert b.created_by_username == "johndoe" def test_bounty_optional_fields_can_be_none(self): b = Bounty( @@ -41,6 +57,8 @@ class TestBounty: assert b.text is None assert b.link is None assert b.due_date_ts is None + assert b.deleted_at is None + assert b.created_by_username is None def test_bounty_comparison_equal(self): b1 = Bounty( @@ -103,6 +121,8 @@ class TestRoomData: assert rd.room_id == -1001 assert rd.bounties == [] assert rd.next_id == 1 + assert rd.timezone is None + assert rd.admin_user_ids == [] def test_create_dm_room_data(self): rd = RoomData( @@ -113,6 +133,8 @@ class TestRoomData: assert rd.room_id == 123456 assert rd.bounties == [] assert rd.next_id == 1 + assert rd.timezone is None + assert rd.admin_user_ids == [] def test_room_data_with_bounties(self): b = Bounty( @@ -128,6 +150,25 @@ class TestRoomData: assert rd.bounties[0].text == "Task" assert rd.bounties[0].created_by_user_id == 123 + def test_room_data_with_new_fields(self): + rd = RoomData( + room_id=-1001, + bounties=[], + next_id=1, + timezone="Asia/Jakarta", + admin_user_ids=[123, 456], + ) + assert rd.timezone == "Asia/Jakarta" + assert rd.admin_user_ids == [123, 456] + + def test_room_data_admin_user_ids_defaults_to_empty_list(self): + rd = RoomData( + room_id=-1001, + bounties=[], + next_id=1, + ) + assert rd.admin_user_ids == [] + class TestTrackingData: def test_create_tracking_data(self):