K9
K9 compares A/B shopper journeys, then uses Kane CLI to verify whether the advertised first-order discount reaches the real cart.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证oriz.at
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Premium SaaS — заменяет бумажное меню и сайт ресторана. Тихая роскошь, живые данные, мгновенные обновления. Production: https://oriz.at Supabase project: btydsogglgrtldfiezfu (Frankfurt, eu-central-1) Vercel: авто-деплой из ветки main • Тип: email + пароль (Supabase Auth) • Super Admin: [email protected] — видит все venues и редактирует их через SuperAdminView • Обычный владелец: видит только свой venue • Redirect: /admin → /admin/login если не залогинен (server-side getUser()) Полностью вымышленный ресторан, доступен всем без логина по адресу /demo.查看完整 README ↗
Premium SaaS — заменяет бумажное меню и сайт ресторана. Тихая роскошь, живые данные, мгновенные обновления.
Production: https://oriz.at
Supabase project: btydsogglgrtldfiezfu (Frankfurt, eu-central-1)
Vercel: авто-деплой из ветки main
| Слой | Технология |
|---|---|
| Frontend | Next.js 16 App Router · TypeScript strict · Tailwind v4 |
| Backend | Supabase — Postgres + Auth + Realtime + Storage |
| Хостинг | Vercel (Frankfurt edge) |
| DNS | IONOS → oriz.at |
.env.local)NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY= # только на сервере — для demo и admin-reset
| URL | Что это |
|---|---|
/ | Лендинг (маркетинг) |
/[venueSlug] | Гостевое меню (RSC + Realtime) |
/[venueSlug]/print | Печатная версия / PDF |
/admin | Владелец — управление меню |
/admin/login | Вход (email + пароль) |
/demo | Публичная демо-админка (без логина) |
/api/demo/update | PATCH — изменить поле блюда в демо |
/api/demo/reset | POST/GET — сбросить демо к оригиналу |
/api/caption | POST — AI-генерация Story через Claude |
/api/bot/hook | Telegram bot webhook |
[email protected] — видит все venues и редактирует их через SuperAdminView/admin → /admin/login если не залогинен (server-side getUser())Полностью вымышленный ресторан, доступен всем без логина по адресу /demo.
Venue ID: 9019d1cf-f1af-482f-9673-2a78846fa405
Venue slug: belvedere
Гостевое меню: oriz.at/belvedere
| Секция | section_id |
|---|---|
| Antipasti | 7db0d81e-e139-4586-8e57-599dd85bb948 |
| Zuppe & Insalate | 3e118b21-eddd-4ee2-8575-9a5ced5e60ea |
| Pasta & Risotto | 2db00df6-15f7-4a61-9b51-c2584439a70b |
| Secondi Piatti | 784b8549-e6ff-40ec-915b-157ed82d8a93 |
| Contorni | 7c521dce-3756-46c5-9ade-2dc9b3b58e5f |
| Dolci | 972fe15e-66ea-4809-b298-6490e1f0c498 |
color_bg: #1C1208 (тёмный эспрессо)
color_primary: #C8963E (итальянское золото)
price_cents)is_active) → «Verfügbar» / «Ausverkauft»ai_caption) — через модалallergens)vercel.json → cron 0 3 * * * (каждую ночь в 3:00) вызывает /api/demo/reset.
Эндпоинт делает upsert всех 33 блюд по ID, восстанавливая оригинальные значения включая ai_caption: null и allergens: null.
Важно: в RESET_DATA обязательно должны присутствовать section_id и venue_id — иначе upsert падает с NOT NULL constraint.
/api/demo/update)price_cents, is_active, description, ai_caption, allergensvenue_id = DEMO_VENUE_ID — нельзя изменить блюда из других venue/admin)Компонент ItemEditor (src/components/admin/ItemEditor.tsx):
| Поле | Как работает |
|---|---|
| Цена | Текстовый input, blur → supabase.update, optimistic UI |
| Статус | Кнопка «Verfügbar» / «Ausverkauft», optimistic toggle |
| Фото | Upload в Supabase Storage item-images, сохраняется image_url |
| Story | Модал с textarea (280 символов) + AI-кнопка → /api/caption |
| Аллергены | Inline input, blur → сохранение |
Компонент QRCodeBlock генерирует QR через api.qrserver.com, ссылка ведёт на oriz.at/{slug}.
/[venueSlug]/print — чистая страница для PDF. Скрытые блюда (is_active=false) не отображаются.
/api/caption)itemId → берёт из DB name + descriptionitems.ai_captionai_credits_used / ai_credits_reset в таблице venues, лимит зависит от плана (src/lib/plans.ts)src/lib/plans.ts)| Plan | AI лимит/месяц |
|---|---|
| trial | 5 |
| starter | 20 |
| pro | 100 |
Гостевое меню подписывается на канал venue:{venueId}:items через Supabase Realtime.
Фильтр: venue_id=eq.{venueId}. При UPDATE/INSERT/DELETE — мгновенное обновление без перезагрузки.
Требует: ALTER TABLE items REPLICA IDENTITY FULL (миграция 0002_realtime.sql).
// src/app/page.tsx
const DEMO_VENUES = [
{ slug: "belvedere", isAdmin: false, cta: "Menü öffnen" }, // → /belvedere
{ slug: "demo", isAdmin: true, cta: "Ausprobieren" }, // → /demo
]
Email [email protected] → видит SuperAdminView с таблицей всех venues.
Можно редактировать: название, slug, about, цвета (color_bg, color_primary), logo_url, план, Instagram, Google Maps.
npm install
npm run dev # http://localhost:3000
Суперадмин входит через /admin/login с email + паролем.
Применяются вручную в Supabase SQL Editor:
| Файл | Что делает |
|---|---|
0001_schema.sql | Основные таблицы: venues, sections, items + RLS |
0002_realtime.sql | Realtime publication + replica identity |
0003_... и выше | Добавочные колонки, смотри файлы |
src/
app/
page.tsx — Лендинг
[venueSlug]/page.tsx — Гостевое меню
[venueSlug]/print/page.tsx — Печать/PDF
admin/page.tsx — Реальная админка
demo/page.tsx — Публичная демо-админка
api/
caption/route.ts — AI Story-генерация
demo/update/route.ts — Изменение данных в демо
demo/reset/route.ts — Сброс демо (cron)
components/
admin/
ItemEditor.tsx — Основной редактор блюда
QRCodeBlock.tsx — QR-код блок
SectionNav.tsx — Стики-навигация по секциям (prop topOffset для демо)
SuperAdminView.tsx — Super admin таблица venue
demo/
DemoItemEditor.tsx — Редактор блюда для демо (без фото и AI)
landing/
HeroAtmosphere.tsx — Hero с фото-слайдшоу и cycling-словами
lib/
supabase/
client.ts — Browser client
server.ts — RSC server client (cookies)
types.ts — DB types
plans.ts — AI лимиты по планам
imageUpload.ts — Upload в Supabase Storage