🏠 github.com/maybecocheon/room-checklist

월세방을 점수로 비교하는
현장 체크리스트

원룸을 보고 나오면 금방 잊어버립니다. 그 자리에서 휴대폰으로 체크리스트를 채우면, 쌓인 방들이 카드로 나란히 놓이고 조건에 맞는 것만 골라 볼 수 있습니다.

휴대폰으로 그 자리에서 기록 구글 시트에 저장 사진은 구글 드라이브에 앱 설치 없이 웹에서

← → 방향키 · 클릭 · 스와이프  ·  F 전체화면

01 — 무엇을 하는가 · What it does

기억 대신 기록으로 고릅니다

집을 세 군데쯤 보고 나면 첫 번째 집이 흐려집니다. 수압이 좋았던 게 어디였는지, 곰팡이를 본 게 어느 집이었는지요. 그래서 그 자리에서 적고, 같은 기준으로 점수를 매깁니다.

📝 그 자리에서 적기 (현장 체크리스트)

방향·채광·수압·콘센트·곰팡이·누수·벌레·엘리베이터·중문·주차 같은 것들을 방에서 나오기 전에 체크합니다. 사진도 찍어서 바로 올릴 수 있습니다.

📊 비교 대시보드 (필터 · 정렬 · 나란히 비교)

보증금·월세·도보 시간·점수로 걸러 보고, 원하는 순서로 정렬합니다. 마음에 드는 방 두세 개를 골라 나란히 놓으면, 값이 다른 항목만 색으로 표시됩니다 (차이 비교표).

🖼 사진 정리 (드라이브 연동)

현장에서 찍은 사진이 자동으로 그 방에 붙습니다. 다른 방에 이미 쓴 사진은 고를 수 없게 막아둬서, 같은 사진을 두 방에 붙이는 실수가 나지 않습니다.

✅ 계약할 때 빠뜨리지 않기 (방별 진행 체크리스트)

등기부등본·건축물대장 확인, 특약 넣기, 현장에서 두드려볼 것들까지 21가지를 방마다 따로 체크합니다. 어디까지 했는지 진행률로 보입니다.

점수는 이렇게 매겨집니다 (항목 가중치 합산) — 모든 방이 50점에서 시작해서, 좋은 건 더하고 나쁜 건 뺍니다

모두 50점에서 시작같은 잣대로 재기 위해
더하기 — 남향 +10 · 채광 좋음 +10 · 수압 좋음 +10 · 주차 무료 +8 · 콘센트 넉넉 +5엘리베이터·중문·현관 비밀번호는 각 +5, 옵션은 한 개당 +1
빼기 — 곰팡이 · 누수 · 벌레 각 −10치명적인 건 크게 깎아 위로 못 올라오게
0점점수를 누르면 “왜 이 점수인지” 항목별로 펼쳐 보여줍니다100점
02 — 구조 · Architecture

서버를 따로 두지 않고, 구글 시트를 데이터베이스로

따로 구축한 서버가 없습니다. 화면은 Vercel이 파일 그대로 내려주고, 데이터는 만든 사람의 구글 시트에, 사진은 같은 계정의 구글 드라이브에 쌓입니다. 저장하고 검사하는 일은 구글이 무료로 돌려주는 작은 프로그램 하나가 맡습니다 (Apps Script 웹앱).

