OParl / spec

Spezifikation für eine offene Schnittstelle für Ratsinformationssysteme
https://oparl.org
Creative Commons Attribution Share Alike 4.0 International
61 stars 21 forks source link

Update-Mechanismus #398

Closed sterni24 closed 6 years ago

sterni24 commented 6 years ago

Zur Diskussion um den Pull request #397 bleiben einige Fragen offen:

  1. Wie kann ein Client, der seine Daten über den Update-Modus aktualisiert, bei Ausgabe seines Datenbestandes derzeit die Reihenfolge seiner Tagesordnung bestimmen? Muss er dabei selbst für eine korrekte Sortierung sorgen?

  2. Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?

  3. Ist es überhaupt sinnvoll, auch im Hinblick auf die Aktualität, alle Objekte für den Update-Modus bereitzustellen? Wenn ja, warum wird hier bei LegislativTerm eine Ausnahme gemacht?

Ich bin der Meinung, die Version Oparl 1.1 nicht als schnelle Lösung für den Abgleich bei https://politik-bei-uns.de/ zu veröffentlichen, sondern diese Fragen (und vielleicht noch andere) im Hinblick auf zukünftige Versionen nachhaltig zu klären.

akuckartz commented 6 years ago

Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?

Die Frage (bzw. deren Anlass) verstehe ich nicht. Weshalb sollte es vom Betreiber abhängen, welche Daten sein Server liefern kann?

sterni24 commented 6 years ago

Die Idee dabei ist, dass die vom OKF-Server eingesammelten Daten via OParl-Schnittstelle abgefragt / ausgewertet werden können. Ähnliche Überlegungen für eine zentrale Datenhaltung gab es bereits im Jahr 2016 beim Land Rheinland-Pfalz.

Um für dieses Szenario die korrekte Ausgabe einer Tagesordnung zu gewährleisten, spielt die Sortierung der AgendaItems eine elementare Rolle.

Im Übrigen halte ich nichts davon, im Update-Mechanismus Ausnahmen in Form von eingebetteten Listen (LegislativTermin, AgendaItem) mangels fehlender Objekteigenschaften zu kreieren.

konstin commented 6 years ago

Vorweg: OParl 1.1 (und der Update-Mechasnismus im Allgemeinen) sind in keinster Weise nur für eine sammelnde Zentralinstanzen wie Politik bei Uns, sondern für alle Clients gedacht.

Wie kann ein Client, der seine Daten über den Update-Modus aktualisiert, bei Ausgabe seines Datenbestandes derzeit die Reihenfolge seiner Tagesordnung bestimmen? Muss er dabei selbst für eine korrekte Sortierung sorgen?

Ein Client bekommt die Reihenfolge der Tagesordnungspunkte durch die Reihenfolge der eingebetteten Objekte. Wie er diese speichert bleibt ihm überlassen, die meisten werden vermutlich einfach die Position als zusätzliche Spalte in ihrer Datenbank speichern.

Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?

Beide Server sollten prinzipiell die gleichen Daten ausgeben können.

Ist es überhaupt sinnvoll, auch im Hinblick auf die Aktualität, alle Objekte für den Update-Modus bereitzustellen? Wenn ja, warum wird hier bei LegislativTerm eine Ausnahme gemacht?

Ja, z.B. kann für eine App schnell den lokalen Datenbestand aktualisieren, um darauf dann eine eigene Suche oder eine Offline-Funktion anzubieten.

Bei LegislativTerm war der Gedanke, dass die Liste ja schon in Body exisitiert und es sich daher nicht lohnt, dazu noch eine externe Liste anzubieten. Es wäre aber kein Problem, auch für LegislativTerm noch eine externe Liste hinzuzufügen.

Ich bin der Meinung, die Version Oparl 1.1 nicht als schnelle Lösung für den Abgleich bei https://politik-bei-uns.de/ zu veröffentlichen, sondern diese Fragen (und vielleicht noch andere) im Hinblick auf zukünftige Versionen nachhaltig zu klären.

Die nachhaltigere (und deutlich einfachere) Lösung wäre es, die internen Listen durch URL-Listen ersetzen. Diese Ausgabe könnten OParl-1.0-Clients aber nicht mehr verstehen und OParl-Server müssten zu großen Teilen neu geschrieben werden, was wir vermeiden wollten. In OParl 1.1 versuchen wir daher, die in OParl 1.0 fehlenden Funktionen ohne Kompatibilitätsbruch nachzurüsten.

