尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证FindBack is a privacy-first lost-item recovery service. An owner registers an item and receives a printable QR tag. A finder scans the QR code without logging in, reports where the item was found or where it was left, and the owner sees the report in a private dashboard.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
QR 키링으로 분실물을 더 안전하고 빠르게 돌려받으세요. FindBack은 물리적인 QR 키링과 웹 애플리케이션을 연결하는 프라이버시 중심의 분실물 찾기 서비스입니다. 물건 주인은 개인정보를 노출하지 않고, 습득자는 로그인이나 앱 설치 없이 발견 사실을 바로 알릴 수 있습니다. GDGoC Korea University BYPP 해커톤 출품작입니다. 우산, 물병, 가방처럼 캠퍼스에서 흔히 잃어버리는 물건들은 되찾을 방법이 마땅치 않습니다. 이름표에 연락처를 적으면 개인정보가 노출되고, 분실물 보관소는 확인이 번거롭습니다. FindBack은: • 물건에 붙인 QR 태그를 스캔하면 습득자가 로그인 없이 발견 위치를 제보할 수 있고 • 제보는 즉시 주인의 비공개 대시보드로 전달되며 • QR/공개 페이지 어디에도 주인의 이름, 이메일, 전화번호, DB ID, 대시보드 URL이 노출되지 않습니다.查看完整 README ↗
QR 키링으로 분실물을 더 안전하고 빠르게 돌려받으세요.
FindBack은 물리적인 QR 키링과 웹 애플리케이션을 연결하는 프라이버시 중심의 분실물 찾기 서비스입니다. 물건 주인은 개인정보를 노출하지 않고, 습득자는 로그인이나 앱 설치 없이 발견 사실을 바로 알릴 수 있습니다.
GDGoC Korea University BYPP 해커톤 출품작입니다.
🔗 라이브 데모: https://findback-ten.vercel.app
우산, 물병, 가방처럼 캠퍼스에서 흔히 잃어버리는 물건들은 되찾을 방법이 마땅치 않습니다. 이름표에 연락처를 적으면 개인정보가 노출되고, 분실물 보관소는 확인이 번거롭습니다. FindBack은:
public_token(QR용)과 짧은 recovery_code(예: 7K2M9P, QR이 안 될 때 수동 입력용)가 생성됩니다./items/[id]/tag 페이지에서 45×65mm 크기의 태그(앞면: 마스코트, 뒷면: QR + 코드)를 인쇄해 물건에 부착합니다.{NEXT_PUBLIC_APP_URL}/f/{publicToken}을 인코딩합니다 — 이 URL 자체에는 owner_id나 DB 내부 id가 전혀 포함되지 않습니다./recover에서 코드 입력)하면 /f/[publicToken] 공개 페이지가 열리고, 위치·전달 방법·메시지를 남길 수 있습니다./api/reports 라우트를 통해서만 저장되며, 주인의 대시보드에 즉시(Realtime) 반영됩니다./f/[publicToken], /recover, /api/reports, /api/recover)은 서버 전용 서비스 롤 클라이언트(src/lib/supabase/admin.ts)로 접근하며, 클라이언트에는 반드시 안전한 필드만 선별해 전달합니다(src/lib/publicItem.ts).SUPABASE_SERVICE_ROLE_KEY 환경 변수로만 존재하고, server-only 패키지로 클라이언트 번들 유입을 방지합니다.found_reports 테이블을 Supabase Realtime publication에 추가해 아이템 상세 페이지가 새 제보를 즉시 반영합니다.src/
app/ 라우트 (App Router)
components/ 공유 UI (마스코트, 상태 뱃지, 아이템 카드 등)
lib/
supabase/ client / server / admin 클라이언트 + 타입
validation.ts zod 스키마
codes.ts public_token / recovery_code 생성
statusTransitions.ts 상태 전이 규칙
notifications/email.ts 이메일 알림 추상화 (Resend, 선택)
supabase/migrations/
20260918000000_initial_schema.sql 전체 스키마 + RLS + 스토리지 정책
20260919000000_add_report_geolocation.sql 제보 GPS 좌표(선택) 컬럼 추가
20260920000000_add_item_reward_amount.sql 물건 보상금(선택, 데모용) 컬럼 추가
npm install
cp .env.example .env.local # 아래 "Supabase 설정" 참고해 값 채우기
npm run dev # http://localhost:3000
anon public key, service_role key를 복사해 .env.local에 채웁니다.http://localhost:3000/auth/callback과 배포 도메인의 /auth/callback을 추가합니다.supabase/migrations/의 두 파일이 items, found_reports(GPS 좌표 컬럼 포함), item_status_events 테이블, RLS 정책, findback-media 공개 스토리지 버킷을 모두 생성합니다.Supabase CLI가 있다면:
supabase link --project-ref YOUR-PROJECT-REF
supabase db push
CLI가 없다면 Supabase 대시보드의 SQL Editor에 supabase/migrations/ 안의 파일들을 파일명 순서대로(타임스탬프 오름차순) 그대로 붙여넣어 실행해도 동일합니다.
.env.example 참고. 실제로 코드에서 사용하는 변수만 나열했습니다.
| 변수 | 용도 |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase 프로젝트 URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | 브라우저/서버 공용 publishable 키 (RLS 적용됨, 기존 NEXT_PUBLIC_SUPABASE_ANON_KEY도 계속 지원) |
SUPABASE_SERVICE_ROLE_KEY | 서버 전용. /api/reports, /api/recover, /f/[publicToken]에서만 사용 |
NEXT_PUBLIC_APP_URL | QR 코드/이메일 링크에 사용할 배포 URL |
RESEND_API_KEY (선택) | 설정 시 발견 제보 이메일 알림 발송 |
RESEND_FROM_EMAIL (선택) | 알림 발신자 주소 |
자격 증명은 절대 커밋하지 마세요. .env*는 .gitignore에 포함되어 있습니다.
NEXT_PUBLIC_APP_URL은 배포될 실제 도메인으로).https://YOUR-DOMAIN/auth/callback을 추가합니다.public_token은 소유자 정보와 무관한 24바이트 랜덤 문자열이며, 공개 페이지가 반환하는 필드는 이름·카테고리·설명·사진·상태·반환 안내뿐입니다(toPublicItemView).items/found_reports/item_status_events 테이블에는 익명 사용자를 위한 직접 조회/삽입 RLS 정책이 없습니다. 공개 조회와 제보 저장은 오직 서버의 Route Handler가 검증을 마친 뒤 서비스 롤 클라이언트로 수행합니다 — 브라우저에서 PostgREST를 직접 호출해도 막힙니다.server-only 패키지가 실수로 클라이언트 컴포넌트에서 import될 경우 빌드 타임에 에러를 발생시킵니다.owner_id = auth.uid() 기반 RLS가 적용됩니다.RESEND_API_KEY가 없으면 콘솔에 개발용 로그만 남기고 실제 메일은 보내지 않습니다.lost/returned 두 이벤트만 정밀 기록합니다. found는 제보 도착 시각(found_reports.created_at)으로 타임라인에 표시됩니다.src/lib/constants.ts와 각 컴포넌트에 모여 있어 이후 next-intl 등으로 쉽게 확장 가능한 구조로 작성했습니다./items/[id], /f/[publicToken]): 컴포넌트 로컬 state만 사용합니다. 메시지는 저장되지 않고, 양쪽 기기 간 실시간으로 전달되지 않으며, 새로고침하면 초기화됩니다./store): 상품 목록은 정적 데이터이고, "구매하기"를 누르면 토스/카카오페이 스타일의 결제 완료 화면을 흉내만 냅니다. 실제 결제사와 연동되어 있지 않으며 어떤 결제도 발생하지 않습니다./f/[publicToken]): 보상금 금액 자체는 items.reward_amount에 실제로 저장되어 여러 기기에서 동일하게 보이지만, 습득자가 "보상금 수령 신청"을 눌렀을 때 뜨는 성공 배너는 화면 연출일 뿐이며 실제 송금은 이루어지지 않습니다.npm run dev 실행 후 http://localhost:3000/login에서 이메일 매직링크로 로그인합니다./items/new에서 물건을 하나 등록합니다(사진은 선택)./items/[id]/tag로 이동합니다./f/[publicToken]을 엽니다 — 개인정보가 전혀 보이지 않는지 확인합니다./recover에서 태그에 적힌 코드를 입력해 같은 공개 페이지로 이동하는지 확인합니다. 존재하지 않는 코드를 입력하면 어떤 코드가 유사한지 드러내지 않는 일반 오류만 표시되는지 확인합니다.npm run lint # ESLint
npx tsc --noEmit # (또는 npm run build가 타입체크를 포함합니다)
npm run test # Vitest 단위 테스트 (코드 생성, zod 검증, 공개 데이터 필터링, 상태 전이)
npm run build # 프로덕션 빌드
개발 과정과 의사결정 기록은 BUILD_LOG.md를 참고하세요.