generated from coulomb/repo-seed
issue-facade was renamed to issue-core. Update the dependency declaration and the three Python imports it touched. Model field names (issue_facade_backend, issue_facade_id) and the Django setting ISSUE_FACADE_LOCAL_DB stay as-is — they are persisted/semantic identifiers, not part of the package wiring. All 20 aufgaben tests pass after the rewire. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
from datetime import datetime, timezone
|
|
|
|
from issue_core.core.models import Issue, IssueState, Label, Priority
|
|
|
|
from .issue_backends import gitea_configured, local_backend, remote_backend
|
|
|
|
|
|
def aufgabe_zu_issue(aufgabe) -> Issue:
|
|
"""Konvertiert eine Aufgabe in ein issue-facade Issue-Objekt."""
|
|
prioritaet_map = {1: Priority.HIGH, 2: Priority.MEDIUM, 3: Priority.LOW}
|
|
labels = [
|
|
Label(name='task'),
|
|
Label(name=f'priority:{prioritaet_map.get(aufgabe.prioritaet, Priority.MEDIUM).value}'),
|
|
]
|
|
if aufgabe.typ:
|
|
labels.append(Label(name=aufgabe.typ))
|
|
|
|
now = datetime.now(timezone.utc)
|
|
return Issue(
|
|
id='',
|
|
number=0,
|
|
title=aufgabe.titel,
|
|
description=aufgabe.beschreibung or '',
|
|
state=IssueState.OPEN,
|
|
created_at=now,
|
|
updated_at=now,
|
|
labels=labels,
|
|
)
|
|
|
|
|
|
def lokales_issue_erstellen(aufgabe) -> dict:
|
|
"""
|
|
Legt ein Issue im lokalen SQLite-Backend an.
|
|
Gibt {'issue_facade_id', 'issue_key', 'sync_status'} zurück.
|
|
"""
|
|
issue = aufgabe_zu_issue(aufgabe)
|
|
with local_backend() as b:
|
|
created = b.create_issue(issue)
|
|
return {
|
|
'issue_facade_id': str(created.id),
|
|
'issue_key': f'#{created.number}',
|
|
'sync_status': created.state.value,
|
|
}
|
|
|
|
|
|
def an_gitea_delegieren(aufgabe, external_issue) -> dict:
|
|
"""
|
|
Schiebt ein lokales Issue nach Gitea.
|
|
Gibt {'issue_facade_backend', 'issue_facade_id', 'issue_url', 'issue_key', 'sync_status'} zurück.
|
|
Wirft ValueError wenn Gitea nicht konfiguriert ist.
|
|
"""
|
|
with remote_backend() as b:
|
|
if b is None:
|
|
raise ValueError('Gitea nicht konfiguriert (ISSUE_FACADE_GITEA fehlt in settings)')
|
|
issue = aufgabe_zu_issue(aufgabe)
|
|
created = b.create_issue(issue)
|
|
url = ''
|
|
if created.sync_metadata:
|
|
url = created.sync_metadata.get('url', '')
|
|
return {
|
|
'issue_facade_backend': 'gitea',
|
|
'issue_facade_id': str(created.number),
|
|
'issue_url': url,
|
|
'issue_key': f'#{created.number}',
|
|
'sync_status': created.state.value,
|
|
}
|
|
|
|
|
|
def status_synchronisieren(external_issue) -> str:
|
|
"""
|
|
Liest den aktuellen Status aus dem konfigurierten Backend.
|
|
Gibt den neuen sync_status-String zurück.
|
|
"""
|
|
from django.utils import timezone as dj_tz
|
|
|
|
backend_ctx = (
|
|
remote_backend() if external_issue.issue_facade_backend == 'gitea'
|
|
else local_backend()
|
|
)
|
|
with backend_ctx as b:
|
|
if b is None:
|
|
raise ValueError('Backend nicht verfügbar')
|
|
issue = b.get_issue(external_issue.issue_facade_id)
|
|
|
|
neuer_status = issue.state.value if issue else 'error'
|
|
external_issue.sync_status = neuer_status
|
|
external_issue.letzter_sync = dj_tz.now()
|
|
external_issue.save(update_fields=['sync_status', 'letzter_sync'])
|
|
return neuer_status
|
|
|
|
|
|
def issue_schliessen(external_issue) -> None:
|
|
"""Setzt das Issue im Backend auf CLOSED."""
|
|
backend_ctx = (
|
|
remote_backend() if external_issue.issue_facade_backend == 'gitea'
|
|
else local_backend()
|
|
)
|
|
with backend_ctx as b:
|
|
if b is None:
|
|
return
|
|
issue = b.get_issue(external_issue.issue_facade_id)
|
|
if issue:
|
|
issue.state = IssueState.CLOSED
|
|
b.update_issue(issue)
|
|
external_issue.sync_status = 'closed'
|
|
external_issue.save(update_fields=['sync_status'])
|
|
|
|
|
|
def get_adapter(system: str):
|
|
"""Rückwärtskompatible Stub — gibt None zurück (kein manuelles Adapter-Dict mehr)."""
|
|
return None
|