Um für dieses Szenario die korrekte Ausgabe einer Tagesordnung zu gewährleisten, spielt die Sortierung der AgendaItems eine elementare Rolle.

Im Übrigen halte ich nichts davon, im Update-Mechanismus Ausnahmen in Form von eingebetteten Listen (LegislativTermin, AgendaItem) mangels fehlender Objekteigenschaften zu kreieren.

Bei LegislativeTerm würde wie oben beschrieben eine zusätzliche externe Liste in Body ausreichen. für AgendaItem wäre eine agendaItemOrder wie von @Medo42 in https://github.com/OParl/spec/pull/397#issuecomment-372151093 beschrieben nötig.

akuckartz commented 6 years ago

korrekte Ausgabe einer Tagesordnung

Diese Anforderung betrifft auch andere Proxy-Server und ist auch unabhängig von dem Datenformat, welches die Server liefern. Ich selbst lege z.B. auch bei einer Ausgabe als Linked Data viel Wert auf die korrekte Reihenfolge der TOPs.

akuckartz commented 6 years ago

die internen Listen durch URL-Listen ersetzen. [...] OParl-Server müssten [dann aber] zu großen Teilen neu geschrieben werden

Auch wenn ich nicht sehr optimistisch bezüglich der Code-Qualität bin: Diese Bewertung des Aufwands halte ich für gewagt.

sterni24 commented 6 years ago

Es geht mir nicht darum, interne Listen durch URL-Listen zu ersetzen. Es geht darum, für den Update-Modus einen sauberen, generischen Ansatz zu finden, mit dem alle Objekte zeitsparend und ohne großen Aufwand aktualisiert werden können. Hierzu werden interne Listen nicht benötigt.

Bei LegislativeTerm würde wie oben beschrieben eine zusätzliche externe Liste in Body ausreichen. für AgendaItem wäre eine agendaItemOrder wie von @Medo42 in #397 (comment) beschrieben nötig.

Wird das nun so umgesetzt?

konstin commented 6 years ago

Wird das nun so umgesetzt?

