Skip to content

This is an internal working record, not an everyday instruction. It was written while the system was being rebuilt, for whoever maintains it. If you are here to do today's work, use the everyday documents instead: Procedures · Processes · Runbooks · The working day, step by step

CTC Billing, QBO, Files And Email Sequence Diagram Catalog

  • Status: CURRENT SOURCE-RECONCILED AND TARGET DIAGRAM INPUT
  • Operating profile: ctc-execution
  • Source reconciliation: CTC_BILLING_QBO_FILES_EMAIL_RECONCILIATION.md
  • Policy matrix: CTC_BILLING_QBO_FILES_EMAIL_POLICY_DECISION_MATRIX.md
  • Cutover matrix: CTC_BILLING_QBO_FILES_EMAIL_PARITY_AND_CUTOVER_MATRIX.md
  • Audience: Process owner, Office/Billing, support, Wiki editor, P5/P6/P8/P12/P11 migration writers.
  • Important: CURRENT diagrams describe reconciled source behavior. TARGET diagrams describe recommended migration architecture and are not current Runtime behavior.

1. Diagram Legend

CURRENT
= source-reconciled present adapter behavior

TARGET
= reconstruction/migration design requiring policy and implementation approval

Local Commit
!= Provider Result
!= File Object Result
!= Email Result
!= Composite Daily Close

A diagram is explanatory. The linked process/data/interface contracts remain authoritative.


2. Current Billing And Document Composite

flowchart TB
    Source[Source Work / Rate / Customer Evidence]
    Generic[Generic AP/AR Transaction]
    AR[Container AR Confirm]
    QBO[QuickBooks Invoice]
    Object[Stored File Object]
    Link[Transaction File Link]
    BOL[BOL Email]
    Pack[Packing List Target/Parts]
    Daily[Daily Billing Close Reconciliation]

    Source --> Generic
    Source --> AR
    AR --> QBO
    Generic --> Link
    Object --> Link
    Source --> BOL
    Link --> BOL
    Source --> Pack

    Generic --> Daily
    AR --> Daily
    QBO --> Daily
    Link --> Daily
    BOL --> Daily
    Pack --> Daily
Daily reconciliation observes child checkpoints.
It does not mutate them into one universal status.

3. CURRENT — Generic Transaction Create/Edit/Close

sequenceDiagram
    actor Office
    participant UI as Transaction Page
    participant API as BMS Transaction API
    participant Helper as Current PHP Helpers
    database DB as MySQL

    Office->>UI: Select source/account/company or existing transaction
    UI->>API: Create/Edit/Close request
    API->>Helper: Source command or generic table mutation
    Helper->>DB: Insert/update header and/or lines
    DB-->>Helper: Current write result
    Helper-->>API: Legacy value/debug result
    API-->>UI: Response
    UI->>API: Refresh transaction detail/list
    API->>DB: Tenant-scoped header/line read
    DB-->>UI: Authoritative local result

Current close hazard

sequenceDiagram
    actor Office
    participant UI
    participant API
    database DB

    Office->>UI: Select multiple rows
    UI->>API: PATCH close with common fields
    API->>DB: Bulk update selected IDs
    Note over API,DB: No documented prior-state or QBO guard.
    alt response received
        DB-->>UI: Generic success
        UI->>DB: Reread every intended ID
    else response lost
        Note over Office,DB: Some/all rows may already be committed.
        Office->>DB: Reread every selected ID before any repeat
    end

4. TARGET — Semantic Generic Transaction Command

sequenceDiagram
    actor Office
    participant React as React Billing UI
    participant Next as Next.js Adapter
    participant App as Transaction Application
    participant Policy as State/Batch Policy
    database DB as MySQL Repository

    Office->>React: Review compatible transactions
    React->>Next: CloseTransactions DTO + expected versions
    Next->>App: Authenticated tenant/actor command
    App->>DB: Read exact headers/lines/provider links
    App->>Policy: Validate state, company, account and fields
    alt incompatible/stale
        Policy-->>React: Stable conflict + exact current state
    else valid
        App->>DB: Conditional per-row transaction updates
        App->>DB: Record correction/transition evidence
        App->>DB: Exact reread
        DB-->>React: Per-row committed result
    end

