Commit Graph
369 Commits
Author SHA1 Message Date
tiennm99 d62e8a72b3 feat(monkeyd): export monkeydd.com novels as PDF via /monkeyd_crawl
Add the monkeyd module, which crawls a novel and sends the rendered PDF back
as a Telegram document. Crawling and rendering come from the monkeyd-crawler
submodule, resolved through a go.mod replace directive.

The command is admin-only and restricted to monkeydd.com: one run makes
hundreds of outbound requests over minutes, and the extractor only understands
that site. Exports run one at a time and on a detached goroutine, because
handlers are dispatched synchronously and an inline crawl would block every
other command.

The runtime image gains DejaVuSans; font discovery probes system paths and the
distroless base ships none, so PDF rendering would otherwise fail in
production. CI checks out submodules and the builder copies the submodule
go.mod before go mod download, which needs it to resolve the build list.
2026-07-29 23:07:23 +07:00
tiennm99 dbdbceda30 docs(lol): add leaguepedia score enrichment research and plan
Research: after lolesports began marking matches completed without
publishing results, evaluated independent score sources. Established
that wrappers of lolesports (lolesportsapi.com, Pupix, Apify) inherit
the gap, and that getCompletedEvents/getStandings are equally stale, so
only a source with its own ingestion helps. Leaguepedia is the only free
candidate; commercial providers run $2k-10k/mo.

Plan: 4 phases for filling missing gameWins/outcome from Leaguepedia's
Cargo API. lolesports stays authoritative for schedule and for any score
it does publish. Additive throughout - every failure path degrades to the
existing "score pending" line.

Joins on team name plus date rather than team codes: Riot already sends
Team.Name matching Leaguepedia's Team1/Team2, which removes the code
mapping table and the per-split OverviewPage handling that the research
had flagged as the main maintenance burden.

Phase 1 is a hard gate. Fandom rate-limited and then refused the
connection during research, so it was never confirmed that Leaguepedia
actually holds the scores Riot is missing. That check can cancel the plan.

Plan is pre-validation. A verification pass found three items not yet
recorded in the files: slices.ContainsFunc in phase 4 has no precedent in
this repo (explicit loops are the house style), the TTL index citation
should read startup.go:35-52, and the Bo2 tie handling in phase 3 is
unnecessary - all 26 allowlisted-league events are Bo3 with zero ties.
2026-07-26 12:57:56 +07:00
tiennm99 f151e68c0a fix(lol): omit score when a finished match has none published
lolesports drives event.state off the broadcast timeline but fills
result.outcome and result.gameWins from a separate per-game ingestion
path. A match therefore reads as "completed" for hours before gaining a
score, and in that window every team carries {"outcome": null,
"gameWins": 0}.

The renderer used `Result != nil` as its has-a-score test, which cannot
catch this: the result object is present, only its contents are empty.
The absent gameWins fell through to Go's zero value and printed as a
literal 0, so an unscored series was reported as a definitive draw
("MKOI 0-0 KC") with neither side bolded.

Gate the score on a declared outcome instead, and render unscored
finished matches as the matchup alone with a pending marker. An outcome
on either side is enough to trust the score - it proves the ingestion
ran. inProgress keeps rendering 0-0, which is truthful for a live series
that has not resolved its first game.

