Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Ring Platform v1.6.4 organizes code by App Router route groups, feature domains, and a provider-owned hook layer that prevents duplicate network subscriptions.
Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections below apply to both audiences; audience-specific blocks follow.
ring-platform.org/
├── app/ # Next.js 16 App Router + app/api route handlers
├── components/ # Shared UI, navigation, providers
├── features/ # Domain modules (auth, store, wallet, news, …)
├── hooks/ # Root hooks — see hooks/HOOKS-README.md
├── lib/ # database, payments, locale-config, tunnel
├── services/ # email AI CRM, blockchain oracle
├── locales/ # next-intl JSON bundles (en, uk, ru)
├── data/ # schema.sql + migrations/
└── docs/ # MDX documentation (docs/{locale}/**)Not in public OSS tree: k8s/, cli/, propagation/ (gitignored).
| Area | Path |
|---|---|
| PaymentConductor | lib/payments/conductor/ |
| Locale SSOT | lib/locale-config.ts, i18n/routing.ts |
| Database abstraction | lib/database/ (db(), getSharedPgPool()) |
| Auth.js v5 | auth.ts, features/auth/components/session-provider.tsx |
| Client app shell | components/providers/app-client-shell.tsx |
A Ring clone is a white-label fork of this tree. Feature code stays inside features/{domain}/ so Reggie propagation and your customizations do not collide with core platform plumbing.
Database, auth, and SSOT guardrails for clone operators hiring integrators.
What keeps pages fast without extra infrastructure.
PostgreSQL-primary vs Firebase-backed deployments.
Typical clone scenarios:
Ring Platform v1.6.4 organizes code by App Router route groups, feature domains, and a provider-owned hook layer that prevents duplicate network subscriptions.
Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections below apply to both audiences; audience-specific blocks follow.
ring-platform.org/
├── app/ # Next.js 16 App Router + app/api route handlers
├── components/ # Shared UI, navigation, providers
├── features/ # Domain modules (auth, store, wallet, news, …)
├── hooks/ # Root hooks — see hooks/HOOKS-README.md
├── lib/ # database, payments, locale-config, tunnel
├── services/ # email AI CRM, blockchain oracle
├── locales/ # next-intl JSON bundles (en, uk, ru)
├── data/ # schema.sql + migrations/
└── docs/ # MDX documentation (docs/{locale}/**)Not in public OSS tree: k8s/, cli/, propagation/ (gitignored).
| Area | Path |
|---|---|
| PaymentConductor | lib/payments/conductor/ |
| Locale SSOT | lib/locale-config.ts, i18n/routing.ts |
| Database abstraction | lib/database/ (db(), getSharedPgPool()) |
| Auth.js v5 | auth.ts, features/auth/components/session-provider.tsx |
| Client app shell | components/providers/app-client-shell.tsx |
A Ring clone is a white-label fork of this tree. Feature code stays inside features/{domain}/ so Reggie propagation and your customizations do not collide with core platform plumbing.
Database, auth, and SSOT guardrails for clone operators hiring integrators.
What keeps pages fast without extra infrastructure.
PostgreSQL-primary vs Firebase-backed deployments.
Typical clone scenarios:
Ring Platform v1.6.4 organizes code by App Router route groups, feature domains, and a provider-owned hook layer that prevents duplicate network subscriptions.
Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections below apply to both audiences; audience-specific blocks follow.
ring-platform.org/
├── app/ # Next.js 16 App Router + app/api route handlers
├── components/ # Shared UI, navigation, providers
├── features/ # Domain modules (auth, store, wallet, news, …)
├── hooks/ # Root hooks — see hooks/HOOKS-README.md
├── lib/ # database, payments, locale-config, tunnel
├── services/ # email AI CRM, blockchain oracle
├── locales/ # next-intl JSON bundles (en, uk, ru)
├── data/ # schema.sql + migrations/
└── docs/ # MDX documentation (docs/{locale}/**)Not in public OSS tree: k8s/, cli/, propagation/ (gitignored).
| Area | Path |
|---|---|
| PaymentConductor | lib/payments/conductor/ |
| Locale SSOT | lib/locale-config.ts, i18n/routing.ts |
| Database abstraction | lib/database/ (db(), getSharedPgPool()) |
| Auth.js v5 | auth.ts, features/auth/components/session-provider.tsx |
| Client app shell | components/providers/app-client-shell.tsx |
A Ring clone is a white-label fork of this tree. Feature code stays inside features/{domain}/ so Reggie propagation and your customizations do not collide with core platform plumbing.
Database, auth, and SSOT guardrails for clone operators hiring integrators.
What keeps pages fast without extra infrastructure.
PostgreSQL-primary vs Firebase-backed deployments.
Typical clone scenarios:
features/store/StoreProviderfeatures/, tunnel providers unchanged.features/news/ services; do not duplicate global notification providers.use-auth.ts |
SessionProvider |
useAuth() |
SSOT: features/auth/components/session-provider.tsx — not components/providers/session-provider.tsx (deleted) |
use-fcm.ts | FCMProvider | internal / useFCM() in provider only | Token upsert via app/_actions/fcm.ts |
use-tunnel.ts | TunnelProvider | useTunnel() | Shared WSS/SSE connection |
use-unread-count.ts | NotificationProvider | useNotificationContext() | Nav badges must use context |
use-credit-balance.ts | CreditBalanceProvider | useCreditBalanceContext() | Module-scope bootstrap single-flight (5s TTL, keyed by userId) |
use-credit-history.ts | CreditHistoryProvider | useCreditHistoryContext() | Wallet routes only |
use-vendor-status.ts | (no provider) | useVendorStatus() | Single-flight + 30s TTL; SSOT for GET /api/vendor/status |
| Web Vitals | WebVitalsProvider | — | Buffers metrics → one debounced POST /api/analytics/web-vitals |
One 15-minute background poll; no refetch on focus/reconnect — cuts redundant GET /api/auth/session across every useSession() consumer.
Documented in hooks/HOOKS-README.md § P4:
hooks/use-vendor-status.ts replaces inline fetch('/api/vendor/status') in sidebar layouts.hooks/use-credit-balance.ts survives Strict Mode remounts.components/providers/web-vitals-provider.tsx batches useReportWebVitals (1.5s debounce).features/store/config.ts → getCachedProductCatalog() ('use cache' + cacheTag('store:products')).components/providers/session-provider.tsx and auth-provider.tsx.Enforce locally:
| Module | Path | Role |
|---|---|---|
| Database | lib/database/ | db(), getSharedPgPool(), adapters |
| Auth config | auth.ts | Auth.js v5 handlers + auth() |
| Payments | lib/payments/conductor/ | PaymentConductor |
| Locale | lib/locale-config.ts | SSOT for en / uk / ru |
Use db() from @/lib/database for all domain persistence. getSharedPgPool() is the sanctioned escape hatch for PostGIS raw SQL only — never new Pool( outside lib/database/.
All Server Actions use file-level 'use server' in app/_actions/. Derive userId from await auth() — never from client parameters. See Best practices for the canonical pattern.
app/
├── (public)/[locale]/ # Marketing, store, blog
├── (authenticated)/[locale]/ # Editor, entities, settings
├── (admin)/[locale]/ # Admin panels
├── (confidential)/[locale]/ # Tier-gated docs
├── api/ # Route handlers (auth, store, payments, …)
├── _actions/ # Server Actions
└── layout.tsx
features/{domain}/
├── components/
├── hooks/ # optional — domain-scoped only
├── services/
├── lib/
└── index.ts # public APIfeatures/store/StoreProviderfeatures/, tunnel providers unchanged.features/news/ services; do not duplicate global notification providers.use-auth.ts |
SessionProvider |
useAuth() |
SSOT: features/auth/components/session-provider.tsx — not components/providers/session-provider.tsx (deleted) |
use-fcm.ts | FCMProvider | internal / useFCM() in provider only | Token upsert via app/_actions/fcm.ts |
use-tunnel.ts | TunnelProvider | useTunnel() | Shared WSS/SSE connection |
use-unread-count.ts | NotificationProvider | useNotificationContext() | Nav badges must use context |
use-credit-balance.ts | CreditBalanceProvider | useCreditBalanceContext() | Module-scope bootstrap single-flight (5s TTL, keyed by userId) |
use-credit-history.ts | CreditHistoryProvider | useCreditHistoryContext() | Wallet routes only |
use-vendor-status.ts | (no provider) | useVendorStatus() | Single-flight + 30s TTL; SSOT for GET /api/vendor/status |
| Web Vitals | WebVitalsProvider | — | Buffers metrics → one debounced POST /api/analytics/web-vitals |
One 15-minute background poll; no refetch on focus/reconnect — cuts redundant GET /api/auth/session across every useSession() consumer.
Documented in hooks/HOOKS-README.md § P4:
hooks/use-vendor-status.ts replaces inline fetch('/api/vendor/status') in sidebar layouts.hooks/use-credit-balance.ts survives Strict Mode remounts.components/providers/web-vitals-provider.tsx batches useReportWebVitals (1.5s debounce).features/store/config.ts → getCachedProductCatalog() ('use cache' + cacheTag('store:products')).components/providers/session-provider.tsx and auth-provider.tsx.Enforce locally:
| Module | Path | Role |
|---|---|---|
| Database | lib/database/ | db(), getSharedPgPool(), adapters |
| Auth config | auth.ts | Auth.js v5 handlers + auth() |
| Payments | lib/payments/conductor/ | PaymentConductor |
| Locale | lib/locale-config.ts | SSOT for en / uk / ru |
Use db() from @/lib/database for all domain persistence. getSharedPgPool() is the sanctioned escape hatch for PostGIS raw SQL only — never new Pool( outside lib/database/.
All Server Actions use file-level 'use server' in app/_actions/. Derive userId from await auth() — never from client parameters. See Best practices for the canonical pattern.
app/
├── (public)/[locale]/ # Marketing, store, blog
├── (authenticated)/[locale]/ # Editor, entities, settings
├── (admin)/[locale]/ # Admin panels
├── (confidential)/[locale]/ # Tier-gated docs
├── api/ # Route handlers (auth, store, payments, …)
├── _actions/ # Server Actions
└── layout.tsx
features/{domain}/
├── components/
├── hooks/ # optional — domain-scoped only
├── services/
├── lib/
└── index.ts # public APIfeatures/store/StoreProviderfeatures/, tunnel providers unchanged.features/news/ services; do not duplicate global notification providers.use-auth.ts |
SessionProvider |
useAuth() |
SSOT: features/auth/components/session-provider.tsx — not components/providers/session-provider.tsx (deleted) |
use-fcm.ts | FCMProvider | internal / useFCM() in provider only | Token upsert via app/_actions/fcm.ts |
use-tunnel.ts | TunnelProvider | useTunnel() | Shared WSS/SSE connection |
use-unread-count.ts | NotificationProvider | useNotificationContext() | Nav badges must use context |
use-credit-balance.ts | CreditBalanceProvider | useCreditBalanceContext() | Module-scope bootstrap single-flight (5s TTL, keyed by userId) |
use-credit-history.ts | CreditHistoryProvider | useCreditHistoryContext() | Wallet routes only |
use-vendor-status.ts | (no provider) | useVendorStatus() | Single-flight + 30s TTL; SSOT for GET /api/vendor/status |
| Web Vitals | WebVitalsProvider | — | Buffers metrics → one debounced POST /api/analytics/web-vitals |
One 15-minute background poll; no refetch on focus/reconnect — cuts redundant GET /api/auth/session across every useSession() consumer.
Documented in hooks/HOOKS-README.md § P4:
hooks/use-vendor-status.ts replaces inline fetch('/api/vendor/status') in sidebar layouts.hooks/use-credit-balance.ts survives Strict Mode remounts.components/providers/web-vitals-provider.tsx batches useReportWebVitals (1.5s debounce).features/store/config.ts → getCachedProductCatalog() ('use cache' + cacheTag('store:products')).components/providers/session-provider.tsx and auth-provider.tsx.Enforce locally:
| Module | Path | Role |
|---|---|---|
| Database | lib/database/ | db(), getSharedPgPool(), adapters |
| Auth config | auth.ts | Auth.js v5 handlers + auth() |
| Payments | lib/payments/conductor/ | PaymentConductor |
| Locale | lib/locale-config.ts | SSOT for en / uk / ru |
Use db() from @/lib/database for all domain persistence. getSharedPgPool() is the sanctioned escape hatch for PostGIS raw SQL only — never new Pool( outside lib/database/.
All Server Actions use file-level 'use server' in app/_actions/. Derive userId from await auth() — never from client parameters. See Best practices for the canonical pattern.
app/
├── (public)/[locale]/ # Marketing, store, blog
├── (authenticated)/[locale]/ # Editor, entities, settings
├── (admin)/[locale]/ # Admin panels
├── (confidential)/[locale]/ # Tier-gated docs
├── api/ # Route handlers (auth, store, payments, …)
├── _actions/ # Server Actions
└── layout.tsx
features/{domain}/
├── components/
├── hooks/ # optional — domain-scoped only
├── services/
├── lib/
└── index.ts # public API
// features/auth/components/session-provider.tsx
<NextAuthSessionProvider
session={session}
refetchInterval={15 * 60}
refetchOnWindowFocus={false}
refetchWhenOffline={false}
>
./scripts/validate-provider-ssot.sh
// features/auth/components/session-provider.tsx
<NextAuthSessionProvider
session={session}
refetchInterval={15 * 60}
refetchOnWindowFocus={false}
refetchWhenOffline={false}
>
./scripts/validate-provider-ssot.sh
// features/auth/components/session-provider.tsx
<NextAuthSessionProvider
session={session}
refetchInterval={15 * 60}
refetchOnWindowFocus={false}
refetchWhenOffline={false}
>
./scripts/validate-provider-ssot.sh