Commit Graph
51 Commits
Author SHA1 Message Date
tiennm99 f9f7c0f766 docs(stock): document dividend event buttons 2026-07-21 18:20:14 +07:00
tiennm99 acc291e9cc refactor(portfolio): retire completed migrations 2026-07-21 17:13:19 +07:00
tiennm99 3a8da63211 feat(portfolio): nest asset positions 2026-07-21 16:42:33 +07:00
tiennm99 fbe0d8ec53 docs(portfolio): document cost basis and P&L 2026-07-21 15:52:30 +07:00
tiennm99 6cd89e768c refactor(commands): standardize parameter conventions 2026-07-21 14:51:28 +07:00
tiennm99 d31b3d6b20 fix(commands): remove examples from command discovery 2026-07-21 13:52:53 +07:00
tiennm99 5d46057101 fix(commands): render examples conditionally with inline help code 2026-07-21 13:21:01 +07:00
tiennm99 0866ab4ed3 feat(commands): improve discovery and normalize parameters 2026-07-21 11:45:20 +07:00
tiennm99 55c4520673 test: provision MongoDB 8 with Testcontainers 2026-07-21 09:39:06 +07:00
tiennm99 1f767c596a refactor: adopt cross-platform Go development workflow 2026-07-21 09:05:20 +07:00
tiennm99 6c29d89200 docs(stock): document dividend commands 2026-07-20 17:33:10 +07:00
tiennm99 6ef9c2c4cf feat(modules): remove world cup module
The 2026 tournament has ended, so the schedule and daily digest commands
have no upcoming matches to report. Drops the module, its catalog entry,
command menu entries, and the WC_FOOTBALL_DATA_TOKEN env var.

Stored subscriber and match-cache documents are left in place.
2026-07-20 11:03:59 +07:00
tiennm99 268938d6b7 refactor(stats): remove completed startup migrations 2026-07-09 15:44:23 +07:00
tiennm99 f67aa7cb7e fix(misc): fall back wheelofnames to text reply 2026-07-09 14:38:04 +07:00
tiennm99 0bd7d71513 feat(misc): promote wheelofnames gif command 2026-07-09 13:14:11 +07:00
tiennm99 beb263318a feat(misc): add wheelofnamesbeta render API 2026-07-07 00:12:58 +07:00
tiennm99 2fc50f53ce docs: record wheelofnames implementation 2026-07-03 11:12:49 +07:00
tiennm99 ae06f10ff0 refactor: remove completed startup migrations 2026-07-01 11:42:59 +07:00
tiennm99 f73c2c61ec feat(stats): migrate command history 2026-07-01 11:10:36 +07:00
tiennm99 bdb8757dbe feat: rename lol schedule module 2026-07-01 10:38:49 +07:00
tiennm99 6eeb7ef447 feat(stats): use queryable Mongo usage records 2026-07-01 10:22:03 +07:00
tiennm99 564b6635d4 refactor(modules): remove twentyq genai integration 2026-06-29 10:07:21 +07:00
tiennm99 7d31c6d199 refactor(config): remove price URL env overrides 2026-06-29 09:23:20 +07:00
tiennm99 c3bbbd01fe feat(server): register command menu on startup 2026-06-29 01:08:51 +07:00
tiennm99 5077ff0181 feat(wc): add world cup schedule module 2026-06-29 00:59:30 +07:00
tiennm99 95d4b2227d fix(deploynotify): preserve coolify source commit 2026-06-29 00:20:04 +07:00
tiennm99 6e35c222d3 refactor(deploy): remove retired aws support 2026-06-29 00:11:42 +07:00
tiennm99 2ebff606b3 build(coolify): rename compose file 2026-06-29 00:00:22 +07:00
tiennm99 3023272047 docs(deploy): mark AWS decommission complete, record teardown deviations 2026-06-28 23:44:12 +07:00
tiennm99 9102279db6 fix(deploynotify): reference SOURCE_COMMIT in compose so it reaches container
Coolify passes predefined vars to Docker Compose via --env-file for
interpolation only; a var reaches the container solely if the compose file
references it. Removing the reference left SOURCE_COMMIT unset, so deploynotify
reported "unknown". Re-add SOURCE_COMMIT: ${SOURCE_COMMIT:-} per Coolify docs.
2026-06-28 23:30:03 +07:00
tiennm99 30c6427694 fix(deploynotify): stop clobbering Coolify-injected SOURCE_COMMIT
Declaring SOURCE_COMMIT: ${SOURCE_COMMIT:-} in compose resolved to an empty
string at parse time and overrode the value Coolify auto-injects into the
container at runtime, so gitSHA stayed empty and the owner DM was skipped.
Remove the declaration; the bot already reads SOURCE_COMMIT from the container
env at startup.
2026-06-28 23:17:27 +07:00
tiennm99 2f4b1b7504 fix(deploynotify): read commit SHA from Coolify SOURCE_COMMIT runtime env
Baking SOURCE_COMMIT as a Docker build arg never worked: Coolify exposes it
as a runtime env var, not a build arg, so gitSHA was always empty and the owner
DM was skipped. Read SOURCE_COMMIT from the container env at startup (falling
back to the ldflags-baked gitSHA for local builds), forward it via the compose
environment, and drop the dead build-arg baking.
2026-06-28 23:08:17 +07:00
tiennm99 6b807959e9 build(coolify): use SOURCE_COMMIT build arg for deploynotify
Coolify sets SOURCE_COMMIT automatically; consume it as the build arg
feeding the baked commit SHA instead of a manually-passed GIT_SHA.
2026-06-28 22:15:12 +07:00
tiennm99 3e8d6bf2a7 refactor(storage): replace KVStore with generic typed DocStore[T]
Delete the byte-oriented KVStore/VersionedStore abstraction and the
DynamoDB/memory KV backends. Add a generic typed store (DocStore[T] with
Provider/Collection/Typed) persisting each value as a flattened native
Mongo document (storedDoc[T] via bson inline) — no value envelope.

