<!-- task=m-backtest-multi-timeframe-coverage/01_monthly_worker_core plan=2 tag=REVIEW_REVIEW_API -->
# Plan - REVIEW_REVIEW_API

## Meta

- Task: m-backtest-multi-timeframe-coverage/01_monthly_worker_core
- Milestone: agent-roadmap/phase/backtest-loop/milestones/backtest-multi-timeframe-coverage.md
- Lane: local
- Gate: G07
- Tag: REVIEW_REVIEW_API
- Status: planned
- Scope: monthly-bars follow-up completion fixes
- Parent: REVIEW_API

## Context

The second review confirmed the contract fields and some parser registrations were added, and Go checks pass. The remaining blockers are concrete and local: client parser-map test failure, missing API monthly forwarding tests, aggregator error/no-data/provider-symbol behavior, ineffective persistence/query separation test, and inaccurate review evidence.

## Archive Evidence Snapshot

- Archived plans:
  - `agent-task/m-backtest-multi-timeframe-coverage/01_monthly_worker_core/plan_local_G07_0.log`
  - `agent-task/m-backtest-multi-timeframe-coverage/01_monthly_worker_core/plan_local_G07_1.log`
- Archived reviews:
  - `agent-task/m-backtest-multi-timeframe-coverage/01_monthly_worker_core/code_review_local_G07_0.log`
  - `agent-task/m-backtest-multi-timeframe-coverage/01_monthly_worker_core/code_review_local_G07_1.log`
- Latest verdict: FAIL
- Required summary:
  - `cd apps/client && flutter test` fails in `apps/client/test/contracts/alt_contracts_test.dart` because expected parser count/list still omits the three monthly messages.
  - API monthly forwarding lacks direct handler tests for success, validation, worker errors, nil response, connect failure, and session registration.
  - `Aggregator.AggregateMonthlyBars` still suppresses storage read errors when any provenance exists.
  - No-data behavior was changed to zero-count success without the stronger contract/documentation required by the plan.
  - Provider-specific symbol matching still checks `inst.ProviderSymbols[requestedSymbol]` instead of comparing `inst.ProviderSymbols[string(provider)]` with the requested symbols.
  - The aggregator persistence test fake ignores `UpsertBar` and does not re-read monthly/daily bars separately through `GetBars`.
  - The active review evidence claimed API monthly tests existed and misidentified the Flutter failure as a pre-existing `widget_test` issue.
- Verification evidence from latest review:
  - `bin/contracts-check`: passed with no output.
  - `go test ./packages/contracts/gen/go/...`: passed, `[no test files]`.
  - `go test ./services/worker/internal/marketdata/aggregation ./services/worker/internal/socket ./services/worker/internal/contracts`: passed.
  - `go test ./services/api/internal/socket ./services/api/internal/workerclient ./services/api/internal/contracts`: passed, but this does not prove the missing monthly API tests exist.
  - `go test ./services/worker/internal/storage/postgres -run 'Test.*Bar'`: passed.
  - `git diff --check`: passed.
  - `cd apps/client && flutter test`: failed in `alt_contracts_test.dart` with `Expected: <49> Actual: <52>`.
  - `bin/lint`: exit 0 with existing `avoid_print` info diagnostics.
- Affected files to inspect first:
  - `apps/client/test/contracts/alt_contracts_test.dart`
  - `services/api/internal/socket/market_test.go`
  - `services/worker/internal/marketdata/aggregation/aggregator.go`
  - `services/worker/internal/marketdata/aggregation/aggregator_integration_test.go`
  - `agent-task/m-backtest-multi-timeframe-coverage/01_monthly_worker_core/CODE_REVIEW-local-G07.md`

## Scope

In scope:

