Commit Graph

306 Commits

Author SHA1 Message Date
martbost b811b96e33 Payments feeds: post who missed a share and who got it (on-chain pass-ups and off-chain walk-ups)
Marty, 2026-09-16: make missing a payout visible. On a TierPaid with hops>0 the PassedUp events of the
same tx name the skipped positions, with the reason and how many qualifying buyers they had; the post
says the amount and who received it instead. On a Purchase whose buyer was routed past an unactivated
sponsor (movedByTx set by sponsorSyncOnEvent), the post names the sponsor who missed the whole sale
and the upline who now owns that buyer for good. Both go to the main feed and the shared payments
topic unless the events mode is 'none'.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 13:25:31 -05:00
martbost 230c250c64 Earnings pane: Trace a payment card sits at the top
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 12:30:46 -05:00
martbost a727ab1ce5 Payment trace: self-serve "who was paid, who was skipped and why" per purchase (Earnings tab + admin member card)
Marty, 2026-09-16, after the third "why didn't my sponsor get paid" thread of the day (livedreams / gracie25,
Morten / Terry's linked wallets). GET /api/my/trace?who=<#|username> (yourself, anyone up to 3 levels
below you, or your own 3 uplines) and GET /api/admin/trace?who= list every purchase the member was
part of, newest first: buyer, sponsor, package, then levels 1-3 with the recipient, the skipped
positions and the reason ("not qualified: had N of 2 qualifying buyers then"), the platform share, and
a verify link. Linked extra wallets are named after their owner. Earnings tab card "Trace a payment";
admin member card gets a "Payment trace" section; chatbot canned answer + AI prompt route the
question there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 12:24:53 -05:00
martbost dffcaa113b Never hold a sale for an unactivated sponsor: walk up to the first payable upline, referral follows the money
Marty, 2026-09-16: a purchase must never wait on a sponsor who has not linked a wallet / switched on
payouts. /api/sponsor and /me now walk the site's sponsor line upward to the first upline that is
activated with payouts on (not on the no-payout list) and the buy proceeds under them; nobody
activated -> the catch position (#1). The buyer sees a one-line notice and carries on; admin gets a
heads-up. When the position is created on-chain (MemberActivated), sponsorSyncOnEvent re-points the
buyer's stored sponsor to whoever was paid (#1 included), so the referral leaves the skipped
sponsor's line for good, then sends the pointed notices: the skipped sponsor(s) are told they lost
this referral permanently and how to switch on payouts; the sponsor who was paid is told the
referral is theirs for good and to coach the one who missed it (teach-forward). Admin lookup:
GET /api/admin/sponsor-resolve?ref=. Only a transient chain error still pauses a buy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 11:18:14 -05:00
martbost a85a198e95 Chain index keeps the full event history (was a 600-event window); one-time rescan from the deploy block
Hugh's Earnings page showed no payouts, referrals or purchases: /api/my/activity read the last 600
events and the window had moved past his Sept 9-10 activity. Ten other readers (dashboard earned
total, leaderboard, holding-tank own-buy check, admin member view, growth snapshot, P&L, burner
match) treated the same list as complete. KEEP_EVENTS 600 -> 250000; chain.rescan() rebuilds from
deployBlock without re-firing onEvent (no repeat Telegram/email), keeps real ts for known events and
estimates ts by block height for backfilled ones; runs once at boot when a filled window is found;
admin routes POST /api/admin/chain/rescan and GET /api/admin/chain/status. State file only rewritten
when events changed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:36:28 -05:00
martbost dda8c976b0 No native dialogs: Shorts report prompt -> inline reason buttons; admin drip confirms -> IAP.confirmBox
Same class of bug as the campaign #27 false report: the Shorts report was a prompt() pre-filled with
'inappropriate'. Members now tap a reason button on purpose or cancel. Script tags bumped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:23:00 -05:00
martbost 616f328db5 Report-an-ad dialog: site dialog with no default reason (was a native prompt pre-filled with "broken")
Campaign #27 (house AdRevSplit text ad) was reported "broken" with no note while the target framed
and loaded fine; the report dialog was prompt() with 'broken' as the default value, so one stray OK
filed it. Now IAP.ask with an explicit, validated reason and an optional note; common.js tag bumped
on all pages.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 10:21:53 -05:00
martbost 69d672665c Credit activity ledger: every earn and spend logged with a reason, listed under Campaigns
Hugh earned a 10-credit sign-in bonus, then bought a 280-credit extension; earned credits spend
first, so Earned read 0 and the bonus looked lost. There was no record a member could check.
Now every real credit movement writes a credit_log row (JSON store in file mode): welcome, sign-in
bonus with streak, daily claim, inbox reads, video watches, verified visits, milestone/leaderboard
bonuses, partner codes, admin/team grants, AI Copy Engine charges + refunds, flat buys (featured
run, extension, visit pack, more visits), login-ad days, and metered delivery rolled up per
campaign per day; on-chain purchased-credit spends are marked. GET /api/my/credits/activity;
dashboard shows the last 40 under Campaigns (also when there are no campaigns) with a link from
Earn credits. Chatbot canned answer + AI prompt updated; my.js tag bumped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 08:41:43 -05:00
martbost ffacf741da Extend run / visits top-up: budget = charged + this buy (release parked credits); featured row shows days left
Hugh extended his featured link and his balance fell 1,133 -> 0: the row still carried the 1,400
parked by the old add-credits button, and reactivating it reserved that budget again. Both flat
paths now set budget to spent + accrued + cost. Featured Run column shows "N of M days left"
(Hugh: "says 14 but it's actually 7") and "M days done" after the run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 08:19:33 -05:00
martbost 28bce75913 Featured links: Extend run (book more days) replaces Buy more views; visit packs top up by visits; campaign rows say paid up front and runs through
Hugh and Michael both added credits to a featured run expecting more days. Featured is a flat
daily buy, so the credits sat unspent until the run ended and their balance read 0 meanwhile.
Now: /api/my/campaigns/:id/extend books extra days after the current run (or from today if it
ended) and charges them at once; top-up refuses featured; a visits top-up buys more visits at the
pack rate, charged now; rows show paid up front + day count + runs through <date> / run ended;
explainer under the campaign table; chatbot canned answer + AI prompt updated; my.js v tag bumped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 07:38:37 -05:00
martbost b1a1cbff5e Achievement badge image rendered on the server with ffmpeg (a phone canvas sent a blank card); admin re-post route
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 03:30:01 -05:00
martbost 84d9f49d4b Held purchase: nudge the sponsor automatically (email + on-site) to link a wallet and switch on payouts, once an hour at most
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 23:43:11 -05:00
martbost b7cc06b28c Overview: click a chip in Your line at a glance to open that member's Activity panel on My line
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 18:54:00 -05:00
martbost 0da7c796b8 Campaigns: visit packs show 'paid up front' and delivered-of-total instead of a spent bar (Michael's 3,000-credit pack looked used up)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 16:13:26 -05:00
martbost 4d578fadac Lead with the $20 activation language; free-member POL earning no longer volunteered (Marty); chatbot answers truthfully only when asked point-blank
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 15:00:01 -05:00
martbost 310384cdad Credits versus POL spelled out: level 1 needs payouts on (no purchase), free members earn credits; home page block, earning page, join step 3, chatbot (Clinton's question)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 14:29:39 -05:00
martbost 66b3c83d3d Burner: when a campaign's pinned position is dry on-chain, settle the spend from another funded position on the same account (credits are pooled per account)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 12:49:16 -05:00
martbost 92e7304882 Daily growth snapshot to the Telegram payments feed and shared topic (sign-ups, purchases, POL paid, campaigns, viewing, lifetime totals); admin preview/send-now routes and settings
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 12:43:19 -05:00
martbost 8ca019a5b3 Pipeline advice follows the main wallet's buyer count (what the contract pays on); card states the linked-positions rule; chatbot knows it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 12:26:02 -05:00
martbost 560d758ed9 Pipeline: count linked positions' buyers on member cards, the way My line and badges do; show the main/positions split on the card
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 12:22:25 -05:00
martbost 02f742f90a Pipeline: sponsor follow-up board (stages from the ledger, notes/follow-ups/tags, stage messages into chat), gated by pipelineMode with a coming-soon card until launch; training cards can wait on the same switch
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 11:01:03 -05:00
martbost 56aa7418ad Payment and missed-payment notices also land in the on-site inbox (login pop-up + Messages card), with who bought, share in POL and dollars, and the transaction link
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 10:44:48 -05:00
martbost d6d771d93e Missed-payout email: tell the skipped member who bought, what they missed in POL and dollars, buyers needed, and how to close the gap
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 10:39:12 -05:00
martbost 87fa837165 Campaigns table: click sources stacked so the Clicks column stays narrow, card layout up to 900px; audit alert-day persisted, rounding-scale diffs ignored
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 07:31:16 -05:00
martbost 653c6d486e Launch checklist: launch graphics (wide + square), five day-by-day posts and a DM with link and FOUNDER code, copy buttons
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 07:12:23 -05:00
martbost c5e4dc423b Launch checklist: four promoter swipe emails with the member's link and the FOUNDER code, copy buttons
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 07:05:57 -05:00
martbost e03dbbffcf Audit: ignore history already refunded and campaigns older than the hourly log; login daily fee capped at remaining budget
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 05:45:57 -05:00
martbost 84a9063bbe Admin > Reports: counters audit (views vs delivery logs, login days charged vs shown, featured views, clicks vs views, spend vs budget), daily with Telegram alert
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 05:32:13 -05:00
martbost 86a7f83874 Login ads: charge the daily fee only on days the ad was actually shown (last_shown_day); featured views counted
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 05:26:16 -05:00
martbost 7423347c95 Featured strip: count impressions (one per viewer per campaign per hour) so featured advertisers see views and the by-hour chart
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 05:21:58 -05:00
martbost a19a3fc31e Campaigns list: stacked cards on phones with the buttons at the bottom, no sideways scroll (Jim, 2026-09-15)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 04:37:43 -05:00
martbost f155a8cc24 Sponsor hold: a named sponsor that cannot be paid (payouts off, chain lookup failed, unknown) blocks the first purchase and activation with a message and alerts the admin, instead of silently crediting the company
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 21:00:27 -05:00
martbost 1533d377cc Member updates: paced + retried Sendy opt-in checks (unknowns never cached as declines), explicit recipient list for repairs, recipients recorded on the send log
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 14:24:27 -05:00
martbost 6e8f1ccf9d Member updates: closing text after the notes (sign-off placement)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 14:21:13 -05:00
martbost 14868753c0 Member updates: saved draft (loads into the admin card, Save draft button)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 14:11:51 -05:00
martbost 024170e7f8 Member updates: audience defaults to newsletter opt-ins (Sendy list status), explicit 'everyone' option; sendy.status()
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 13:47:13 -05:00
martbost 7bb956e896 Admin > Releases: email an update to members (pick notes, intro, audience, preview, test, send; opt-outs honoured; send log)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 13:40:01 -05:00
martbost 203ebdb4bf Dashboard payload carries lineBannerUrl so the Overview launch mark counts the banner item (was 7 of 8 vs 8 of 8 on /launch)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 12:17:12 -05:00
martbost 119644d688 Line at a glance + My line: every level shows who made their $20+ buy and how many qualifying buyers of their own they have (Clinton); 60s member cache for line views
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 11:29:10 -05:00
martbost 0a19e77e7f Badges count qualifying buyers across linked positions (never regress); line chips light on any of a member's positions; buyers tile notes linked-position buyers
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 10:44:36 -05:00
martbost 1fad5bdab2 No-payout positions (siteConfig.noPayoutIds, default 25): linkage only. Buy-from picker disables them, purchases from them refused, joins routed away from them and their upline chain
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 10:30:58 -05:00
martbost e699513636 My line: show who sponsored each person on every row, all three levels
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 10:15:44 -05:00
martbost f2c155a6d2 My line: sixth grid column so the Activity button sits on the row
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 09:58:47 -05:00
martbost 201d249738 My line: Activity drop-down on every row, all three levels (last seen, stage, ads today, campaigns, link views, line, wallet, badges, Working/Quiet); Video Maker font override for local runs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 09:56:14 -05:00
martbost 32028b1e8e Video Maker: live progress bar (stage labels + ffmpeg -progress percent, queue position), page polls every 2.5s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 09:04:38 -05:00
martbost d57fc40299 Toolkit: render the Spark/Circuit/Nexus sections for members below Surge too (early return skipped them); log toolkit errors
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 08:43:35 -05:00
martbost 96760158df Video Maker: size every end-card line to the frame width; two-line headline and footer in portrait
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 07:18:51 -05:00
martbost 9316dfc0db Toolkit: ship the rest of the ladder (Spark templates + handout, Circuit Video Maker + split tester, Nexus Leader Ops, grants, co-brand, partner code)
- Spark: one-tap banner/text campaign templates aimed at the member's link (POST /api/my/toolkit/template); printable QR handout at /handout/<username>
- Circuit: videomaker.js renders every promo video/short with the member's end card + QR via ffmpeg (Dockerfile adds ffmpeg + ttf-dejavu), hosted in Spaces; split tester compares join angles
- Nexus: Leader Ops (three-level triage, stalled flags, one-click nudges), AI team broadcast kind + Send to my team, credit grants from the leader's earned pool, co-branded join page (sponsor bio for level-3 sponsors), member-funded partner code (promo_codes.funder; redemption charges the funder) + /partners?ref=<username>
- toolkit ladder all live; chatbot updated; my.js v20260914e, site.css v20260914c, join.js/partners.js v20260914a

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 07:15:43 -05:00
martbost 0f030a4943 Copy Engine: scrub en dashes too
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 06:44:11 -05:00
martbost c1f58b2acf Promo toolkit by badge + AI Copy Engine at Surge: posts, DMs, follow-ups, objection replies, emails, stories in the member's name; monthly free allowance by badge (20/60/150), then ad credits per generation; admin usage view
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 06:42:55 -05:00