Commit Graph
104 Commits
Author SHA1 Message Date
tiennm99 e4b24f03e4 feat(misc): polish wheel beta animation 2026-07-06 13:48:51 +07:00
tiennm99 0097e897a0 fix(misc): satisfy wheel spin lint 2026-07-06 13:23:12 +07:00
tiennm99 924bc6322d feat(misc): improve wheel beta spin animation 2026-07-06 13:12:22 +07:00
tiennm99 9b728aa41e fix(misc): hold wheel beta result 2026-07-06 12:31:37 +07:00
tiennm99 9dc99d4abc fix(misc): label wheel beta slices 2026-07-06 12:26:53 +07:00
tiennm99 ea99b6c119 fix(misc): tune wheel beta timing 2026-07-06 12:16:15 +07:00
tiennm99 7c239cd976 fix(misc): improve wheel beta animation 2026-07-06 11:47:41 +07:00
tiennm99 5dad4179ce feat(misc): add wheelofnames beta animation 2026-07-06 11:41:20 +07:00
tiennm99 0e39b49e8b feat(misc): add random command and wheel draft streaming 2026-07-06 11:26:50 +07:00
tiennm99 4398395e2a feat(lol): add EWC schedule support 2026-07-06 09:40:01 +07:00
tiennm99 e1e4c594db feat(gold): show buy and sell prices in portfolio 2026-07-03 13:34:34 +07:00
tiennm99 54f20f28d2 feat(misc): add wheelofnames command 2026-07-03 11:12:34 +07:00
tiennm99 df8924d562 refactor(lol): remove match cache cleanup logic 2026-07-01 16:53:11 +07:00
tiennm99 8ba3da62c1 feat(lol): make match cache fallback-only 2026-07-01 16:41:59 +07:00
tiennm99 3a58a2e776 refactor: remove completed migration logic 2026-07-01 16:20:30 +07:00
tiennm99 dce115f3f5 perf(stats): simplify username lookup index 2026-07-01 16:06:03 +07:00
tiennm99 e9322fb6bc feat(lol): expire match cache 2026-07-01 13:40:37 +07:00
tiennm99 9a264f40f5 feat: refine command names and behavior 2026-07-01 13:19:42 +07:00
tiennm99 ae06f10ff0 refactor: remove completed startup migrations 2026-07-01 11:42:59 +07:00
tiennm99 126b70dfa0 fix(stats): merge legacy trade command counts 2026-07-01 11:21:11 +07:00
tiennm99 f73c2c61ec feat(stats): migrate command history 2026-07-01 11:10:36 +07:00
tiennm99 d90af97d55 feat(commands): simplify portfolio command names 2026-07-01 10:53:52 +07:00
tiennm99 b86aca6b1d feat: rename wc schedule commands 2026-07-01 10:42:56 +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 0aaf9acf60 fix(cron): claim daily pushes by ict day 2026-07-01 09:31:58 +07:00
tiennm99 c2311bc569 fix(lolschedule): silence empty daily push 2026-06-30 09:01:40 +07:00
tiennm99 0d866cb7a0 fix(wc): send silent daily push at midnight ict 2026-06-30 08:56:01 +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 5077ff0181 feat(wc): add world cup schedule module 2026-06-29 00:59:30 +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 3aa07ac16d feat(modules): log every command with input, sender, chat, result
Emit one structured line per authorized command: input text, sender id +
username, chat type/id/title (DM vs group), and outcome (INFO ok / ERROR with
err). Replaces the prior error-only log; denied commands stay silent.
2026-06-28 22:52:55 +07:00
tiennm99 d84c7b619c fix(server): retry webhook clear on startup past transient empty-body error
Telegram's edge can return an empty body on the first request after a cold
container start, failing the single best-effort DeleteWebhook with 'unexpected
end of JSON input' and leaving a stale webhook that 409s getUpdates. Retry up
to 5 times with a 1s backoff so long polling is reliably unblocked.
2026-06-28 22:33:34 +07:00
tiennm99 5bfee58964 refactor(server): drop HTTP /cron route; run crons in-process only
The in-process scheduler is the sole cron trigger on self-host, so the
/cron/{name} HTTP endpoint and its CRON_SHARED_SECRET are dead surface.
Reduce the HTTP server to GET / (health) and remove the cron secret config,
SSM binding, and now-unused timeout.
2026-06-28 22:15:04 +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 79e438546f refactor(storage): replace value-bytes CAS with version-field optimistic lock
Replace content-addressed storage versioning (CAS) with explicit version fields
on documents. Versions are managed via optimistic locking pattern: Get returns
version, Put increments atomically and fails if version mismatch detected.
Callers (portfolio, lolschedule) updated to use GetVersioned/PutVersioned,
simplifying concurrency handling and eliminating CAS overhead.
2026-06-28 12:52:32 +07:00
tiennm99 5f8819ae46 refactor(stock): remove FireAnt income-events command
Drop FireAnt-based /income command per AWS decommission plan. Simplifies
stock module and reduces third-party dependencies. Updates telegram-commands.json.
2026-06-28 09:58:25 +07:00
tiennm99 f66dd61a8b feat(cron): add in-process cron scheduler
Add robfig/cron-based task scheduler with per-UTC-date idempotency guard. Enables
scheduled jobs (e.g., daily price checks) without external scheduler dependency.
Module interface updated to support cron registration.
2026-06-28 09:58:12 +07:00
tiennm99 c1530af018 refactor(stock): drop symbol cache 2026-06-25 17:30:57 +07:00
tiennm99 350f1efee1 fix(stock): drop yahoo price fallback 2026-06-25 17:16:54 +07:00
tiennm99 35372d25d7 fix(stock): expose ssi quote response errors 2026-06-25 16:12:12 +07:00
tiennm99 e15f6ae1f1 fix(stock): use ssi price provider 2026-06-25 15:51:33 +07:00
tiennm99 d02a110d8e fix(modules): fetch stats prices sequentially to reuse pooled connections
Parallelizing the per-symbol fetches opened N simultaneous TLS handshakes into
an empty connection pool. On the memory-constrained Lambda (256MB ~0.15 vCPU)
those CPU-bound handshakes thrashed and each exceeded the per-fetch timeout, so
every ticker rendered "(no price)". Sequential fetches reuse the price client's
keep-alive connection (one handshake), which is why the code was sequential by
design.