Der Kommentar war (ebenso wie das Pull Request #397) als Vorschlag zur Diskussion gedacht. Wenn die Frage als Zustimmung zu agendaItemOrder gemeint ist, werde ich das gerne dem Pull Request hinzufügen.

sterni24 commented 6 years ago

Die Bezeichnung der Eigenschaft würde ich noch ändern in order oder numberOrder.

Medo42 commented 6 years ago

Die Bezeichnung der Eigenschaft würde ich noch ändern in order oder numberOrder.

Dem Namen nach würde das eher zu einer numerischen Eigenschaft an AgendaItem passen. Reden wir hier noch über das selbe?

sterni24 commented 6 years ago

Wir reden über den fehlenden Sortierschlüssel in AgendaItem. M. E. reicht hier ein numerischer Wert von 1 bis n aus.

Medo42 commented 6 years ago

Das ist allerdings ein gänzlich anderer Vorschlag als das, was bisher unter dem Namen agendaItemOrder diskutiert wurde (das war eine Eigenschaft im Meeting-Objekt, die die IDs der AgendaItems in der entsprechenden Reihenfolge enthält). Und ich bekomme gerade das erste mal mit, dass "Sortierschlüssel in AgendaItem" als Lösungsvorschlag überhaupt im Raum steht.

Mit dieser Alternative könnte ich auch arbeiten, aber eine laufende Nummer ist m.E. etwas spezifischer als nötig wenn es nur darum geht eine Reihenfolge festzulegen. Das führt dazu, dass sich bei Hinzukommen eines AgendaItems in der Mitte der Liste alle nachfolgenden AgendaItems ebenfalls ändern müssen (d.h. sie müssen auch synchronisiert werden), da sich ihre laufende Nummer erhöhen muss.

sterni24 commented 6 years ago

Sorry, das mit der Eigenschaft in Meeting hab ich wohl überlesen. Noch einmal zum Update-Modus:

In der von @konstin beschriebenen Version und Ihrem Vorschlag muss der Client im Update-Modus zunächst alle AgendItem-Objekte des Meetings entfernen und die neuen gemäß interner Liste oder der agendaItemOrder (deren Objekte dann nachgelesen werden müssen) neu hinzufügen. Das kann es nicht sein, zumal, wenn sich nur ein AgendaItem ändert, immer das dazugehörige Meeting-Objekt (obwohl sich dieses vielleicht gar nicht geändert hat) mit allen AgendaItems erneut ausgegeben werden muss.

Von der Laufzeit dürfte das keine große Rolle spielen, aber aus Entwicklersicht, sowohl server- als auch clientseitig, ist diese Lösung nicht zu empfehlen. Ich plädiere für die bereits weiter oben von mir beschriebene Lösung.

@Medo42, es wäre schön, wenn Sie sich in diesem Forum bekannt machen würden.

konstin commented 6 years ago

agendaItemOrder sollte der Einfachheit halber immer mit Meeting ausgegeben werden sollte, auch wenn dadurch etwas Redundanz entsteht.

Wenn sich ein Tagesordnungspunkt ändert, z.B. weil sich sein Titel geändert hat, müsste bei beiden Vorschlägen nur der Tagesordnungspunkt vom Client neu heruntergeladen werden.

Wenn ein Tagesordnungspunkt in hinzukommt oder gelöscht wird, müsste mit agendaItemOrder nur das Meeting und das betroffene AgendaItem aktualisiert werden. Mit order in Meeting hingegen würden sich alle Tagesordnungspunkte nach dem neuen bzw. gelöschten ändern, das sich order ändert. Bei den mir bekannten langen Tagesordnungen würde mit order in Meeting die Menge der für eine Aktualisierung übertragen Daten und Objekten deutlich größer sein als mit agendaItemOrder.

Nach meiner Erfahrung wären beide Vorschläge etwa dem gleichen recht geringen Aufwand implementierbar (sowohl mit Yii in PHP als auch mit django in Python wären es < 10 Zeilen Code). Auf Grund meiner Erwartungen zur Laufzeit favorisiere ich agendaItemOrder.

Medo42 commented 6 years ago

Im Interesse der Transparenz: Mein Name ist Simeon Maxein, und ich entwickle als Angestellter der Chamaeleon AG einen OParl-Client. Ich diskutiere hier allerdings im Moment nicht "im Auftrag der Firma" sondern habe mich eher dazu verleiten lassen Vorschläge zu schreiben, wenn ich beim Lesen eine Idee hatte von der die Spezifikation mMn profitieren würde. Eigentlich wollte ich mich gar nicht so weit "einklinken", aber so kann es kommen ;)

Ich sehe nicht, dass man bei einer Änderung der Reihenfolge in agendaItemOrder alle AgendaItems des Meetings neu abfragen müsste. Der Client hat diese AgendaItems doch bereits in seinem lokalen Datenbestand vorliegen und muss lediglich deren Reihenfolge aktualisieren. Egal ob der Client diese Reihenfolge nun intern als laufende Nummer ausdrückt oder ob er seinerseits eine sortierte Liste o.ä. verwendet - diese Aktualisierung dürfte trivial sein.

Für den Server kann es eigentlich auch nicht schwierig sein agendaItemOrder auszugeben, da er ja bereits für die Eigenschaft agendaItems eine sortierte Liste der AgendaItems ausgeben kann. Für agendaItemOrder muss er diese Ausgabe lediglich auf die IDs beschränken.

sterni24 commented 6 years ago

@Medo42 Danke für Ihre Nachricht.

Ich sehe nicht, dass man bei einer Änderung der Reihenfolge in agendaItemOrder alle AgendaItems des Meetings neu abfragen müsste.

Mit der Ausgabe der agendaItemOrder im Update-Modus haben Sie nur die Möglichkeit, die Reihenfolge der Objekte mit dem lokalen System abzustimmen. Allerdings ändert sich in aller Regel mit der Reihenfolge auch die Eigenschaft number. Darüber hinaus haben Sie keinen Anhaltspunkt, ob sich sonst irgendetwas geändert hat.

zu den Punkten von @konstin:

Wenn sich ein Tagesordnungspunkt ändert, z.B. weil sich sein Titel geändert hat, müsste bei beiden Vorschlägen nur der Tagesordnungspunkt vom Client neu heruntergeladen werden.

Woher weiß der Client, welcher der Tagesordnungspunkte sich geändert hat? Oder wollen Sie im Update-Modus nur die hinzugefügten, geänderten und gelöschten IDs in agendaItemOrder bereitstellen?

Wenn ein Tagesordnungspunkt hinzukommt oder gelöscht wird, müsste mit agendaItemOrder nur das Meeting und das betroffene AgendaItem aktualisiert werden.

das kann so gar nicht sein, siehe Ausführung zur Eigenschaft number weiter oben.

Für den Server kann es eigentlich auch nicht schwierig sein agendaItemOrder auszugeben, da er ja bereits für die Eigenschaft agendaItems eine sortierte Liste der AgendaItems ausgeben kann. Für agendaItemOrder muss er diese Ausgabe lediglich auf die IDs beschränken.

Von der Laufzeit dürfte das keine große Rolle spielen, aber aus Entwicklersicht, sowohl server- als auch clientseitig, ist diese Lösung nicht zu empfehlen.

Bei der unmittelbaren Abfrage der AgendaItems im Update-Modus braucht es überhaupt keine Sonderbehandlung, außer der Aufnahme der neuen Eigenschaft order.

Medo42 commented 6 years ago

Allerdings ändert sich in aller Regel mit der Reihenfolge auch die Eigenschaft number.

Das verringert in der Tat den Vorteil der agendaItemOrder-Lösung. Die Nummerierung von AgendaItems ist allerdings oft strukturiert, so dass beim Einfügen eines Unterpunkts eventuell nur bei wenigen folgenden AgendaItems die number-Eigenschaft geändert werden muss. Wie groß der Unterschied zwischen den beiden Mechanismen in der Realität wäre kann man vermutlich nur durch eine Analyse echter Änderungen in einem bestehenden System herausfinden, und ich glaube diesen Aufwand will hier niemand betreiben.

Woher weiß der Client, welcher der Tagesordnungspunkte sich geändert hat?

Genau wie bei allen anderen Objekttypen - daher, dass geänderte AgendaItems in der entsprechenden Objektliste am Body-Objekt bereitgestellt werden.

Ich denke, wir haben die wichtigsten Punkte zu beiden Ansätzen besprochen. Wie oben schon erwähnt finde ich beide Lösungen akzeptabel und verzichte daher auf weitere Argumente zu meiner Präferenz.

konstin commented 6 years ago

Wahrscheinlich wird der Unterschied mit einem Beispiel klarer.

Es gebe Listen für AgendaItem und Meeting:

https://oparl.example.org/body/0/list/agendaitem

https://oparl.example.org/body/0/list/meeting

Weiterhin gebe es einen Termin mit 50 Tagesordnungspunkten, den wir im Folgenden betrachten.

Beim ersten Abruf am 1.1.2000 lädt der Client entweder die Seiten Terminliste herunter oder die Terminliste mit omit_internal und dazu die Liste der Tagesordnungspunkte. Er speichert alle Objekte in einer lokalen Datenbank.

Nach den ersten Abruf des Client wird ein einzelner TOP in die Mitte der Tagesordnung des Termins hinzugefügt. (Der Fall, bei dem ein TOP gelöscht wird, verläuft analog.)

Der Client will nun am 2.1.2000 seinen Datenbestand mit omit_internal aktualisieren. In beiden Fällen lädt er dabei die Terminliste und die Liste der TOP mit omit_internal und dem passenden Wert für modified_since herunter.

https://oparl.example.org/body/0/list/agendaitem?omit_internal=True?modified_since=2000-01-02T00%3A12%3A00%2B01%3A00

https://oparl.example.org/body/0/list/meeting?omit_internal=True?modified_since=2000-01-02T00%3A12%3A00%2B01%3A00

Fall 1: order

Der Termin ist unverändert, d.h. die zurückgegebene Terminliste ist leer.

Bei der Liste der TOP ist der eingefügte TOP geändert, da er neu erstellt wurde. Außerdem hat sich bei den 25 TOP dahinter order um 1 erhöht, diese sind also auch geändert.

Es werden also insgesamt 26 Objekte übertragen.

Fall 2: agendaItemOrder

In dem Termin hat sich das Feld agendaItemOrder geändert, es ist also ein Eintrag in der Terminliste.

Bei der List der TOP ist wieder der eingefügte TOP neu. Alle anderen TOP haben sich nicht geändert.

Es werden also insgesamt 2 Objekte übertragen. Sollte sich durch den eingefügten TOP number von dahinterliegenden TOP verändern, kann die Zahl auch höher sein, jedoch nie höher als die 27, d.h. die Zahl aus Fall 1 plus den Termin.

