Skip to content

[NM-617] feat: 제목 없이 남기는 의견 게시판 신설 (/feedback/) - #11

Merged
ParkMazorika merged 2 commits into
mainfrom
feature/feedback-board
Oct 15, 2026
Merged

ParkMazorika merged 2 commits into
mainfrom
feature/feedback-board

Conversation

@ParkMazorika

@ParkMazorika ParkMazorika commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

사용자 의견을 메일보다 가볍게 받을 의견 게시판을 /feedback/에 만든다.

무엇이 바뀌나

  • /feedback/ 신설: 댓글처럼 닉네임(비우면 익명)과 내용만 받고 제목은 없다. 남긴 글과 운영팀 답변을 같은 페이지에 공개한다. 스타일은 지원 페이지를 따랐다.
  • 진입 경로: 랜딩 푸터·FAQ, 지원 페이지 상단·푸터에 링크를 달았다. 게시판 헤더·푸터에서 홈·고객지원으로 돌아간다.
  • 배포 대상: sitemap.xml과 scripts/build-pages.py에 feedback을 추가했다.

서버 구조

별도 서버 없이 운영 계정 드라이브의 스프레드시트 + Apps Script 웹 앱이 읽기·쓰기를 맡는다.

파일 역할
scripts/feedback/Code.gs 시트에 바인딩한 서버 코드. 배포 산출물에 들어가지 않는다
scripts/feedback/README.md 설정·재배포·운영 방법

운영은 시트의 글 탭에서 한다. 답변 칸에 쓰면 「널스메이트 팀」 답변으로 보이고, 공개를 N으로 바꾸면 숨겨진다.

보안상 판단

  • 권한 최소화: @OnlyCurrentDoc으로 이 시트 하나만 접근한다. 웹 앱 액세스는 「모든 사용자」지만, 할 수 있는 일은 공개 글 읽기와 글쓰기뿐이다.
  • XSS·수식 주입: 글은 textContent로만 그린다. =·+·-·@로 시작하는 입력은 수식으로 실행되지 않게 저장한다.
  • 작성 제한은 브라우저별로 건다 (30초 간격, 시간당 5개). Apps Script는 IP를 알 수 없어 페이지가 저장한 무작위 ID로 구분한다. 사이트 전체 제한은 한 사람의 도배가 모두를 막으므로 두지 않았다. ID를 바꾸는 봇은 막지 못한다 — 문제가 되면 Cloudflare Turnstile을 붙인다.
  • 사칭 방지: 「널스메이트」「운영자」 등이 들어간 닉네임은 페이지·서버 양쪽에서 거절한다.
  • 전송 안정성: keepalive로 보내 전송 중에 창을 닫아도 요청이 끝까지 간다.

확인한 것

배포된 웹 앱에 대해 확인했다.

  • 글 읽기·쓰기 (curl, 로컬 페이지에서 크롬으로 직접 작성)
  • 30초 내 재작성 거절, 사칭 닉네임 거절, 브라우저 ID 없는 요청 거절
  • <script>가 든 글이 실행되지 않고 글자로 보임 (목업 데이터)
  • keepalive 요청이 리다이렉트를 거쳐 응답까지 받음
  • 시트에서 답변 작성 → 페이지 표시 (운영자 확인 필요)
  • 모바일 화면 실기기 확인

검토 포인트

  • 사용자 글이 운영 계정 Google 드라이브에 저장된다. 개인정보처리방침에 반영이 필요한지 검토가 필요하다. 페이지에는 환자 정보·연락처를 적지 말라는 안내만 있다.
  • 지금은 글이 바로 공개된다. 승인 후 공개로 바꾸려면 Code.gs의 REQUIRE_APPROVAL을 true로 하고 재배포한다.
image

사용자 의견을 메일보다 가볍게 받을 곳을 만든다. 글은 댓글처럼 닉네임
(비우면 익명)과 내용만 받고 제목은 두지 않는다. 남긴 글과 운영팀 답변은
같은 페이지에 공개된다. 스타일은 지원 페이지(landing.css)를 그대로 따랐다.

서버는 두지 않는다. 운영 계정 드라이브의 스프레드시트에 바인딩한 Apps
Script 웹 앱이 읽기·쓰기를 맡고(scripts/feedback/Code.gs), 운영자는 시트의
답변·공개 칸으로 답변과 숨김을 관리한다. scripts/는 배포 산출물에 들어가지
않으므로 서버 코드는 공개 사이트에 올라가지 않는다.

보안상 판단:

- @OnlyCurrentDoc으로 권한을 이 시트 하나로 줄였다. 웹 앱 액세스가
  「모든 사용자」라 호출은 누구나 할 수 있지만, 할 수 있는 일은 공개 글
  읽기와 글쓰기뿐이다.
- 글은 textContent로만 그려 XSS를 막고, =·+·-·@로 시작하는 입력은 시트
  수식으로 실행되지 않게 저장한다.
- 작성 제한은 브라우저별로 건다(30초 간격, 시간당 5개). Apps Script는
  IP를 알 수 없어 페이지가 저장한 무작위 ID로 구분한다. 사이트 전체
  제한은 한 사람의 도배가 모두의 글쓰기를 막으므로 두지 않았다. ID를
  바꾸는 봇은 막지 못한다 — 필요하면 Turnstile을 붙인다.
- 「널스메이트」「운영자」 등이 들어간 닉네임은 운영팀 사칭이 되므로
  페이지와 서버 양쪽에서 거절한다.
- 전송은 keepalive로 보내 보내는 중에 창을 닫아도 요청이 끝까지 간다.

랜딩 푸터·FAQ, 지원 페이지 상단·푸터에서 게시판으로 연결하고, 사이트맵과
build-pages.py 배포 대상에 feedback을 추가했다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ParkMazorika ParkMazorika self-assigned this Oct 15, 2026
390px 폭에서 확인한 두 가지를 고친다.

- 헤더의 「홈으로」가 보이지 않았다. landing.css가 모바일에서
  `.header-inner nav>a:not(.button)`을 숨기는데, 랜딩의 섹션 메뉴를 접는
  규칙이 게시판 헤더 링크에도 걸렸다. 지원 페이지처럼 nav 밖에 두어 로고
  말고도 돌아갈 길을 남긴다.
- h1이 한 줄로 넘쳐 「들려주세요」가 잘렸다. landing.css의 h1은
  nowrap이라 지원 페이지와 같이 white-space:normal로 푼다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ParkMazorika ParkMazorika changed the title feat: 제목 없이 남기는 의견 게시판 신설 (/feedback/) [NM-617] feat: 제목 없이 남기는 의견 게시판 신설 (/feedback/) Oct 15, 2026
@ParkMazorika
ParkMazorika changed the base branch from develop to main October 15, 2026 10:08
@ParkMazorika
ParkMazorika merged commit 1687c9c into main Oct 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant