# Cross-month history visibility

## Metadata

- Date: 2026-08-02
- Status: Implemented and runtime-active
- Scope: desktop daily history, monthly publications and company-channel job history
- Confidence: Verified implementation and runtime evidence
- Source: frontend/backend inspection, controlled read-only PostgreSQL queries, automated tests and isolated browser QA
- Business-data mutation: none

## Reported symptom

After the Bangkok business month advanced from July to August, users could no longer see the prior month's daily,
monthly or company-channel records from the default page state.

## Root-cause evidence

- `arr_web/static/app.js` makes both `loadJobs()` and `loadMonthly()` query `localMonth()` directly. Their history
  panels expose pagination but no visible month control.
- The company page initializes `#company-report-month` to `localMonth()` and uses the same input for C/O generation
  state/payload and history filtering. Its visible label is screen-reader-only and the control sits in the generation
  setup panel, so its history-filter role is easy to miss.
- All three backend list contracts already accept a month. Daily rows are filtered by `business_date` with a
  `created_at` fallback, monthly publications by `period_start`, and company jobs by `report_month`.
- A controlled repeatable-read query on 2026-08-02 found 30 daily jobs and four monthly publications for 2026-07,
  versus zero and zero for 2026-08.
- Local company job state retains one 2026-06 job and four 2026-07 jobs; July contains three succeeded and one failed
  job across all three C/O periods. June/July company workbooks and July monthly archives also remain on disk.

## Finding

This is a history-navigation/display-state defect, not evidence of data deletion. Entering a new month makes the
default frontend requests target an empty current month and provides no discoverable daily/monthly path back; the
company path exists but conflates generation scope with history scope.

## Implemented repair

- Added authenticated read-only `GET /api/history-months`. It merges daily/monthly counts from the guarded PostgreSQL
  repository with company job-state counts and introduces no table, migration or report-data change.
- Added consistent previous/month/next/`本月` controls to Daily Report, monthly processing and company generation
  history. Daily and monthly default independently to their latest non-empty month.
- Pagination and empty states name the selected month. Empty months expose a direct link to the latest month with that
  record type.
- Split company `生成月份` from history `查看月份`; changing either one no longer changes the other. A newly submitted
  company job moves only the history view to the submitted month.
- Monthly polling continues to read the selected viewing month. It is presentation state only and is never added to
  the report-generation contract.
- Added Chinese, English and Thai copy and responsive wrapping/focus treatment.

## Acceptance results

- A direct guarded read-only repository call returns `2026-07` with 30 daily and four monthly records. Durable company
  job state contributes four July and one June jobs; all three July histories therefore become the initial view while
  the Bangkok current month is empty.
- `node --check`, Python compilation and `git diff --check` pass. The complete project discovery passes 356 tests with
  10 environment-conditional skips.
- Isolated authenticated browser QA at 1440, 900 and 390 pixels found no document-level horizontal overflow. Tables
  retain their intentional internal scroll on narrow screens.
- Chinese, English and Thai mobile controls remain within the 390-pixel viewport. Company history was changed from
  July to empty August, exposed `查看 2026年7月`, and returned to four July rows while `生成月份` remained August.
- The production Web process on port 8766 was restarted under detached Screen after verification; `/healthz` returned
  `ready`. The isolated QA service was stopped. No upload, source activation, report generation or business-data write
  was performed.
