# Company-channel early generation and period completeness state

## Metadata

- Date: 2026-07-31
- Scope: `arr_web/company_jobs.py`, `arr_web/static/app.js`, `arr_web/static/index.html`, `arr_web/static/styles.css`, `tests/test_arr_web_company_reports.py`, `tests/test_arr_web.py`
- Change type: generation eligibility, period-state copy and confirmation guidance
- Business-data mutation: none

## Behavior facts

- A current-month C/O period can be submitted before its calendar completion boundary. The backend still derives the
  same fixed `as_of_date`: the 10th for `01-10`, the 20th for `11-20` and natural month-end for `21-month-end`.
- The report processor continues to read the current committed Finance snapshot through that cutoff. A later source
  commit is not retroactively inserted into an existing workbook; the user can generate the same period again.
- Historical months remain rerunnable. Future report months are rejected by the backend and disabled in the frontend to
  avoid creating an empty future-month workbook.
- The right-side period state now says `周期未结束` or `周期已结束`. The state describes calendar completeness in the
  Bangkok timezone and no longer controls whether a valid current/historical period can be generated.
- An incomplete-period confirmation explicitly says the workbook uses current stored data and may need a later rerun.
- `period_release_at` remains as a compatibility alias for callers/tests; the implementation-facing name is
  `period_complete_at`.

## Verification

- `node --check arr_web/static/app.js`: passed.
- Python compilation for the changed backend/tests: passed.
- HTML parser check: passed.
- Focused suite: `28 tests`, `OK` (`tests.test_arr_web`, `tests.test_arr_web_company_reports`).
- Project virtual-environment full discovery: `348 tests`, `OK (skipped=10)`.
- No real report generation, upload, database write or business-data mutation was performed.
