Required member profile: username + verified email per position, gated at proof of ownership
Marty, 2026-09-16: leaders can write but 94% of positions cannot receive (47 of 771 have ever signed in to messaging, 482 messages sit 85% unread). profiles.js stores username + verified email per POSITION (one wallet holds one position, so a Triple Play holder has three; the person is the email and one email may hold several positions). Seeds the 40 emails already on file from member-alerts.json, pre-filled but unverified so confirming costs one tap. Writes are only ever accepted from a session that PROVED ownership: wallet personal_sign (messages.verifyChallenge) or the Telegram Mini App bridge. The public /my/<id> page is untouched and cannot write a profile, verified by test: all four endpoints 401 unauthenticated while /my/21 stays 200. Endpoints GET /api/public/profile, POST .../username, .../email-start, .../email-verify, plus GET /api/admin/profiles for coverage. Email codes: 6 digits, 15 min, 60s cooldown, 5/day, 6 tries. profile-gate.js is a two-step modal that cannot be dismissed, fired on dashboard boot (covers the Mini App landing) and right after a wallet sign-in. Chatbot canned answer + AI prompt updated. 28 unit tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,6 +51,8 @@
|
||||
a:()=>`Yes — every position includes a real members area: <strong>The Circle Method</strong> (10-lesson recruiting & coaching course + a real cash-out walkthrough) on the <a href="/training">training page</a>, the <a href="/replays">weekly team webinar replays</a>, your <a href="/my">live coaching dashboard</a>, <a href="/tools">promo tools</a> personalized with your invite link, printable playbooks, wallet-verified team messaging, and the Telegram companion bot + Mini App. No passwords — access is proven by the wallet that owns your position (one free signature that can't move funds), and inside the Telegram Mini App it unlocks automatically. Lesson 1 and all the how-it-works videos are public so you can inspect everything before joining.`},
|
||||
{k:['no money','cant afford','can not afford',"can't afford",'broke','they dont have','waiting on payday','no funds to join'],
|
||||
a:()=>`"No money" is usually one of three things — sort it first. (1) Most often it means "this sounds expensive/complicated": entry is ${pol()} POL${usd()||" — a small one-time amount"} — payable with a regular debit card right on the <a href="/join-now">join page</a>. (2) Sometimes it's a priority thing: send the "Pocket Change" video from <a href="/tools">Promo Tools</a> and let it do the talking. (3) If they're genuinely broke: tell them honestly "don't join yet" — never rent money, never money they can't afford to lose. Ask "when's payday?" and follow up then — their invite link doesn't expire and the team keeps building publicly while they wait. One hard rule: never pay someone's entry for them.`},
|
||||
{k:['username','set up my profile','profile','my email','email address','why do you need my email','asking for my email','confirm my email','verification code','code did not arrive','required profile','member profile'],
|
||||
a:()=>`When you sign in to your position for the first time (one free wallet signature, or automatically inside the Telegram Mini App), you're asked for two things once: a <strong>username</strong> and a <strong>confirmed email</strong>. It takes about a minute and it's required to open the member area. Why: your team leader has no way to reach you otherwise, and your email is how you get a note the moment a payout lands in your wallet. Your email is never shown to other members and never sold, and you can change it any time. The code arrives in seconds — check spam the first time. If you already gave an email for payout alerts, it's pre-filled and you just confirm it. Viewing a position's public page at <a href="/my">rmcircle.team/my</a> never asks for anything.`},
|
||||
{k:['own the level','need to own','have to buy the level','catch without','still at scintilla','upline not upgraded','sponsor not upgraded','only pays 2','only pays two','only 2 payments','seems small','2 then 4','level is your reach'],
|
||||
a:()=>`Two facts that surprise people, both straight from the contract code: (1) To catch your two matrix children's FIRST upgrade (Ascensus), you only need to be <strong>qualified with your two directs</strong> — you do NOT need to own Ascensus yourself, because the contract checks the catcher against the level the buyer is jumping FROM (Scintilla, which everyone has). Owning levels extends your REACH: catching a Fabrica payment from 2 generations down requires Ascensus, and so on — your level is your reach, which is why the team stays one level ahead of its deepest active layer. There's a 97-second video on exactly this — "Your level is your reach" — on the <a href="/training">training page</a> (Video 7). And to watch the whole discipline run on a REAL position (every upgrade funded by the catch before it), see <a href="/training#textbook-play">"The Textbook Play"</a>. (2) Yes, each depth pays a fixed count — 2, then 4, then 8, one payment per person — but each deeper generation pays <strong>twice as much per person at twice the width</strong> (full-generation value quadruples per level), generations keep filling over time via recruiting and spillover, and pass-ups from under-leveled members add catches on top. Exact numbers: <a href="/how-pay-works#exact-costs">how-pay-works#exact-costs</a> — mechanical maximums, never promised income. Want it as a printable chart personalized to YOUR position (shows which generations you're catching now vs. which need your next level)? <a href="/generation-pay">rmcircle.team/generation-pay</a> — enter your ID and print.`},
|
||||
{k:['5 million','5,090','1.7 million','1,696','running total','total through','fabrica is 8','ascensus is 4','rows shifted','one level off','which level pays','level you hold','they pay you when'],
|
||||
|
||||
Reference in New Issue
Block a user