7 Commits

Author SHA1 Message Date
shokollm
66d2a9fb86 feat: add Category model and update storage for categories
Models & Storage layer for category feature (Issue #85):

- Add Category dataclass to core/models.py
  - id (slug): lowercase alphabetic only
  - name: display name
  - created_at: Unix timestamp
  - deleted_at: soft delete timestamp (None if active)

- Add category_ids field to Bounty dataclass
  - list[str] for multiple categories per bounty
  - Default empty list for backward compatibility

- Add categories field to RoomData dataclass
  - list[Category] for room-level categories
  - Default empty list

- Update JsonFileRoomStorage to serialize/deserialize:
  - Category fields (id, name, created_at, deleted_at)
  - Bounty.category_ids
  - RoomData.categories

Backward compatible: existing data without categories works fine.
2026-04-09 10:23:33 +00:00
shokollm
8494b4621c feat: switch admin identification from user_id to username
- Replace admin_user_ids (list[int]) with admin_usernames (list[str])
- Update all service methods to use username for permission checks
- Add delete button to bot responses for message cleanup
- Update tests to match new implementation

Note: Breaking change - existing data files need fresh start
2026-04-09 08:02:36 +00:00
shokollm
fee8504813 feat: add deleted_at, created_by_username to Bounty; timezone, admin_user_ids to RoomData
Issue #41: Model updates for Phase 2 features

Bounty model:
- Add deleted_at: int | None - timestamp when deleted (soft-delete)
- Add created_by_username: str | None - username for display purposes

RoomData model:
- Add timezone: str | None - room's timezone (e.g., "Asia/Jakarta")
- Add admin_user_ids: list[int] - list of admin user IDs

Storage adapter updated to handle new fields in load/save operations.
Tests added for new fields.
2026-04-04 04:59:58 +00:00
shokollm
b2854393ae Address PR #19 review feedback round 3:
- TrackingData.group_id renamed to room_id (works for both group and DM)
- Removed room_id from TrackedBounty (it's just a lightweight pointer)
2026-04-02 22:34:19 +00:00
shokollm
330203e6ef Address PR #19 review feedback round 2:
- Bounty.created_by_user_id is now non-optional (always required)
- Removed is_group from RoomData (negative room_id is self-documenting)
- Added room_id to TrackedBounty to track which room bounty was tracked from
- Added clarifying docstrings explaining TrackingData vs TrackedBounty
- Updated tests to match new model structure
2026-04-02 22:24:12 +00:00
shokollm
f1ef33451c Address PR #19 review feedback: simplify models
- Remove GroupBounty/PersonalBounty subclasses, use Bounty with optional created_by_user_id
- Combine UserData/GroupData into RoomData with room_id and is_group fields
- Add group_id field to TrackingData (supports negative Telegram group IDs)
- Add test_bounty_comparison_not_equal for verifying different bounties are not equal
- Update core/__init__.py exports
2026-04-02 21:47:26 +00:00
shokollm
db09a518d1 feat(core): implement domain dataclasses for issue #5
- Create core/__init__.py
- Create core/models.py with all domain dataclasses:
  - Bounty (base class)
  - GroupBounty (extends Bounty)
  - PersonalBounty (extends Bounty)
  - TrackedBounty
  - GroupData
  - TrackingData
  - UserData
- Create tests/test_models.py with 15 passing tests

Fixes #5
2026-04-02 20:15:41 +00:00