- MongoDB is the only runtime backend; memory kept for tests/local.
- All modules + deploynotify use typed stores; persisted structs carry
  bson tags == json names (incl. nested lolschedule/wordle types).
- lolschedule wraps its array/scalar values in named structs.
- migrate-dynamo-to-mongo writes the flattened shape via Typed[bson.M]
  with wrap rules; Scan/--dry-run/--verify retained.

Verified: go vet/build clean; full go test green hermetically and
in-container vs real Mongo 7 + DynamoDB Local (storage integration +
migrator e2e).
2026-06-28 18:02:11 +07:00
tiennm99 e75d9bc378 feat(storage): store mongo values as native BSON documents
Implement mongodb_value_codec to encode portfolio/gold/stock values as native
BSON documents instead of JSON-serialized byte strings. Reduces storage size,
improves query efficiency, and eliminates unmarshal overhead. Native BSON
encoding preserves int64 fidelity and enables future native-format queries.
Add NativeValueRepresentation and Int64Fidelity tests validating lossless
encoding. Update migration tool comments. Document native-value behavior
in deploy guide. Update phase-01 plan with implementation notes.
2026-06-28 12:52:48 +07:00
tiennm99 15343f6fa7 docs(selfhost): add Coolify deploy + AWS decommission guides; retire AWS docs
Add comprehensive Coolify deployment guide with MongoDB Atlas + networking setup.
Add AWS decommission runbook for safe teardown. Update AWS guides to note
deprecation. Update main README with self-hosted quickstart and architecture overview.
2026-06-28 09:58:37 +07:00
tiennm99 350f1efee1 fix(stock): drop yahoo price fallback 2026-06-25 17:16:54 +07:00
tiennm99 57356ac312 docs(gold): document VNAppMob SJC pricing and env vars 2026-06-15 10:49:19 +07:00
tiennm99 e6ad2891dd refactor(stock): rename trading module to stock
Rename the `trading` module to `stock` across code, config, and docs for
naming consistency with the sibling coin/gold modules.