Also collapses the score extraction both branches duplicated into
shared helpers.
2026-07-26 09:16:39 +07:00
tiennm99 c34199c08b docs(stock): record stock info delivery 2026-07-23 12:27:12 +07:00
tiennm99 cba943d74d feat(stock): add detailed stock info command 2026-07-23 12:27:12 +07:00
tiennm99 5d1e676d72 docs(stock): finalize stock-events delivery 2026-07-23 10:08:47 +07:00
tiennm99 73ee9a1fa8 docs(stock): add stock-events plan artifacts 2026-07-23 10:05:44 +07:00
tiennm99 3d1a3d88bb feat(stock): add stock events lookup 2026-07-23 10:03:41 +07:00
tiennm99 26a6e7444b docs(stock): record dividend retirement workflow 2026-07-22 18:56:07 +07:00
tiennm99 02bef11e1c fix(stock): retire dividend command and migrate stats 2026-07-22 18:55:57 +07:00
tiennm99 9c0cdde83b docs(portfolio): document mobile column layout 2026-07-22 17:36:29 +07:00
tiennm99 2da872f237 fix(portfolio): tighten mobile column formatting 2026-07-22 17:36:29 +07:00
tiennm99 fda0bbd0b1 feat(stock): persist per-user dividend history 2026-07-22 16:17:29 +07:00
tiennm99 b6f6361c94 feat: format compact portfolio numbers 2026-07-22 12:27:52 +07:00
tiennm99 a1f0a682fc fix(stock): note currency in portfolio title 2026-07-22 10:59:40 +07:00
tiennm99 f2dd69f8bc docs: remove completed implementation records 2026-07-21 19:13:34 +07:00
tiennm99 cb4520830a docs(deploy): refresh persisted storage layout 2026-07-21 19:13:28 +07:00
tiennm99 bc2d3528cb refactor(coin): retire completed startup cleanup 2026-07-21 19:13:23 +07:00
tiennm99 907d07f0af refactor(metrics): remove unused AI counters 2026-07-21 19:13:15 +07:00
tiennm99 c9fa4ac6dd chore(stock): log dividend event checks 2026-07-21 18:50:48 +07:00
tiennm99 39955669a8 fix(coin): remove stale dividend cursor fields 2026-07-21 18:50:30 +07:00
tiennm99 4b15ff1634 docs(stock): document dividend event buttons 2026-07-21 18:20:14 +07:00
tiennm99 372d45be89 feat(stock): add dividend event buttons 2026-07-21 18:19:50 +07:00
tiennm99 aeec01a6d0 docs(stock): research dividend event APIs 2026-07-21 17:13:43 +07:00
tiennm99 2078363421 refactor(portfolio): retire completed migrations 2026-07-21 17:13:19 +07:00
tiennm99 2f6b65103e feat(portfolio): nest asset positions 2026-07-21 16:42:33 +07:00
tiennm99 c2d3738d6a docs(portfolio): document cost basis and P&L 2026-07-21 15:52:30 +07:00
tiennm99 78ded3d7a4 feat(portfolio): track stock and coin cost basis 2026-07-21 15:52:05 +07:00
tiennm99 93bef70f18 refactor(commands): standardize parameter conventions 2026-07-21 14:51:28 +07:00
tiennm99 f3751ccdd5 fix(commands): remove examples from command discovery 2026-07-21 13:52:53 +07:00
tiennm99 5fb394b942 fix(commands): render examples conditionally with inline help code 2026-07-21 13:21:01 +07:00
tiennm99 7872077c4b feat(commands): improve discovery and normalize parameters 2026-07-21 11:45:20 +07:00
tiennm99 f3c046f985 test: provision MongoDB 8 with Testcontainers 2026-07-21 09:39:06 +07:00
tiennm99 ae8064fd2b refactor: adopt cross-platform Go development workflow 2026-07-21 09:05:20 +07:00
tiennm99 5a1d889648 docs(stock): document dividend commands 2026-07-20 17:33:10 +07:00
tiennm99 a444815f34 feat(stock): add ratio dividend commands 2026-07-20 17:32:37 +07:00
tiennm99 ec7aa74bff 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 296ce97633 feat(misc): add protected /ff giving-up template
Replies with a fixed Vietnamese copypasta for when T1 starts losing, built
from the local community's running jokes. Protected, so it stays out of the
public command menu like the other gated commands.
2026-07-19 20:09:22 +07:00
tiennm99 a68cc1162f feat(modules): match commands case-insensitively
Mobile keyboards autocapitalize, so a typed /Ping silently did nothing and
read as the bot being broken. Registered names are lowercase-only per
validateCommand, so folding case cannot make two commands collide, and the
canonical Command.Name still drives stats, metrics, hooks, and logs.
2026-07-19 20:09:16 +07:00
tiennm99 d86cdd0fbb build: update Go toolchain and crypto dependency 2026-07-09 18:18:01 +07:00
tiennm99 5600a80ae0 refactor(stats): remove completed startup migrations 2026-07-09 15:44:23 +07:00
tiennm99 a59e9a32c3 fix(misc): fall back wheelofnames to text reply 2026-07-09 14:38:04 +07:00
tiennm99 ba50511a83 feat(misc): promote wheelofnames gif command 2026-07-09 13:14:11 +07:00
tiennm99 e703b5a4f7 refactor(misc): share disclaimer template 2026-07-09 11:34:53 +07:00
tiennm99 482a737309 feat(misc): add VNG disclaimer aliases 2026-07-07 11:19:27 +07:00
tiennm99 8199a870ea docs(plans): remove plan artifacts 2026-07-07 10:19:51 +07:00
tiennm99 93272a35e7 feat(coin): allow upstream-supported tickers 2026-07-07 10:12:29 +07:00
tiennm99 54b1747d7b feat(misc): add wheelofnamesbeta render API 2026-07-07 00:12:58 +07:00
tiennm99 194caf17eb fix(lol): rename next week command 2026-07-06 20:46:10 +07:00
tiennm99 00a5ff1c0b feat(lol): add tomorrow and next-week schedules 2026-07-06 20:20:07 +07:00