📜 Cập nhật gần đây

Những gì chúng tôi vừa phát hành. Kaching được cập nhật nhiều lần mỗi tuần, mọi thay đổi đều được theo dõi công khai trên git.

polish Wave-2 — F-6 today verdict+order, all getUserLang sites, smoke green
2026-05-21

Operator: '繼續修,追求完美' (continue, pursue perfection). All Wave-1 queued items shipped + live-verified in zh-Hant via Telegram Web. F-6 — /today now correct - bot.command('today'): ORDER BY desc(ev_score) — was returning insertion-order top-3 which on staging happened to be 3 RED zero-EV traps. Now surfaces GREEN/YELLOW/RED in EV-desc order. - card-line FTL × 5 locales: add {$verdict} param so e

e7b3dc0
fix user.lang honored across bot handlers + bundle rebuild + deploy:staging branch fix
2026-05-21

Staging smoke test 2026-05-21 found 8 bugs. This commit lands 4 in-session fixes; 4 remain queued. Fixed (this commit): F-1 i18n bundle staleness packages/i18n/src/bundle.generated.ts was 2026-05-20 00:43; iter-7/8 FTL edits never re-bundled. translate() returned empty for any new key → ctx.reply(empty) silently rejected by Telegram. Bundle now regenerated (262 keys × 5 locales). F-3 dep

10de914
docs v2.1 — N-bot future architecture appendix
2026-05-21

