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
20 changes: 12 additions & 8 deletions robosystems_client/api/connections/create_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
44 changes: 28 additions & 16 deletions robosystems_client/api/connections/set_connection_write_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
20 changes: 16 additions & 4 deletions robosystems_client/api/robo_ledger_fiscal_close/close_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
34 changes: 31 additions & 3 deletions robosystems_client/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)"""
Expand Down Expand Up @@ -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
}

"""
Expand Down Expand Up @@ -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

Expand All @@ -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!]!
}

Expand Down Expand Up @@ -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."""
Expand Down
4 changes: 4 additions & 0 deletions robosystems_client/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down Expand Up @@ -1165,6 +1168,7 @@
"ClassificationLite",
"ClosePeriodOperation",
"ClosePeriodResponse",
"ClosePeriodResponseGateFindingCounts",
"ClosePeriodResponseRuleSummaryType0",
"ClosePeriodResponseStampedStatementSets",
"ClosePeriodResponseStatementRuleSummaryType0",
Expand Down
Loading
Loading