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.
This commit is contained in:
shokollm
2026-04-09 10:23:33 +00:00
parent 235a89653f
commit 66d2a9fb86
2 changed files with 45 additions and 2 deletions

View File

@@ -11,7 +11,7 @@ import os
import tempfile
from pathlib import Path
from core.models import Bounty, RoomData, TrackingData, TrackedBounty
from core.models import Bounty, Category, RoomData, TrackingData, TrackedBounty
class JsonFileRoomStorage:
@@ -57,16 +57,28 @@ class JsonFileRoomStorage:
created_by_user_id=b["created_by_user_id"],
deleted_at=b.get("deleted_at"),
created_by_username=b.get("created_by_username"),
category_ids=b.get("category_ids", []),
)
for b in data.get("bounties", [])
]
categories = [
Category(
id=c["id"],
name=c["name"],
created_at=c["created_at"],
deleted_at=c.get("deleted_at"),
)
for c in data.get("categories", [])
]
return RoomData(
room_id=data["room_id"],
bounties=bounties,
next_id=data["next_id"],
timezone=data.get("timezone"),
admin_usernames=data.get("admin_usernames", []),
categories=categories,
)
def save(self, room_data: RoomData) -> None:
@@ -76,6 +88,15 @@ class JsonFileRoomStorage:
"next_id": room_data.next_id,
"timezone": room_data.timezone,
"admin_usernames": room_data.admin_usernames or [],
"categories": [
{
"id": c.id,
"name": c.name,
"created_at": c.created_at,
"deleted_at": c.deleted_at,
}
for c in room_data.categories
],
"bounties": [
{
"id": b.id,
@@ -86,6 +107,7 @@ class JsonFileRoomStorage:
"created_by_user_id": b.created_by_user_id,
"deleted_at": b.deleted_at,
"created_by_username": b.created_by_username,
"category_ids": b.category_ids,
}
for b in room_data.bounties
],