docs/architecture/dose-and-program.md

Dose And Program History

This slice covers dose history, program history, correction application, active-program scheduling, draft programs, and backfill.

Dose And Program UI Flow

flowchart LR
    subgraph UI["UI"]
        DOSE["Dosing page"]
        PROGRAM["Program page"]
        DRAWER["Tank-method element drawer"]
        TEMPLATES["Entry templates"]
        CORR["ICP correction checkboxes"]
    end

    subgraph API["REST API Gateway"]
        DOSEELEMENTS["POST /dose/elements/list"]
        DOSEGET["POST /dose/history"]
        DOSELIST["POST /dose/history/list"]
        DOSESAVE["POST /dose/history/save"]
        DOSEDELETE["POST /dose/history/delete"]
        PROGGET["POST /program/history"]
        PROGLIST["POST /program/history/list"]
        PROGSAVE["POST /program/history/save"]
        PROGDELETE["POST /program/history/delete"]
        APPLYCORR["POST /corrections"]
        TEMPLATE["POST /user/template"]
    end

    subgraph Lambdas["Lambdas"]
        L_DOSEELEMENTS["dose-list-dose-elements"]
        L_DOSEGET["get-dose-history"]
        L_DOSELIST["dose-list-dose-history"]
        L_DOSESAVE["dose-save-dose-history-apigw"]
        L_DOSEDELETE["dose-delete-dose-history"]
        L_PROGGET["dose-get-program-history"]
        L_PROGLIST["dose-list-program-history"]
        L_PROGSAVE["dose-save-program-history"]
        L_PROGDELETE["dose-delete-program-history"]
        L_APPLYCORR["corrections-apply-correction"]
        L_TEMPLATE["user-entry-template-list"]
    end

    subgraph Data["DynamoDB"]
        DOSEE["env-dose-element"]
        DOSEH["env-dose-history"]
        PROGH["env-program-history"]
        TEMPLATE_T["env-user-entry-template"]
        DRAFTFB["env-program-draft-feedback"]
        REEFREV["env-reef-review"]
    end

    DOSE --> DRAWER --> DOSEELEMENTS --> L_DOSEELEMENTS --> DOSEE
    PROGRAM --> DRAWER
    DOSE --> DOSEGET --> L_DOSEGET --> DOSEH
    DOSE --> DOSELIST --> L_DOSELIST --> DOSEH
    DOSE --> DOSESAVE --> L_DOSESAVE --> DOSEH
    DOSE --> DOSEDELETE --> L_DOSEDELETE --> DOSEH
    PROGRAM --> PROGGET --> L_PROGGET --> PROGH
    PROGRAM --> PROGLIST --> L_PROGLIST --> PROGH
    PROGRAM --> PROGSAVE --> L_PROGSAVE --> PROGH
    PROGRAM --> PROGDELETE --> L_PROGDELETE --> PROGH
    TEMPLATES --> TEMPLATE --> L_TEMPLATE --> TEMPLATE_T
    CORR --> APPLYCORR --> L_APPLYCORR --> PROGH
    L_APPLYCORR --> DOSEH
    L_PROGSAVE --> DRAFTFB
    L_PROGSAVE --> REEFREV
    L_APPLYCORR --> REEFREV

Async Dose Generation

