FloCafe
FloCafe is the free, local-first restaurant POS in the FloPOS ecosystem. Run orders, tables, kitchen display, and local data without a software subscription.
제주의 맛을 클릭 한 번에, 한 상자로.
Translation pending
CommerceHTML · JavaScriptGitHub @jeongeunlee0OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗제주 특산품을 골라 담고 주문하는 쇼핑몰과, 날씨를 보고 서귀포 관광지를 골라 주는 에이전트(서귀포 길잡이)를 담은 프로젝트입니다.
main 브랜치에 푸시하면 Vercel이 자동 배포)지금 상태를 정직하게 적어 두면: 쇼핑몰은 Supabase(LIVE) 에 연결돼 상품 · 회원가입 · 장바구니 · 주문 · 방명록이 DB에 저장되고, 결제는 체험 결제입니다(실제 결제 없음). 에이전트는 키가 없어도 규칙 기반 안내로 답하고, 키가 있으면 Claude 가 답합니다. 자세한 내용은 알려진 한계를 보세요.
| 구성 | 위치 | 설명 |
|---|---|---|
| 쇼핑몰 | index.html + src/shop/ | 3D 메인 화면, 상품 28개, 장바구니, 체험 결제와 주문·반품, 로그인, 방명록, 문의 채팅 |
| 서귀포 길잡이 | guide.html + src/guide/ | 3D 지도 + 대화. 날씨·관람객 통계 도구를 쓰는 에이전트 |
| 에이전트 API | api/agent.js, api/_lib/ | Vercel 서버리스 함수. Claude(키가 있을 때) 또는 규칙 기반(키가 없을 때) + 호출 제한 |
| 상품 데이터 | public/data/products.json | 상품의 단일 원본 |
| DB | supabase/ | 스키마(schema.sql) → 보안 보완(patch_2026-11-01_security.sql) → 상품 시드(seed_products.sql) 순서로 실행. 보완 파일은 쓰기를 가입한 계정으로만 제한하고, 주문 단가 · 이름과 방명록 작성자를 DB가 직접 채워요 |
| 도구 | scripts/ | 데이터 점검·시드 생성·관람객 CSV 가져오기·커서 생성·브라우저 회귀 검사 |
필요한 것: Node.js (^20.19.0 또는 >=22.12.0, Vite 8 요구 사항).
npm install
npm run dev
http://localhost:5173/ 을 엽니다. 키를 하나도 설정하지 않아도 쇼핑몰은 체험 모드로, 에이전트는 규칙 기반 안내로 바로 동작합니다.
src/shop/supabase-config.js 의 프로젝트(supabase-carmine-bridge, day4 게임과 공유)를 기본으로 쓰고, 화면 맨 위 배지가 LIVE 로 보입니다. 환경변수 VITE_SUPABASE_URL · VITE_SUPABASE_ANON_KEY 가 있으면 그 값이 먼저 쓰입니다.| 명령 | 하는 일 |
|---|---|
npm run dev | 개발 서버 (에이전트 API도 같은 서버에서 동작) |
npm run build / npm run preview | 배포용 빌드 / 빌드 결과 미리보기 |
npm run lint | oxlint |
npm run validate:data | 상품 JSON 점검 (중복·카테고리 표기·가격 범위) |
npm run build:seed | products.json → supabase/seed_products.sql 생성 |
npm run import:visitors -- <파일.csv> | 내려받은 관람객 CSV 를 검증해 api/_data/ 에 정리해 넣기 (--dry-run 은 검증만) |
npm run build:cursor | 귤 커서 SVG → public/cursor.css 생성 |
npm run check | lint + 데이터 점검 + 빌드를 한 번에 |
.env.example 을 복사해 .env.local 로 만듭니다. .env* 는 .gitignore 에 들어 있어 커밋되지 않습니다.
| 이름 | 어디서 쓰나 | 필요한 때 |
|---|---|---|
VITE_SUPABASE_URL | 쇼핑몰(브라우저) | Supabase 모드 |
VITE_SUPABASE_ANON_KEY | 쇼핑몰(브라우저) | Supabase 모드. anon 키는 공개용이라 브라우저에 노출돼도 됩니다 |
ANTHROPIC_API_KEY | 에이전트 API(서버 전용) | Claude 가 답하게 하려면. 없으면 규칙 기반 안내로 답합니다 |
RATE_LIMIT_PER_MIN, RATE_LIMIT_PER_DAY | 에이전트 API(서버 전용) | 선택. IP당 호출 제한(기본 8회/분 · 60회/일) |
VITE_ 접두사가 붙은 값만 브라우저로 나갑니다. ANTHROPIC_API_KEY 는 접두사가 없어서 서버에서만 읽힙니다. 이 키를 VITE_ 로 바꾸면 안 됩니다.
쇼핑몰 화면 아래쪽 "Supabase 연결 설정"에 URL·키를 직접 넣어도 되지만, 그 브라우저에만 저장됩니다.
.
├─ index.html 쇼핑몰 마크업 (스타일·스크립트는 src/shop)
├─ guide.html 서귀포 길잡이 화면
├─ src/
│ ├─ shop/ 쇼핑몰 (아래 5절)
│ │ ├─ main.js 진입점: 모듈을 연결하고 시작
│ │ ├─ shop.css 전체 스타일
│ │ ├─ util.js $, esc, won, 카테고리 도우미, 토스트 …
│ │ ├─ state.js 상태 객체 S 한 곳
│ │ ├─ api.js 데이터 계층: demo(브라우저) / remote(Supabase)
│ │ ├─ payments.js 결제 연동 지점 (지금은 체험 결제)
│ │ ├─ render.js 상태 → 화면
│ │ ├─ session.js 로그인 사용자 데이터·방명록 다시 불러오기
│ │ ├─ ui.js 서랍·모달, 로그인 탭
│ │ ├─ actions.js data-action 레지스트리 + 클릭 리스너 하나
│ │ ├─ forms.js 폼·입력 이벤트(로그인, 방명록, 검색, 정렬, Esc)
│ │ ├─ chat.js 문의 응대 채팅
│ │ ├─ content.js 제주어·토스트 문구
│ │ ├─ art.js 상품 일러스트(SVG)
│ │ ├─ effects.js 장바구니 날아가기, 스크롤 효과
│ │ └─ scene.js three.js 메인 장면
│ └─ guide/ 길잡이 화면 (main.js, guide.css)
├─ api/
│ ├─ agent.js Vercel 함수: 입력 검증 → 호출 제한 → Claude 또는 규칙 기반
│ ├─ _lib/sites.js 관광지 6곳(이름·좌표·실내외)
│ ├─ _lib/tools.js 도구 2개: 날씨(Open-Meteo), 관람객 통계(CSV)
│ ├─ _lib/rules.js 키가 없을 때 쓰는 규칙 기반 안내
│ ├─ _lib/limit.js 호출 제한
│ └─ _data/ ← 관람객 CSV를 여기에 둡니다 (아래 8절)
├─ public/
│ ├─ data/products.json 상품 원본
│ └─ cursor.css 귤 마우스 커서 (생성 파일)
├─ supabase/
│ ├─ schema.sql 테이블·RLS 정책
│ └─ seed_products.sql 상품 시드 (생성 파일)
├─ scripts/
│ ├─ products.mjs 데이터 점검 / 시드 SQL 생성
│ ├─ import-visitors.mjs 관람객 CSV 검증·정리
│ ├─ make-cursor.mjs 커서 SVG 원본 + 생성기
│ └─ browser-regression.js 브라우저 회귀 검사 50개 (콘솔에 붙여 넣어 실행)
├─ prompt.html (사이트와 무관) 스키마 요청용 프롬프트 안내 페이지
├─ vercel.json 함수에 api/_data 포함
├─ vite.config.js 멀티 페이지 빌드 + 개발 중 /api/agent 연결
└─ package.json
모듈은 한 방향으로만 의존합니다(순환 참조 없음). → 는 "가져다 쓴다"는 뜻입니다.
util (아무것도 가져다 쓰지 않음)
state → util
payments → util
api → util, state
render → util, art, state, api, content, payments
session → state, api, render
ui → util, state, api
effects → util, art
chat → util, state, api, content
actions → util, state, api, render, session, ui, effects, content, chat, payments
forms → util, state, api, render, session, ui, chat
scene → util
main → 위 모두를 연결하고 시작
핵심 아이디어 다섯 가지:
S 한 곳 (state.js). 화면은 render.js 의 함수가 S 를 읽어 그립니다. 상태가 바뀌면 해당 render*() 만 다시 부릅니다.api (api.js). Supabase 키가 있으면 remote, 없으면 demo 가 api 가 됩니다. 두 객체는 같은 함수 이름(cart, order, signIn …)을 가지므로 화면 코드는 어느 쪽인지 알 필요가 없습니다. 기능을 추가할 때는 두 객체 모두에 함수를 추가해야 합니다.actions.js). 버튼에 data-action="add" data-id="4" 처럼 이름표를 달면, 문서에 달린 클릭 리스너 하나가 ACTIONS['add'] 를 찾아 실행합니다. 새 버튼은 ACTIONS 에 함수 하나만 추가하면 됩니다.payments.js). "주문하기"는 결제 확인 창을 열고, requestPayment() 가 성공해야만 api.order() 로 주문이 만들어집니다. 실패하면 주문도 장바구니 변경도 없습니다. 지금은 체험 결제(실제 청구 없음, 카드·계좌 정보를 받지 않음)이며, 실제 결제사를 붙일 때는 이 함수만 바꾸면 됩니다.chat.js). INTENTS 배열의 한 줄이 한 가지 질문 유형입니다. test(질문) 이 참이면 reply(질문) 이 { text, actions } 를 돌려줍니다. 위에서부터 처음 맞는 것이 답합니다.
This is the beginning of the README. Read the rest at the original. Read the full README ↗