Skip to content

Commit bb53fe0

Browse files
committed
logic pass complete, pending UI
1 parent 3f87338 commit bb53fe0

2 files changed

Lines changed: 92 additions & 89 deletions

File tree

src/logic/scheduler.py

Lines changed: 91 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,98 @@
11
"""
2-
scheduler.py (v0.4)
3-
-------------------
4-
Core scheduler logic for SchedPlus (v0.4).
5-
6-
This module provides the `Task` dataclass and the `Scheduler` class.
7-
The `Scheduler` is responsible for in-memory task management and
8-
exposes small wrapper methods to persist/load tasks via the storage
9-
layer so UIs (Tkinter/PyQt) do not need to know storage paths.
2+
scheduler.py
3+
------------
4+
DB-backed scheduler façade for SchedPlus.
5+
6+
This class used to manage JSON storage.
7+
It now delegates all persistence to the Repository.
8+
9+
UI-friendly method names are preserved for compatibility:
10+
- add_task
11+
- update_task
12+
- delete_task
13+
- list_tasks
14+
- get_task
15+
- add_comment
16+
- list_comments
17+
- assign_tag
18+
- get_tags
1019
"""
1120

12-
import uuid
13-
from dataclasses import dataclass, field
14-
from typing import List
15-
from datetime import datetime
16-
17-
@dataclass
18-
class Task:
19-
id: str = field(default_factory=lambda: str(uuid.uuid4()))
20-
date: str = ""
21-
time: str = ""
22-
text: str = ""
23-
createdAt: str = field(default_factory=lambda: datetime.utcnow().isoformat())
24-
updatedAt: str = field(default_factory=lambda: datetime.utcnow().isoformat())
25-
26-
def to_dict(self):
27-
return {
28-
"id": self.id,
29-
"date": self.date,
30-
"time": self.time,
31-
"text": self.text,
32-
"createdAt": self.createdAt,
33-
"updatedAt": self.updatedAt,
34-
}
35-
36-
@classmethod
37-
def from_dict(cls, data: dict):
38-
return cls(
39-
id=data.get("id", str(uuid.uuid4())),
40-
date=data.get("date", ""),
41-
time=data.get("time", ""),
42-
text=data.get("text", ""),
43-
createdAt=data.get("createdAt", datetime.utcnow().isoformat()),
44-
updatedAt=data.get("updatedAt", datetime.utcnow().isoformat()),
45-
)
21+
from typing import Optional, List
22+
from storage.repository import Repository
23+
from storage.models import Entry, Comment, Tag
24+
25+
4626
class Scheduler:
4727
"""
48-
The Scheduler class manages a list of tasks.
49-
In v0.4, tasks are stored in memory and the class exposes
50-
simple `save_tasks`/`load_tasks` helpers that delegate to the
51-
storage layer. This keeps UIs decoupled from storage details.
28+
Scheduler provides a UI-friendly API for task operations.
29+
30+
NEW RULE:
31+
- Scheduler now requires a Repository instance.
32+
- No JSON loading or saving.
33+
- No Task dataclass.
5234
"""
5335

54-
def __init__(self):
55-
self.tasks: List[Task] = []
56-
57-
def add_task(self, date: str, time: str, text: str):
58-
"""
59-
Add a new task to the scheduler.
60-
No validation yet — this will be added in v0.2+.
61-
"""
62-
task = Task(date=date, time=time, text=text)
63-
self.tasks.append(task)
64-
65-
def save_tasks(self, filepath: str = None):
66-
"""
67-
Persist current tasks using the storage layer.
68-
69-
This method performs a local import to avoid import cycles
70-
between `logic.storage` and `logic.scheduler`.
71-
"""
72-
try:
73-
from . import storage as _storage
74-
75-
_storage.save_tasks(self.tasks, filepath) if filepath else _storage.save_tasks(self.tasks)
76-
except Exception:
77-
# Intentionally swallow errors here; storage will log on failure.
78-
pass
79-
80-
def load_tasks(self, filepath: str = None):
81-
"""
82-
Load tasks from the storage layer into `self.tasks`.
83-
Returns the loaded list of tasks.
84-
"""
85-
try:
86-
from . import storage as _storage
87-
88-
self.tasks = _storage.load_tasks(filepath)
89-
except Exception:
90-
self.tasks = []
91-
92-
return self.tasks
93-
94-
def get_tasks(self) -> List[Task]:
95-
"""Return the list of tasks."""
96-
return self.tasks
36+
def __init__(self, repo: Repository):
37+
self.repo = repo
38+
39+
# ---------------------------------------------------------
40+
# Task CRUD (Entry CRUD)
41+
# ---------------------------------------------------------
42+
43+
def add_task(
44+
self,
45+
title: str,
46+
description: Optional[str] = None,
47+
due_date: Optional[str] = None,
48+
) -> Entry:
49+
return self.repo.create_entry(
50+
title=title,
51+
description=description,
52+
due_date=due_date,
53+
)
54+
55+
def update_task(
56+
self,
57+
task_id: int,
58+
title: Optional[str] = None,
59+
description: Optional[str] = None,
60+
due_date: Optional[str] = None,
61+
completed: Optional[bool] = None,
62+
) -> Optional[Entry]:
63+
return self.repo.update_entry(
64+
entry_id=task_id,
65+
title=title,
66+
description=description,
67+
due_date=due_date,
68+
completed=completed,
69+
)
70+
71+
def delete_task(self, task_id: int) -> None:
72+
self.repo.delete_entry(task_id)
73+
74+
def get_task(self, task_id: int) -> Optional[Entry]:
75+
return self.repo.get_entry(task_id)
76+
77+
def list_tasks(self) -> List[Entry]:
78+
return self.repo.list_entries()
79+
80+
# ---------------------------------------------------------
81+
# Comments
82+
# ---------------------------------------------------------
83+
84+
def add_comment(self, task_id: int, text: str) -> Comment:
85+
return self.repo.add_comment(task_id, text)
86+
87+
def list_comments(self, task_id: int) -> List[Comment]:
88+
return self.repo.list_comments(task_id)
89+
90+
# ---------------------------------------------------------
91+
# Tags
92+
# ---------------------------------------------------------
93+
94+
def assign_tag(self, task_id: int, tag_name: str) -> Tag:
95+
return self.repo.assign_tag(task_id, tag_name)
96+
97+
def get_tags(self) -> List[Tag]:
98+
return self.repo.get_tags()

src/startup/controller.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def _launch_mode(mode: StartupMode):
8080
run_migration(repo)
8181

8282
# 4. Create DB-backed scheduler
83+
# NOTE: Scheduler now requires a Repository instance.
8384
scheduler = Scheduler(repo)
8485

8586
# ---------------------------------------------------------

0 commit comments

Comments
 (0)