fix(process): derive target date from message send day, not processing day
A message sent yesterday but processed today (e.g. by the next service run) landed in today's daily note. The send time was captured in received_at but only HH:MM reached the LLM; the date defaulted to date.today(). Now today/weekday in the processor context are derived per item from received_at, so "gestern"/"heute" resolve relative to when the message was actually written. Adds day_context() helper and a regression test (sent 2026-06-25, processed 2026-06-26 -> note 2026-06-25). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5bf79d6b92
commit
d2f8319772
|
|
@ -21,6 +21,11 @@ def _read_frontmatter(text: str) -> dict[str, str]:
|
|||
return out
|
||||
|
||||
|
||||
def day_context(d: date) -> dict:
|
||||
"""today/weekday for a given date (the message's send day)."""
|
||||
return {"today": d.isoformat(), "weekday": WEEKDAYS_DE[d.weekday()]}
|
||||
|
||||
|
||||
def collect_vault_context(vault_path: Path, today: date) -> dict:
|
||||
persons: list[dict] = []
|
||||
persons_dir = vault_path / "00 Kontext" / "Personen"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from datetime import date, datetime
|
||||
from pathlib import Path
|
||||
from .context import collect_vault_context
|
||||
from .context import collect_vault_context, day_context
|
||||
from .queue import Queue
|
||||
from .vault_writer import VaultWriter
|
||||
from .processor_protocol import ProcessorInput
|
||||
|
|
@ -18,9 +18,14 @@ def process_once(processor, queue: Queue, writer: VaultWriter, vault_path: Path,
|
|||
try:
|
||||
received_dt = datetime.fromisoformat(item.received_at)
|
||||
received_time = received_dt.strftime("%H:%M")
|
||||
# Default day is the message's SEND day, not the processing day,
|
||||
# so a message sent yesterday but processed today lands in
|
||||
# yesterday's note. "gestern"/"heute" in the text are relative
|
||||
# to the send day. Fall back to `today` if received_at is unusable.
|
||||
send_day = day_context(received_dt.date())
|
||||
payload = ProcessorInput(
|
||||
today=ctx["today"],
|
||||
weekday=ctx["weekday"],
|
||||
today=send_day["today"],
|
||||
weekday=send_day["weekday"],
|
||||
received_time=received_time,
|
||||
persons=ctx["persons"],
|
||||
projects=ctx["projects"],
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Antworte ausschließlich mit einem JSON-Objekt nach folgendem Schema. Kein Flie
|
|||
|
||||
# Regeln
|
||||
|
||||
1. **target_date:** Standard = `today` aus dem Context. Bei „gestern" → today − 1, „vorgestern" → today − 2. Bei explizitem Datum (z.B. „am 12. Juni") dieses verwenden.
|
||||
1. **target_date:** Standard = `today` aus dem Context. `today` ist der **Sendetag der Nachricht** (nicht der Verarbeitungstag), also der Tag, an dem Christian die Nachricht geschrieben hat. Bei „gestern" → today − 1, „vorgestern" → today − 2 (relativ zum Sendetag). Bei explizitem Datum (z.B. „am 12. Juni") dieses verwenden.
|
||||
2. **target_path:** Immer `05 Daily Notes/{target_date}.md`.
|
||||
3. **entry_markdown:** Beginnt IMMER mit `## HH:MM`. Nutze `received_time` aus dem Context.
|
||||
4. **Meta-Anweisungen entfernen:** Phrasen wie „Schreib ins Journal, dass …", „Notier dir, dass …", „Merk dir …" gehören NICHT in den Eintragstext. Liste sie in `raw_excluded`.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,23 @@ class FakeProcessor:
|
|||
return self._output
|
||||
|
||||
|
||||
class CapturingProcessor:
|
||||
"""Records the payload it was asked to process and echoes today as target."""
|
||||
def __init__(self):
|
||||
self.payload = None
|
||||
|
||||
def health_check(self):
|
||||
return True
|
||||
|
||||
def process(self, payload):
|
||||
self.payload = payload
|
||||
return ProcessorOutput(
|
||||
target_date=payload.today,
|
||||
target_path=f"05 Daily Notes/{payload.today}.md",
|
||||
entry_markdown=f"## {payload.received_time}\n{payload.text}",
|
||||
)
|
||||
|
||||
|
||||
def make_item(update_id=1, text="Hallo"):
|
||||
return QueueItem(
|
||||
update_id=update_id,
|
||||
|
|
@ -74,6 +91,35 @@ def test_process_fails_item_on_error(tmp_path):
|
|||
assert data["attempts"] == 1
|
||||
|
||||
|
||||
def test_target_date_follows_send_day_not_processing_day(tmp_path):
|
||||
# Message sent yesterday (2026-06-25), processed today (2026-06-26).
|
||||
# The daily note must be the send day, not the processing day.
|
||||
vault = tmp_path / "vault"
|
||||
(vault / "05 Daily Notes").mkdir(parents=True)
|
||||
queue = Queue(tmp_path / "q")
|
||||
item = QueueItem(
|
||||
update_id=1,
|
||||
received_at="2026-06-25T08:13:42+02:00",
|
||||
type="text",
|
||||
text="Neue Charge Kefir angesetzt",
|
||||
)
|
||||
queue.enqueue(item)
|
||||
processor = CapturingProcessor()
|
||||
writer = VaultWriter(vault)
|
||||
process_once(
|
||||
processor, queue, writer,
|
||||
vault_path=vault,
|
||||
today=date(2026, 6, 26), # processing day differs from send day
|
||||
processed_at="2026-06-26T06:55:22+02:00",
|
||||
)
|
||||
# The processor must have been told today = the send day, with matching weekday.
|
||||
assert processor.payload.today == "2026-06-25"
|
||||
assert processor.payload.weekday == "Donnerstag" # 2026-06-25 is a Thursday
|
||||
# And the entry landed in the send-day note.
|
||||
data = json.loads((tmp_path / "q" / "done" / "1.json").read_text(encoding="utf-8"))
|
||||
assert data["target_path"] == "05 Daily Notes/2026-06-25.md"
|
||||
|
||||
|
||||
def test_process_records_result_fields(tmp_path):
|
||||
vault = tmp_path / "vault"
|
||||
(vault / "05 Daily Notes").mkdir(parents=True)
|
||||
|
|
|
|||
Loading…
Reference in New Issue