- launch.ts policy: LAUNCH_MODE=free_early_access default; effective access = published && (free || early); intended tier (access) never rewritten - Billing off server-side: /api/subscribe 503 honest copy; subscribe CTAs render disabled 'قريباً' from first paint; /subscription early-access panel + /api/notify (LaunchNotifications) with honest 503 when mail transport off - Signup trust: verification email at signup (Users afterChange), no confirm-password, 429 message fidelity, typo suggestion, live password hint - Agent pipeline: pickFields strips access/readingMinutes, sourceId dedup, secret-scan 422 (pattern names only), string-content rejected (was silently replaced), publish stays explicit opt-in - lexical.ts: root unwrap fix — lexicalToText/countLexicalWords returned 0 for real serialized trees (secret scan + readingMinutes were inert) - llms-full.txt: fetchIndexDocs(true) — bodies were never selected - Content honesty: contentType/authorName/sourceId fields + migration, readingMinutes computed at write (160 wpm) + backfill script, byline, 'حُدّث' freshness - SEO/AI-SEO: metadata rewrite (published-only, og:image 1200x630), Article + BreadcrumbList + FAQPage + Organization JSON-LD, isAccessibleForFree honest, table renderer, robots AI-crawler policy (10 named bots), llms.txt + llms-full.txt, /topics/* hubs + sitemap, noindex auth pages, www 301 - Ops: backup-db.sh (restore rehearsed on VPS), docs copies (launch readiness + marketing audit + owner-inputs for L-03), GLOSSARY.md entries Verified: tsc --noEmit 0, npm run build 0, local smoke (ghost VIP read, subscribe/notify/agent APIs, signup token, 429 on 6th, llms/topics/sitemap, og:image/JSON-LD)
50 lines
3.5 KiB
Markdown
50 lines
3.5 KiB
Markdown
# GLOSSARY — أنور بي آي
|
|
|
|
Implementation-free vocabulary shared across code, QA, and product talk.
|
|
|
|
## العضوية / Entitlement
|
|
|
|
A user's paid access level. Server-derived from `users.role`: `vip` or `admin` counts as entitled; `free` does not. Never cached client-side as a boolean.
|
|
|
|
## مفتوح / Unlocked
|
|
|
|
Whether the current viewer may read a given post's full body: `post.access === 'free' || entitled`. Derived per request; never stored on the user.
|
|
|
|
## تعليق / Comment
|
|
|
|
A moderated note by an authenticated member on a published post. Lifecycle `pending → approved | rejected`; only `approved` is publicly visible; only admins move status; authors cannot edit or delete their own comments (moderated model). Authors see their own `pending` comments on the post page tagged «قيد المراجعة».
|
|
|
|
## اسم العرض / Display name
|
|
|
|
The public author label of a comment: a snapshot of `users.fullName` taken at submit time, or the fixed word «عضو» when absent. Never the email.
|
|
|
|
## الهوية / Identity
|
|
|
|
- **Canonical domain: `anwarpy.ai`** — the Cloudflare zone (`anwarpi.ai` references are legacy being replaced; see repo history).
|
|
- **Contact inbox: `hello@anwarpy.ai`** — receives via Cloudflare Email Routing, forwards to ahmedalkhair.sa@gmail.com.
|
|
- **Sender: `noreply@anwarpy.ai`** — sends via Cloudflare Email Sending (REST).
|
|
|
|
## الاشتراك قريبًا / Coming soon
|
|
|
|
The public state of the subscribe flow while billing is disabled. From the first paint the UI renders a disabled «قريباً» button (when `LAUNCH_MODE` disables billing there is no active «اشترك الآن» that fails late); if a request is still attempted while Stripe keys are absent, `POST /api/subscribe` returns `{ comingSoon: true }` with no `url`, and the button shows an in-page retry state — **not a redirect** to `/payment-success` and no VIP is minted there either way. No VIP is granted without a Stripe-verified session.
|
|
|
|
## الوصول المبكر المجاني / Free early access
|
|
|
|
The launch policy (`LAUNCH_MODE=free_early_access`, the compose default): every approved **published** post is readable and its approved files downloadable without an account, regardless of the post's intended tier. Billing stays off; nothing is charged or auto-subscribed. The mode has no date expiry — the ~two-week checkpoint is a review date, not a cutoff.
|
|
|
|
## الطبقة المقصودة / Intended tier
|
|
|
|
The post's `access` field (`free` | `vip`) — what the content is meant to be once billing is enabled. The launch never rewrites it: a VIP-designated post opened by early access keeps `access: 'vip'` so rollback is instant and cards/comparisons stay truthful.
|
|
|
|
## الوصول الفعلي / Effective access
|
|
|
|
The decision actually enforced at request time: `status: 'published'` **and** (`access: 'free'` **or** free early access). One policy (`src/lib/launch.ts`) feeds pages, `/api/posts/[slug]`, the file gate, and the llms exports, so visible labels and served bytes can't disagree. A draft is never readable in any mode.
|
|
|
|
## كتابة موثوقة / Trusted write
|
|
|
|
An operation on a member record performed by server code (email verification, payment activation, billing webhook, seed), as opposed to a client request. Client requests can never set a member's privilege, verification, or billing fields.
|
|
|
|
## موثّق / Verified
|
|
|
|
Whether the member confirmed their email address. Required to comment; admins are exempt; set only by server code, never by client requests.
|