Ich favorisiere Fall 2, da gemittelt deutlich weniger Objekte übertragen werden.

sterni24 commented 6 years ago

@konstin Wie sieht der Inhalt Ihrer Eigenschaft agendaItemOrder aus? Woher weiß der abrufende Client, an welcher Position sich dieser eine (neue) Top befindet?

akuckartz commented 6 years ago

@konstin schrieb:

Außerdem hat sich bei den 25 TOP dahinter order um 1 erhöht, diese sind also auch geändert.

In Programmiersprachen wie Basic war es früher üblich, dass am Anfang jeder Zeile eine Zeilennummer angegeben werden musste. Damit nicht beim Einfügen einer Zeile immer in allen Folgezeilen die Zeilennummern geändert werden mussten gab es eine simple Konvention: Es wurde generell in Zehnerschritten nummeriert (https://de.wikipedia.org/wiki/BASIC#Programmierbeispiel). Dann konnte z.B. zwischen den unmittelbar aufeinander folgenden Zeilen 50 und 60 eine Zeile 55 eingefügt werden.

konstin commented 6 years ago

agendaItemOrder könnte z.B. wie folgt aussehen:

Beim ersten Abruf:

{
  "id": "https://oparl.example.org/body/0/meeting/0",
  "type": "https://spec.oparl.org/1.1/Meeting",
  "agendaItemOrder": [
    "https://oparl.example.org/body/0/agendaitem/0",
    "https://oparl.example.org/body/0/agendaitem/1",
    ...    
    "https://oparl.example.org/body/0/agendaitem/23",
    "https://oparl.example.org/body/0/agendaitem/24",
    "https://oparl.example.org/body/0/agendaitem/25",
    ...
    "https://oparl.example.org/body/0/agendaitem/48",
    "https://oparl.example.org/body/0/agendaitem/49"
  ],
  ...
}

Beim zweiten Abruf:

{
  "id": "https://oparl.example.org/body/0/meeting/0",
  "type": "https://spec.oparl.org/1.1/Meeting",
  "agendaItemOrder": [
    "https://oparl.example.org/body/0/agendaitem/0",
    "https://oparl.example.org/body/0/agendaitem/1",
    ...
    "https://oparl.example.org/body/0/agendaitem/23",
    "https://oparl.example.org/body/0/agendaitem/24",
    // Der neue TOP
    "https://oparl.example.org/body/0/agendaitem/50", 
    "https://oparl.example.org/body/0/agendaitem/25",
    ...
    "https://oparl.example.org/body/0/agendaitem/48",
    "https://oparl.example.org/body/0/agendaitem/49"
  ],
  ...
}

@akuckartz Das wäre tatsächlich eine Möglichkeit, ist aber schwierig zu Debuggen und setzt voraus, dass das RIS die Position zusätzlich mit Intervall speichert.

sterni24 commented 6 years ago

@akuckartz Netter Versuch, dann liefern Sie mal gleich eine Routine zum neu durchnummerieren mit! :sunglasses:

Auch wenn wir hier mit 1000er oder besser 1024er Schritten arbeiten, lässt sich das Problem nicht zu 100% lösen. Da der Server in @konstin's Beispiel im agentaItem keine order liefert, kann der Client es nicht einsortieren.

Nun hat @konstin in seinem Beispiel doch den vollen Satz an Tagesordnungspunkten geliefert. Was soll der Client nun damit machen?

akuckartz commented 6 years ago

Irgendwie hatte ich schon befürchtet, dass mein Kommentar als Unterstützung für Alternative 1 verstanden werden könnte :smiley: Das ist aber nicht der Fall. Es gibt ja auch gute Gründe, warum man in Programmen heutzutage keine Zeilennummern mehr angeben muss. Aber auch Alternative 2 gefällt mir aufgrund der Redundanzen nicht.

Leider kann ich aktuell keinen konkreten Alternativ-Vorschlag liefern, der auch mir gefallen würde (Material als Grundlage für eine allgemeine Lösung sammele ich hier: https://github.com/OpenGovLD/specs/wiki/Replication)

konstin commented 6 years ago

Nun hat @konstin in seinem Beispiel doch den vollen Satz an Tagesordnungspunkten geliefert. Was soll der Client nun damit machen?

Der Client hat über die Liste der TOP die aktuelle Menge an TOP.

Nun kann er für alle geänderten Termine zum einen agendaItemOrder direkt mit dem Termin speichern, um beim Anzeigen des Termins die zugehörigen TOP aus seiner Datenbank abzurufen und dann in der Reihenfolge von agendaItemOrder anzuzeigen.

Er kann aber auch selbst einen Wert mit der gleichen Bedeutung wie order zu jedem TOP speichern. Der Vorteil gegenüber dem Vorschlag mit order liegt hier darin, dass agendaItemOrder als Liste von urls deutlich kompakter ist als die TOP in einer externen Objektliste, die ggf. durch die Paginierung auch noch mehrere http-Abfragen braucht.

In Python könnte man das ganze z.B. wie folgt aussehen:

for modified_agenda_item in get_agenda_items(omit_internal=True, modified_since="2000-01-02T00:12:00+01:00"):
    agenda_item = get_or_create_agenda_item_from_db(modified_agenda_item["id"])
    agenda_item.update(modified_agenda_item)
    agenda_item.save()
for modified_meeting in get_meetings(omit_internal=True, modified_since="2000-01-02T00:12:00+01:00"):
    meeting = get_or_create_meeting_from_db(modified_meeting ["id"])
    meeting.update(oparl_meeting)
    meeting.save()
    for order, id in enumerate(oparl_meeting["agendaItemOrder"]):
        agenda_item = get_agenda_item_by_oparl_id(id)
        agenda_item.order = order
        agenda_item.save()
sterni24 commented 6 years ago

Wenn ich den Code von @konstin richtig interpretiere, werden in der ersten for-Schleife genau die agentaItems aktualisiert, die sich verändert haben. Hierbei rufen sie dieselbe externe Objektliste ab, die ggf. durch die Paginierung noch mehrere http-Abfragen braucht.

In meinem Ansatz unterstelle ich, dass jeder RIS-Hersteller für die Tagesordnung eine Sortierung (1-n oder 10, 20, 30 ...) vorhält. Unter der Voraussetzung, dass die Eigenschaft order im AgendaItem-Objekt mit zwingend beschrieben ist und vor dem ersten Update-Lauf eine Vollaktualisierung stattgefunden hat, wäre mein Vorschlag für den Update-Mechanismus damit voll umgesetzt.

Gestatten Sie mir zu der zweiten for-Schleife ein paar Anmerkungen:

  1. Der Server muss für alle AgendaItems, deren Termine sich nicht geändert haben, die Meeting-Objekte bereitstellen, obwohl dieses nicht in der modified-since-Liste enthalten ist.
  2. Der Server muss in agendaItemOrder eine zusätzliche Liste füllen, auch wenn gar keine AgendaItems geändert wurden. Ggf. kann diese Liste dann entfallen.
  3. Um die Punkte 1. und 2. korrekt umzusetzen, bedarf es einiger serverseitiger DB-Zugriffe mehr.
  4. Der Vorteil, mal schnell eine aktuelle Terminliste mit omit_internal zu ziehen, wäre dahin, weil sich der Server damit beschäftigt seine agendaItemOrder zu füllen.
  5. Wer soll die Umsetzung aller möglichen Szenarien testen?

Da ich davon ausgehe, dass nicht nur wir die OParl-Version 1.1. unterstützen werden, wäre es schön, wenn sich in dieser Sache der eine oder andere RIS-Hersteller zu Wort meldet.

bschalitz commented 6 years ago

wäre es schön, wenn sich in dieser Sache der eine oder andere RIS-Hersteller zu Wort meldet.

Ich bestätige die von @sterni24 genannten Punkte . Mit dem Verändern der Tagesordnung ändern sich die Nummer der nachfolgenden Punkte. Klar gibt es auch hierarchische Tagesordnungen, die meisten Kunden arbeiten jedoch ohne Unternummerierung.

Ebenso die Punkte 1.-3. des letzten Beitrags.

konstin commented 6 years ago

Ohne Unternummerierung fällt der Performace-Vorteil von agendaItemOder weg. Ich habe daher die Variante mit order in 788156ef22ffe148c74ba3e25467d44d0d25e465 implementiert und dazu in 98851fb92005689c920744992db903536a74cff3 den Sonderfall mit legislativeTerm in Body besseitigt. Damit sollte #397 vollständig sein.