📜 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.
Pre-launch ops blocker fix — caught during session 497 audit before any user-facing launch. Three production gaps that would have broken first-user experience: 1. **Bot webhook pointed at STAGING worker** — @kaching_777_bot was delivering all updates to `kaching-bot-webhook-staging.workers.dev` which talks to staging D1 (35 bonuses, test data). New users opening the bot would have hit a
bot-webhook wrangler.toml top-level IS the prod config (matches mini-app-api + collector-cron pattern). The `--env prod` flag broke prod deploy because there's no `[env.prod]` block — only `[env.staging]` exists at the bottom. This caused all of Wave-6 through Wave-11 to deploy successfully to staging but silently fail on prod (bot-webhook only; the other 3 services were fine). Users on prod were
streak-break-warning push fires when a user's streak ends in ~1h. The previous copy just said "open /today to keep it alive" — leaving the Stars-sink product (Streak Freeze, 25⭐ = 1 missed-day save) invisible at the exact churn moment. New copy adds the Streak Freeze option as a clear alternative: "Open /today (free) — or buy 🛡️ Streak Freeze for 25⭐ to skip a day." 5 locales (en / ja / vi / zh
The "📺 Skip via ad" button copy made the rewarded-video path look like a chore. New copy puts the reward FIRST: "📺 Get 50⭐ now (watch ad)" — explicit value exchange instead of vague "skip". UI: 4 ad-flow strings now localized (was hardcoded English) - miniapp-quest-ad-btn = "📺 Get {$reward}⭐ now (watch ad)" - miniapp-quest-ad-loading = "📺 Loading ad…" - miniapp-quest-ad-done = "✓ {$reward}⭐ e
Wave-8 retracted the "AI personalized rec" claim because no code actually delivered a personalized ranking. Wave-9 ships the real signal so we can honestly re-add the claim. NEW: bot-webhook personalizeForSvip(bonuses, userId, env) - Inputs: ev_score-sorted candidate list + user id - Reads last 30d of affiliate_clicks for this user (1 D1 select, fail-soft) - Derives: - claimed_operator_ids: Set
Iter ledger: 5.6 → 8.2 → 8.2 verify → code apply → 9.0/10 LOCK ✅ Per-critic final: Core 9.0 / Revenue 9.0 / Spec-Code 9.5 / UX 8.5 / OpSafety 9.0 All 5 BLK closed; full ledger in closure doc. Upstream skill fixes (in dotfiles-private LIVING F-W21-008 + product-genesis Phase 0 Q3/Q4/Q5 HARD follow-ups): future projects catch this class of "做到最後發現付費點不好" at design time before code ship. Post-LOCK o
Two-track polish: (a) push notifications now i18n-bundled + show per-user cashback (b) all hollow-promise copy retracted — only list code-enforced perks PUSH ENGINE — i18n + per-user cashback in every push body - packages/push-engine: imports translate from @kaching/i18n + rateForTier from @kaching/cashback-engine. renderDailyText / renderFomoText / renderRealtimeGreenText all switch from
Polish pass to make the value proposition concrete at every decision moment: bot card, /me page, /subscribe shop, quest reward. PUSH ENGINE — VIP-only real-time GREEN alert - packages/push-engine: new runRealtimeGreenAlert(env) — queries fresh bonuses (verdict=GREEN, scraped_at >= now-6h), anti-joins push_events for idempotency under collector double-runs, fans out to VIP/SVIP cohort by cou
Iter-3 commit f740e40 missed this file (Read-first error). Now applied: 19-cost-model.md § 4 Channel 3 (Ad serving): - Old: 50% MAU × 2 ad/day × $0.01 = ~$13k/mo (abstract placeholder) - New: GigaPub $1.83 CPM × 50% MAU × 5 cap × 30day / 1000 = ~$2.75k/mo rewarded at 200k MAU Mature - Subtotal revised: ~$20k/mo → ~$10k/mo (honest conservative) - Total Mature Revenue: $99k → $89k (down 10%) - Ne
Per polish-loop iter-2 report (8.2/10, below 8.5 LOCK). 3 doc drift items: 1. 32-miniapp-uiux Invite tab (line 348-349, 370): - VIP perks listed were stale (獨家 partner bonus / Bonus 早 2hr) — these were never the code-shipped perks. Replaced with KCH-F-102 real perks (10% cashback / 3× push / ad-free). - Subscribe CTA stale: "300 Stars/wk" → "180 Stars/月" (reconciled to KCH-F-
Per polish-loop iter-1 BLK-5 + memory feedback_no_silent_destruction.md: production code changes require explicit user authorization. This doc contains: - Full proposed diff for packages/stars-payment/src/index.ts (new export handleSubscriptionPaused — ~40 lines) - D1 schema check (paused_at column verify, migration if needed) - Webhook router update for apps/bot-webhook/src/index.ts - Test sce
Per polish-loop product-grade agent report (5.6/10 warning band, 5 BLK). 4 doc patches applied this iter; BLK-5 code fix proposed separately. BLK-1 (core-experience-loop 4/10): No dedicated subscription screen/paywall → NEW docs/design/35-monetization-storyboard.md (per-trigger [前/當/後] + 6 entry surface + 3 conversion benchmarks + alternative-choice impact + stream priority resolved: KC
Per LIVING F-W21-008 (Kaching 2026-05 retrospective): Phase 0 was skipped when project started. Per spec-retrofit Phase 0' pattern, inferring answers from existing design docs + code, then aligning against new Phase 0 Q3/Q4/Q5 HARD follow-ups to find design depth gaps. 3 root causes for "做到最後發現付費點+廣告點不好": 1. 🔴 Backend flow complete but UX storyboard missing (no [前/當/後] for triggers) 2. 🔴 3 mone
Operator pushed the value-prop question hard: '為什麼用戶要看廣告,為什 麼要付費,你能說服你自己嗎?' Audit found: subscription was an empty flag — vip_tier='vip' stored in D1 but NO code read it. Free + VIP got identical experience: same cashback rate (flat 5%), same daily push (1×), same 'Skip via ad' CTAs. I could not honestly recommend the sub. This commit ships three real, code-enforced perks together. Each gated by
Operator: '看廣告目前是什麼模式?' Honest audit found TWO critical bugs that meant Mini App client side was largely broken since day 1. F-11 (CRITICAL): window.__API_BASE__ never injected - _api.js fell back to https://api.kaching.gg which is NXDOMAIN - Every Mini App in-Telegram API call (quest/claim/streak/me/badges/ cashback/ad-request/ad-completion) silently died - Fix: Layout.astro injects 'window.__
Operator: '信息推送要正常' (push notifications must work) — verified end-to-end on staging Telegram. New ops endpoints in bot-webhook (Bearer INTERNAL_API_TOKEN gated): - POST /internal/trigger-push?task=daily — fires runDailyPush manually (still honors isLocalHour cohort filter — only fires for users in their 8am local window) - POST /internal/trigger-push?task=fomo — fires runFomoPush manually -
Operator: '追求完美,確保所有都完成' — pursue perfection, all features verified. Deep dive surfaced 3 more real bugs + 1 mock smell. F-Stars (CRITICAL): Stars 'subscriptions' were one-time charges packages/stars-payment/src/createInvoice missed subscription_period parameter per Bot API 7.7+. Telegram saw the invoice as one-time digital good not recurring sub. User paid 180⭐ → 30 days → nothing. Fix:
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
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
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
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
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
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
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
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
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
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
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
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
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