① 사용자 화면 — 휴대폰 · PC (프론트엔드)
👤 방을 보고 나와서 입력
보는 건 누구나 가능하고, 적고 고치는 건 비밀번호가 필요합니다
⚡ 점수는 이 화면에서 바로 계산 (클라이언트 연산)
서버에 물어보지 않아서 입력하는 즉시 숫자가 바뀝니다. 결과만 시트에 같이 저장합니다
📊 카드 목록 · 걸러보기 · 나란히 비교
부동산 이름 목록은 쌓인 데이터에서 저절로 만들어집니다
방 목록
주세요
여기
있습니다
이거 저장
해 주세요
② 구글 쪽 프로그램 (백엔드 · Code.gs)
📤 목록 내주기 (doGet)
시트에 쌓인 방을 통째로 내려줍니다. 날짜가 하루씩 밀리지 않도록 한국 시간 기준 문자열 (시트 시간대 변환) 로 맞춰서 보냅니다
🔒 비밀번호 검사 — 진짜 문지기 (isAuthorized)
저장·수정·삭제는 반드시 여기를 먼저 통과해야 합니다. 틀리면 그대로 돌려보냅니다
📥 저장하기 (doPost — 등록 · 수정 · 삭제)
통과한 요청만 시트에 적습니다. 두 사람이 동시에 저장해도 순서대로 처리되게 잠금 (LockService) 을 걸어둡니다
🤖 쓰는 동안 AI를 부르지 않습니다 (런타임 LLM 호출 없음)
체크 항목과 배점은 미리 정해 코드에 박아뒀습니다 → 빠르고, 돈이 안 들고, 결과가 늘 같습니다
읽고
쓰기
③ 만든 사람의 구글 계정 (데이터 저장소)
📄 구글 시트 (데이터베이스 역할)
방 이름·주소·보증금·월세·도보·점수·메모·체크 진행 상황이 한 줄씩 쌓입니다. 시트를 공유하면 그대로 같이 보는 도구가 됩니다
🖼 구글 드라이브 — 사진첩 (이미지 스토리지)
현장 사진을 올려두면 목록에 자동으로 뜹니다. 긴 쪽 1600px로 줄여 올리기 때문에 느리지 않습니다
🔑 비밀번호가 사는 단 한 곳 (스크립트 속성)
구글 쪽 설정값으로만 보관합니다. 코드에도, 웹페이지에도, 깃 기록에도 없습니다
03 — 인증 · Authentication

웹페이지 안에 비밀은 숨길 수 없습니다

처음에는 비밀번호가 웹페이지 안에 그냥 적혀 있었습니다. 그런데 브라우저가 읽어야 하는 값은 사람도 똑같이 읽을 수 있습니다. 그래서 검사를 구글 쪽 (서버) 으로 옮겼습니다.

저장 버튼을 누르면 이렇게 흘러갑니다

  1. 1
    비밀번호를 입력합니다 — 이 값은 화면이 열려 있는 동안만 (브라우저 메모리) 기억되고, 새로고침하면 사라집니다. 코드 어디에도 적히지 않습니다.
  2. 2
    먼저 맞는지 물어봅니다 (사전 확인 · verify) — 구글 쪽 프로그램에 “이 비밀번호 맞나요?”만 보냅니다. 틀리면 입력 창이 닫히지 않습니다.
  3. 3
    맞으면 입력 폼이 열립니다 — 여기까지는 편하게 쓰라고 있는 단계입니다.
  4. 4
    실제로 저장할 때 다시 보냅니다 — 저장·삭제 요청에도 비밀번호를 같이 실어 보냅니다.
  5. 5
    구글 쪽에서 한 번 더 검사합니다 (서버측 재검증) — 여기가 진짜 문지기입니다. 앞 단계를 건너뛰고 요청을 직접 보내도 여기서 막힙니다.
  6. 6
    통과한 것만 시트에 적힙니다.

🚫 숨기면 되는 거 아닌가요

알아보기 어렵게 바꿔 적어도 (난독화 · 인코딩) 소용없습니다. 브라우저가 실행하려면 결국 원래 값으로 돌려놔야 하고, 그 과정을 사용자도 똑같이 볼 수 있기 때문입니다.

✅ 두 겹으로 막습니다

앞쪽 (1차 · 화면 단계) 은 잘못 누르는 걸 막아주는 편의 장치이고, 뒤쪽 (2차 · 서버 단계) 이 실제 방어선입니다. 앞쪽만 뚫어도 뒤쪽에서 걸리게 해 두었습니다.

⚠️ 그래도 남는 한계

  • 보는 건 누구나 가능합니다 (조회 공개) — 주소를 아는 사람은 방 목록을 볼 수 있습니다
  • 비밀번호는 하나뿐 — 사람마다 따로 주는 방식이 아닙니다
  • 가족·친구끼리 쓰는 정도이고, 민감한 정보를 담을 곳은 아닙니다
04 — 만든 방식 · Workflow

정할 땐 대화로, 고칠 땐 확인으로

체크 항목과 배점은 AI와 대화하면서 정한 뒤 코드에 박아 고정 (규칙 기반 계산) 했습니다. 그래서 쓰는 동안에는 AI를 부르지 않습니다 — 빠르고, 돈이 안 들고, 같은 방은 늘 같은 점수가 나옵니다.