5. CURRENT — AR Billing Preview And Confirm

sequenceDiagram
    actor Office
    participant UI as AR Billing UI
    participant API as AR Billing API
    participant App as PHP AR Helper
    database DB as MySQL

    Office->>UI: Select booking/container candidate(s)
    UI->>API: Preview request
    API->>App: Resolve context/preset/rates/sources
    App->>DB: Read authoritative source/rate data
    DB-->>UI: Calculated invoice lines

    Office->>UI: Complete
    UI->>API: Confirm items[]
    API->>DB: BEGIN one request transaction
    loop each item
        API->>DB: Resolve candidate again
        alt existing eligible unsynced container AR
            API->>DB: Rewrite header to READY
            API->>DB: Soft-delete old active lines
            API->>DB: Insert reviewed lines
        else no container AR
            API->>DB: Insert header + lines
        end
    end
    alt every item valid
        API->>DB: COMMIT
        DB-->>UI: Confirmed transaction UUIDs
    else one item invalid
        API->>DB: ROLLBACK all items
        API-->>UI: Failure
    end

Current browser handoff to QBO

sequenceDiagram
    actor Office
    participant UI as AR Billing Browser
    participant Confirm as Confirm API
    participant QBOApi as QBO Sync API
    database DB

    UI->>Confirm: Confirm selected invoices
    Confirm->>DB: Commit local AR invoice(s) READY
    DB-->>UI: transaction UUIDs
    alt browser continues
        UI->>QBOApi: qbo-sync(transaction UUIDs)
    else browser/network interrupted
        Note over UI,DB: Local READY invoice exists with no proven QBO attempt.
    end

6. TARGET — Local Confirm With Durable Effect Intent

sequenceDiagram
    actor Office
    participant React
    participant Next
    participant App as AR Application
    database DB
    participant Worker

    Office->>React: Confirm reviewed candidate(s)
    React->>Next: Confirm DTO/fingerprint
    Next->>App: ConfirmContainerInvoices
    App->>DB: BEGIN
    App->>DB: Validate source/preset/rate and active uniqueness
    App->>DB: Insert/version local invoice and lines
    App->>DB: Persist QBO delivery intent when applicable
    App->>DB: COMMIT
    DB-->>React: Local invoice READY/PENDING_QBO readback
    Worker->>DB: Claim pending QBO intent asynchronously

The local invoice result remains valid when the provider is delayed or unavailable.


7. CURRENT — QBO Group Success

sequenceDiagram
    participant UI as Browser
    participant API as QBO Sync API
    database DB
    participant QBO as QuickBooks Online

    UI->>API: transaction UUIDs + group mode
    API->>DB: Validate group mappings/state
    API->>DB: Set rows SYNCING + claim token in QBO_ERROR
    API->>QBO: createInvoice(payload)
    QBO-->>API: invoice ID/doc/sync token
    API->>DB: Set QBO fields and SYNCED where claim token matches
    DB-->>API: all rows updated
    API-->>UI: group SYNCED

8. CURRENT — QBO Provider Created, Local Save Uncertain

sequenceDiagram
    participant API as QBO Sync API
    database DB
    participant QBO as QuickBooks Online
    actor Support

    API->>DB: Claim rows SYNCING
    API->>QBO: createInvoice
    QBO-->>API: Provider invoice created
    API->>DB: Save provider ID and SYNCED
    alt save/response succeeds
        DB-->>API: reconciled
    else DB write/response fails
        API->>DB: Attempt ERROR update using claim token
        Note over DB,QBO: Provider invoice may exist while local state is ERROR, SYNCING or unknown.
        Support->>QBO: Search customer/doc/amount/time
        Support->>DB: Compare local transaction group
        alt provider invoice found
            Support->>DB: Reconcile local provider ID/status through approved path
        else provider absence established
            Support->>DB: Approve retry of same intent only
        end
    end