- Module: internal/modules/trading -> internal/modules/stock (package,
  factory, registry key in cmd/server)
- Commands: trade_* -> stock_* (telegram-commands.json)
- Env/SAM params: TRADING_INCOME_EVENTS_* -> STOCK_INCOME_EVENTS_*
- ModulesCSV updated in template.yaml, samconfig.toml, deploy.yml
- Add cmd/migrate-stock-key: idempotent, non-destructive DynamoDB
  partition copy (pk=trading -> pk=stock) with dry-run default

Production DynamoDB data already migrated (8 keys: 2 portfolios + 6
symbol-cache rows); old trading partition retained as rollback snapshot.
2026-06-12 14:52:12 +07:00
tiennm99 8b4690df6a fix(deploy): include coin module in ModulesCSV overrides
coin was registered in the catalog and template default but absent from
the ModulesCSV override in both deploy.yml and samconfig.toml, so the
deployed Lambda never loaded it and all coin_* commands went unregistered.

Add a registration checklist to docs/deploy-aws.md to prevent recurrence.
2026-06-12 11:22:16 +07:00
tiennm99 2304657cb6 feat(gold): add gold paper trading module
Opt-in module for gold paper trading with VND currency.
Commands: /gold_topup, /gold_buy, /gold_sell, /gold_stats.
Pricing: spot XAU USD converted to VND per luong via GoldPrice.org + ExchangeRate-API.
Features: FX caching, dust normalization (1e-9), HTTPS-only URL validation,
per-user key locking, namespace isolation from trading module.
2026-06-11 17:13:02 +07:00
tiennm99 340172206a feat: add trade income events check 2026-06-05 14:21:38 +07:00
tiennm99 daeaf0c605 chore: drop CF→AWS migration tooling and stale JS-port references
The CF→AWS data migration (closed 2026-05-16) is long done and the
tooling isn't wired into any production path. Remove the one-shot binary,
its support package, and the migration runbook.

In live code, replace 'JS-parity' / 'same shape as JS' / 'cross-runtime
KV migration' comments with the real, stable reason for each behavior
(wire-format invariant, null-vs-zero distinction, CloudWatch alarm field
name, etc.). 24 files touched across lolschedule, loldle, wordle, twentyq,
trading, misc, util, server, metrics, ai, keylock.

- delete cmd/migrate_cf_data/
- delete internal/migration/
- delete docs/cf-to-aws-migration-runbook.md
2026-05-25 09:39:17 +07:00
tiennm99 efe79be9ac docs(security): audit reports + IAM least-privilege plan + project policy
Captures the 2026-05-18 security review session output:

- plans/reports/code-reviewer-260518-1019-security-aws-infra.md
- plans/reports/code-reviewer-260518-1019-security-go-app.md
- plans/reports/researcher-260518-1019-security-dependencies.md
- docs/deploy-aws-free-tier-guide.md (adds free-tier hard rule +
  accepted security trade-offs as project standards)

Plan for the two HIGH-severity findings (F1, F2) targeting
github-deploy-miti99bot OIDC role: plans/260518-1019-iam-least-privilege/.
Plan was red-team-reviewed (15 findings applied) and validate-interviewed
(4 decisions recorded). Zero unresolved contradictions. Implementation
not yet started; phase 1 is standalone and lowest risk.

Other audit findings (F3 CORS, F4 root handler, F5-F16) deferred to
future commits; rationale in audit report.
2026-05-18 16:50:38 +07:00
tiennm99 1f5f304041 ci(deploy): auto-register Telegram webhook + commands after SAM deploy
Append two steps to .github/workflows/deploy.yml that POST setWebhook
and setMyCommands against the freshly-deployed Function URL, reading
credentials from SSM. Mirrors `make telegram-setup` but inlined to
avoid the Makefile's --profile admin assumption.

