- pyproject already sets asyncio_mode=auto, so async def tests are
collected as async automatically. Removed the redundant decorator
from four files (test_i18n, test_llm_csv_parser, test_ticker_validate,
test_localization_integration); the bare async def is enough.
- StrategicLogTranslation.log_id used the _PK autoincrement type for
a non-PK FK column. Replaced with a portable BigInteger that emits
Integer on SQLite and BigInteger elsewhere — matches the migration's
sa.BigInteger() declaration.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The route's resolve-slice loop is T212-specific — it looks tickers up
against the InstrumentMap, which only has T212's universe. For the LLM
path the ticker is already Yahoo-ready (e.g. VOD.L, ASML.AS), so
sending it through resolve_slice produced spurious "could not be
resolved" warnings and dropped the positions.
Fix: ParsedPie gains a ``tickers_resolved`` flag (default False for
T212 backward-compat); _apply_mapping in the LLM path sets it True
and also extracts currency from the LLM-mapped currency_col into a
new ``ParsedPosition.currency`` field. The route branches on the flag:
LLM-path positions are kept verbatim with a best-effort InstrumentMap
lookup for nicer name/currency overrides, never dropped.
Integration test tightened to assert all 5 IBKR fixture positions
round-trip with the right currencies (USD / GBP / EUR).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Heuristic refined from the plan draft: candidate header rows must be
followed by a row containing at least one numeric token. Without this,
IBKR-style multi-line preambles (all-text rows before the real header)
would be mistaken for the header at preamble=0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>