From 4ec7c3c83831612dd5a9dad7a8a315be67b13b3d Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Thu, 8 Oct 2026 13:54:46 -0500 Subject: [PATCH] feat(connections): shadow write policy and the shadow close receipt Regenerated from robosystems #1733 and #1738. The write-policy request takes 'qb_authoritative' or 'shadow'; 'native' is no longer accepted, since it is what disconnecting or severing leaves. The close receipt and the period-drafts read carry the shadow fields. --- .../api/connections/create_connection.py | 20 ++++--- .../set_connection_write_policy.py | 44 +++++++++----- .../robo_ledger_fiscal_close/close_period.py | 20 +++++-- robosystems_client/graphql/schema.graphql | 34 ++++++++++- robosystems_client/models/__init__.py | 4 ++ .../models/close_period_response.py | 59 +++++++++++++++++++ ...ose_period_response_gate_finding_counts.py | 47 +++++++++++++++ .../models/link_bank_account_response.py | 2 +- .../models/mercury_connection_config.py | 5 +- .../models/set_write_policy_request.py | 7 ++- .../set_write_policy_request_write_policy.py | 2 +- 11 files changed, 207 insertions(+), 37 deletions(-) create mode 100644 robosystems_client/models/close_period_response_gate_finding_counts.py diff --git a/robosystems_client/api/connections/create_connection.py b/robosystems_client/api/connections/create_connection.py index 5ad648b2..209a7b24 100644 --- a/robosystems_client/api/connections/create_connection.py +++ b/robosystems_client/api/connections/create_connection.py @@ -113,8 +113,9 @@ def sync_detailed( allowed per provider per graph, except 'external' which allows one per source_name and 'plaid' which allows one per bank login (a connection still waiting on Link is returned instead of a second). Plaid: returns a pending connection — `POST /oauth/init` returns a `link_token` for Plaid Link. A - bank feed (Mercury, Plaid) is refused (409) beside a live QuickBooks connection or on a graph with - no chart of accounts. + bank feed (Mercury, Plaid) names the entity its accounts book to (`entity_id`, the group parent when + omitted) and is refused (409) when that entity has no chart of accounts or is the one QuickBooks + keeps; QuickBooks is refused (409) when the group parent's books are already native. Args: graph_id (str): @@ -154,8 +155,9 @@ def sync( allowed per provider per graph, except 'external' which allows one per source_name and 'plaid' which allows one per bank login (a connection still waiting on Link is returned instead of a second). Plaid: returns a pending connection — `POST /oauth/init` returns a `link_token` for Plaid Link. A - bank feed (Mercury, Plaid) is refused (409) beside a live QuickBooks connection or on a graph with - no chart of accounts. + bank feed (Mercury, Plaid) names the entity its accounts book to (`entity_id`, the group parent when + omitted) and is refused (409) when that entity has no chart of accounts or is the one QuickBooks + keeps; QuickBooks is refused (409) when the group parent's books are already native. Args: graph_id (str): @@ -190,8 +192,9 @@ async def asyncio_detailed( allowed per provider per graph, except 'external' which allows one per source_name and 'plaid' which allows one per bank login (a connection still waiting on Link is returned instead of a second). Plaid: returns a pending connection — `POST /oauth/init` returns a `link_token` for Plaid Link. A - bank feed (Mercury, Plaid) is refused (409) beside a live QuickBooks connection or on a graph with - no chart of accounts. + bank feed (Mercury, Plaid) names the entity its accounts book to (`entity_id`, the group parent when + omitted) and is refused (409) when that entity has no chart of accounts or is the one QuickBooks + keeps; QuickBooks is refused (409) when the group parent's books are already native. Args: graph_id (str): @@ -229,8 +232,9 @@ async def asyncio( allowed per provider per graph, except 'external' which allows one per source_name and 'plaid' which allows one per bank login (a connection still waiting on Link is returned instead of a second). Plaid: returns a pending connection — `POST /oauth/init` returns a `link_token` for Plaid Link. A - bank feed (Mercury, Plaid) is refused (409) beside a live QuickBooks connection or on a graph with - no chart of accounts. + bank feed (Mercury, Plaid) names the entity its accounts book to (`entity_id`, the group parent when + omitted) and is refused (409) when that entity has no chart of accounts or is the one QuickBooks + keeps; QuickBooks is refused (409) when the group parent's books are already native. Args: graph_id (str): diff --git a/robosystems_client/api/connections/set_connection_write_policy.py b/robosystems_client/api/connections/set_connection_write_policy.py index 985293a9..124b26a1 100644 --- a/robosystems_client/api/connections/set_connection_write_policy.py +++ b/robosystems_client/api/connections/set_connection_write_policy.py @@ -106,10 +106,13 @@ def sync_detailed( ) -> Response[ConnectionResponse | ErrorResponse | HTTPValidationError]: """Set Connection Write Policy - Opt a connection into or out of outbound write-back. 'qb_authoritative' makes QuickBooks the source - of truth — RoboSystems-originated entries (manual JEs, schedule drafts) publish to QuickBooks when - executed or at close. 'native' keeps RoboSystems authoritative with no write-back. This is the - explicit operator opt-in for writing to your books of record. + Choose how a live connection and RoboSystems share the books. 'qb_authoritative', the default, makes + QuickBooks the book of record: RoboSystems-originated entries (manual JEs, schedule drafts) publish + to QuickBooks when executed or at close. 'shadow' keeps QuickBooks the book of record and writes + nothing to it: the close posts nothing locally either, its drafts become shadowed expectations + compared with what QuickBooks holds, and its gates are recorded as findings. 'native' is not a + choice here: it is what disconnecting or severing leaves, books kept in RoboSystems with no + connection to write to. This is the explicit operator opt-in for writing to your books of record. Args: graph_id (str): @@ -149,10 +152,13 @@ def sync( ) -> ConnectionResponse | ErrorResponse | HTTPValidationError | None: """Set Connection Write Policy - Opt a connection into or out of outbound write-back. 'qb_authoritative' makes QuickBooks the source - of truth — RoboSystems-originated entries (manual JEs, schedule drafts) publish to QuickBooks when - executed or at close. 'native' keeps RoboSystems authoritative with no write-back. This is the - explicit operator opt-in for writing to your books of record. + Choose how a live connection and RoboSystems share the books. 'qb_authoritative', the default, makes + QuickBooks the book of record: RoboSystems-originated entries (manual JEs, schedule drafts) publish + to QuickBooks when executed or at close. 'shadow' keeps QuickBooks the book of record and writes + nothing to it: the close posts nothing locally either, its drafts become shadowed expectations + compared with what QuickBooks holds, and its gates are recorded as findings. 'native' is not a + choice here: it is what disconnecting or severing leaves, books kept in RoboSystems with no + connection to write to. This is the explicit operator opt-in for writing to your books of record. Args: graph_id (str): @@ -187,10 +193,13 @@ async def asyncio_detailed( ) -> Response[ConnectionResponse | ErrorResponse | HTTPValidationError]: """Set Connection Write Policy - Opt a connection into or out of outbound write-back. 'qb_authoritative' makes QuickBooks the source - of truth — RoboSystems-originated entries (manual JEs, schedule drafts) publish to QuickBooks when - executed or at close. 'native' keeps RoboSystems authoritative with no write-back. This is the - explicit operator opt-in for writing to your books of record. + Choose how a live connection and RoboSystems share the books. 'qb_authoritative', the default, makes + QuickBooks the book of record: RoboSystems-originated entries (manual JEs, schedule drafts) publish + to QuickBooks when executed or at close. 'shadow' keeps QuickBooks the book of record and writes + nothing to it: the close posts nothing locally either, its drafts become shadowed expectations + compared with what QuickBooks holds, and its gates are recorded as findings. 'native' is not a + choice here: it is what disconnecting or severing leaves, books kept in RoboSystems with no + connection to write to. This is the explicit operator opt-in for writing to your books of record. Args: graph_id (str): @@ -228,10 +237,13 @@ async def asyncio( ) -> ConnectionResponse | ErrorResponse | HTTPValidationError | None: """Set Connection Write Policy - Opt a connection into or out of outbound write-back. 'qb_authoritative' makes QuickBooks the source - of truth — RoboSystems-originated entries (manual JEs, schedule drafts) publish to QuickBooks when - executed or at close. 'native' keeps RoboSystems authoritative with no write-back. This is the - explicit operator opt-in for writing to your books of record. + Choose how a live connection and RoboSystems share the books. 'qb_authoritative', the default, makes + QuickBooks the book of record: RoboSystems-originated entries (manual JEs, schedule drafts) publish + to QuickBooks when executed or at close. 'shadow' keeps QuickBooks the book of record and writes + nothing to it: the close posts nothing locally either, its drafts become shadowed expectations + compared with what QuickBooks holds, and its gates are recorded as findings. 'native' is not a + choice here: it is what disconnecting or severing leaves, books kept in RoboSystems with no + connection to write to. This is the explicit operator opt-in for writing to your books of record. Args: graph_id (str): diff --git a/robosystems_client/api/robo_ledger_fiscal_close/close_period.py b/robosystems_client/api/robo_ledger_fiscal_close/close_period.py index 4c8f0b45..4a2d0573 100644 --- a/robosystems_client/api/robo_ledger_fiscal_close/close_period.py +++ b/robosystems_client/api/robo_ledger_fiscal_close/close_period.py @@ -120,7 +120,10 @@ def sync_detailed( isn't set up). Period must be exactly `closed_through + 1` — sequence violations return 422 with structured `blockers`. Common blockers: `sync_stale` (override with `allow_stale_sync=true` after manual verification), `period_incomplete` (draft entries unbalanced), `sequence_violation` (out-of- - order). + order). Under a QuickBooks connection whose write_policy is `shadow`, the close observes instead: + nothing is written to QuickBooks or posted, the drafts become `shadowed` expectations + (`entries_shadowed`), and the gates that would have blocked are returned as `gate_findings` rather + than enforced. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -170,7 +173,10 @@ def sync( isn't set up). Period must be exactly `closed_through + 1` — sequence violations return 422 with structured `blockers`. Common blockers: `sync_stale` (override with `allow_stale_sync=true` after manual verification), `period_incomplete` (draft entries unbalanced), `sequence_violation` (out-of- - order). + order). Under a QuickBooks connection whose write_policy is `shadow`, the close observes instead: + nothing is written to QuickBooks or posted, the drafts become `shadowed` expectations + (`entries_shadowed`), and the gates that would have blocked are returned as `gate_findings` rather + than enforced. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -215,7 +221,10 @@ async def asyncio_detailed( isn't set up). Period must be exactly `closed_through + 1` — sequence violations return 422 with structured `blockers`. Common blockers: `sync_stale` (override with `allow_stale_sync=true` after manual verification), `period_incomplete` (draft entries unbalanced), `sequence_violation` (out-of- - order). + order). Under a QuickBooks connection whose write_policy is `shadow`, the close observes instead: + nothing is written to QuickBooks or posted, the drafts become `shadowed` expectations + (`entries_shadowed`), and the gates that would have blocked are returned as `gate_findings` rather + than enforced. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -263,7 +272,10 @@ async def asyncio( isn't set up). Period must be exactly `closed_through + 1` — sequence violations return 422 with structured `blockers`. Common blockers: `sync_stale` (override with `allow_stale_sync=true` after manual verification), `period_incomplete` (draft entries unbalanced), `sequence_violation` (out-of- - order). + order). Under a QuickBooks connection whose write_policy is `shadow`, the close observes instead: + nothing is written to QuickBooks or posted, the drafts become `shadowed` expectations + (`entries_shadowed`), and the gates that would have blocked are returned as `gate_findings` rather + than enforced. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. diff --git a/robosystems_client/graphql/schema.graphql b/robosystems_client/graphql/schema.graphql index 47563927..30b58075 100644 --- a/robosystems_client/graphql/schema.graphql +++ b/robosystems_client/graphql/schema.graphql @@ -2376,7 +2376,8 @@ type PeriodCloseStatus { One schedule's contribution to a period close — drafted closing entry plus its reversal (when `auto_reverse=True`). -`status` is the closing entry's draft/posted lifecycle. The +`status` is the closing entry's draft/posted lifecycle (`shadowed` when a +shadow close took the draft as an expectation and posted nothing). The reversal mirrors the same shape with `reversal_*` fields. """ type PeriodCloseItem { @@ -2403,7 +2404,9 @@ schema and both SDKs derive from it, and an opaque blob would push the shape onto every reader to rediscover. """ type CloseReceipt { - """Receipt schema version; 1 is the first shipped shape""" + """ + Receipt schema version; 1 is the first shipped shape, 2 adds the shadow fields + """ version: Int! """Period this receipt is for (YYYY-MM)""" @@ -2436,6 +2439,18 @@ type CloseReceipt { """structure_id -> minted fact_set_id""" stampedStatementSets: JSON! statementRuleSummary: JSON + + """ + The close ran in shadow: nothing written to QuickBooks, nothing posted, the drafts shadowed, the gates recorded as findings + """ + shadow: Boolean! + entriesShadowed: Int! + + """Blocker codes a shadow close recorded instead of enforcing""" + gateFindings: [String!]! + + """Each finding's size: days stale, or a count""" + gateFindingCounts: JSON } """ @@ -2610,7 +2625,7 @@ type PeriodDrafts { qbWritebackConnectionId: String """ - write_policy of the publishing QB connection ('qb_authoritative' / 'hybrid'), or null when there is no write-back connection. + write_policy of the publishing QB connection ('qb_authoritative' / 'hybrid'), 'shadow' when the connection runs in shadow, or null when there is no write-back connection. """ qbWritePolicy: String @@ -2619,6 +2634,14 @@ type PeriodDrafts { """Number of drafts that post locally only (no QB write-back).""" localOnlyCount: Int! + + """ + True when the connection runs in shadow: the close writes nothing to QuickBooks and posts nothing; every draft becomes a shadowed expectation compared with what QuickBooks holds. + """ + shadow: Boolean! + + """Number of drafts the close will shadow (all of them, in shadow).""" + shadowedCount: Int! drafts: [DraftEntry!]! } @@ -2656,6 +2679,11 @@ type DraftEntry { True if closing the period will publish this draft to QuickBooks — i.e. the graph has a qb_authoritative/hybrid QB connection AND this is an RL-originated draft (schedule/manual) not already in QB. False means it posts locally only. """ willPublishToQb: Boolean! + + """ + What the close does with this draft: 'publish' writes it to QuickBooks, 'post' posts it locally, 'shadow' takes it as an expectation with nothing written or posted (a shadow connection). + """ + closeDisposition: String! } """A single line item within a draft entry.""" diff --git a/robosystems_client/models/__init__.py b/robosystems_client/models/__init__.py index ad2311d5..6d04cb08 100644 --- a/robosystems_client/models/__init__.py +++ b/robosystems_client/models/__init__.py @@ -59,6 +59,9 @@ from .classification_lite import ClassificationLite from .close_period_operation import ClosePeriodOperation from .close_period_response import ClosePeriodResponse +from .close_period_response_gate_finding_counts import ( + ClosePeriodResponseGateFindingCounts, +) from .close_period_response_rule_summary_type_0 import ( ClosePeriodResponseRuleSummaryType0, ) @@ -1165,6 +1168,7 @@ "ClassificationLite", "ClosePeriodOperation", "ClosePeriodResponse", + "ClosePeriodResponseGateFindingCounts", "ClosePeriodResponseRuleSummaryType0", "ClosePeriodResponseStampedStatementSets", "ClosePeriodResponseStatementRuleSummaryType0", diff --git a/robosystems_client/models/close_period_response.py b/robosystems_client/models/close_period_response.py index a81708b5..4a0b8d32 100644 --- a/robosystems_client/models/close_period_response.py +++ b/robosystems_client/models/close_period_response.py @@ -9,6 +9,9 @@ from ..types import UNSET, Unset if TYPE_CHECKING: + from ..models.close_period_response_gate_finding_counts import ( + ClosePeriodResponseGateFindingCounts, + ) from ..models.close_period_response_rule_summary_type_0 import ( ClosePeriodResponseRuleSummaryType0, ) @@ -47,6 +50,16 @@ class ClosePeriodResponse: close. Pairs with rule_summary. statements_stamped (bool | Unset): Whether the close stamped the period's canonical statement FactSets (the close-time pivot). False when the tenant hasn't set up reporting yet — see statement_stamp_note. Default: False. + shadow (bool | Unset): True when the close ran in shadow (the QuickBooks connection's write_policy is 'shadow'): + nothing was written to QuickBooks, nothing posted, the in-window drafts were shadowed, and the gates that would + have blocked the close are in gate_findings. Default: False. + entries_shadowed (int | Unset): Drafts a shadow close took as expectations (status 'shadowed') instead of + posting. Always 0 outside shadow. Default: 0. + gate_findings (list[str] | Unset): Blocker codes a shadow close recorded instead of enforcing: sync_stale, + pending_obligations, stranded_obligations, reconciling_items, unposted_source_events, unreconciled_accounts. + Empty outside shadow. + gate_finding_counts (ClosePeriodResponseGateFindingCounts | Unset): Each finding's size: days stale for + sync_stale, a count for the rest. statement_stamp_note (None | str | Unset): Soft-skip reason when statements_stamped is false: no_coa_mapping | no_entity | no_statement_structures | no_taxonomy. stamped_statement_sets (ClosePeriodResponseStampedStatementSets | Unset): structure_id -> fact_set_id for every @@ -65,6 +78,10 @@ class ClosePeriodResponse: rule_summary: ClosePeriodResponseRuleSummaryType0 | None | Unset = UNSET evaluated_structure_ids: list[str] | Unset = UNSET statements_stamped: bool | Unset = False + shadow: bool | Unset = False + entries_shadowed: int | Unset = 0 + gate_findings: list[str] | Unset = UNSET + gate_finding_counts: ClosePeriodResponseGateFindingCounts | Unset = UNSET statement_stamp_note: None | str | Unset = UNSET stamped_statement_sets: ClosePeriodResponseStampedStatementSets | Unset = UNSET statement_rule_summary: ( @@ -106,6 +123,18 @@ def to_dict(self) -> dict[str, Any]: statements_stamped = self.statements_stamped + shadow = self.shadow + + entries_shadowed = self.entries_shadowed + + gate_findings: list[str] | Unset = UNSET + if not isinstance(self.gate_findings, Unset): + gate_findings = self.gate_findings + + gate_finding_counts: dict[str, Any] | Unset = UNSET + if not isinstance(self.gate_finding_counts, Unset): + gate_finding_counts = self.gate_finding_counts.to_dict() + statement_stamp_note: None | str | Unset if isinstance(self.statement_stamp_note, Unset): statement_stamp_note = UNSET @@ -148,6 +177,14 @@ def to_dict(self) -> dict[str, Any]: field_dict["evaluated_structure_ids"] = evaluated_structure_ids if statements_stamped is not UNSET: field_dict["statements_stamped"] = statements_stamped + if shadow is not UNSET: + field_dict["shadow"] = shadow + if entries_shadowed is not UNSET: + field_dict["entries_shadowed"] = entries_shadowed + if gate_findings is not UNSET: + field_dict["gate_findings"] = gate_findings + if gate_finding_counts is not UNSET: + field_dict["gate_finding_counts"] = gate_finding_counts if statement_stamp_note is not UNSET: field_dict["statement_stamp_note"] = statement_stamp_note if stamped_statement_sets is not UNSET: @@ -159,6 +196,9 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.close_period_response_gate_finding_counts import ( + ClosePeriodResponseGateFindingCounts, + ) from ..models.close_period_response_rule_summary_type_0 import ( ClosePeriodResponseRuleSummaryType0, ) @@ -206,6 +246,21 @@ def _parse_rule_summary( statements_stamped = d.pop("statements_stamped", UNSET) + shadow = d.pop("shadow", UNSET) + + entries_shadowed = d.pop("entries_shadowed", UNSET) + + gate_findings = cast(list[str], d.pop("gate_findings", UNSET)) + + _gate_finding_counts = d.pop("gate_finding_counts", UNSET) + gate_finding_counts: ClosePeriodResponseGateFindingCounts | Unset + if isinstance(_gate_finding_counts, Unset): + gate_finding_counts = UNSET + else: + gate_finding_counts = ClosePeriodResponseGateFindingCounts.from_dict( + _gate_finding_counts + ) + def _parse_statement_stamp_note(data: object) -> None | str | Unset: if data is None: return data @@ -259,6 +314,10 @@ def _parse_statement_rule_summary( rule_summary=rule_summary, evaluated_structure_ids=evaluated_structure_ids, statements_stamped=statements_stamped, + shadow=shadow, + entries_shadowed=entries_shadowed, + gate_findings=gate_findings, + gate_finding_counts=gate_finding_counts, statement_stamp_note=statement_stamp_note, stamped_statement_sets=stamped_statement_sets, statement_rule_summary=statement_rule_summary, diff --git a/robosystems_client/models/close_period_response_gate_finding_counts.py b/robosystems_client/models/close_period_response_gate_finding_counts.py new file mode 100644 index 00000000..3a54e24a --- /dev/null +++ b/robosystems_client/models/close_period_response_gate_finding_counts.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ClosePeriodResponseGateFindingCounts") + + +@_attrs_define +class ClosePeriodResponseGateFindingCounts: + """Each finding's size: days stale for sync_stale, a count for the rest.""" + + additional_properties: dict[str, int] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + close_period_response_gate_finding_counts = cls() + + close_period_response_gate_finding_counts.additional_properties = d + return close_period_response_gate_finding_counts + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> int: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: int) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/link_bank_account_response.py b/robosystems_client/models/link_bank_account_response.py index a4e63d9c..e6b67852 100644 --- a/robosystems_client/models/link_bank_account_response.py +++ b/robosystems_client/models/link_bank_account_response.py @@ -28,7 +28,7 @@ class LinkBankAccountResponse: previous entity's chart. Default: 0. pairs_across_entities (int | Unset): Open transfer pairs whose two legs now sit on two entities, because only one leg's account moved. Intercompany; the commit guard refuses them until the other leg follows. Default: 0. - changed (bool | Unset): False when the link already stood. Default: True. + changed (bool | Unset): False when the link already stood and no line moved. Default: True. """ connection_id: str diff --git a/robosystems_client/models/mercury_connection_config.py b/robosystems_client/models/mercury_connection_config.py index f7eb902a..db7f2fa8 100644 --- a/robosystems_client/models/mercury_connection_config.py +++ b/robosystems_client/models/mercury_connection_config.py @@ -16,8 +16,9 @@ class MercuryConnectionConfig: """Mercury bank-feed connection configuration. - A bank feed is native accounting: the graph must already have a chart of - accounts and no live QuickBooks connection. Over OAuth (the hosted + A bank feed is native accounting: the entity its accounts land on must + already have a chart of accounts and must not be the one QuickBooks keeps + (the group parent, while QuickBooks is connected). Over OAuth (the hosted default) the connection is created `pending_oauth` and activated by the callback. `api_key` — a personal **read-only** Mercury token — connects at once without a browser round-trip, but only on deployments that turn diff --git a/robosystems_client/models/set_write_policy_request.py b/robosystems_client/models/set_write_policy_request.py index efc9b6b6..04302043 100644 --- a/robosystems_client/models/set_write_policy_request.py +++ b/robosystems_client/models/set_write_policy_request.py @@ -21,8 +21,11 @@ class SetWritePolicyRequest: until its code path ships. Attributes: - write_policy (SetWritePolicyRequestWritePolicy): 'native' = RoboSystems authoritative, no write-back; - 'qb_authoritative' = QuickBooks authoritative, entries publish to QB. + write_policy (SetWritePolicyRequestWritePolicy): 'qb_authoritative' = QuickBooks authoritative, entries publish + to QB; 'shadow' = QuickBooks authoritative and RoboSystems only observes: nothing is written to QuickBooks, the + close posts nothing locally, its drafts become shadowed expectations and its gates are findings. 'native', books + kept in RoboSystems with no write-back, is what disconnecting or severing leaves, not a choice for a live + connection. """ write_policy: SetWritePolicyRequestWritePolicy diff --git a/robosystems_client/models/set_write_policy_request_write_policy.py b/robosystems_client/models/set_write_policy_request_write_policy.py index 85611477..fd522bc1 100644 --- a/robosystems_client/models/set_write_policy_request_write_policy.py +++ b/robosystems_client/models/set_write_policy_request_write_policy.py @@ -2,8 +2,8 @@ class SetWritePolicyRequestWritePolicy(str, Enum): - NATIVE = "native" QB_AUTHORITATIVE = "qb_authoritative" + SHADOW = "shadow" def __str__(self) -> str: return str(self.value)