Blind resend is prohibited.


9. TARGET — QBO Intent, Attempt And Reconciliation Worker

stateDiagram-v2
    [*] --> PENDING
    PENDING --> CLAIMED: worker claim
    CLAIMED --> PROVIDER_ACCEPTED: provider returns invoice
    CLAIMED --> UNKNOWN_PROVIDER_RESULT: timeout/transport ambiguity
    CLAIMED --> FAILED_RETRYABLE: clear provider rejection/config issue
    PROVIDER_ACCEPTED --> SYNCED: local reconciliation commit
    PROVIDER_ACCEPTED --> UNKNOWN_PROVIDER_RESULT: local save uncertainty
    UNKNOWN_PROVIDER_RESULT --> SYNCED: provider search finds intended invoice
    UNKNOWN_PROVIDER_RESULT --> FAILED_RETRYABLE: provider absence established
    FAILED_RETRYABLE --> CLAIMED: approved retry
    FAILED_RETRYABLE --> MANUAL_REVIEW: threshold/policy
    UNKNOWN_PROVIDER_RESULT --> MANUAL_REVIEW: unresolved duplicate risk
    CLAIMED --> FAILED_FINAL: non-retryable decision
    SYNCED --> [*]
    FAILED_FINAL --> [*]
sequenceDiagram
    participant App as TypeScript Application
    database DB
    participant Worker
    participant QBO

    App->>DB: Commit QboInvoiceIntent
    Worker->>DB: Claim intent and create attempt
    Worker->>QBO: Search prior identity when needed
    alt intended invoice found
        QBO-->>Worker: provider invoice
    else absence established
        Worker->>QBO: Create invoice with supported request identity
        QBO-->>Worker: provider invoice
    else unknown
        QBO-->>Worker: timeout/ambiguous
    end
    Worker->>DB: Persist attempt/result/reconciliation
    App->>DB: Project local invoice provider state

sequenceDiagram
    actor Office
    participant UI as Transaction File UI
    participant Media as Media Upload API
    participant Storage as EFS/S3
    participant Link as Transaction Document API
    database DB

    Office->>UI: Select file and intended transaction(s)
    UI->>Media: Upload binary
    Media->>Storage: Store object
    Storage-->>Media: path/url/uuid/storage metadata
    Media-->>UI: uploaded object metadata
    UI->>Link: Register metadata for transaction IDs
    Link->>DB: Insert T_FILE link row(s)
    alt every link succeeds
        DB-->>UI: registered result
        UI->>DB: Reread every intended transaction file
    else registration fails
        Note over Storage,DB: Object may exist without intended links.
        Office->>Storage: Do not upload again before checking object metadata
        Office->>DB: Compare existing links
    end

11. CURRENT — Shared-Path Delete Risk

sequenceDiagram
    actor Office
    participant API as File Delete API
    database DB
    participant Storage

    Office->>API: Delete selected T_FILE row
    API->>DB: Read selected row/path/storage
    Note over DB: Other active T_FILE rows may share the same path.
    API->>Storage: Storage-specific object cleanup may occur
    API->>DB: Soft-delete selected row
    Note over DB,Storage: Another active link can become unreadable if shared object was removed.

Target policy must inventory references before object cleanup.


flowchart LR
    Upload[UploadFileObject]
    Object[(FileObject)]
    LinkCmd[LinkFileToTransaction]
    Link[(FileLink)]
    Read[Readability Check]
    Unlink[UnlinkFile]
    Cleanup[Cleanup Evaluation]
    Worker[Cleanup Worker]
    Storage[Object Storage]

    Upload --> Storage
    Upload --> Object
    LinkCmd --> Object
    LinkCmd --> Link
    Link --> Read
    Read --> Storage
    Unlink --> Link
    Unlink --> Cleanup
    Cleanup -->|no active link/hold| Worker
    Worker --> Storage
    Worker --> Object

