mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-08-24 12:26:58 +00:00
docs: correct stale module claims and document amlich edge cases
README omitted /lol_subscribe and /lol_unsubscribe, called gold opt-in though an empty MODULES loads every catalog module, and left out both the amlich 1800-2199 bound and the lol module's PandaScore token. The gold factory comment repeated the same opt-in claim. Promote the lunar algorithm decision record and known-issue list into docs/ so they survive cleanups of plans/.
This commit is contained in:
@@ -9,12 +9,12 @@ Atlas via long polling and an in-process cron scheduler.
|
||||
|---|---|
|
||||
| `util` | `/help`, `/info`, `/stickerid` |
|
||||
| `misc` | `/ping`, `/ping_stats`, `/random`, `/wheelofnames`, `/ff`, `/the_answer`, `/trongtruonghop` + `/tth`, `/trongtruonghopvng` + `/tthvng` disclaimers |
|
||||
| `amlich` | Vietnamese lunar calendar: `/amlich` (dương lịch → âm lịch, defaults to today), `/duonglich` (âm lịch → dương lịch, `nhuan` flag for leap months); dates accept `d`, `d/m`, or `d/m/yyyy` — missing parts fill from today in the input's calendar |
|
||||
| `amlich` | Vietnamese lunar calendar: `/amlich` (dương lịch → âm lịch, defaults to today), `/duonglich` (âm lịch → dương lịch, `nhuan` flag for leap months); dates accept `d`, `d/m`, or `d/m/yyyy` — missing parts fill from today in the input's calendar. Years 1800–2199 only |
|
||||
| `wordle` | Daily Wordle game |
|
||||
| `loldle` | League-of-Legends "guess the champion" |
|
||||
| `lol` | Pro-match schedule (`/lol`, `/lol_tomorrow`, `/lol_this_week`, `/lol_next_week`) + daily push |
|
||||
| `lol` | Pro-match schedule (`/lol`, `/lol_tomorrow`, `/lol_this_week`, `/lol_next_week`), per-chat digest opt-in (`/lol_subscribe`, `/lol_unsubscribe`) + daily push at 08:00 ICT |
|
||||
| `stock` | VN-stocks paper trading |
|
||||
| `gold` | Gold paper trading (opt-in; VNAppMob SJC buy/sell VND/luong) |
|
||||
| `gold` | Gold paper trading (VNAppMob SJC buy/sell VND/luong) |
|
||||
| `coin` | Crypto paper trading in USD (Binance -> Coinbase -> CoinGecko price fallback) |
|
||||
| `stats` | `/stats` (top commands), `/stats users`, `/stats user <username>`, `/stats cmd <command_name>` |
|
||||
| `monkeyd` | `/monkeyd_crawl <url> [font_size]` export a monkeydd.com novel as a PDF, `/monkeyd_tags <url>` list its tags as hashtags |
|
||||
@@ -39,6 +39,17 @@ Future commands must follow the
|
||||
[command parameter conventions](docs/command-parameter-conventions.md). Keep
|
||||
command metadata, handler usage text, tests, and documentation aligned.
|
||||
|
||||
### Lunar calendar accuracy
|
||||
|
||||
`/amlich` and `/duonglich` port Hồ Ngọc Đức's truncated-Meeus algorithm, the
|
||||
same one behind most Vietnamese calendar apps, over the years 1800–2199.
|
||||
Output matches published Vietnamese calendars on every verifiable date. It
|
||||
diverges from Chinese-calendar sources in some years by design (Vietnam uses
|
||||
UTC+7, China UTC+8), and month boundaries from 2072 on carry irreducible
|
||||
uncertainty. See
|
||||
[amlich known issues](docs/amlich-known-issues.md) for the decision record and
|
||||
the full edge-case list.
|
||||
|
||||
### Stock corporate events
|
||||
|
||||
`/stock_events <ticker> [days]` lists SSI iBoard corporate actions for a VN
|
||||
@@ -213,6 +224,8 @@ internal/systemstate/ shared `system` collection helper for startup migra
|
||||
third_party/monkeyd-crawler/ git submodule; resolved by a go.mod replace directive
|
||||
compose.yml Coolify self-host stack (single bot service)
|
||||
docs/deploy-coolify-selfhosted.md Self-host deploy and operations guide
|
||||
docs/command-parameter-conventions.md Command parameter syntax rules
|
||||
docs/amlich-known-issues.md Lunar algorithm decision and known edge cases
|
||||
```
|
||||
|
||||
## Run locally
|
||||
@@ -252,6 +265,11 @@ The bot uses long polling, so a local run talks to Telegram directly — no
|
||||
`ngrok` or public URL. The server clears any existing webhook on startup. The
|
||||
dev bot is created manually; its token is injected through the environment.
|
||||
|
||||
The `lol` module reads its schedule from the PandaScore REST API and needs
|
||||
`LOL_PANDASCORE_TOKEN` (free tier). Without it every `/lol*` fetch fails while
|
||||
the rest of the bot runs normally. See [`.env.example`](.env.example) for the
|
||||
full variable list.
|
||||
|
||||
Persistent MongoDB locally (auto-selected when `MONGO_URL` is set):
|
||||
|
||||
```sh
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# Amlich: Algorithm Decision and Known Issues
|
||||
|
||||
Reference for `internal/modules/amlich`. Records why the current conversion
|
||||
algorithm was chosen and which edge cases it is known to get wrong or to
|
||||
report differently from other sources.
|
||||
|
||||
## Algorithm
|
||||
|
||||
The module ports Hồ Ngọc Đức's truncated-Meeus algorithm (`lunar.go`), the
|
||||
de-facto standard behind essentially every Vietnamese calendar app and site.
|
||||
Supported range is 1800–2199; both commands reject anything outside it with an
|
||||
explicit message.
|
||||
|
||||
A full Meeus *Astronomical Algorithms* ch. 49 implementation (25 periodic + 14
|
||||
planetary new-moon terms, apparent solar longitude with nutation and
|
||||
aberration, Espenak–Meeus piecewise ΔT, month 11 anchored by bisecting the
|
||||
winter solstice) was written and diffed against the current one over every day
|
||||
of 1800–2199 — 146,097 days. They disagree on 270 days (0.18%), which is 9
|
||||
lunations, every one a new moon within ±2 minutes of 17:00 UT (= midnight at
|
||||
UTC+7).
|
||||
|
||||
Two of those nine are historically verifiable, and the current algorithm is
|
||||
right on both: 20/6/1944 (published Vietnamese calendar: 30/4 nhuận) and
|
||||
7/7/1967 (30/5 Đinh Mùi). Vietnam used the Chinese-calendar convention of UTC+8
|
||||
before the 1968 reform, which puts these new moons unambiguously on the next
|
||||
civil day; the higher-precision engine lands on the wrong side of both. The
|
||||
remaining seven fall in 2072–2199, where ΔT uncertainty exceeds the disputed
|
||||
margin, so neither engine can claim them.
|
||||
|
||||
Both dates are pinned in `lunar_test.go` `knownDates` so a future
|
||||
"higher-precision" rewrite cannot silently flip them.
|
||||
|
||||
## Known issues
|
||||
|
||||
**Razor-edge lunations from 2072 on.** New moon within ~2 minutes of UTC+7
|
||||
midnight, so the month boundary — and therefore output within roughly 30 days
|
||||
of it — may differ by one day from future official tables: 09/12/2072,
|
||||
15/11/2077, 07/05/2130, 26/05/2150, 17/05/2159, 22/01/2175, 26/01/2199. Not
|
||||
fixable today, only documentable. The bot gives no caveat for these dates.
|
||||
|
||||
**ΔT extrapolation drift.** The two-branch polynomial diverges from actual
|
||||
Earth rotation (ΔT has been roughly flat near 69 s since ~2016 against
|
||||
predicted growth), reaching minutes-level error past 2100. It only matters near
|
||||
a razor-edge boundary, but it means everything from about 2070 onward is a
|
||||
best-effort prediction.
|
||||
|
||||
**Solar-term precision.** `sunLongitude` returns true longitude without
|
||||
nutation or aberration, a systematic offset of about 10 minutes in solar-term
|
||||
timing. A solstice or trung khí within ~10 minutes of midnight could shift
|
||||
month numbering or leap-month placement for a whole lunar year. The 1800–2199
|
||||
diff found zero such occurrences — low probability, high impact.
|
||||
|
||||
**No override for decreed changes.** The module is pure astronomy. A
|
||||
state-decreed deviation or rule change would diverge silently. None has
|
||||
occurred since 1968.
|
||||
|
||||
## Correct output that gets reported as a bug
|
||||
|
||||
**Divergence from Chinese-calendar sources.** Vietnam uses UTC+7 and China
|
||||
UTC+8, so the two calendars genuinely differ in some years — historically 1985
|
||||
and 2007, upcoming around 2030 and 2053. Users cross-checking against a Chinese
|
||||
source will see a mismatch that is not an error.
|
||||
|
||||
**`/duonglich` defaults inside leap months.** A bare day argument fills in the
|
||||
current month as a regular month; the leap month requires the explicit `nhuan`
|
||||
flag. In leap years such as 2028 (leap 5) and 2031 (leap 3) this is ambiguous
|
||||
to the user, but the output is correct for what was entered.
|
||||
|
||||
## Handled, with regression tests
|
||||
|
||||
- Lunation overshoot that returned lunar day 0 (07/05/2054, 09/04/2062) —
|
||||
fixed, covered by `TestSolarToLunar_LunationOvershoot`.
|
||||
- Leap month 11 in 2033, the classic stress case — correct, covered by
|
||||
`TestLeapMonthTable`.
|
||||
- Gregorian 2100 being a non-leap year — handled by the JD arithmetic.
|
||||
- Out-of-range years — rejected cleanly at the 1800/2199 bounds.
|
||||
|
||||
## Open questions
|
||||
|
||||
1. Should the seven razor-edge lunations from 2072 on carry a caveat in the
|
||||
bot's reply? Currently silent.
|
||||
2. Should pre-1968 UTC+8 be modelled explicitly? The current algorithm matches
|
||||
the published record on both known razor-edge cases by numeric coincidence
|
||||
rather than by rule. An explicit UTC+8 mode would change roughly 1/24 of
|
||||
pre-1968 month boundaries and diverge from the standard everyone else uses —
|
||||
not worth doing unless a user reports a concrete mismatch.
|
||||
3. Revisit the ΔT model if the flat IERS trend persists. A data-driven update
|
||||
only pays off near razor-edge boundaries.
|
||||
4. Watch for state calendar bureau tables published past 2100; they would be
|
||||
the first ground truth for the 2072+ disputes.
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"github.com/tiennm99/miti99bot/internal/modules"
|
||||
)
|
||||
|
||||
// New is the gold paper-trading module factory. It is opt-in through MODULES
|
||||
// and keeps its portfolio state separate from the stock module.
|
||||
// New is the gold paper-trading module factory. It keeps its portfolio state
|
||||
// separate from the stock module.
|
||||
func New(deps modules.Deps) modules.Module {
|
||||
s := newState(deps.Store)
|
||||
return modules.Module{
|
||||
|
||||
Reference in New Issue
Block a user