Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing N9Life content
Preparing N9Life content
Preparing N9Life content
/n9 is the Cosmic Mirror. Unauthenticated visitors see the N9Life landing inside N9LifeLandingShell. Authenticated visitors see N9LifePanelClient, which loads today's mirror from GET /api/n9life/numerology/today and mounts NumerologyControlPanel.
L3 app/[locale]/today/page.tsx redirects to /n9. Primary nav remaps the pack "today" slot to /n9. Overflow / Mini App menu lists Council, the five systems, and Practitioners. Store, Opportunities, Games, and Docs are excluded from that menu. These library pages still resolve at /docs/... if you open the URL.
The panel is the member's daily desk:
SacredDayRoulette draws today's Personal Day when a birth date exists, otherwise Universal Day. Copy says "day wheel". The filename still contains roulette so that existing imports keep working.meanings.numerology.day.* and meanings.moon.* with English fallback).stance strings are not shown.status === 'ready'.panel.vaultCta to /n9/vault, panel.specialistsCta to /n9/specialists.panel.titles.{level} (Apprentice through Guru). The database may still store an English title; the UI prefers the locale key.Mini App uses the same panel component. Locale follows Telegram language_code (ua becomes uk), not Accept-Language. The floating profile avatar and the iOS Safari FCM install banner are hidden in Mini App.
N9LifePanelClient calls GET /api/n9life/numerology/today?date=YYYY-MM-DD using the device's local civil date. The route is auth-gated (auth() after connection()). It:
buildTodayForUser.n9life_council_log for that user, date, and each council topic.+10, cap by last_attendance_date). Missing table 42P01 is ignored so a fresh database still returns the mirror.Save goes to POST /api/n9life/profile with birthDate, name parts, birthTime, birthPlace, birthLat, birthLng, birthTz. If lat/lng exist and tz is empty, the API fills tz with tz-lookup.
BirthPlacePicker wraps Layer 1 LocationMapModal with persistProfile={false}. Choosing a birth city must not write the member's current cultural address. Hidden inputs carry birthLat and birthLng. Timezone is shown read-only with a manual override from Intl.supportedValuesOf('timeZone').
If persistProfile is left at its default true, the map save calls updateProfile and overwrites cultural location. Birth place pickers on this clone and in the pack must pass false.
features/n9life/bot/handlers.ts speaks Telegram Bot API over fetch (no Telegraf). /council calls buildTodayForUser, then prints today's practice and agreeing systems using n9life-home.bot.* with English fallbacks. /numerology prints Personal Day, Life Path, moon, mood, and disclaimer. Vault text is not imported on this path.
Panel chrome is n9life-home.panel.* (EN/UK/RU, 286 keys, parity 0). Engine headlines, moon, type, authority, and hall names are evolvement.meanings.*. Profile keys that contain a slash are stored as 5-1 in next-intl (chart.profileKey.replace('/', '-')) because a slash is a nested-message path.
0.75 sits in config for later.evolvement.council.aiSynthesis: false)./n9 is the Cosmic Mirror. Unauthenticated visitors see the N9Life landing inside N9LifeLandingShell. Authenticated visitors see N9LifePanelClient, which loads today's mirror from GET /api/n9life/numerology/today and mounts NumerologyControlPanel.
L3 app/[locale]/today/page.tsx redirects to /n9. Primary nav remaps the pack "today" slot to /n9. Overflow / Mini App menu lists Council, the five systems, and Practitioners. Store, Opportunities, Games, and Docs are excluded from that menu. These library pages still resolve at /docs/... if you open the URL.
The panel is the member's daily desk:
SacredDayRoulette draws today's Personal Day when a birth date exists, otherwise Universal Day. Copy says "day wheel". The filename still contains roulette so that existing imports keep working.meanings.numerology.day.* and meanings.moon.* with English fallback).stance strings are not shown.status === 'ready'.panel.vaultCta to /n9/vault, panel.specialistsCta to /n9/specialists.panel.titles.{level} (Apprentice through Guru). The database may still store an English title; the UI prefers the locale key.Mini App uses the same panel component. Locale follows Telegram language_code (ua becomes uk), not Accept-Language. The floating profile avatar and the iOS Safari FCM install banner are hidden in Mini App.
N9LifePanelClient calls GET /api/n9life/numerology/today?date=YYYY-MM-DD using the device's local civil date. The route is auth-gated (auth() after connection()). It:
buildTodayForUser.n9life_council_log for that user, date, and each council topic.+10, cap by last_attendance_date). Missing table 42P01 is ignored so a fresh database still returns the mirror.Save goes to POST /api/n9life/profile with birthDate, name parts, birthTime, birthPlace, birthLat, birthLng, birthTz. If lat/lng exist and tz is empty, the API fills tz with tz-lookup.
BirthPlacePicker wraps Layer 1 LocationMapModal with persistProfile={false}. Choosing a birth city must not write the member's current cultural address. Hidden inputs carry birthLat and birthLng. Timezone is shown read-only with a manual override from Intl.supportedValuesOf('timeZone').
If persistProfile is left at its default true, the map save calls updateProfile and overwrites cultural location. Birth place pickers on this clone and in the pack must pass false.
features/n9life/bot/handlers.ts speaks Telegram Bot API over fetch (no Telegraf). /council calls buildTodayForUser, then prints today's practice and agreeing systems using n9life-home.bot.* with English fallbacks. /numerology prints Personal Day, Life Path, moon, mood, and disclaimer. Vault text is not imported on this path.
Panel chrome is n9life-home.panel.* (EN/UK/RU, 286 keys, parity 0). Engine headlines, moon, type, authority, and hall names are evolvement.meanings.*. Profile keys that contain a slash are stored as 5-1 in next-intl (chart.profileKey.replace('/', '-')) because a slash is a nested-message path.
0.75 sits in config for later.evolvement.council.aiSynthesis: false)./n9 is the Cosmic Mirror. Unauthenticated visitors see the N9Life landing inside N9LifeLandingShell. Authenticated visitors see N9LifePanelClient, which loads today's mirror from GET /api/n9life/numerology/today and mounts NumerologyControlPanel.
L3 app/[locale]/today/page.tsx redirects to /n9. Primary nav remaps the pack "today" slot to /n9. Overflow / Mini App menu lists Council, the five systems, and Practitioners. Store, Opportunities, Games, and Docs are excluded from that menu. These library pages still resolve at /docs/... if you open the URL.
The panel is the member's daily desk:
SacredDayRoulette draws today's Personal Day when a birth date exists, otherwise Universal Day. Copy says "day wheel". The filename still contains roulette so that existing imports keep working.meanings.numerology.day.* and meanings.moon.* with English fallback).stance strings are not shown.status === 'ready'.panel.vaultCta to /n9/vault, panel.specialistsCta to /n9/specialists.panel.titles.{level} (Apprentice through Guru). The database may still store an English title; the UI prefers the locale key.Mini App uses the same panel component. Locale follows Telegram language_code (ua becomes uk), not Accept-Language. The floating profile avatar and the iOS Safari FCM install banner are hidden in Mini App.
N9LifePanelClient calls GET /api/n9life/numerology/today?date=YYYY-MM-DD using the device's local civil date. The route is auth-gated (auth() after connection()). It:
buildTodayForUser.n9life_council_log for that user, date, and each council topic.+10, cap by last_attendance_date). Missing table 42P01 is ignored so a fresh database still returns the mirror.Save goes to POST /api/n9life/profile with birthDate, name parts, birthTime, birthPlace, birthLat, birthLng, birthTz. If lat/lng exist and tz is empty, the API fills tz with tz-lookup.
BirthPlacePicker wraps Layer 1 LocationMapModal with persistProfile={false}. Choosing a birth city must not write the member's current cultural address. Hidden inputs carry birthLat and birthLng. Timezone is shown read-only with a manual override from Intl.supportedValuesOf('timeZone').
If persistProfile is left at its default true, the map save calls updateProfile and overwrites cultural location. Birth place pickers on this clone and in the pack must pass false.
features/n9life/bot/handlers.ts speaks Telegram Bot API over fetch (no Telegraf). /council calls buildTodayForUser, then prints today's practice and agreeing systems using n9life-home.bot.* with English fallbacks. /numerology prints Personal Day, Life Path, moon, mood, and disclaimer. Vault text is not imported on this path.
Panel chrome is n9life-home.panel.* (EN/UK/RU, 286 keys, parity 0). Engine headlines, moon, type, authority, and hall names are evolvement.meanings.*. Profile keys that contain a slash are stored as 5-1 in next-intl (chart.profileKey.replace('/', '-')) because a slash is a nested-message path.
0.75 sits in config for later.evolvement.council.aiSynthesis: false).