13. CURRENT — BOL Email

sequenceDiagram
    actor Office
    participant API as BOL Email API
    database DB
    participant Render as Scale/File Preparation
    participant Gmail

    Office->>API: Send BOL for transload
    API->>DB: Read transload/reference/billing company
    API->>DB: Resolve BOL recipients and active files
    API->>Render: Optional scale PDF + temp attachment copies
    API->>Gmail: Send subject {reference} BOL and Weight
    Gmail-->>API: Code/Message + message/thread payload or failure
    API->>Render: Delete temporary local files
    API-->>Office: Provider response
    Note over API,DB: No durable business send ledger is persisted.

Unknown response recovery

sequenceDiagram
    actor Office
    participant App
    participant Gmail

    Office->>App: Send BOL
    App->>Gmail: Send message
    Gmail-->>App: Accepted
    Note over Office,App: Browser/API response is lost.
    Office->>Gmail: Search Sent by recipient + subject/reference + time
    alt message found
        Office->>App: Record/escalate reconciled provider result
    else absence established
        Office->>App: Retry through approved send path
    end

14. CURRENT — Packing List Target-Part Partial Result

sequenceDiagram
    actor Office
    participant API as Packing List Email API
    participant Build as Model/Attachment Builder
    participant Gmail

    Office->>API: Send CUSTOMER/INSPECTOR/BOTH
    API->>Build: Generate body and attachment batches
    loop each target
        loop each part
            API->>Gmail: Send target subject (Part X of Y)
            alt provider success
                Gmail-->>API: success
                API->>API: Append Results[target,part]
            else failure/timeout
                Gmail-->>API: failure/unknown
                API-->>Office: Failure + earlier in-memory Results
                Note over Office,Gmail: Earlier target/parts remain sent.
            end
        end
    end
    API-->>Office: Complete only when every target/part succeeded

Current API cannot resume one missing part. Full target replay can duplicate earlier messages.


15. TARGET — Durable Packing Email Batch

flowchart TB
    Batch[PackingEmailBatch v1]
    Customer[Target CUSTOMER]
    Inspector[Target INSPECTOR]
    C1[Part 1/N]
    C2[Part 2/N]
    I1[Part 1/N]
    Attempt[EmailAttempt]
    Result[Provider Message/Thread]

    Batch --> Customer
    Batch --> Inspector
    Customer --> C1
    Customer --> C2
    Inspector --> I1
    C1 --> Attempt
    C2 --> Attempt
    I1 --> Attempt
    Attempt --> Result
sequenceDiagram
    actor Office
    participant App
    database DB
    participant Worker
    participant Gmail

    Office->>App: Request packing email batch
    App->>DB: Freeze source/options/recipients/part hashes
    App->>DB: Commit target-part intents
    Worker->>DB: Claim one unresolved target-part
    Worker->>Gmail: Search prior identity or send part
    Gmail-->>Worker: message/thread/failure/unknown
    Worker->>DB: Persist exact target-part result
    App->>DB: Read whole batch projection
    DB-->>Office: Sent/failed/unknown per target-part

A content or partition change creates a new batch version.


16. Universal Unknown-Result Recovery

flowchart TB
    Missing[Response missing / timeout / partial result]
    Classify{Which boundary?}
    Local[Local transaction/header/lines]
    Provider[QBO or Gmail]
    Object[File object]
    Link[File link]
    Read[Read authoritative IDs/states/evidence]
    Result{Committed result?}
    Done[Use existing result; do not repeat]
    MissingPart[Identify exact missing command/effect]
    Retry[Retry only missing eligible boundary]
    Escalate[Manual review / provider search / support]

    Missing --> Classify
    Classify --> Local
    Classify --> Provider
    Classify --> Object
    Classify --> Link
    Local --> Read
    Provider --> Read
    Object --> Read
    Link --> Read
    Read --> Result
    Result -->|yes| Done
    Result -->|no and absence proven| MissingPart
    Result -->|unknown| Escalate
    MissingPart --> Retry

