Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring Platform content
Preparing Ring Platform content
Preparing Ring Platform content
Use Founder / Developer tabs in the docs sidebar to filter this page. Personal file media, mood audio, and peer-game availability are separate routes under the same username — see Ring File Cabinet and Peer Games. Visit telemetry joins ring-wide analytics — see Monitoring & Analytics.
Every user with a reserved username can expose a public profile at /{username} (locale-prefixed as needed). The page is App Router server-rendered with dynamic SEO metadata. Related public surfaces:
| URL | Purpose |
|---|---|
/{username} | Profile header, bio, NFT listings, blog/staking when enabled; records personal_page_view for non-owners |
/{username}/img | Public File Cabinet gallery lightbox (visibility=public) |
/{username}/player | Public mood player (DaVinci shell + right-rail playlists) |
/{username}/games | Public peer-game availability (“Play with me”) |
/profile/songs | Private mood-player manage |
/profile/games | Private Member manage for enabled game slugs |
Owners see a visit stats widget (unique 24h / 7d, broken down by visitor role). Self-views are skipped so refreshing your own page does not inflate uniques.
The public profile is the member’s trust face: who they are, what they sell/list, which media they choose to show, and (via Peer Games) which free mini-games they accept. Visibility for the main profile page is all-or-nothing today — private profiles 404. Unique-visit stats help members see whether their page is attracting guests vs subscribers vs members without counting themselves.
Same-workflow: signed-in /profile Professional widgets (Organization, tags, My CV) feed the public trust face.
Next-step: member-gated /file-cabinet + gallery curation; public /img from visibility=public.
Depends-on: personal_page_view joins first-party analytics_events and admin personalPages.
Same-workflow: public /{username}/games availability and Member /profile/games manage.
Use Founder / Developer tabs in the docs sidebar to filter this page. Personal file media, mood audio, and peer-game availability are separate routes under the same username — see Ring File Cabinet and Peer Games. Visit telemetry joins ring-wide analytics — see Monitoring & Analytics.
Every user with a reserved username can expose a public profile at /{username} (locale-prefixed as needed). The page is App Router server-rendered with dynamic SEO metadata. Related public surfaces:
| URL | Purpose |
|---|---|
/{username} | Profile header, bio, NFT listings, blog/staking when enabled; records personal_page_view for non-owners |
/{username}/img | Public File Cabinet gallery lightbox (visibility=public) |
/{username}/player | Public mood player (DaVinci shell + right-rail playlists) |
/{username}/games | Public peer-game availability (“Play with me”) |
/profile/songs | Private mood-player manage |
/profile/games | Private Member manage for enabled game slugs |
Owners see a visit stats widget (unique 24h / 7d, broken down by visitor role). Self-views are skipped so refreshing your own page does not inflate uniques.
The public profile is the member’s trust face: who they are, what they sell/list, which media they choose to show, and (via Peer Games) which free mini-games they accept. Visibility for the main profile page is all-or-nothing today — private profiles 404. Unique-visit stats help members see whether their page is attracting guests vs subscribers vs members without counting themselves.
Same-workflow: signed-in /profile Professional widgets (Organization, tags, My CV) feed the public trust face.
Next-step: member-gated /file-cabinet + gallery curation; public /img from visibility=public.
Depends-on: personal_page_view joins first-party analytics_events and admin personalPages.
Same-workflow: public /{username}/games availability and Member /profile/games manage.
Use Founder / Developer tabs in the docs sidebar to filter this page. Personal file media, mood audio, and peer-game availability are separate routes under the same username — see Ring File Cabinet and Peer Games. Visit telemetry joins ring-wide analytics — see Monitoring & Analytics.
Every user with a reserved username can expose a public profile at /{username} (locale-prefixed as needed). The page is App Router server-rendered with dynamic SEO metadata. Related public surfaces:
| URL | Purpose |
|---|---|
/{username} | Profile header, bio, NFT listings, blog/staking when enabled; records personal_page_view for non-owners |
/{username}/img | Public File Cabinet gallery lightbox (visibility=public) |
/{username}/player | Public mood player (DaVinci shell + right-rail playlists) |
/{username}/games | Public peer-game availability (“Play with me”) |
/profile/songs | Private mood-player manage |
/profile/games | Private Member manage for enabled game slugs |
Owners see a visit stats widget (unique 24h / 7d, broken down by visitor role). Self-views are skipped so refreshing your own page does not inflate uniques.
The public profile is the member’s trust face: who they are, what they sell/list, which media they choose to show, and (via Peer Games) which free mini-games they accept. Visibility for the main profile page is all-or-nothing today — private profiles 404. Unique-visit stats help members see whether their page is attracting guests vs subscribers vs members without counting themselves.
Same-workflow: signed-in /profile Professional widgets (Organization, tags, My CV) feed the public trust face.
Next-step: member-gated /file-cabinet + gallery curation; public /img from visibility=public.
Depends-on: personal_page_view joins first-party analytics_events and admin personalPages.
Same-workflow: public /{username}/games availability and Member /profile/games manage.
personal_page_view events land in analytics_events; admins see personalPages on /admin/analytics.
/{username} as anonymous visitor — owner widget should show a unique visit after a non-owner hit./profile/gallery (member+)./profile/songs.Per-field public contact toggles (email, phone, social) are not shipped as independent switches yet — treat the personal-page toggle as the current gate.
ROUTES.PUBLIC_PROFILE_GAMESROUTES.PROFILE_SONGSROUTES.PROFILE_GAMESROUTES.PROFILE_GALLERY| Concern | Path |
|---|---|
| Event type | personal_page_view → analytics_events via insertAnalyticsEventBatch |
| Recorder | features/analytics/lib/personal-page-analytics.ts → recordPersonalPageView |
| Owner skip | Page: if (isOwner) return before record; recorder: skip when visitorUserId === profileUserId |
| Types SSOT | features/analytics/types/personal-page.ts (PersonalPageVisitStats, role buckets) |
| Owner widget action | getPersonalPageViewStats in features/auth/services/personal-page-stats.ts (owner or platform admin) |
| Widget UI | features/auth/components/personal-page-widget.tsx |
| Admin rollup | getPersonalPagePlatformStats → PlatformAnalyticsSummary.personalPages on /admin/analytics |
| Engagement join | analytics-db.ts includes personal_page_view with docs_page_view / page_view / app_load in pageViews aggregates |
| Kill switch | ANALYTICS_DISABLE_STORAGE=true — recorder no-ops |
Stats shape: unique24h / unique7d, visits24h / visits7d, byRole24h / byRole7d (unique + visits per role). Visitor identity prefers user id, else session key, else anon IP.
features/auth/services/get-user-by-username.ts — cache()’d queryDocs on users with case-insensitive username.
photoURL), name, @username, bio/api/nft-market/listings?username=…Users control public visibility through the username / personal-page flow. Public → page renders; Private → route returns 404.
| Endpoint | Purpose |
|---|---|
GET /api/auth/check-username | Availability |
GET /api/nft-market/listings?username= | Public listings |
POST /api/auth/telegram/callback | Telegram verification callback |
File Cabinet gallery data is not a separate public REST list — the img page reads via listPublicGalleryByOwner. Peer-game availability uses user_peer_games (migration 043_peer_games.sql).
Prerequisite: reserved username before public /{username} routes resolve.
personal_page_view events land in analytics_events; admins see personalPages on /admin/analytics.
/{username} as anonymous visitor — owner widget should show a unique visit after a non-owner hit./profile/gallery (member+)./profile/songs.Per-field public contact toggles (email, phone, social) are not shipped as independent switches yet — treat the personal-page toggle as the current gate.
ROUTES.PUBLIC_PROFILE_GAMESROUTES.PROFILE_SONGSROUTES.PROFILE_GAMESROUTES.PROFILE_GALLERY| Concern | Path |
|---|---|
| Event type | personal_page_view → analytics_events via insertAnalyticsEventBatch |
| Recorder | features/analytics/lib/personal-page-analytics.ts → recordPersonalPageView |
| Owner skip | Page: if (isOwner) return before record; recorder: skip when visitorUserId === profileUserId |
| Types SSOT | features/analytics/types/personal-page.ts (PersonalPageVisitStats, role buckets) |
| Owner widget action | getPersonalPageViewStats in features/auth/services/personal-page-stats.ts (owner or platform admin) |
| Widget UI | features/auth/components/personal-page-widget.tsx |
| Admin rollup | getPersonalPagePlatformStats → PlatformAnalyticsSummary.personalPages on /admin/analytics |
| Engagement join | analytics-db.ts includes personal_page_view with docs_page_view / page_view / app_load in pageViews aggregates |
| Kill switch | ANALYTICS_DISABLE_STORAGE=true — recorder no-ops |
Stats shape: unique24h / unique7d, visits24h / visits7d, byRole24h / byRole7d (unique + visits per role). Visitor identity prefers user id, else session key, else anon IP.
features/auth/services/get-user-by-username.ts — cache()’d queryDocs on users with case-insensitive username.
photoURL), name, @username, bio/api/nft-market/listings?username=…Users control public visibility through the username / personal-page flow. Public → page renders; Private → route returns 404.
| Endpoint | Purpose |
|---|---|
GET /api/auth/check-username | Availability |
GET /api/nft-market/listings?username= | Public listings |
POST /api/auth/telegram/callback | Telegram verification callback |
File Cabinet gallery data is not a separate public REST list — the img page reads via listPublicGalleryByOwner. Peer-game availability uses user_peer_games (migration 043_peer_games.sql).
Prerequisite: reserved username before public /{username} routes resolve.
personal_page_view events land in analytics_events; admins see personalPages on /admin/analytics.
/{username} as anonymous visitor — owner widget should show a unique visit after a non-owner hit./profile/gallery (member+)./profile/songs.Per-field public contact toggles (email, phone, social) are not shipped as independent switches yet — treat the personal-page toggle as the current gate.
ROUTES.PUBLIC_PROFILE_GAMESROUTES.PROFILE_SONGSROUTES.PROFILE_GAMESROUTES.PROFILE_GALLERY| Concern | Path |
|---|---|
| Event type | personal_page_view → analytics_events via insertAnalyticsEventBatch |
| Recorder | features/analytics/lib/personal-page-analytics.ts → recordPersonalPageView |
| Owner skip | Page: if (isOwner) return before record; recorder: skip when visitorUserId === profileUserId |
| Types SSOT | features/analytics/types/personal-page.ts (PersonalPageVisitStats, role buckets) |
| Owner widget action | getPersonalPageViewStats in features/auth/services/personal-page-stats.ts (owner or platform admin) |
| Widget UI | features/auth/components/personal-page-widget.tsx |
| Admin rollup | getPersonalPagePlatformStats → PlatformAnalyticsSummary.personalPages on /admin/analytics |
| Engagement join | analytics-db.ts includes personal_page_view with docs_page_view / page_view / app_load in pageViews aggregates |
| Kill switch | ANALYTICS_DISABLE_STORAGE=true — recorder no-ops |
Stats shape: unique24h / unique7d, visits24h / visits7d, byRole24h / byRole7d (unique + visits per role). Visitor identity prefers user id, else session key, else anon IP.
features/auth/services/get-user-by-username.ts — cache()’d queryDocs on users with case-insensitive username.
photoURL), name, @username, bio/api/nft-market/listings?username=…Users control public visibility through the username / personal-page flow. Public → page renders; Private → route returns 404.
| Endpoint | Purpose |
|---|---|
GET /api/auth/check-username | Availability |
GET /api/nft-market/listings?username= | Public listings |
POST /api/auth/telegram/callback | Telegram verification callback |
File Cabinet gallery data is not a separate public REST list — the img page reads via listPublicGalleryByOwner. Peer-game availability uses user_peer_games (migration 043_peer_games.sql).
Prerequisite: reserved username before public /{username} routes resolve.