Token and webhook-secret are masked via ::add-mask:: before any echo.
Jobs fail loudly on Telegram API errors via `jq -e .ok`.

Mark the manual setWebhook snippets in docs/deploy-aws.md and
docs/deploy-aws-free-tier-guide.md as break-glass.
2026-05-16 10:55:43 +07:00
tiennm99 39491d134e docs(plans): close cf→aws phases 01-02 and amend locked decisions
- phase-01: mark complete; record live D1+KV inventory outcome (9 durable
  KV keys, trading source is KV not D1, retired modules skipped)
- phase-02: mark complete; toolchain verified end-to-end against prod CF
- phase-03: rewrite to flat KV copy (D1-transform branch dropped)
- plan.md: amend staging-only decision to permit pre-cutover bulk import
  against the live table while it has no AWS-served writes
- runbook: lock matrix and trading source, document Phase 02 commands
2026-05-16 10:33:46 +07:00
tiennm99 75e936096d fix(plans): align cf-to-aws migration and cutover docs
Lock the Cloudflare-to-AWS migration matrix and runbook against the live DynamoDB runtime shape, and gate AWS cutover on verified migration parity instead of assuming a symmetric rollback.
2026-05-15 23:54:06 +07:00
tiennm99 0502ea28d2 fix(ci): pin deploy role ARN for OIDC auth
The deploy workflow no longer relies on a missing AWS_ACCOUNT_ID secret,
preventing invalid assume-role ARNs and matching the repo's documented AWS setup.
2026-05-15 22:36:15 +07:00
tiennm99 dbfee38232 Fix AWS Lambda deploy setup 2026-05-15 22:18:27 +07:00
tiennm99 f3b9891a54 refactor: rename module to miti99bot, canonicalize AWS deploy path
Rename:
- Go module github.com/tiennm99/miti99bot-go → github.com/tiennm99/miti99bot
- CloudFormation stack miti99bot-aws-port → miti99bot
- Drop "port", "Cloud Run", "GCP", "cutover", "Phase NN" framing from
  active code and docs — project reads as canonical AWS-Lambda from now on.

AWS deploy guide + flow fix:
- New docs/deploy-aws-free-tier-guide.md — Ubuntu 24.04 ARM64 onboarding
  with project-local venv (pip awscli + sam-cli), SSM secrets via read -s,
  idempotent OIDC provider + role creation, $1 budget alarm.
- Drop sam build from the pipeline — provided.al2023 + makefile builder
  expects a Makefile in CodeUri (build/lambda/, the output dir), so the
  step always fails. sam deploy --template-file template.yaml now reads
  the raw template and zips build/lambda/ directly.
- Rollback section rewritten — use continue-update-rollback /
  cancel-update-stack / git-SHA redeploy. Drop the broken
  --use-previous-template recipe.
- DynamoDB free-tier row corrected (on-demand is 2.5M read / 1M write
  request units, not 25 RCU/WCU).

Updated:
- README.md fully rewritten (drops port/legacy framing, lists modules,
  points new users at the free-tier guide).
- aws/README.md retitled "AWS account setup", phase numbers stripped.
- Makefile / .github/workflows/deploy.yml — sam deploy flow.
- samconfig.toml — stack_name = "miti99bot".
- Go comments — Cloud Run → Lambda, Cloud Scheduler → EventBridge
  Scheduler, Cloud Logging → CloudWatch Logs.
- Struct field GCPProject → FirestoreProject (env GOOGLE_CLOUD_PROJECT
  unchanged).

Plus advisory reports under plans/reports/ from the code-reviewer +
researcher passes that informed the fixes.

Verified: go vet ./..., go build ./..., go test ./... all green.
2026-05-13 22:05:38 +07:00