FloCafe
FloCafe는 구독 없이 무료로 주문·테이블·주방 디스플레이·로컬 데이터를 관리하는 로컬 퍼스트 레스토랑 POS입니다
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Tikatero is Sound Matrix’s events and ticketing platform. This repository is a Next.js app with three surfaces:
//console/adminThe shared design system is at /styleguide. Product context lives in docs/BUILD-PLAN.md. The approved visual reference is docs/tikatero-v3-prototype.html.
pnpm install
cp .env.example .env.local
pnpm dev
.env.example lists variable names only. Put real values in .env.local or the host’s secret store. Do not commit secrets.
Schema, row level security, and the local seed live in supabase/.
supabase start
supabase db reset
pnpm test:db
pnpm test:db runs the database checks: anonymous reads of published events, organiser order isolation, ticket writes, the append-only audit log, the publish rule, and single-use redemption.
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm exec playwright test
Prices are stored as integer paise and shown in Indian rupees, including GST. Times on screen use India Standard Time (Asia/Kolkata).
The server-only lib/email/send.ts exports send. Later features can call it;
this PR does not wire notifications to payments, tickets, events or verification.
Staff can inspect all 14 sample templates at /admin/emails/preview without a
Resend key. The gallery never sends email.
Environment names only (put values in the host’s secret store):
RESEND_API_KEY (existing name)EMAIL_FROM (new; a sender on your verified domain)EMAIL_REPLY_TO (new; optional reply address)CONTACT_TO_EMAIL (server only; inbox for the public contact form; leave empty in this repo)The public /contact form saves each message in contact_messages. When
RESEND_API_KEY, EMAIL_FROM, and CONTACT_TO_EMAIL are set, the server emails
that inbox and sets the visitor as reply-to. The destination address is never
shown on the site, in errors, or in the browser bundle. If those values are
missing, or Resend does not accept the email, the message stays saved and the
visitor still sees success. reCAPTCHA v3 runs on this form only when both reCAPTCHA v3
keys are set. Live paid checkout still fails closed without reCAPTCHA v3.
Use the existing NEXT_PUBLIC_SITE_URL as the production HTTPS site origin for
absolute logo and button URLs. It contains no secret. The shared email layout
uses public/brand/tikatero-email-logo.png, a faithful PNG export of the existing
brand SVG, with a solid coral
CTA fallback for email clients that do not support gradients. INR values reuse
the existing paise formatter and add incl. GST; all times use the existing IST
formatter.
Apply the new migration before using the sender. It adds one nullable
email_log.idempotency_key column, backfills one identity per legacy notification,
and adds a unique index plus a server-role-only atomic claim function. Existing
email log columns and staff-only read RLS are preserved. Only the server service
client writes logs. Email bodies, attachment bytes and raw provider errors are
never written to logs or printed.
Identity is (template, trimmed entityRef, lowercased trimmed recipient). Use a
stable entity reference, such as an order UUID or an event-change revision ID.
A new reminder/change that intentionally needs a separate email must have its
own stable revision/reference; changing copy alone does not bypass deduplication.
A database claim is committed before the provider is called. The wrapper also
passes its opaque key to Resend. Configuration skips log skipped_not_configured
and can be claimed once later when configuration is added. A missing Resend key
never constructs the SDK or crashes a page. Missing/invalid sender or production
site configuration also skips. If the database is unavailable, logging_failed
is returned and no email is attempted.
The no-duplicates guarantee deliberately favors at-most-once delivery attempts:
sending, sent, and unknown claims are never automatically reclaimed. Resend
retains its own keys for only 24 hours. If a process stops after claiming, delivery
may be missed; if the provider times out, it may already have accepted the email.
Reconcile held records with the provider before any intentional new notification.
Do not delete claims or add blind retries. The one exception is order confirmation:
the payments cron may delete an order_confirmed row only when its status is
failed_provider or failed_render, then try that order again. sent_unlogged
means the provider accepted the email but the final log update failed; its existing
claim still blocks a repeat. sent means accepted by the provider, not guaranteed
inbox delivery. Webhook delivery tracking is later work.
order_confirmed accepts an optional attachments array of { filename, content, contentType? }. Content must be a Buffer or base64 string; remote paths are not
accepted. Maximum 50 attachments and 10 MB combined decoded content. No attachment
or email content is stored in email_log. Template data and optional actionPath
are typed; action paths must stay on the configured site. Defaults point to
existing account/console/admin surfaces; later integrations supply their intended
deep links.
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