- revert stock and coin stats loops to sequential (keep the reply-budget
  sub-context and 3s per-fetch timeout)
- log per-symbol fetch failures instead of silently swallowing them
2026-06-25 14:28:25 +07:00
tiennm99 97f376025d fix(modules): reserve reply budget and cap price-fetch timeouts in stats handlers
Stats handlers reused the single bounded update context for both upstream
price fetches and the final Telegram reply, while per-upstream HTTP timeouts
equalled the whole-handler budget. One slow upstream drained the deadline and
the reply failed with "context deadline exceeded" (observed on /stock_stats).

- add chathelper.FetchContext: fetches run under a child context that reserves
  a tail of the deadline for the reply, which is sent on the original context
- cap kbs/coin/gold/vnappmob HTTP timeouts at 3s so one hung upstream cannot
  consume the reply budget
- fetch held stock/coin prices concurrently (bounded) so total latency tracks
  the slowest single fetch instead of their sum; per-symbol failures degrade to
  a "no price" line and the summary still sends
2026-06-25 14:07:59 +07:00
tiennm99 68cc1486ea fix(coin): improve sell insufficient message 2026-06-20 09:52:23 +07:00
tiennm99 919fa74665 fix(coin): sell command accepts USD amount with dust and zero-price guards
- Change /coin_sell semantics from quantity to USD amount

- Add price-validity and dust-quantity guards to buy/sell

- Improve usage text and error messages

- Add tests for invalid amount, dust, zero price, and insufficient holdings
2026-06-16 17:27:39 +07:00
tiennm99 9eef87ad52 fix(coin): use Binance public market-data endpoint data-api.binance.vision 2026-06-15 14:09:11 +07:00
tiennm99 67387ff350 fix(gold): parse VNAppMob JWT object wrapper 2026-06-15 12:20:40 +07:00