일이 흘러간 순서

  1. 1
    문제를 다시 정의합니다 — “비밀번호를 숨겨줘”라는 요청을 “웹페이지 안에는 숨길 데가 없다”는 사실에서 다시 봅니다
  2. 2
    나눠서 동시에 알아봅니다 (병렬 조사 · 서브에이전트) — 한쪽은 코드 구조를 훑고, 다른 쪽은 어떻게 고칠지 설계합니다
  3. 3
    정해진 절차는 절차대로 (스킬) — 그림 그리기, 문서 만들기, 브라우저로 확인하기처럼 반복되는 일은 매번 새로 고민하지 않습니다
  4. 4
    고칩니다 — 검사를 서버로 옮기고, 예전 기록에 남아 있던 비밀번호까지 지웠습니다 (깃 히스토리 재작성)
  5. 5
    추측하지 않고 직접 확인합니다 (실측 검증) — 실제로 요청을 보내 응답을 읽어봅니다
  6. 6
    올리고 다시 확인합니다 — 기대와 다르면 1번으로 돌아갑니다

🐛 이렇게 해서 찾은 진짜 문제

화면에는 “연결에 실패했습니다” (Failed to fetch) 한 줄만 떴는데, 원인이 세 개나 겹쳐 있었습니다 — 함수가 잘못 겹쳐 쓰여 있었고 (중첩 정의), 공개 설정이 잘못돼 있었고 (배포 액세스 권한), 고친 코드가 아직 반영되지 않은 상태였습니다 (재배포 누락).

😨 그중 제일 아찔했던 것

비밀번호 검사 함수가 실수로 자기 자신 안에 들어가 있어서 (중첩 정의로 호출 불가), 아무 값도 돌려주지 못하고 있었습니다. 결과적으로 비밀번호 없이도 저장이 되던 상태였습니다. 화면만 봐서는 절대 알 수 없었고, 실제로 요청을 보내 응답을 읽어보고서야 드러났습니다.

💡 남는 교훈

증상이 하나라고 원인도 하나인 건 아닙니다. “아마 이것 때문일 것”을 멈추고 직접 보내서 답을 읽는 것, 그게 세 개를 갈라낸 유일한 방법이었습니다.

05 — 배포 · Deploy

배포 — 화면은 자동, 구글 쪽은 수동

저장소가 공개되어 있어서 누구나 그대로 가져가 자기 구글 계정에 붙여 쓸 수 있습니다. 올리는 길이 두 갈래인데 서로 완전히 따로 놉니다 — 여기서 가장 많이 헷갈립니다.

두 갈래 — 한쪽은 자동, 한쪽은 수동

프론트엔드 — 자동
index.html 수정→ 커밋·푸시까지 Claude Code가 (git push)→ 저절로 다시 배포 (Vercel)→ ✅ 바로 반영
백엔드(Apps Script) — 수동
Code.gs 수정→ 저장→ 배포 관리 → ✏️ → “새 버전” → 배포→ ✅ 반영 ← 이 단계를 빼먹으면 저장은 됐는데
   예전 코드가 계속 돌아갑니다

🚀 화면 올리기 — 처음 한 번

1. vercel.com/new 에서 위 저장소 고르기
2. 종류는 Other 그대로
3. Deploy 누르기

따로 설정할 게 없습니다. 이후로는 코드를 올릴 때마다 저절로 반영됩니다.

⚙️ 구글 쪽 준비 — 자기 계정으로

1. 시트 → 확장 프로그램 → Apps Script
2. 준비된 코드 붙여넣기
3. 설정값 (스크립트 속성) 에 비밀번호 넣기
4. 배포할 때 “모든 사용자”로
5. 나온 주소를 WEB_APP_URL 에 넣기

🧯 막히면 여기부터

“연결 실패” (Failed to fetch) 가 뜨면 → 구글 쪽이 JSON 대신 오류 페이지를 돌려준 상태입니다.

공개 범위 (액세스 권한) 가 “구글 계정이 있는 사람”으로 되어 있으면 로그인 창으로 튕깁니다. “모든 사용자”여야 합니다.

새 버전으로 다시 배포했는지 확인하세요. 열에 아홉은 이것입니다.