Required readback identities:

  • transaction IDs/UUIDs and lines;
  • booking/container invoice identity;
  • QBO group/effect/provider invoice identity;
  • file object UUID/path and every active link;
  • BOL source/recipient/subject/provider message;
  • Packing batch/target/part/provider message.

17. TARGET — One-Writer Cutover

sequenceDiagram
    participant Old as PHP Current Writer
    participant Selector as Capability/Cohort Selector
    participant New as TypeScript Command or Worker
    database DB as MySQL
    participant Verify as Parity/Observation

    Old->>DB: Accepted current writes
    New->>DB: Read shadow only
    Verify->>DB: Compare old/new projections
    Note over Selector: Activate one bounded command/effect cohort.
    Selector->>Old: Disable selected write/effect
    Selector->>New: Enable selected write/effect
    New->>DB: Single authoritative mutation/intent
    Verify->>DB: Exact state/effect readback
    alt rollback required
        Selector->>New: Disable new writer/claims
        Verify->>DB: Reconcile committed and in-flight state
        Selector->>Old: Resume only new eligible work
    else accepted
        Verify->>Old: Classify callers until caller-zero
    end

18. Daily Billing Close Operator Sequence

sequenceDiagram
    actor Billing as Office/Billing
    participant Local as Local Transactions/AR
    participant QBO
    participant Files
    participant Email as BOL/Packing Email
    participant Close as Daily Close Worklist

    Billing->>Close: Open unresolved/current work
    Close->>Local: Read applicable local checkpoints
    Close->>QBO: Read applicable provider/local reconciliation
    Close->>Files: Read object/link/readability
    Close->>Email: Read BOL and target-part evidence
    Close-->>Billing: Per-checkpoint status and next owner
    loop each applicable child
        alt verified
            Billing->>Close: Mark human disposition VERIFIED
        else intentionally not applicable
            Billing->>Close: Mark NOT_APPLICABLE with reason
        else unresolved but owned
            Billing->>Close: CARRY exact state/evidence/owner
        else unknown/unsafe
            Billing->>Close: BLOCK and escalate
        end
    end

The worklist does not mark child records complete.


19. Diagram-To-Document Map

Diagram family Process owner Runbook/Wiki projection
Composite checkpoints Billing Close composite billing, ctc-daily
Generic transaction Transaction lifecycle billing
AR preview/confirm AR Billing confirm ar-billing-qbo
QBO effect/reconciliation QBO delivery ar-billing-qbo, errors-recovery
File object/link Transaction document billing, errors-recovery
BOL email BOL email billing, errors-recovery
Packing target-part Packing List email billing, errors-recovery
One-writer migration P12 capability packet Internal reconstruction docs; user Wiki only shows stable route changes.

20. Maintenance Triggers

Review the applicable diagrams when any of these changes:

  • local transaction state or close command;
  • AR batch atomicity, uniqueness or correction;
  • QBO grouping, state, provider client, retry or reconciliation;
  • file upload/object/link/delete behavior;
  • BOL recipients/attachments/subject/provider response;
  • Packing targets/options/part splitting/resume;
  • daily close owner/cadence/disposition;
  • React/Next.js/TypeScript/worker ownership;
  • one-writer, rollback or caller-zero.

Do not update only the diagram. Reconcile the owning process, data/interface packet, Runbook and Wiki projection.

---

Source: docs/processes/CTC_BILLING_QBO_FILES_EMAIL_SEQUENCE_DIAGRAMS.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.