Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
사진과 영상을 담는 푸르른 스튜디오입니다. 원하는 날짜와 시간을 선택하여 예약해 주시기 바랍니다.
Translation pending
LifestyleTypeScript · PLpgSQLGitHub @Jo-Seong-YunOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
사진/영상 촬영 스튜디오 '푸르른 스튜디오'의 온라인 예약 사이트. 손님이 비어 있는 시간을 직접 보고 예약을 잡는다. 개발 계획은 docs/ROADMAP.md에 있다. • Next.js 16 (App Router) + TypeScript • Tailwind CSS 4 • Supabase (Postgres / Auth / Storage) — Phase 2부터 • Vitest — 시간 계산 로직 테스트 • 배포: Vercel Supabase를 아직 연결하지 않았다면 docs/SUPABASE_SETUP.md를 먼저 따라간다. vercel.json에서 함수 실행 리전을 icn1(서울)로 고정했다. Vercel Hobby 플랜은 기본값이 미국 리전(iad1)이라, 손님·관리자 요청이 서버를 거쳐 서울 리전의 Supabase까지 태평양을 두 번(왕복) 건너가게 된다. 매 요청마다 겪는 지연이라 캐시로는 안 가려지고, 인증 확인처럼 서버가 Supabase를 불러야 하는 동작일수록 체감이 크다. 비밀 키 세 층.Read the full README ↗
사진/영상 촬영 스튜디오 '푸르른 스튜디오'의 온라인 예약 사이트. 손님이 비어 있는 시간을 직접 보고 예약을 잡는다.
개발 계획은 docs/ROADMAP.md에 있다.
npm install
cp .env.example .env.local # 값은 Supabase 프로젝트에서 가져온다 — docs/SUPABASE_SETUP.md 참고
npm run dev
Supabase를 아직 연결하지 않았다면 docs/SUPABASE_SETUP.md를 먼저 따라간다.
| 명령 | 설명 |
|---|---|
npm run dev | 개발 서버 |
npm run build | 프로덕션 빌드 |
npm test | 테스트 실행 |
npm run test:watch | 테스트 감시 모드 |
npm run typecheck | 타입 검사 |
npm run lint | ESLint |
npm run format | Prettier 포맷 |
app/ 화면 (App Router)
lib/
time.ts ★ 시간대 규칙. 모든 날짜/시간 계산의 기준
availability/
slots.ts ★ 예약 가능 시간 계산 (순수 함수)
range.ts Postgres tstzrange 파싱·겹침 판정
load.ts DB에서 읽어 slots.ts에 넘기는 서버 함수
supabase/
client.ts 브라우저용 클라이언트 (anon 키, RLS 적용)
server.ts 서버 컴포넌트용 클라이언트 (로그인 세션 유지)
admin.ts service role 클라이언트 — 서버 전용, RLS 우회
database.types.ts 테이블 타입 (db:types로 재생성)
supabase/
migrations/ 스키마 SQL. 파일명 순서대로 적용된다
seed.sql 로컬 개발용 예시 데이터
docs/ 기획 문서
proxy.ts 로그인 세션 갱신 (Next 16에서 middleware의 새 이름).
/admin 경로에만 걸려 있다
vercel.json에서 함수 실행 리전을 icn1(서울)로 고정했다. Vercel Hobby
플랜은 기본값이 미국 리전(iad1)이라, 손님·관리자 요청이 서버를 거쳐
서울 리전의 Supabase까지 태평양을 두 번(왕복) 건너가게 된다. 매 요청마다
겪는 지연이라 캐시로는 안 가려지고, 인증 확인처럼 서버가 Supabase를
불러야 하는 동작일수록 체감이 크다.
비밀 키 세 층.
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (sb_publishable_..., 옛 이름 anon)
— 브라우저에 노출돼도 되는 키. RLS가 실제 방어선SUPABASE_SECRET_KEY (sb_secret_..., 옛 이름 service_role)
— RLS를 완전히 우회한다. lib/supabase/admin.ts에서만, 서버 코드에서만 쓴다.
"server-only" 임포트가 실수로 클라이언트에 섞이는 걸 막아준다docs/SUPABASE_SETUP.md 3번)이중예약은 DB가 막는다, 앱이 아니라.
reservations 테이블에 EXCLUDE USING gist 제약이 있다. 같은 시간대에
requested/confirmed 예약 두 개를 동시에 넣으면 두 번째가 거절된다.
"조회 후 저장" 방식의 경쟁 조건을 애초에 차단한다.
예약 가능 시간은 서버에서만 계산한다.
운영시간·휴무·차단 테이블은 관리자 전용 RLS라 손님 키로는 못 읽는다.
차단 사유("시험", "개인 일정")가 손님에게 새지 않도록, 서버가 대신 읽고
lib/availability/load.ts가 계산 결과만 내려준다.
시간은 전부 lib/time.ts를 거친다.
저장은 UTC, 계산과 표시는 한국 시간(KST)이다.
Vercel 서버는 UTC로 도니까 new Date()의 날짜를 그대로 믿으면 밤 9시 이후 하루가 어긋난다.
날짜가 필요하면 kstToday(), kstDateString()을 쓴다.
비밀 키는 커밋하지 않는다.
.env*는 .gitignore에 있다.
SUPABASE_SECRET_KEY는 서버에서만 쓰고 NEXT_PUBLIC_ 접두사를 붙이지 않는다.
docs/SUPABASE_SETUP.md 참고)/admin/schedule — 요일별 운영시간, 주간 캘린더 차단, 날짜 단위 휴무, 손님 화면 미리보기)