Commit graph

12 commits

Author SHA1 Message Date
4c1793e4e9 docs: mobile responsiveness design spec
Captures the decisions from the brainstorm: phones-only (≤480px),
all views in scope, right-side hamburger drawer, per-file @media
blocks, hide secondary indicator columns. User opted to iterate on
the coded product rather than running through writing-plans; spec
exists so the rationale survives the session.
2026-05-28 18:30:42 +02:00
2ecf250d53 localization: digest is shared, not per-user (corrected design)
The user pointed out that the only genuinely per-user AI surface is
portfolio analysis. The strategic log AND the email digest are both
shared cycles — generated once per cycle, consumed by many users.

For the digest, this means:
- _generate_variants still produces one English variant per tone (as
  today, unchanged)
- A new helper translates each variant once per active non-en lang in
  parallel via asyncio.gather, producing a {(tone, lang): content}
  table for the duration of the job run
- The per-user send loop selects (user.digest_tone, user.lang),
  falling back to the English variant of the same tone on miss

Translation count per run = tones × non-en active langs = 3 today.
100 Italian users no longer mean 100 translation calls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 16:22:41 +02:00
8af1da12dd docs: implementation plan for Italian localization
11 TDD-style tasks: i18n service, translation helper, model + migration,
ai_log_job translation fan-out, per-user surfaces (analyse, digest),
localized /log endpoint, PATCH /api/settings/language, dropdown UI, and
final regression + manual smoke.

Per-user surfaces append "Respond in Italian." to the system prompt
(one extra line, no extra LLM call). The strategic log is generated in
English, then fanned out to translate() per active non-en language in
parallel via asyncio.gather. The /log endpoint serves the matching
translation row when present, English fallback otherwise.

Translation uses the default call_llm provider chain — no separate
cheap-model carve-out needed at DeepSeek's $0.28/M output pricing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 16:13:29 +02:00
e6308260a5 docs: localization spec — explicit no-tier-gating decision
Translate for any user with lang='it' regardless of paid/free status.
Italian + UK are the first markets, so IT availability is part of the
public-facing experience — a free-tier visitor needs to see the AI in
Italian to convert. At ~$0.005/day total cost the gating isn't worth
the savings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 16:08:28 +02:00
76f81648e5 docs: spec for Italian localization (ES/FR/DE as WIP)
Hybrid model: per-user surfaces (analyse, digest, chat) generated
directly in the target language via a "Respond in Italian" clause
appended to the system prompt. Shared content (strategic log)
generated in English as today, then post-translated and cached per
language in a new strategic_log_translations table. Translation calls
fan out in parallel with asyncio.gather so total job latency stays
bounded by max(single call).

No separate translation-model setting — DeepSeek-4-flash at $0.28/M
output is cheap enough that the routine cost is noise (~$0.005/day
with Italian only at 24 logs/day).

Users.lang VARCHAR(8) DEFAULT 'en'. Settings dropdown lists all four
options but ES/FR/DE are disabled UI-side and rejected server-side
against an ACTIVE_LANGUAGES allowlist — flipping them on later is a
one-line constant change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 15:50:10 +02:00
ae3f104fa7 docs: implementation plan for manual portfolio composition
12 TDD-style tasks: two backend endpoints (validate + historical),
router registration, dashboard markup, and five JS slices building the
edit-mode behaviour (toggle → ticker validate → Add → date-mode →
delete via delegation). CSS pass and final manual smoke close it out.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:36:32 +02:00
4c92d8a3e7 docs: spec for manual portfolio composition
Dashboard-native edit mode: EDIT button toggles in-place editing; the
add-position form has on-blur ticker validation against a new paid
endpoint, qty input, and an avg-cost / bought-on-date toggle. Only
avg_cost + qty are persisted to localStorage (no acquisition date,
no server-side holdings). Empty state replaces "Import a CSV" with
the inline form so brand-new users can act without leaving the page.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:23:23 +02:00
08b4dddcdd docs: implementation plan for LLM-fallback CSV parser
12 TDD tasks covering model + migration, fingerprint, dialect detection,
mapping validation/application, LLM extraction (mocked in tests), cache
orchestration, route wiring + paid gate, UI copy tweaks, and final
manual smoke.
2026-05-27 11:41:44 +02:00
0254515989 docs: refine LLM-CSV spec — keep real sample row, drop user attribution
- Drop first_seen_user_id; sample is anonymous by construction
- Rename sample_dummy → sample_row, store the upload's first real data
  row verbatim (one row, no totals, no other positions, no link to a
  user). Narrow, deliberate exception to the "no holdings persisted"
  invariant — gives the operator material for hand-writing future
  native parsers.
- Drop the cache self-heal behaviour; operator owns eviction. Reinforce
  the non-goal of auto-promoting learned formats to code.
2026-05-27 11:21:43 +02:00
263ecc0d3b docs: spec for LLM-fallback CSV parser
Transparent fallback after parse_t212_csv: LLM extracts a column-mapping
(not the data), result is cached globally by header fingerprint, replay
is deterministic Python. Stored dummy contains headers + synthetic row
only — no user holdings ever persisted.
2026-05-27 11:15:42 +02:00
8bc546220d docs: implementation plan for beta + paid-gap rollout
Twelve-task plan covering the BETA chip, free-tier 6h news cap, daily
+ Sunday digest job, one-click unsubscribe, settings UI, sign-up
checkbox, pricing copy, and an admin send-test-digest CLI. Each task
is TDD where feasible.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:28:39 +02:00
eabf8b6a7f docs: spec for beta indicator + paid/free gap (digests + news cap)
Design doc for three coordinated closed-beta changes: a BETA chip in
the app header, a 6h news-window cap on the free tier, and email
digests (daily for paid Mon-Sat, Sunday weekly for everyone). Draft;
awaits implementation plan.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:06:15 +02:00