sequenceDiagram
    participant UI as Program / Corrections UI
    participant SaveProgram as dose-save-program-history
    participant ApplyCorrection as corrections-apply-correction
    participant BackfillQ as SQS env-dose-generate-past-dose
    participant DailyQ as SQS env-dose-save-daily-dose
    participant CorrectionQ as SQS FIFO env-icp-correction.fifo
    participant Backfill as generate-past-program-history
    participant ApplyDaily as dose-apply-daily-dose
    participant SaveDaily as dose-save-daily-dose
    participant SaveDose as save-dose-history-sqs
    participant ProgramHistory as env-program-history
    participant DoseHistory as env-dose-history
    participant ReefReview as env-reef-review
    participant EventBridge as EventBridge 01:00 UTC
    participant WS as ws-dose-history-notify

    UI->>SaveProgram: Save active, draft, or inactive program
    SaveProgram->>ProgramHistory: Persist program
    opt activating generated draft
        SaveProgram->>ReefReview: Mark draft action applied and store decisions
    end
    alt edit current active program
        SaveProgram->>ProgramHistory: Close old active as inactive
        SaveProgram->>ProgramHistory: Save edited values as new active
        SaveProgram-->>UI: Historical generated dose rows remain unchanged
    else backdated active or inactive program
        SaveProgram->>BackfillQ: Publish bounded backfill through today
        BackfillQ->>Backfill: Event source mapping invokes
        Backfill->>CorrectionQ: Publish selected-weekday dose-history writes
    end

    EventBridge->>ApplyDaily: Run daily schedule
    ApplyDaily->>ProgramHistory: Read active programs
    ApplyDaily->>DailyQ: Publish due selected-weekday elements
    DailyQ->>SaveDaily: Event source mapping invokes
    SaveDaily->>DoseHistory: Create daily dose rows

    UI->>ApplyCorrection: Apply checked ICP corrections
    ApplyCorrection->>CorrectionQ: Publish correction dose rows
    ApplyCorrection->>ReefReview: Mark correction actions applied / partially applied
    CorrectionQ->>SaveDose: Event source mapping invokes
    SaveDose->>DoseHistory: Create or merge dose rows
    DoseHistory->>WS: DynamoDB stream
    WS-->>UI: Update dose nav/detail without refresh

Queue Chains

flowchart LR
    subgraph Correction["Checked ICP Corrections"]
        APPLY["Lambda: corrections-apply-correction"] -->|"SendMessage"| CORRQ1["SQS FIFO: env-icp-correction.fifo"]
        APPLY -->|"Update action status"| REEFREV1["DynamoDB: env-reef-review"]
        CORRQ1 -->|"event source mapping"| SAVESQS1["Lambda: save-dose-history-sqs"]
        SAVESQS1 --> DOSEH1["DynamoDB: env-dose-history"]
    end

    subgraph Backfill["Program Backfill"]
        SAVEPROG["Lambda: dose-save-program-history"] -->|"SendMessage"| BACKFILLQ["SQS: env-dose-generate-past-dose"]
        BACKFILLQ -->|"event source mapping"| GENPAST["Lambda: generate-past-program-history"]
        GENPAST -->|"SendMessage"| CORRQ2["SQS FIFO: env-icp-correction.fifo"]
        CORRQ2 -->|"event source mapping"| SAVESQS2["Lambda: save-dose-history-sqs"]
        SAVESQS2 --> DOSEH2["DynamoDB: env-dose-history"]
    end

    subgraph Daily["Daily Scheduled Dosing"]
        EVENT["EventBridge 01:00 UTC"] --> APPLYDAILY["Lambda: dose-apply-daily-dose"]
        APPLYDAILY -->|"SendMessage"| DAILYQ["SQS: env-dose-save-daily-dose"]
        DAILYQ -->|"event source mapping"| SAVEDAILY["Lambda: dose-save-daily-dose"]
        SAVEDAILY --> DOSEH3["DynamoDB: env-dose-history"]
    end

Draft Program Activation

flowchart TB
    ICP["ICP processing"] --> DRAFT["Create draft program for Pro users"]
    DRAFT --> REVIEW["User reviews and edits draft"]
    REVIEW --> ACTIVATE["Activate draft"]
    ACTIVATE --> OLD["Move existing active program to inactive"]
    ACTIVATE --> NEW["Save draft as active program"]
    ACTIVATE --> FEEDBACK["Store original suggestion vs activated values"]
    ACTIVATE --> REEFREVIEW["Mark Reef Review draft action applied"]
    FEEDBACK --> FUTURE["Future suggestions use user's own history and prior outcomes"]

Notes

  • Dose and program drawers use the selected tank dosing method catalog.
  • Manual dose entry can fan out one screen into multiple dated dose-history records using dose count.
  • Program backfill honors element weekday checkboxes and does not generate future rows.
  • Editing an active program versions it instead of rewriting historical generated dose records.
  • Applying ICP correction checkboxes updates the linked Reef Review action status immediately after the correction dose write is queued. Multi-day corrections can move from pending to partially_applied before all expected correction days are applied.
  • Activating a generated draft program marks the linked Reef Review draft action as applied and records the user's accepted or overridden program values in the review decisions list.
  • Iron/Iron-X and Manganese/Manganese-X are treated as equivalent active-program signals for suggestions and charting, while retaining their distinct dose element records.