Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,32 @@ for historical context.

## Unreleased

Companion runtime/macros version: **0.64.0**.

- Revalidate the complete current release contract after successful selected
snapshot serialization; source, target, key or field revocation suppresses
the prepared event without a frame or private diagnostics.

- Prepare selected Changed snapshots before stream release. Discard late scalar
refusals and private policy diagnostics without emitting even an error frame,
and preserve clean delivery of subsequent authorized events.

- Seed cycle detection with the same complete typed target identity and origin
encoding used by propagated events, including composite and append-only sources.

- Generate real composite-key and read-only projection subscriptions with typed
complete-key filters and current row/field/provenance authorization.
- Emit complete typed composite direct witnesses only after committed generated
repository mutations; preserve trusted rollback and propagation fences.
- Expose generated subscriptions under read-only schema policy while retaining
empty mutation roots and rejecting arbitrary extra subscriptions.
- Read-only and composite `GraphQLOperations` entities require both serde derives
for generated Changed observer events, matching writable scalar-key entities.
- Keep private repository sources closed to GraphQL notification release pending
a separate explicit projection-authorization contract.

## 0.63.0 (unreleased)

Companion runtime/macros version: **0.63.0**.

- Seed propagated-event cycle detection with the complete typed target identity and origin so cycles cannot re-emit the direct source.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ cynic-parser = { version = "=0.11.2", features = ["pretty"] }
futures = "0.3"
getrandom = "0.3"
graphql-composition = "=0.12.2"
graphql-orm = { path = "crates/graphql-orm", version = "0.63.0", default-features = false }
graphql-orm = { path = "crates/graphql-orm", version = "0.64.0", default-features = false }
graphql-orm-ai-tool-profiles = { path = "crates/graphql-orm-ai-tool-profiles", version = "0.16.2" }
graphql-orm-backup = { path = "crates/graphql-orm-backup", version = "0.10.0", default-features = false }
graphql-orm-operation-catalog = { path = "crates/graphql-orm-operation-catalog", version = "0.4.2" }
Expand Down
55 changes: 48 additions & 7 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,46 @@ workspace release tag for every chosen workspace package and record its full
commit from the release manifest. Neither the runtime nor macros crate is
published to crates.io.

## 0.61.0 to 0.62.0: runtime keyset ordering

Upgrade runtime and macros together. A generated `…Keyset` query now accepts `orderBy: [EntityKeysetOrderByInput!]`. Each entry selects exactly one readable, persisted sortable scalar, for example `[{title: ASC}, {rank: DESC}]`. Primary-key fields are accepted. Computed, relation, spatial and decimal orders are absent from this input; ordinary list ordering retains its separate input type. A complete readable scalar primary key is required. Entities with private or unsupported primary keys retain their configured keyset surface without registering an unusable runtime order input.

Each dynamic order appends missing primary-key columns in ascending order. NULL values sort last in either direction; backward windows reverse comparison and null placement internally, then return canonical order. Duplicate fields, empty entries and empty lists fail before SELECT. Every order field, including an implicit key component, requires current field policy even when omitted from the payload.

Dynamic cursors bind the entity, exact ordered columns, directions and null placement. A cursor for a different order or the configured default is rejected. Omit `orderBy` to retain the configured order and existing cursor bytes. Repository callers may use `keyset_page_ordered` or `keyset_connection_page_ordered`; existing methods stay unchanged. Every composite primary-key component participates in configured and runtime validation. No schema or data migration is required.
## 0.63.0 to 0.64.0: composite and read-only Changed

A successful selected snapshot is released only after a second current source,
target, key and field authorization check. Hosts whose serialization hooks await
or revoke authority do not release the prepared value under stale permissions.

Changed snapshot and scalar nullability are preserved. Generated delivery
prepares the selected snapshot before yielding a stream item. A late scalar
refusal or policy error discards the whole event and its private diagnostics,
including nullable failures, without emitting an error frame. Subsequent allowed
events remain clean. Internal observer DTOs are unchanged.

Upgrade runtime and macros together. Composite-primary-key entities now expose
real generated `…Changed` subscriptions with an optional complete `EntityKeyInput`.
Their event includes a stable opaque `id` and typed `key`. All primary-key fields
must be authorized before either identity is released. Composite repository
mutations queue typed trusted witnesses and propagation only after commit;
rollback never delivers these notifications. Existing raw composite observers
receive added change-kind and provenance fields and must update exhaustive
struct patterns for this pre-1.0 capability change.

