From 04b9a4756e00c7e3bd82981b1557d9e94691bfc3 Mon Sep 17 00:00:00 2001 From: rucki Date: Fri, 28 Aug 2026 11:18:05 +0200 Subject: [PATCH] Preserve team visibility when editing items --- AGENTS.md | 80 ++++++++++++++++++++++++++++ core/templates/core/_edit_form.html | 1 + core/templates/core/item_editor.html | 2 +- core/tests.py | 33 ++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..22922a2 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,80 @@ +# my2dos – Projektkontext für Pi + +## Zweck +my2dos ist eine kleine persönliche Produktivitäts- und Wissens-App für Aufgaben, Notizen, Links, Journal-Einträge, Tags, Teams, Collections und Kanban. + +## Tech Stack +- Python / Django +- Django Templates +- HTMX für partielle Updates +- Alpine.js für UI-Interaktionen im Browser +- SQLite lokal (`db.sqlite3`) +- Virtuelle Umgebung: `.venv/` + +## Wichtige Pfade +- `core/models.py` – Datenmodelle, Tag-/Link-Metadaten-Sync +- `core/views.py` – Hauptlogik, Item-Erstellung/Bearbeitung, Teams, Collections, API +- `core/forms.py` – Django Forms +- `core/templates/core/` – UI Templates +- `core/tests.py` – Tests +- `my2dos/settings.py` – Django Settings +- `README.md` – Setup und Basis-Dokumentation + +## Zentrale Konzepte +- `Item.kind`: `todo`, `note`, `link`, `journal` +- `Item.visibility`: `private`, `team`, `public` +- Tags werden aus `#tag` im Content extrahiert und mit `Item.sync_metadata()` synchronisiert. +- Team-Tags entsprechen `Team.slug`. +- Ein Team-Tag wie `#myteam` macht ein Item automatisch zum Team-Item. +- Team-Items behalten die Verknüpfung über `Item.team` und `Item.visibility = team`. +- Interne Links haben die Form `[[note:1]]`, `[[todo:2]]` oder `[[3]]`. +- Collections können manuell oder tag-basiert sein. +- Tag-basierte Collections verwenden Content-Tags, Team-Tags sollen dabei nicht als Content-Filter genutzt werden. + +## Häufige Befehle +Setup: + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +.venv/bin/python manage.py migrate +.venv/bin/python manage.py createsuperuser +``` + +Server starten: + +```bash +.venv/bin/python manage.py runserver +``` + +Tests ausführen: + +```bash +.venv/bin/python manage.py test core +``` + +Einzelne Testklasse ausführen: + +```bash +.venv/bin/python manage.py test core.tests.TestKlasse +``` + +## Arbeitsregeln für Coding-Agenten +- Vor Änderungen relevante Dateien lesen. +- Änderungen möglichst klein und gezielt halten. +- Bestehende UI-/Template-Struktur respektieren. +- Nach funktionalen Änderungen Tests ergänzen oder anpassen. +- Wenn möglich mindestens `.venv/bin/python manage.py test core` ausführen. +- Keine grossen Refactorings ohne explizite Nachfrage. +- Keine Änderungen an Datenbank/Migrationen ohne Notwendigkeit. +- Bei Änderungen an Team-/Tag-Logik besonders auf Seiteneffekte bei Collections, API und Bearbeiten-Formularen achten. + +## Bekannte/Für die Zukunft relevante Themen +- Team-Tags und Content-Tags klar getrennt halten. +- Bearbeiten von Team-Items darf die Team-Verknüpfung nicht verlieren. +- Collections müssen Sichtbarkeit/Team-Kompatibilität von enthaltenen Items beachten. +- Mobile UI nutzt eigene Tag-Picker und Quick-Composer-Interaktionen. + +## Notizen für neue Sessions +Wenn eine neue Pi-Session in diesem Verzeichnis gestartet wird, zuerst diese Datei, `README.md` und bei Bedarf `core/models.py`, `core/views.py`, `core/forms.py` sowie `core/tests.py` berücksichtigen. diff --git a/core/templates/core/_edit_form.html b/core/templates/core/_edit_form.html index e8fe1c1..bf4e2de 100644 --- a/core/templates/core/_edit_form.html +++ b/core/templates/core/_edit_form.html @@ -19,6 +19,7 @@
{% if item.kind == 'todo' %}
{% endif %} diff --git a/core/templates/core/item_editor.html b/core/templates/core/item_editor.html index f219ddc..e150b1d 100644 --- a/core/templates/core/item_editor.html +++ b/core/templates/core/item_editor.html @@ -23,7 +23,7 @@
{% include 'core/_format_toolbar.html' %}
-
+
{% if item.kind == 'todo' %}
{% endif %}
diff --git a/core/tests.py b/core/tests.py index af767c7..6564025 100644 --- a/core/tests.py +++ b/core/tests.py @@ -147,6 +147,39 @@ class NavigationAndLayoutTests(TestCase): self.assertLess(toolbar_position, file_position) +class TeamItemEditTests(TestCase): + def setUp(self): + self.user = get_user_model().objects.create_user(username='team-editor', password='secret') + self.team = Team.objects.create(name='Docs team', slug='docs', owner=self.user) + TeamMembership.objects.create(team=self.team, user=self.user, role=TeamMembership.Role.OWNER) + self.client.force_login(self.user) + + def test_editing_team_item_preserves_team_link(self): + item = Item.objects.create( + owner=self.user, team=self.team, kind=Item.Kind.TODO, + content='Original #docs', visibility=Item.Visibility.TEAM, + ) + item.sync_metadata() + + response = self.client.post(reverse('edit_item', args=[item.id]), { + 'content': 'Updated #docs', 'comment': '', 'visibility': Item.Visibility.TEAM, 'url': '', + }) + + self.assertEqual(response.status_code, 200) + item.refresh_from_db() + self.assertEqual(item.team, self.team) + self.assertEqual(item.visibility, Item.Visibility.TEAM) + + def test_team_visibility_is_selected_in_edit_forms(self): + item = Item.objects.create( + owner=self.user, team=self.team, content='Original #docs', visibility=Item.Visibility.TEAM, + ) + response = self.client.get(reverse('edit_item', args=[item.id])) + self.assertContains(response, '