Compare commits
2 Commits
235a89653f
...
43d07eae92
| Author | SHA1 | Date | |
|---|---|---|---|
| 43d07eae92 | |||
|
|
66d2a9fb86 |
@@ -11,7 +11,7 @@ import os
|
|||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from core.models import Bounty, RoomData, TrackingData, TrackedBounty
|
from core.models import Bounty, Category, RoomData, TrackingData, TrackedBounty
|
||||||
|
|
||||||
|
|
||||||
class JsonFileRoomStorage:
|
class JsonFileRoomStorage:
|
||||||
@@ -57,16 +57,28 @@ class JsonFileRoomStorage:
|
|||||||
created_by_user_id=b["created_by_user_id"],
|
created_by_user_id=b["created_by_user_id"],
|
||||||
deleted_at=b.get("deleted_at"),
|
deleted_at=b.get("deleted_at"),
|
||||||
created_by_username=b.get("created_by_username"),
|
created_by_username=b.get("created_by_username"),
|
||||||
|
category_ids=b.get("category_ids", []),
|
||||||
)
|
)
|
||||||
for b in data.get("bounties", [])
|
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(
|
return RoomData(
|
||||||
room_id=data["room_id"],
|
room_id=data["room_id"],
|
||||||
bounties=bounties,
|
bounties=bounties,
|
||||||
next_id=data["next_id"],
|
next_id=data["next_id"],
|
||||||
timezone=data.get("timezone"),
|
timezone=data.get("timezone"),
|
||||||
admin_usernames=data.get("admin_usernames", []),
|
admin_usernames=data.get("admin_usernames", []),
|
||||||
|
categories=categories,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, room_data: RoomData) -> None:
|
def save(self, room_data: RoomData) -> None:
|
||||||
@@ -76,6 +88,15 @@ class JsonFileRoomStorage:
|
|||||||
"next_id": room_data.next_id,
|
"next_id": room_data.next_id,
|
||||||
"timezone": room_data.timezone,
|
"timezone": room_data.timezone,
|
||||||
"admin_usernames": room_data.admin_usernames or [],
|
"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": [
|
"bounties": [
|
||||||
{
|
{
|
||||||
"id": b.id,
|
"id": b.id,
|
||||||
@@ -86,6 +107,7 @@ class JsonFileRoomStorage:
|
|||||||
"created_by_user_id": b.created_by_user_id,
|
"created_by_user_id": b.created_by_user_id,
|
||||||
"deleted_at": b.deleted_at,
|
"deleted_at": b.deleted_at,
|
||||||
"created_by_username": b.created_by_username,
|
"created_by_username": b.created_by_username,
|
||||||
|
"category_ids": b.category_ids,
|
||||||
}
|
}
|
||||||
for b in room_data.bounties
|
for b in room_data.bounties
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,20 @@
|
|||||||
"""Domain dataclasses for JIGAIDO bounty tracker."""
|
"""Domain dataclasses for JIGAIDO bounty tracker."""
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Category:
|
||||||
|
"""A category for organizing bounties in a room.
|
||||||
|
|
||||||
|
Categories are per-room and support soft delete.
|
||||||
|
The id (slug) must be lowercase alphabetic only (e.g., "bug", "feature").
|
||||||
|
"""
|
||||||
|
|
||||||
|
id: str # slug: lowercase alphabetic only, e.g., "bug", "feature"
|
||||||
|
name: str # display name: e.g., "Bug", "Feature"
|
||||||
|
created_at: int
|
||||||
|
deleted_at: int | None = None # soft delete
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -12,6 +26,8 @@ class Bounty:
|
|||||||
|
|
||||||
The deleted_at field indicates soft-delete: None means not deleted,
|
The deleted_at field indicates soft-delete: None means not deleted,
|
||||||
a value means deleted at that Unix timestamp.
|
a value means deleted at that Unix timestamp.
|
||||||
|
|
||||||
|
The category_ids field lists category slugs associated with this bounty.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
id: int
|
id: int
|
||||||
@@ -22,6 +38,7 @@ class Bounty:
|
|||||||
created_by_user_id: int
|
created_by_user_id: int
|
||||||
deleted_at: int | None = None
|
deleted_at: int | None = None
|
||||||
created_by_username: str | None = None
|
created_by_username: str | None = None
|
||||||
|
category_ids: list[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -45,6 +62,7 @@ class RoomData:
|
|||||||
|
|
||||||
The timezone field stores the room's timezone (e.g., "Asia/Jakarta"), default UTC+0.
|
The timezone field stores the room's timezone (e.g., "Asia/Jakarta"), default UTC+0.
|
||||||
The admin_usernames field lists usernames who have admin privileges in this room.
|
The admin_usernames field lists usernames who have admin privileges in this room.
|
||||||
|
The categories field contains all categories for organizing bounties in this room.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
room_id: int
|
room_id: int
|
||||||
@@ -52,10 +70,13 @@ class RoomData:
|
|||||||
next_id: int
|
next_id: int
|
||||||
timezone: str | None = None
|
timezone: str | None = None
|
||||||
admin_usernames: list[str] | None = None
|
admin_usernames: list[str] | None = None
|
||||||
|
categories: list[Category] = field(default_factory=list)
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.admin_usernames is None:
|
if self.admin_usernames is None:
|
||||||
self.admin_usernames = []
|
self.admin_usernames = []
|
||||||
|
if self.categories is None:
|
||||||
|
self.categories = []
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
Reference in New Issue
Block a user