Read-only public entities accept the same generated trusted propagation channel.
Entities whose `GraphQLOperations` derive now generates Changed events need
`serde::Serialize` and `serde::Deserialize` for the observer payload. This includes
read-only projections and composite entities with repository mutations, matching
the existing writable scalar-key Changed contract. Add both derives to affected
fixtures and consumers when upgrading.
No insert/update/delete capability or schema management is added. Under a read-only
`schema_roots!` policy the mutation root stays empty while generated subscriptions
and their operation-catalogue entries remain present. Arbitrary extra subscriptions
retain their read-only-schema rejection. Raw or deserialized observer events do not
enter generated delivery.

The full target key, current source/target rows, selected scalar fields, key fields,
relation tuples and per-hop provenance are checked for each release. Omitted keys
retain entity-wide authorized delivery. This implements the public composite/read-only
slice of issue #191. Private repository source fields remain non-subscribable;
private-source projection authorization and the complete dependent AI notification
graph remain unfinished, so draft #189 and issue #184 are not completed by this change.
No data/schema migration is required.

## 0.62.0 to 0.63.0: propagation relation tuples

Expand All @@ -44,6 +77,14 @@ and read-only trusted projection subscriptions remain separate unfinished work;
this change does not complete #191, #184 or draft #189. No data/schema migration
or downstream pin change is included.

## 0.61.0 to 0.62.0: runtime keyset ordering

Upgrade runtime and macros together. A generated `…Keyset` query now accepts `orderBy: [EntityKeysetOrderByInput!]`. Each entry selects exactly one readable, persisted sortable scalar, for example `[{title: ASC}, {rank: DESC}]`. Primary-key fields are accepted. Computed, relation, spatial and decimal orders are absent from this input; ordinary list ordering retains its separate input type. A complete readable scalar primary key is required. Entities with private or unsupported primary keys retain their configured keyset surface without registering an unusable runtime order input.

Each dynamic order appends missing primary-key columns in ascending order. NULL values sort last in either direction; backward windows reverse comparison and null placement internally, then return canonical order. Duplicate fields, empty entries and empty lists fail before SELECT. Every order field, including an implicit key component, requires current field policy even when omitted from the payload.

Dynamic cursors bind the entity, exact ordered columns, directions and null placement. A cursor for a different order or the configured default is rejected. Omit `orderBy` to retain the configured order and existing cursor bytes. Repository callers may use `keyset_page_ordered` or `keyset_connection_page_ordered`; existing methods stay unchanged. Every composite primary-key component participates in configured and runtime validation. No schema or data migration is required.

## 0.60.0 to 0.61.0: subscription primary-key selection

Upgrade runtime/macros together. Generated single-key subscriptions gain an optional `key` argument, using the entity primary key scalar and configured argument casing. Existing operations remain valid. For example, `recordChanged(key: "…", filter: {actions: [UPDATED]})` watches one row. Key selection narrows notifications only: it never grants row, field, scope, assurance, deleted-preimage or propagated-source authority. Refresh schema/catalogue snapshots. Composite-key subscriptions remain unsupported by this change. No data or schema migration is required.
Expand Down
2 changes: 1 addition & 1 deletion crates/graphql-orm-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql-orm-macros"
version = "0.63.0"
version = "0.64.0"
edition = "2024"
authors = ["Toby Martin"]
description = "Procedural macros for async-graphql and ORM-backed entities, relations, and CRUD operations."
Expand Down
9 changes: 9 additions & 0 deletions crates/graphql-orm-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ The scalar-only input, complete primary-key suffix, order-bound cursor and curre
field authorization are described in the
[migration guide](../../MIGRATION.md#0610-to-0620-runtime-keyset-ordering).

Generated Changed delivery prepares the selected snapshot before yielding a
stream item. Late scalar refusals and policy errors, including nullable fields,
discard the entire event and private diagnostics without an error frame. A
later authorized event starts with clean response errors.

Version 0.64.0 generates complete composite-key and read-only projection change
subscriptions independently of mutation exposure. See the
[migration guide](../../MIGRATION.md#0630-to-0640-composite-and-read-only-changed).

Version 0.63.0 resolves generated upward propagation using complete relation
from/to tuples and revalidates the current mapping at release. See the
[migration guide](../../MIGRATION.md#0620-to-0630-propagation-relation-tuples).
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading