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.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
시민의 친환경 이동을 인증받아 CO₂ 회피배출량으로 환산하고, 집계 결과로 보상 대상을 선정해 실물 지급까지 집행한 시민 참여형 웹서비스 (Next.js + Supabase, 2026년 운영 종료)
翻訳待ち
Loading the full README. The saved excerpt is shown below.
시민이 걷기·자전거·대중교통으로 이동한 기록을 인증받으면, 승용차 대비 줄인 CO₂만큼 화면 속 작물이 자라는 웹서비스입니다. 광주 지역 환경봉사동아리(G.P.S)의 공모사업 참여자를 대상으로 2026년 여름에 실제로 운영했습니다. 인증 심사와 집계를 거쳐 감축량 상위 15명에게 동아리가 직접 키운 작물로 만든 수제청을 배송하는 것으로 종료했습니다. 서비스 https://green-mile-farm.vercel.app · 상태 챌린지 종료(2026-08-20) 참여자·감축량·수확 달성자 수치는 서비스 첫 화면의 "함께 만드는 변화" 영역에서 실시간 집계로 확인할 수 있습니다. 인증 건수·승인/반려 건수는 개인정보가 포함된 운영 데이터베이스 기준이라 외부에 공개하지 않습니다. 이 저장소의 코드 초안은 대부분 생성형 AI가 작성했습니다. 커밋 34건 전부에 Co-Authored-By 표기를 남겨 사실을 기록으로 확인할 수 있게 했습니다.Read the full README ↗
시민이 걷기·자전거·대중교통으로 이동한 기록을 인증받으면, 승용차 대비 줄인 CO₂만큼 화면 속 작물이 자라는 웹서비스입니다. 광주 지역 환경봉사동아리(G.P.S)의 공모사업 참여자를 대상으로 2026년 여름에 실제로 운영했습니다. 인증 심사와 집계를 거쳐 감축량 상위 15명에게 동아리가 직접 키운 작물로 만든 수제청을 배송하는 것으로 종료했습니다.
서비스 https://green-mile-farm.vercel.app · 상태 챌린지 종료(2026-08-20)
| 구분 | 기간 |
|---|---|
| 개발 | 2026-06-24 ~ 2026-08-20 (커밋 이력 기준 58일) |
| 챌린지 운영 | 2026-07-06 ~ 2026-08-20 (당초 08-02 예정에서 1회 연장) |
| 인증 검토·보상 집행 | 운영기간 중 상시 ~ 마감 후 정산 |
| 자동 상태점검 가동 | 2026-08-07 ~ 2026-08-30 |
| 지표 | 값 |
|---|---|
| 가입자 | 47명 |
| 실제 인증 참여자 | 17명 (가입 대비 36.2%) |
| 인증 접수·전수 검토 | 101건 |
| 승인 확정 / 반려 | 66건 / 35건 (반려율 34.7%) |
| 승인 인증 이동거리 | 368.7km (걷기 29건 · 버스 28건 · 자전거 7건 · 지하철 2건) |
| 추정 회피배출량 | 69.41 kgCO₂e — 자체 산정 기준의 추정치입니다. 알려진 한계 참고 |
| 5kg 수확 달성 | 3명 (화면 속 작물 성장 판정 기준) |
| 실물 보상 배송 | 15명 (감축량 상위 15명, 전원 배송 완료) |
참여자·감축량·수확 달성자 수치는 서비스 첫 화면의 "함께 만드는 변화" 영역에서 실시간 집계로 확인할 수 있습니다. 인증 건수·승인/반려 건수는 개인정보가 포함된 운영 데이터베이스 기준이라 외부에 공개하지 않습니다.
이 저장소의 코드 초안은 대부분 생성형 AI가 작성했습니다. 커밋 34건 전부에 Co-Authored-By 표기를 남겨 사실을 기록으로 확인할 수 있게 했습니다.
| 단계 | 본인이 한 것 | AI가 한 것 |
|---|---|---|
| 요구사항 정의 | 무엇을 만들지, 어떤 규칙으로 운영할지, 어떤 데이터를 남길지 결정 | 요구사항을 화면·표·함수 단위로 분해 |
| 설계 판단 | 방식 선택과 거부, 되돌릴 수 없는 변경 사전 차단 | 선택지와 장단점 제시 |
| 위험 검토 | 보안·개인정보·데이터 손실 위험 지적, 근거를 코드로 확인하도록 요구 | 지적된 위험의 코드·설정 확인 |
| 구현·검증 | 작업 지시 → 결과 검토 → 직접 써보고 오류 재현 → 수정 요청 → 재확인 | 코드 작성 및 지적 사항 수정 |
| 배포 | 배포 시점 판단 (요청이 있을 때만 배포하도록 규칙화) | 빌드·타입 검사 통과까지만 수행 |
| 운영·검산 | 인증 101건 전수 검토 · 반려 사유 작성 · 보상 대상 선정 · 집계 검산 · 배송 집행 | 점검 자동화 코드·검산 스크립트 작성 |
AI에게 변경을 금지한 영역을 따로 지정해 두었습니다 — 지도 핀 좌표 스냅과 거리 계산, 인증 제출·사진검증·촬영정보 처리, 작물 성장 5단계, 통계 집계 방식. 보상이 걸린 계산 로직에서 되돌릴 수 없는 변경이 가장 위험하다고 판단했기 때문입니다.
작업 맥락과 의사결정 근거는 HANDOFF.md와 COWORK_HANDOFF.md에 남겼습니다. "기능을 고쳐 다시 배포할 때는 인수인계 문서도 함께 갱신한다"는 규칙을 정하고 전용 커밋 8건으로 지켰습니다(커밋 제목 HANDOFF.md 갱신 —으로 확인 가능).
flowchart LR
U["참가자 브라우저<br/>PC · 모바일"]
V["Vercel<br/>Next.js 14 App Router<br/>서버에서 거리·감축량 계산<br/>관리자 페이지 6종"]
S["Supabase<br/>Auth · 로그인<br/>PostgreSQL · 표 8개<br/>Storage · 인증사진(비공개)<br/>RLS 정책 12개"]
K["카카오 지도<br/>핀 좌표 · 30m 격자 스냅"]
C["Vercel Cron<br/>매일 1회 상태점검 31항목"]
U -- HTTPS --> V
V -- 서버 조회 --> S
V --> K
C --> V
| 영역 | 기술 |
|---|---|
| 프런트·서버 | Next.js 14.2.35 (App Router) · React 18 · TypeScript 5 · Tailwind CSS 3.4.1 |
| 데이터베이스 | Supabase (PostgreSQL 17.6, 서울 리전) — 로그인 · DB · 파일저장소 · 행 수준 접근제어(RLS) |
| 외부 API | 카카오 지도(JS·REST) · 다음 우편번호 · exifr(사진 촬영정보 추출) |
| 배포·자동화 | Vercel (main 브랜치 push 시 자동 배포) + Vercel Cron |
이 구성을 고른 이유 — 운영 인원이 사실상 1명이었습니다. 서버를 직접 두면 장애 대응을 할 수 없으므로, 로그인·데이터베이스·파일저장소·접근제어를 한 곳에서 관리하고 배포가 자동인 조합을 택했습니다. 감축량 계산은 전부 서버에서 수행해 참가자 쪽에서 값을 바꿀 수 없게 했습니다.
| 경로 | 용도 |
|---|---|
/admin | 통계 — 가입·참여·승인·수확·감축량 집계 |
/admin/certifications | 인증 검토 — 사진 4장·이동 구간·촬영정보 확인 후 승인/반려, 거리 수정 |
/admin/participants | 참가자 명부 — 1인당 집계, 열 정렬, CSV 내려받기(/admin/export) |
/admin/health | 상태점검 — 31항목 신호등 표시, 최근 30회 이력 |
/admin/content | 랜딩 내용 — 소개 섹션·고정 문구·이미지 편집 |
/admin/settings | 설정 — 목표 감축량, 챌린지 일정, 배출계수 |
certifications — 본인만 등록·조회, 운영진만 전체 조회·검토. 다른 참가자의 인증은 목록에도 나오지 않습니다.profiles — 본인 또는 운영진만 조회, 수정은 운영진만.certification-photos 버킷 — 비공개. 본인 폴더에만 업로드할 수 있고 본인·운영진만 열람합니다.recovery_attempts / password_reset_tokens — 정책을 아예 두지 않고 anon·authenticated 권한을 회수해 서버(service_role)만 접근합니다. 로그인한 사용자도 읽을 수 없습니다.is_admin) 계정은 이 경로로 재설정 불가. 실패 시 어느 항목이 틀렸는지 구분하지 않고 항상 같은 문구를 반환합니다..env*.local)은 .gitignore로 제외했습니다. 커밋 이력 전체를 확인한 결과 비밀값이 올라간 적은 없습니다.지도 핀 방식으로 바꾼 뒤 직접 테스트하다가, 대학 캠퍼스처럼 큰 단지에서 같은 출발지·도착지인데 값이 다르게 나오는 것을 발견했습니다. 경로 탐색이 일방통행·회전 제한을 반영해 A→B와 B→A가 달라진 탓이었습니다.
보상이 걸린 서비스에서 거리는 곧 보상입니다. 정확도를 조금 손해 보더라도 같은 입력이면 항상 같은 값이 나오는 편이 낫다고 판단해, 하버사인 직선거리 × 보정계수 1.3으로 바꾸고 계산은 서버에서만 수행하게 했습니다. 함께 핀 좌표를 30m 격자로 스냅해 같은 건물이면 같은 좌표가 되도록 했습니다.
lib/kakao.ts (WALK_ROUTE_FACTOR)1225605 → 65c344e → d1c9600supabase/10_distance_edit.sql누적 감축량과 보너스를 계산해 따로 저장하면 화면은 빨라지지만, 나중에 인증을 반려하거나 이동거리를 수정하면 저장된 값과 실제 기록이 어긋납니다. 갱신을 한 곳이라도 빠뜨리면 조용히 틀린 값이 남고, 참가자 화면과 관리자 명부가 서로 다른 숫자를 보여주게 됩니다.
그래서 인증 기록 하나만 원본으로 두고 나머지는 매번 다시 계산하게 했습니다. 보너스도 전용 표를 만들지 않고 certifications에서 계산해, 반려·거리 수정이 자동으로 반영되고 중복·누락이 구조적으로 생길 수 없습니다.
함께 순환 참조도 차단했습니다. 주간 랭킹 보너스는 목표 달성자를 제외하고 주는데, 보너스가 다시 달성 판정에 들어가면 서로를 참조합니다. 달성 판정에는 인증분만 쓰도록 분리했습니다.
supabase/12_bonus_awards.sql · supabase/13_bonus_steady.sql403995dThis is the beginning of the README. Read the rest at the original. Read the full README ↗