---
title: "Cosmic Mirror panel"
description: "Signed-in /n9, Telegram Mini App, day wheel, XP titles, and the birth-place picker that does not overwrite cultural address."
locale: "en"
---
# Cosmic Mirror panel

`/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.

## What the panel shows

The panel is the member's daily desk:

- **Day wheel.** `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.
- **Mirror card.** Personal Day display, Life Path, moon phase, keyed mood (`meanings.numerology.day.*` and `meanings.moon.*` with English fallback).
- **Council card.** Today's practice, agreeing / differing / abstained, evidence keys, tension. Raw `stance` strings are not shown.
- **Chart fields.** Birth date, given / surname / patronymic, full birth name, common name, birth time, birth place map, timezone.
- **Human Design chips.** Type, strategy, authority when `status === 'ready'`.
- **Vault and specialists CTAs.** `panel.vaultCta` to `/n9/vault`, `panel.specialistsCta` to `/n9/specialists`.
- **XP.** Level number plus `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.

## Data load

`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:

1. Builds the profile, mirror, and calendar through `buildTodayForUser`.
2. Upserts `n9life_council_log` for that user, date, and each council topic.
3. Awards daily attendance XP once per UTC date (`+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`.

## Birth place on the panel

`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')`.

> **Warning**
> 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`.

## Bot

`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.

## i18n

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.

## Limits on this page

- Owner notify for specialist match is **not** wired. Threshold `0.75` sits in config for later.
- AI council paragraph is **off** (`evolvement.council.aiSynthesis: false`).
- Desktop Ring user-menu extra for vault reaches signed-in mobile-web avatar only. Mini App hides that avatar; the panel CTA is the universal entry.

  
- [n9life](/docs/n9life.md) — Prerequisite: section hub

  
- [n9life/chart-and-inputs](/docs/n9life/chart-and-inputs.md) — Next-step: how the profile is stored

  
- [n9life/today-and-calendar](/docs/n9life/today-and-calendar.md) — Same-workflow: today API and Personal Day

  
- [n9life/vault-and-privacy](/docs/n9life/vault-and-privacy.md) — See-also: vault CTA target