Per operator question: can a second formal bot point to same content backend? Can staging bot be promoted to another prod? Answer: yes. Appendix documents the path; deferred to Phase 6+ (not blocking Phase 3 single-bot cutover). Sections: - Why N-bot is well-supported (Telegram user_id global, etc.) - 3 code changes (env vars + webhook routing + schema migration 0010) - Push routing pseudocode (r

2e7fbdd
docs v2 — full-replacement strategy with mars2049.online as canonical domain
2026-05-21

Operator pivot 2026-05-21: - User accepts full brand swap (was: worried about losing 10-20k users by changing name). Original team unreachable → no chat_id list will arrive. - Goal: leverage every existing asset, replace everything else. Discovery delta (over v1): - `mars2049.online` is operator-owned (GoDaddy, exp 2027-03), DNS already on Cloudflare (brady.ns + iris.ns). 1.7 years runway, ze

b386c7d
docs inventory all Kaching Keychain entries
2026-05-21

Per operator request: sync all records / passwords / knowledge (including ad marketing config) to Keychain; produce single index doc. Added 17 operational references to Keychain alongside the 11 true-secret entries already there: True secrets (11): - Cloudflare API Token (pre-existing) - kaching-bot-token (legacy staging) - kaching-mars2049-bot-token (Mars2049 prod) - kaching-bot-webhook-secret

c4f10e3
docs Mars2049 → Kaching bot migration transition plan
2026-05-21

Discovery phase complete (read-only; no Telegram-side or worker-side changes made). Captured via Bot API + @BotFather UI inspection through Chrome MCP. Token + old webhook URL stashed in Keychain only. Key findings (legacy state): - Bot id 7949511493, username @Mars2049_Bot, display "Mars2049_Bot" - has_main_web_app: true; menu button URL = https://mars-launch.miniapp.mobi/ with label "Play"; s

934f540
feat client-side reward completion + dashboard config wired
2026-05-21

Pulled from operator's GigaPub partner dashboard (app 760): - BLOCK_ID = "main" (the single Active placement in app 760) - PROJECT_ID = 760 (the app id, used by client SDK script tag) - Integration model per docs.giga.pub/integration-guide.html: pure client- side reward. `<script src="https://ad.gigapub.tech/script?id=760">` loads SDK; `window.showGiga('main').then()` fires after user watche

47ca995
feat swap Adsgram+Monetag → GigaPub (single provider)
2026-05-21

User direction: actual ad provider is GigaPub, not Adsgram/Monetag (which were design-doc placeholders we never signed up for). Code changes: - packages/ad-mediation/src: AdEnv now exposes GIGAPUB_BLOCK_ID + GIGAPUB_HMAC_SECRET (was ADSGRAM_* + MONETAG_*). AdNetwork type union is just 'gigapub' now. requestAdSlot routes to gigapub when block id is set, no_fill otherwise. handleCompletion no

2ef9708
deploy create kaching-app Pages + 3 HMAC secrets + script drift fix
2026-05-21

User: "整個 Kaching 產品可以送審上架了的要求 ... 你自己去鑰匙圈找" — full authority to use CF API token from Keychain and execute operator-tier setup that I CAN do (skipping items that require buying domains, signing up to third-party services, or having two Telegram accounts). Closed prod blockers: - Cloudflare Pages `kaching-app` project created (production-branch=main); mini-app-web built + deployed; all 9 critic

5258915
polish close final 2 caveats — C-4 multi-lang + E-1 slot.report
2026-05-21

User: "全自動,到完成" — autonomous run to finish all closure-plan items. C-4 (api-wired 9→10) — multi-lang data-model Path A: - migrations/0009_bonuses_multilang.sql: 10 NULL-able TEXT columns added to bonuses (title_{en,ja,vi,zh_hans,zh_hant} + summary_{...}) so the spec at 13-data-model.md matches code; rollback = drop or ignore (NULL fallback) - packages/db/src/schema.ts mirrors - apps/collector

8f7d7b3
polish close 5/7 design-docs-alignment caveats under full authority
2026-05-21

User invoked polish-loop --scope=design-docs-alignment --authority=full --apply-closure-plan=2026-05-21. Took recommended Path A on each decision item. Closed: - D-2 (dark-pattern-free 9→10): responsible-gambling.astro:40 + terms.astro:28 rewritten — removed over-promised "we honour their network's GAMSTOP/OASIS" line; replaced with truthful aggregator-stance ("not a licensed operator; /set

ace46b3
docs inventory design-docs-alignment caveats + per-item resolution path
2026-05-21

Audit of docs/polish-locks/design-docs-alignment.lock.yaml § caveats: - 2 SUPERSEDED (C-3 markers 5/6 closed via FLEET-N-024 tracker; C-5 M10 API done in 12b) - 1 partial-superseded (D-1 Cashback M14 — iter-6 RG gate + $20 cap landed; structural residual still user A/B) - 4 real-open (C-1 plural expansion 0.3d / C-2 CI guard 0.5d / C-4 multi-lang data-model 1.0d / D-2 GAMSTOP retract 0.1d) - 1 ext

28831b5
ops provision 5-locale commands + description + short_description via Bot API
2026-05-21

Closes "Telegram bot register" operator action in docs/external-actions.md. All commercial-grade bot directory metadata now set without computer-use intervention (Bot API calls only). ## Completed via Bot API today (session 454) - `setMyCommands` × 5 locales (default + zh + en + ja + vi), 11 cmds each: start / today / search / invite / streak / quest / subscribe / lang / settings / help / sto

e5aebf4
docs close M-6 marker — link 00-scenarios.md:344 + tracker to commit 21c2611
2026-05-21

Companion to 21c2611 (feat: DEFAULT_RTP_BY_GAME constant) — closes the documentation side of FLEET-N-024 M-6 marker: - 00-scenarios.md:344 ⚠️ TO VERIFY → 📌 RESOLVED with full house_edge defaults table + override path + cross-link to code - FLEET-N-024-tracker.md M-6 row status → ✅ closed; summary 4/6 → 5/6 closed; open count 2 → 1 (only M-4 slot.report API remains, external dependency defe

d7d2890
feat FLEET-N-024 M-6 — DEFAULT_RTP_BY_GAME constant + collector wiring
2026-05-21

Closes M-6 (house_edge defaults) — the last code-side marker in FLEET-N-024. M-4 (slot.report API shape) remains open, deferred to Phase F collector sprint (requires external API probe, not codifiable in this cycle). ## Changes - `packages/ev-calculator/src/index.ts`: NEW exported const `DEFAULT_RTP_BY_GAME` with industry-standard RTPs per FLEET-N-024 § M-6 product decision (slot 0.96, table

21c2611
fix /user/me composite — add missing stats sub-object + provision prod secrets
2026-05-20

Self-audit revealed two drifts between claimed-shipped and actual-running: ## /user/me composite missing `stats` Actor A iter-7 P3 claim: 8-key composite (profile + preferences + stats + streak + quests + cashback + badges + rg_status). E2E probe confirmed only 7 keys — stats was named in the return shape but never wired. Fixed: 3 sub-query aggregate via c.env.DB.prepare() (1 D1 sub-request): -

e2a7d7f
ops Phase 1 ASO + locale drafts — 3 platforms × 3 locales
2026-05-20

Drafts written for product-ops Phase 1 (ASO + locale): - 01-aso/tg-miniapp.md: BotFather description + about + commands + welcome message × zh-Hant / en / ja - 01-aso/web.md: meta title + description + OG cards for /, /bonuses, /operators × zh-Hant / en / ja - 01-aso/seo.md: 10 target keywords × 3 locales (manual since no GSC MCP); content pillars (EV literacy / freshness / trust); on-pag

a61ef45
ops Phase 0 pre-submit audit — DOGFOOD product-ops v1.0
2026-05-20

First real run of product-ops skill on this project. Phase 0 actions: - Triaged gitleaks 15 hits → all false-positive (i18n key field patterns: badge-streak-30-criteria etc.). Added .gitleaks.toml allowlist for the specific paths + regex patterns. Re-scan: 0 leaks. - Leveraged iter-8 polish-loop work (CHANGELOG + 4 design docs, 1,617 lines) for release-readiness / editor/vc/vet-eye / i18n-n

85686d2
deploy 3 Workers × 2 envs + R2 lifecycle + smoke green
2026-05-20

iter-8 Actor A + B all deployed end-to-end. Smoke tests green; DLQs bound; R2 lifecycle applied to 4 buckets. Fixed scripts/apply-r2-lifecycle.sh — wrangler 4.x renamed `r2 bucket lifecycle put` → `set`. Verified-by-session: 421_gambli_path-a-iter-5-me-search-3-band

63fc6f0
fix storage GC + perf N+1 + Queue consumer + R2 lifecycle
2026-05-20

Actor B closes the perf + storage gaps surfaced by iter-8 audit (D1 perf 6 / storage-GC 6 / quota-guards 6 — alongside Actor A P0 critical fixes in 4ae74c6). ## Storage GC (4 sub-tasks) ### SG-A — gdpr-finalize.ts cron (NEW) Runbook docs/design/26-runbooks/gdpr-delete-request.md:41 referenced this file but it didn't exist. Created daily 03:00 UTC cron in apps/collector-cron: - Query users WHERE

b1a618e
fix 14 critical fixes — dailyMaintenance bug + RG enforcement + webhook HMAC + bot drift
2026-05-20

iter-8 4 deep critics (D1 perf / storage-GC / quota-guards / product-completion) all returned 6-7 (NOT just polish — found real production bugs + security gaps). Actor A pass closes the 14 P0 items. ## CB-1 — dailyMaintenance bug (PRODUCTION-CORRUPTING) collector-cron line 329 `UPDATE bonuses SET status='expired' WHERE status='active'` — missing `AND expiry < unixepoch()`. EVERY cron tick wiped a

4ae74c6
deploy mini-app-api both deployed; mini-app-web staging up
2026-05-20

Phase F-5 staging deploy complete. Path A end-to-end live on staging. ## Deployments - mini-app-api staging: kaching-mini-app-api-staging (v a1b5a7be...) - mini-app-api prod: kaching-mini-app-api-prod (v e4ae1eb3...) - mini-app-web staging: https://8eef930e.kaching-app-staging.pages.dev ## Smoke verification - /healthz: 200 OK (both envs) - /api/v1/public/stats: 200 OK + valid JSON - /api/v1/

fe58233
docs F-3 + F-4 — 14-api-contract polish + FLEET-N-024 4/6 closed
2026-05-20

Iter-7 api-wired-deep critic returned 7 (estimated 9). Closed remaining doc gaps in one pass. ## F-3 — Spec sync (14-api-contract.md +599/-117) ### Path renames spec → prod-aligned (4 patterns) - /user/quests → /user/quest (singular) - /user/quests/:id/claim → /user/quest/claim with body {user_quest_id} - /user/ad/serve → /user/ad/request - /user/stars/invoice → /user/subscribe/invoice - Removed

9d4bcc5
chore final pre-pivot hex sweep — 4 leftover literals after bulk re-skin
2026-05-20

Phase F-2 actor pass found the bulk UI re-skin already in (commits f83c8df + 8fbba5b from concurrent session). 4 pre-pivot literals slipped past: - apps/mini-app-web/public/styles/tokens.css:29 — `--tg-theme-destructive-text-color: #d14e4e` → `#ef4444` (Path A canonical red) - apps/mini-app-web/src/pages/bonus/[id].astro — unused `verdictColorClass` removed (typecheck hint cleanup) - apps/mini-ap

b0ed2e9
design cosmic hero + /bonuses index page + zh-Hant copy split
2026-05-20

- index.astro: rebuilt with cosmic SVG radar hero (Path A), copy split via isZh heuristic (5-locale Fluent bundle migration to follow) - bonus/[id].astro: editorial detail layout, sticky claim CTA with emerald glow restraint (one per viewport) - BonusCard.astro, Layout.astro: cosmic accent integration - bonuses.astro (NEW): /bonuses listing landing page wired to API - path-a-patterns.css (NEW)

f83c8df
feat Path A regression-lock — pre-pivot hex can't sneak back
2026-05-20

After the 2026-05-19 Path A pivot (Kaching Green #28a85c → Kaching Emerald #10b981, deep navy #0a1730 → #0a0f1f), the spec tokens lived only in prototypes/tokens/{tokens.ts,tokens.css} with no automated guard against accidental rollback. With 100+ files touching design docs in this round, a stale paste could easily reintroduce the retired palette unnoticed. Add @kaching/brand-tokens — tiny packag

8fbba5b
fix 0006 v2 — sentinel-zero pivot after FK rebuild rejection; staging + prod migrated
2026-05-20

v1 0006_user_rg_and_nullable_age.sql attempted SQLite table-rebuild to make `users.age_confirmed_at` NULL-able. D1 rejected at commit: FOREIGN KEY constraint failed: SQLITE_CONSTRAINT (extended: 7500) D1 enforces FK at tx commit even with `PRAGMA foreign_keys=OFF`. Other tables (user_preferences / streaks / quests / cashback_credits / referrals / etc.) reference users.telegram_id → rebuild chur

a974a28
design Path A T1/T2/T3 landed via autonomous Claude Design driver — layout-hierarchy 9→10
2026-05-20

polish-loop v4 design-driver-protocol executed end-to-end via Chrome MCP: navigate claude.ai/design → existing Kaching prototype → paste pushback message per `docs/design/design-requests/web-templates-pathA-followup.md` → poll → click Share → Handoff to Claude Code → capture URL → curl bundle → extract → README banner. ## Bundle - URL: https://api.anthropic.com/v1/design/h/vhBo6CUjY1TyErmKK6iZtw

a06d24c
api 4 production handler fixes — /auth/verify shape + /user/age-confirm + /user/me composite + /user/badges
2026-05-20

Iter-7 api-wired-deep critic (score 7, was estimated 9) found 4 spec↔prod handler gaps causing real user-facing failures. ## P1 — /auth/verify return shape (PRODUCTION-BLOCKING) Pre: returned {jwt, user} Post: returns {jwt, expires_at, user_id, age_confirm_required, rg_status: {self_excluded_until, cooloff_until}} The Mini App deep-link age gate (02-miniapp-spec § 1.5) requires age_confirm_requi

0a49f18
i18n 5-locale polish — banned emoji, ja brand voice, vi calques, zh loan-syntax, EV/wagering inline gloss
2026-05-20

Iter-7 three deep critics (i18n-localization 8 / api-wired-deep 7 / copy-clarity-per-locale 7) flagged ~15 mechanical locale text issues across 5 .ftl files. This commit addresses ALL locale polish; production code + spec sync fixes are next. ## Brand voice violations fixed ### Banned emoji 🎉 (brand spec 31-bot-uiux.md:70 hard ban on 🎉🎊🥳🤑) - subscribe-success / vip-upgraded / svip-upgraded

fe0390d