fix(core): preserve data integrity and bound shared UI and response work
Module Package Release / publish-packages (push) Successful in 13s
Module Package Release / publish-packages (push) Successful in 13s
Release v0.1.46. Coordinated integrity review: GovOPlaN/govoplan-core#298.
This commit is contained in:
Executable
+101
@@ -0,0 +1,101 @@
|
||||
# Integrity-preserving performance contracts
|
||||
|
||||
These are implementation guarantees and regression-test boundaries, not a
|
||||
security certification or production load-test result. Feature-specific policies
|
||||
and help remain in the owning modules' English and German documentation topics.
|
||||
|
||||
## Refreshes, edits and table rendering
|
||||
|
||||
The shell runs at most one module-load refresh per authority generation. Multiple
|
||||
invalidations coalesce into one trailing refresh; stale results and errors cannot
|
||||
replace a newer generation. Focus refreshes are throttled to five seconds and
|
||||
focus/visibility refreshes on hidden pages are suppressed; explicit module
|
||||
invalidations still trigger a read. Authentication/tenant reset disposes the
|
||||
previous controller. Authentication and authorization checks are not cached away.
|
||||
|
||||
Editable modules must reconcile a save against the submitted draft and accepted
|
||||
server revision: edits made while a request is pending remain dirty. Completion
|
||||
must be fenced by security-relevant authority and selection, not merely an auth
|
||||
object's reference identity. A harmless profile refresh must not discard an
|
||||
accepted newly created ID and invite a duplicate create. An old account's mutation
|
||||
continuation must not reload its catalogue into the current account's page.
|
||||
|
||||
DataGrid precomputes first-occurrence row indices once for client sorting and
|
||||
filtering. Duplicate object references, primitive values, `NaN` and sparse arrays
|
||||
retain `Array.indexOf` behavior. Comparator order, visible pagination, server-side
|
||||
pagination, sizing and resize rules are unchanged. Do not replace this with a
|
||||
last-occurrence map or change ordering as a side effect of an optimization.
|
||||
|
||||
## Conditional responses
|
||||
|
||||
The shared JSON GET middleware performs route handling, including authorization,
|
||||
before considering `If-None-Match`. It buffers only responses up to 1 MiB for a
|
||||
body-derived ETag. Known larger responses bypass buffering; an unknown-length
|
||||
stream crossing that limit replays its exact prefix and streams the remainder.
|
||||
No data is truncated and no large joined copy is created. The crossing chunk is
|
||||
already producer-owned: this is not a process-wide or route-output memory limit.
|
||||
Empty chunks do not accumulate. Large responses may no longer receive a
|
||||
middleware-generated ETag/304; explicit route ETags remain intact. Small-response
|
||||
cache semantics and credential/language/context `Vary` fields are retained.
|
||||
|
||||
## Shared helpers and concurrency
|
||||
|
||||
Central helpers replace exact live-code duplicates only. Actor precedence,
|
||||
whitespace handling and service-account differences remain explicit owner choices;
|
||||
historical migration code is not redirected to mutable runtime helpers. Connector
|
||||
search ACL token projection keeps its first-seen ordering and existing 500-token
|
||||
cap, stopping work once that cap is reached. Provider schemas are inferred in one
|
||||
pass without storing a second list of every column value.
|
||||
|
||||
The keyed-list three-way merge retains insertion anchors when unrelated fields
|
||||
change. Concurrent additions use deterministic ordering; contradictory anchors
|
||||
produce a collection-order conflict instead of silently relocating an item.
|
||||
No existing endpoint is newly opted into merge behavior by this change.
|
||||
|
||||
SQL JSON authorization predicates support the explicitly tested SQLite and
|
||||
PostgreSQL dialects, retain exact string membership and reject unsupported
|
||||
dialects. Apply tenant and authorization predicates before counting/pagination;
|
||||
never page a broader result first and filter away unauthorized records afterward.
|
||||
SQLite execution and PostgreSQL SQL compilation are not substitutes for a
|
||||
deployment's PostgreSQL concurrency and representative-data load tests.
|
||||
|
||||
## Migration connection URLs
|
||||
|
||||
Alembic preserves the configured database URL exactly in online and offline
|
||||
migration modes, including percent-encoded credentials and PostgreSQL Unix-socket
|
||||
paths. Escaping applies only at its ConfigParser boundary; operators must not
|
||||
double-escape `%` in `DATABASE_URL` or alter working connection credentials to
|
||||
work around interpolation errors. This does not change the target database,
|
||||
authentication, TLS policy, or migration contents.
|
||||
|
||||
## Deutsch: Integrität vor Geschwindigkeit
|
||||
|
||||
Der zentrale Modul-Refresh bündelt gleichzeitige Auslöser und verwirft veraltete
|
||||
Ergebnisse einschließlich Fehlermeldungen. Ein Wechsel von Anmeldung oder Mandant
|
||||
beendet die bisherige Generation. Fokusaktualisierungen sind auf einen Auslöser
|
||||
je fünf Sekunden begrenzt. Berechtigungsprüfungen bleiben erhalten.
|
||||
|
||||
Speicherantworten dürfen zwischenzeitliche Bearbeitungen nicht überschreiben.
|
||||
Ein unveränderter Berechtigungskontext mit einem neuen Profilobjekt darf eine
|
||||
bereits bestätigte neue ID oder Revision nicht verwerfen. Umgekehrt dürfen alte
|
||||
Anfragen nach einem Kontowechsel keine Daten in den neuen Kontext übernehmen.
|
||||
Die DataGrid-Optimierung erhält Reihenfolge, Filter-, Seiten- und Größenverhalten.
|
||||
|
||||
Die ETag-Middleware puffert höchstens 1 MiB Nutzdaten zuzüglich eines bereits vom
|
||||
Erzeuger gelieferten Grenz-Chunks. Größere Antworten werden vollständig weitergereicht,
|
||||
nicht abgeschnitten; automatisch erzeugte ETags können dabei entfallen.
|
||||
Autorisierung läuft auch bei bedingten Anfragen. Das ist keine allgemeine
|
||||
Speicherbegrenzung für Routen oder Prozesse.
|
||||
|
||||
Gemeinsame Helfer erhalten die bisherigen fachlichen Unterschiede. Listen-Merges
|
||||
bewahren Einfügepositionen oder melden widersprüchliche Reihenfolgen explizit als
|
||||
Konflikt. Datenbankseitige Autorisierung erfolgt vor Zählung und Seitenauswahl.
|
||||
Regressionstests belegen diese Verträge; reale Provider-, PostgreSQL- und Lasttests
|
||||
in einer repräsentativen Umgebung bleiben Teil der Betriebsfreigabe.
|
||||
|
||||
Alembic übernimmt die konfigurierte Datenbank-URL in Online- und Offline-Läufen
|
||||
unverändert, einschließlich prozentkodierter Zugangsdaten und PostgreSQL-
|
||||
Unix-Socket-Pfade. Die Maskierung erfolgt ausschließlich an der ConfigParser-
|
||||
Grenze; `%` in `DATABASE_URL` nicht doppelt maskieren und funktionierende
|
||||
Zugangsdaten nicht als Umgehung ändern. Zieldatenbank, Anmeldung, TLS-Vorgaben und
|
||||
Migrationsinhalte bleiben unverändert.
|
||||
@@ -19,3 +19,72 @@ Connector health and preview diagnostics must contain no credentials, endpoint
|
||||
userinfo, row values, or unbounded remote error bodies. A Datasource origin
|
||||
preserves this contract so registration and staging do not erase source mode,
|
||||
health, pushdown, or preview-limit evidence.
|
||||
|
||||
## Durable CSV imports and original evidence
|
||||
|
||||
`TabularCsvSource` optionally accompanies a durable `TabularSnapshotInput` or
|
||||
`DatasourceStageInput`. It carries the exact submitted Unicode text, delimiter,
|
||||
explicit value mode and parser profile. It is not part of ordinary catalogue,
|
||||
preview or stage DTOs. Transient inspection does not retain original content.
|
||||
|
||||
The `text` mode preserves cell strings, including whitespace, leading zeroes,
|
||||
decimal spelling, boolean-looking text and explicit empty cells. It rejects
|
||||
malformed quoting and rows with missing or extra cells. Header normalization is
|
||||
unchanged. The API default remains `legacy_typed` for existing integrations;
|
||||
interactive CSV imports offer text mode by default and an explicit legacy choice.
|
||||
JSON and existing stored snapshots are not reinterpreted. Core and Datasources
|
||||
retain distinct versioned legacy parser profiles where their historical coercion
|
||||
rules differ. Shared schema inference preserves first-seen column order, missing
|
||||
value nullability and the owning provider's type naming.
|
||||
|
||||
Owners verify that the source reparses to exactly the stored projection, including
|
||||
scalar types: `true`, `1` and `1.0` are not equivalent evidence. Raw input and row
|
||||
projections each have a 5,000,000-byte limit; row parsing is capped at 10,000 rows.
|
||||
The original text has its own UTF-8 SHA-256 and byte count, separate from the
|
||||
existing row fingerprint. Only a small allowlisted source summary enters metadata.
|
||||
Checksums detect drift; they are not digital signatures or protection against an
|
||||
attacker who can rewrite the database and all its evidence.
|
||||
|
||||
Original exports are explicit owner APIs, tenant scoped, integrity checked and
|
||||
`no-store`. Datasources additionally requires administrator scope, audits the
|
||||
export, and denies the whole original when current or historical governance
|
||||
restricts any row or field. Freezing verifies the prior summary before copying
|
||||
source evidence and retains prior policy restrictions, including referenced
|
||||
policy evaluations. At most 32 distinct governance snapshots may accompany one
|
||||
original; further incompatible history fails explicitly. Payload disposal also
|
||||
disposes retained original content. Connectors applies its own current read,
|
||||
tenant and lifecycle checks. See the owning module's documentation for endpoints.
|
||||
|
||||
Original UTF-8 text is not proof of pre-decoding file bytes, and does not undo
|
||||
CSV spreadsheet formula semantics. Exported content is deliberately unmodified;
|
||||
operators must treat it as untrusted input when opening it in a spreadsheet.
|
||||
New nullable columns require the owning modules' additive migrations. Historical
|
||||
rows remain unchanged and report original content unavailable, not reconstructed.
|
||||
Back up retained originals before any schema downgrade that removes those columns.
|
||||
|
||||
## Deutsch: CSV-Datentreue
|
||||
|
||||
Dauerhafte CSV-Importe können den unveränderten übermittelten Unicode-Text mit
|
||||
Trennzeichen, Parserprofil und explizitem Wertemodus aufbewahren. Der Textmodus
|
||||
erhält Zellwerte einschließlich Leerzeichen, führender Nullen und Dezimalschreibweise.
|
||||
Fehlerhafte Zeilen werden abgewiesen. Die API bleibt aus Kompatibilitätsgründen bei
|
||||
der bisherigen Typumwandlung als Standard; im Importdialog ist Text voreingestellt.
|
||||
Bestehende Daten und JSON-Importe werden nicht neu interpretiert.
|
||||
|
||||
Original und Zeilenprojektion werden getrennt begrenzt und geprüft; boolesche
|
||||
Werte, Ganzzahlen und Gleitkommazahlen sind keine austauschbaren Belege. Der
|
||||
Originaltext erscheint weder im Katalog noch in Vorschauantworten. Die expliziten
|
||||
Export-APIs prüfen Mandant, Berechtigungen, Lebenszyklus und gespeicherten Hash.
|
||||
Datasources verlangt zusätzlich Administrationsrechte, protokolliert Exporte und
|
||||
berücksichtigt aktuelle sowie historische Zeilen-, Feld- und Zugriffsrichtlinien.
|
||||
Eingeschränkte Originale werden vollständig gesperrt, nicht teilweise freigegeben.
|
||||
Eingefrorene Kopien übernehmen diese Einschränkungen; nach 32 unterschiedlichen
|
||||
Richtlinienständen wird eine weitere Kopie mit neuer Richtlinie explizit abgewiesen.
|
||||
Die Aufbewahrungsbereinigung entfernt auch das gespeicherte Original.
|
||||
|
||||
Die Grenzen betragen jeweils 5.000.000 UTF-8-Bytes für Original und Projektion
|
||||
sowie 10.000 Zeilen. Prüfsummen sind keine Signaturen. Ein CSV-Original bleibt beim
|
||||
Export unverändert und kann Tabellenkalkulationsformeln enthalten. Frühere
|
||||
Dateikodierungen lassen sich daraus nicht rekonstruieren. Additive Migrationen
|
||||
ändern keine historischen Zeilen; fehlende Originale werden nicht erfunden.
|
||||
Vor einem Schema-Downgrade sind aufbewahrte Originale zu sichern.
|
||||
|
||||
@@ -2768,6 +2768,498 @@
|
||||
"release": "0.1.45",
|
||||
"squash_policy": "reviewed-manual",
|
||||
"track": "release"
|
||||
},
|
||||
{
|
||||
"heads": [
|
||||
{
|
||||
"owner": "govoplan-notifications",
|
||||
"revision": "6e2f91ab4c70"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-poll",
|
||||
"revision": "6e7f8a9b0c1d"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dashboard",
|
||||
"revision": "7b9d2f4a6c8e"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tasks",
|
||||
"revision": "7c4d9a2e1f30"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-records",
|
||||
"revision": "8a6c4e2f1b3d"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-voting",
|
||||
"revision": "8b9c0d1e2f3a"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tickets",
|
||||
"revision": "8d1f4b7a2c5e"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-quick-access",
|
||||
"revision": "9a4e6c2d8f10"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-helpdesk",
|
||||
"revision": "9e2a5c8f1b4d"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-workflow-engine",
|
||||
"revision": "9e6b3f8a2c7d"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-files",
|
||||
"revision": "a2b3c4d5e701"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dataflow",
|
||||
"revision": "a3d7f1c5e9b2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-templates",
|
||||
"revision": "a3f7c9d2e1b4"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-organizations",
|
||||
"revision": "a61e4d9c72b8"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-wiki",
|
||||
"revision": "a7c2e9f4b1d6"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-cases",
|
||||
"revision": "a7c4e2f9b1d6"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-mandates",
|
||||
"revision": "a8b1c2d3e4f5"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-approvals",
|
||||
"revision": "a91c4e72b5d8"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-policy",
|
||||
"revision": "a9c4e7b2d5f8"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-search",
|
||||
"revision": "b2c3d4e5f607"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tenancy",
|
||||
"revision": "b3d8e1f4a6c2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-mail",
|
||||
"revision": "b5d6e7f8091a"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-risk-compliance",
|
||||
"revision": "b9c0d1e2f3a4"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-services",
|
||||
"revision": "b9c2d3e4f5a6"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-audit",
|
||||
"revision": "b9e2f5a8c3d6"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-parties",
|
||||
"revision": "c0d3e4f5a6b7"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-idm",
|
||||
"revision": "c2d3e4f5a6b7"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-identity-trust",
|
||||
"revision": "c3f5a7b9d1e2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-projects",
|
||||
"revision": "c4a1e8f2d6b9"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-core",
|
||||
"revision": "c58a2d7e9f10"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-views",
|
||||
"revision": "c6f2a9d4e7b1"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-reporting",
|
||||
"revision": "c8d5e2f6a9b3"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-decisions",
|
||||
"revision": "d1e4f5a6b7c8"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-calendar",
|
||||
"revision": "d24e5f607182"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-connectors",
|
||||
"revision": "d2a4c6e8f0b1"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-docs",
|
||||
"revision": "d3e7a1c5f9b2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-forms-runtime",
|
||||
"revision": "d6a8b0c2e4f6"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-addresses",
|
||||
"revision": "d6e8f9a0b1c2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-scheduling",
|
||||
"revision": "d7a4c1e8f205"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-postbox",
|
||||
"revision": "d8b4f1a6c9e2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-committee",
|
||||
"revision": "d8b9f0a1c2e3"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-datasources",
|
||||
"revision": "e2b8d4a0f6c3"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-encryption",
|
||||
"revision": "e5b7c9d1f3a4"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-payments",
|
||||
"revision": "e7b9c1d3f5a7"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dist-lists",
|
||||
"revision": "e7c3a9d1b5f2"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-access",
|
||||
"revision": "e9a2c5f8b1d4"
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-campaign",
|
||||
"revision": "f3c7a9d2e6b1"
|
||||
}
|
||||
],
|
||||
"owner_heads": [
|
||||
{
|
||||
"owner": "govoplan-access",
|
||||
"revisions": [
|
||||
"e9a2c5f8b1d4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-addresses",
|
||||
"revisions": [
|
||||
"d6e8f9a0b1c2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-approvals",
|
||||
"revisions": [
|
||||
"a91c4e72b5d8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-audit",
|
||||
"revisions": [
|
||||
"b9e2f5a8c3d6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-calendar",
|
||||
"revisions": [
|
||||
"d24e5f607182"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-campaign",
|
||||
"revisions": [
|
||||
"f3c7a9d2e6b1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-cases",
|
||||
"revisions": [
|
||||
"a7c4e2f9b1d6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-committee",
|
||||
"revisions": [
|
||||
"d8b9f0a1c2e3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-connectors",
|
||||
"revisions": [
|
||||
"d2a4c6e8f0b1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-core",
|
||||
"revisions": [
|
||||
"c58a2d7e9f10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dashboard",
|
||||
"revisions": [
|
||||
"7b9d2f4a6c8e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dataflow",
|
||||
"revisions": [
|
||||
"a3d7f1c5e9b2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-datasources",
|
||||
"revisions": [
|
||||
"e2b8d4a0f6c3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-decisions",
|
||||
"revisions": [
|
||||
"d1e4f5a6b7c8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-dist-lists",
|
||||
"revisions": [
|
||||
"e7c3a9d1b5f2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-docs",
|
||||
"revisions": [
|
||||
"d3e7a1c5f9b2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-encryption",
|
||||
"revisions": [
|
||||
"e5b7c9d1f3a4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-files",
|
||||
"revisions": [
|
||||
"a2b3c4d5e701"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-forms",
|
||||
"revisions": [
|
||||
"e1f2a3b4c5d6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-forms-runtime",
|
||||
"revisions": [
|
||||
"d6a8b0c2e4f6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-helpdesk",
|
||||
"revisions": [
|
||||
"9e2a5c8f1b4d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-identity",
|
||||
"revisions": [
|
||||
"5c6d7e8f9a10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-identity-trust",
|
||||
"revisions": [
|
||||
"c3f5a7b9d1e2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-idm",
|
||||
"revisions": [
|
||||
"c2d3e4f5a6b7"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-mail",
|
||||
"revisions": [
|
||||
"b5d6e7f8091a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-mandates",
|
||||
"revisions": [
|
||||
"a8b1c2d3e4f5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-notifications",
|
||||
"revisions": [
|
||||
"6e2f91ab4c70"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-organizations",
|
||||
"revisions": [
|
||||
"a61e4d9c72b8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-parties",
|
||||
"revisions": [
|
||||
"c0d3e4f5a6b7"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-payments",
|
||||
"revisions": [
|
||||
"e7b9c1d3f5a7"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-policy",
|
||||
"revisions": [
|
||||
"a9c4e7b2d5f8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-poll",
|
||||
"revisions": [
|
||||
"6e7f8a9b0c1d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-postbox",
|
||||
"revisions": [
|
||||
"d8b4f1a6c9e2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-projects",
|
||||
"revisions": [
|
||||
"c4a1e8f2d6b9"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-quick-access",
|
||||
"revisions": [
|
||||
"9a4e6c2d8f10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-records",
|
||||
"revisions": [
|
||||
"8a6c4e2f1b3d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-reporting",
|
||||
"revisions": [
|
||||
"c8d5e2f6a9b3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-risk-compliance",
|
||||
"revisions": [
|
||||
"b9c0d1e2f3a4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-scheduling",
|
||||
"revisions": [
|
||||
"d7a4c1e8f205"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-search",
|
||||
"revisions": [
|
||||
"b2c3d4e5f607"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-services",
|
||||
"revisions": [
|
||||
"b9c2d3e4f5a6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tasks",
|
||||
"revisions": [
|
||||
"7c4d9a2e1f30"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-templates",
|
||||
"revisions": [
|
||||
"a3f7c9d2e1b4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tenancy",
|
||||
"revisions": [
|
||||
"b3d8e1f4a6c2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-tickets",
|
||||
"revisions": [
|
||||
"8d1f4b7a2c5e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-views",
|
||||
"revisions": [
|
||||
"c6f2a9d4e7b1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-voting",
|
||||
"revisions": [
|
||||
"8b9c0d1e2f3a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-wiki",
|
||||
"revisions": [
|
||||
"a7c2e9f4b1d6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "govoplan-workflow-engine",
|
||||
"revisions": [
|
||||
"9e6b3f8a2c7d"
|
||||
]
|
||||
}
|
||||
],
|
||||
"recorded_at": "2026-09-08T10:17:38Z",
|
||||
"release": "0.1.46",
|
||||
"squash_policy": "reviewed-manual",
|
||||
"track": "release"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
|
||||
Reference in New Issue
Block a user