Internal Documentation internal
TalkIDE internal documentation

Tento dokument specifikuje founder-gated invite cascade pro TalkIDE alpha. Systém umožňuje Mirkovi (founder) manuálně kontrolovat rychlost růstu uživatelské základny synchronně s kapacitou Anthropic API tieru. Vychází z rozhodnutí v ADR-020.


1. Founder-Controlled Cascade

Kaskáda probíhá ve fázích dle reálné kapacity platformy:

[Founder — Mirek] přes admin tool

    │  Fáze 1: vygeneruje 5–10 invite tokenů (founder-direct seeding)

[Gen 0: Seeded users]
  invites_granted = 0 (nemohou ještě nikoho zvát)

    │  Fáze 2: Mirek vidí v dashboardu "máme rezervu"
    │          → bulk grant: každý Gen 0 dostane 3 invites

[Gen 0 pozve Gen 1]
  ~30 nových userů v dávce (záleží na aktivitě Gen 0)

    │  Fáze 3: Mirek monitoruje load
    │          → postupně grantuje další invites Gen 0 + Gen 1

[Gen 1 pozve Gen 2]
  ... atd.

Klíčový princip: invites NEJSOU udělované automaticky na základě žádného triggeru. Mirek rozhoduje ručně — capacity recommender (viz sekce 4) mu dává doporučení, ale finální rozhodnutí je vždy na něm.


2. DB Schema

2.1 Tabulka invites

CREATE TABLE invites (
  id                 BIGSERIAL PRIMARY KEY,
  token              VARCHAR(64) UNIQUE NOT NULL,        -- UUID v4
  issued_by_user_id  BIGINT REFERENCES users(id),        -- NULL = founder-direct seeding
  issued_to_email    VARCHAR(255),                        -- optional pre-binding na email
  claimed_by_user_id BIGINT REFERENCES users(id),
  issued_at          TIMESTAMPTZ NOT NULL,
  expires_at         TIMESTAMPTZ NOT NULL,               -- default: issued_at + 30 dní
  claimed_at         TIMESTAMPTZ,
  revoked_at         TIMESTAMPTZ,
  revoked_reason     TEXT,
  status             VARCHAR(20) NOT NULL                -- PENDING | CLAIMED | EXPIRED | REVOKED
);

CREATE INDEX idx_invites_token ON invites (token);
CREATE INDEX idx_invites_status ON invites (status);
CREATE INDEX idx_invites_issued_by ON invites (issued_by_user_id);

issued_by_user_id = NULL identifikuje founder-direct tokeny (Fáze 1 seeding). Tyto tokeny nemají “generaci” zdroje — jsou kořenem kaskády.

2.2 Tabulka user_invite_quota

CREATE TABLE user_invite_quota (
  user_id         BIGINT PRIMARY KEY REFERENCES users(id),
  invites_total   INT NOT NULL DEFAULT 0,
  invites_used    INT NOT NULL DEFAULT 0,
  last_grant_at   TIMESTAMPTZ
);

invites_remaining = invites_total - invites_used. Uživatel může vytvořit invite jen pokud invites_remaining > 0.

2.3 Tabulka invite_grants (audit log)

CREATE TABLE invite_grants (
  id               BIGSERIAL PRIMARY KEY,
  user_id          BIGINT NOT NULL REFERENCES users(id),
  granted_by_admin_id BIGINT NOT NULL REFERENCES users(id),
  count            INT NOT NULL,
  reason           TEXT,                                 -- volný text, např. "30 days active, Gen 0 batch"
  granted_at       TIMESTAMPTZ NOT NULL
);

Každý admin grant je auditovaný. Umožňuje dohledat “kdo, komu, kolik, proč”.

2.4 Rozšíření tabulky users

ALTER TABLE users
  ADD COLUMN invite_generation INT NOT NULL DEFAULT 0;
  -- 0 = founder-seeded (Gen 0), 1 = pozváni Gen 0, 2 = pozváni Gen 1, atd.

Generace se nastaví při claimu invite: generation = issuer.invite_generation + 1. Founder-direct tokeny mají issued_by_user_id = NULL → nový user dostane generation = 0.


3. Admin Tool Requirements

Admin tool je web view (admin-only route v talkide-fe, dostupná jen pro role ADMIN) nebo CLI script jako fallback pro alpha. Obsahuje čtyři panely.

3.1 Users panel

SloupecZdrojPoznámka
Emailusers.email
Generationusers.invite_generation
Joined atusers.created_at
Last activekonverzace nebo session timestamp
Weekly spendsum(api_usage.cost_cents) / aktuální týdenlive
Invites remaininguser_invite_quota.invites_total - invites_used

Akce:

  • Bulk select + grant invites: vybrat N userů → zadat count + reason → INSERT invite_grants
    • update user_invite_quota.invites_total
  • Per-user revoke invites: snížit invites_total (nezruší již odeslaná PENDING pozvání)
  • Suspend: dočasné zablokování přístupu (bez smazání dat)
  • Ban: permanentní revoke + flagging

3.2 Invites panel

FunkcePopis
Generate founder-direct tokensVytvoří N invite záznamů s issued_by_user_id = NULL; výstup = tokeny pro ruční distribuci
List pending invitesFilter: PENDING / CLAIMED / EXPIRED / REVOKED
Per-token detailKdo pozval, komu, kdy vydáno, kdy claimed
Audit trailTimeline: vydání → claim → případný revoke

3.3 Capacity dashboard

Hlavní rozhodovací plocha pro growth management:

WidgetZdroj dat
Weekly spend progress barglobal:monthly_used_cents (Redis, live)
Active users this week (WAU)COUNT DISTINCT user_id z api_usage / posledních 7 dní
Pending outstanding invitesCOUNT invites WHERE status = ‘PENDING’
Capacity recommenderAlgoritmus z sekce 4

Barvy progress baru kopírují Mara fatigue palette: zelená (< 50 %), žlutá (50–70 %), oranžová (70–85 %), červená (> 85 %).

3.4 Mara analytics (read-only)

Podporuje PM rozhodování o budgetu a invite grantech:

MetrikaVýpočet
Top spenders this weekTOP 10 users BY sum(cost_cents) za 7 dní
Cache hit ratesum(cache_read_tokens) / sum(input_tokens + cache_read_tokens)
Avg cost per sessionavg cost per conversation_id
OutliersUživatelé s 3× vyšším spend než medián za týden
Model distribution% requestů na Sonnet vs. Haiku (proxy pro fatigue distribution)

4. Capacity Recommender Algorithm

Algoritmus běží na FE (pure výpočet z dat panelu) — nedává binding rozhodnutí, dává doporučení pro Mirka.

headroom = (weekly_budget - current_weekly_spend) / weekly_budget
projected_new_spend = avg_weekly_spend_per_active_user × pending_outstanding_invites × 0.6
  -- 0.6 = odhad WAU rate nových userů (konzervativní)

if headroom > 0.50 AND (current_weekly_spend + projected_new_spend) < 0.70 × weekly_budget:
    zobraz: "Bezpečné rozdat 30+ invites — kapacita je dostatečná"

elif headroom > 0.30:
    zobraz: "Rozdat 10–15 invites — monitorovat přes víkend"

elif headroom > 0.15:
    zobraz: "POZOR: max 5 invites — jsme blízko capacity cap"

else:
    zobraz: "STOP: žádné nové invites — nejdřív tier upgrade"

Výstup je barevně odlišen (zelená / žlutá / oranžová / červená) a zobrazuje konkrétní čísla (current headroom %, projected WAU po grantu, days to cap).


5. Anti-Abuse Rules

5.1 Per-user pending limit

Max 5 PENDING invites současně na jednoho uživatele. Pokud user má 5 nevyžádaných tokenů a chce vytvořit další, BE vrátí 422 s INVITE_PENDING_LIMIT error kódem. Uvolní se až po claimu nebo expiry existujícího tokenu.

5.2 Burner email blocklist

Při claimu invite BE ověří email invitee proti blocklist doménám (10minutemail, mailinator, guerrillamail, throwam.com a ~100 dalších). Claim na burner doménu → 422 INVITE_BURNER_EMAIL. Blocklist uložen v application.yml (nebo externím config souboru) — aktualizovatelný bez kodu.

5.3 IP rate limit na claim

Max 3 invite claims z jedné IP adresy za 24 hodin. Implementováno v gateway vrstvě (Spring Security nebo rate-limit filter). Překročení → 429 INVITE_IP_RATE_LIMIT.

Cíl: zamezit bulk signupům přes proxy/VPN s rotujícími tokeny.

5.4 Rapid invite notification

Pokud uživatel odešle 5 invites za méně než 1 hodinu → automatická notifikace adminovi (email + dashboard flag). Není automatický block — Mirek rozhodne, jestli je to legitimní.


6. Signup Flow s Invite Tokenem

[User] obdrží invite link: https://talkide.app/join?token=<UUID>


[FE] GET /api/invites/validate?token=<UUID>
    ├── 200 OK: { valid: true, issued_to_email: "..." nebo null }
    ├── 404 NOT_FOUND: token neexistuje
    ├── 410 GONE: token CLAIMED nebo REVOKED
    └── 422 EXPIRED: token expiroval

    ▼ (pokud valid)
[FE] zobrazí signup form (email prefill pokud issued_to_email != null)


[User] vyplní email + heslo → Submit


[FE] POST /api/auth/signup-with-invite
    body: { token, email, password }


[BE]
    1. Znovu validuje token (atomicky, SERIALIZABLE transakce)
    2. Ověří email není burner
    3. Vytvoří users záznam (invite_generation dle issuer)
    4. Aktualizuje invite: status = CLAIMED, claimed_by_user_id, claimed_at
    5. Aktualizuje user_invite_quota.invites_used pro issuera (+1)
    6. Vrátí JWT token (přihlášený)

7. Future Extensions (post-alpha)

Tyto funkce jsou mimo scope alpha — zdokumentovány jako planned extensions aby ovlivnily design DB schéma (přidání sloupců bude additive, ne breaking).

7.1 Earned invites (gamifikace)

TriggerBonus invites
Account age ≥ 30 dní+2
Projekt dosáhne 100 page views+3
5 pozvaných userů aktivních 30+ dní+5

Implementace: scheduled job týdně vyhodnotí podmínky a grantuje invites automaticky (na rozdíl od manuálního admin grantu). Audit log stejnou invite_grants tabulkou s granted_by_admin_id = NULL (system grant).

7.2 Pricing tier integration

Paid tier users dostanou vyšší základní invite kvótu jako benefit. Logika v user_invite_quota — při upgrade na paid tier automatický grant bez manuální akce.

7.3 Quality gating

Pokud uživatel má 3+ invitees, kteří churní do 7 dní od signupu → redukce invite kvóty. Signal: issuer pozval lidi, kteří platformu nepoužívají → pravděpodobně masový invite blast.

Implementace: weekly churn job + notification adminovi před automatickým penalty grantem (Mirek má veto).


References

Was this page helpful?

Thanks for the feedback.