- Update client parser-map test to include monthly parser messages and avoid hard-coded stale parser count.
- Add API monthly forwarding tests for success, validation, worker error mapping, nil response, connect failure, and handler registration.
- Fix aggregator selected-instrument storage read error handling so partial success is not silently returned.
- Resolve no-data behavior according to the follow-up plan: typed error by default, or explicit documented/tested zero-success contract if there is a stronger existing basis.
- Fix provider-specific symbol matching against `ProviderSymbols[string(provider)]`.
- Make the real aggregator persistence test record upserted monthly bars and prove monthly/daily timeframe-separated `GetBars` behavior.
- Correct review artifact evidence to match actual code and command output.

Out of scope:

- Operator YAML/JSONL handoff and roadmap checkbox mutation.
- Provider-native monthly data.
- Flutter UI work.
- Broad package boundary refactor for socket DTOs.

## Work Items

1. Client parser test:
   - Add `AggregateMonthlyBarsRequest`, `AggregateMonthlyBarsResponse`, and `MonthlyProvenance` to `expectedMessages`.
   - Prefer `expect(parsers.length, equals(expectedMessages.length))` so future list edits cannot drift from the literal count.
   - Re-run `cd apps/client && flutter test` and paste the actual output.

2. API monthly forwarding tests:
   - Add a valid monthly aggregate request helper in `services/api/internal/socket/market_test.go`.
   - Test success forwards the request unchanged and returns provenance/counts.
   - Test validation failures do not connect or call the worker.
   - Test worker errors map to typed market errors, nil worker response maps to internal, and connect failure does not forward.
   - Add `AggregateMonthlyBarsRequest` to `TestMarketHandlersRegisteredInSession`.

3. Aggregator behavior:
   - Fix provider symbol matching to compare `inst.ProviderSymbols[string(req.Provider)]` against requested symbol values.
   - Make any selected-instrument `GetBars` error fail the aggregation deterministically.
   - For no-data, either return a deterministic error or explicitly document/test why zero-count success is the intended contract. Do not leave it as an implicit success.

4. Aggregator persistence/query test:
   - Update the fake bar store to record `UpsertBar` calls.
   - Make `GetBars` filter by instrument and timeframe so the test can re-read daily and monthly bars separately.
   - Assert stored monthly bars have `market.TimeframeMonthly` and daily reads remain daily-only.

5. Review evidence:
   - Fill the active review file with accurate completion notes and actual stdout/stderr for every verification command.
   - If a command fails, record the exact failing test and whether it is in scope.
   - Do not ask the user directly. If a selected SDD/Milestone lock decision blocks implementation, fill `사용자 리뷰 요청` and stop for code-review.

## 구현 체크리스트

- [ ] Client parser-map test includes the three monthly messages and `cd apps/client && flutter test` passes or records an in-scope failure accurately.
- [ ] API monthly forwarding tests cover success, validation, worker errors, nil response, connect failure, and session handler registration.
- [ ] Aggregator provider-specific symbol matching uses `ProviderSymbols[string(provider)]`, and selected-instrument storage read errors cannot return partial success.
- [ ] No-data behavior is explicitly implemented and tested as typed error or documented zero-success contract.
- [ ] Aggregator persistence/query test records `UpsertBar` monthly bars and proves monthly/daily `GetBars` separation.
- [ ] `CODE_REVIEW-local-G07.md` contains accurate implementation notes, design decisions, plan deviations, actual verification stdout/stderr, and this final checklist item checked before review.

## Verification

- `bin/contracts-check`
- `go test ./packages/contracts/gen/go/...`
- `go test ./services/worker/internal/marketdata/aggregation ./services/worker/internal/socket ./services/worker/internal/contracts`
- `go test ./services/api/internal/socket ./services/api/internal/workerclient ./services/api/internal/contracts`
- `go test ./services/worker/internal/storage/postgres -run 'Test.*Bar'`
- `cd apps/client && flutter test`
- `bin/lint`
- `git diff --check`

## 범위 결정 근거

- The task remains local-G07 because all remaining work is deterministic source/test repair in bounded contract/API/worker/client parser surfaces.
- No `Roadmap Targets` or `Spec Targets` are claimed here because the parent task did not claim those sections and final operator handoff evidence is still out of scope.
