← 포트폴리오 목록

ESG 자가진단 SaaS

기업과 공공기관이 직접 가입해 ESG·사회적가치 자가진단을 하고 결과 리포트를 받아 보는 B2B 웹 서비스를 실서비스로 전환·납품했습니다.

프로젝트 납품 요약

고객 과제

기업이 직접 만든 ESG 자가진단 웹앱이 로컬에서만 실행되어, 참여 기업과 공공기관이 가입해 진단하고 결과를 받아 볼 수 없었습니다.

개발 범위

원본 화면은 그대로 두고 Supabase 인증·DB 연동, 계정 단위 데이터 격리, 진단 저장 구조 재설계, Netlify 배포 자동화를 붙였습니다.

납품 결과

가입·이메일 인증부터 진단 입력, 리포트 인쇄, 재진단 비교까지 운영 주소에서 동작하는 상태로 납품하고 검수를 지적 없이 마쳤습니다.

아래 프로젝트 개요와 핵심 기능에서 구현 화면을 확인할 수 있습니다.

서비스 타입Web
업종ESG·사회적가치 진단
기술 스택
JavaScriptSupabasePostgreSQLNetlifyGitHub Actions
주요 기능
  • 이메일 인증 가입·로그인 — 세션 만료에도 입력 보존
  • 작성 중 진단 이어 쓰기 — 임시저장과 재시도 안전 제출
  • 재진단과 회차 간 비교 — DB가 매기는 회차 번호
  • 진단 리포트 저장·재조회와 A4 인쇄·PDF 저장
  • 계정 격리·모바일 대응·배포 자동화

프로젝트 개요

범위: 개발

기업과 공공기관이 직접 가입해 ESG·사회적가치 자가진단을 하고 결과 리포트를 받아 보는 B2B 웹 서비스를 실제 운영 서비스로 전환해 납품했습니다. 발주처가 만들어 둔 진단 웹앱은 로컬에서만 실행되고 있었고, 화면과 디자인은 그대로 둔 채 로그인·데이터 저장·배포를 붙여 운영 주소에서 쓸 수 있게 했습니다. 별도 서버를 두지 않고 Supabase와 Netlify만으로 구성해 운영 비용과 관리 부담을 낮췄습니다. 가입과 이메일 인증부터 진단 입력, 리포트 인쇄, 재진단 비교까지 전 과정을 연결하고, 개발 인력이 없는 발주처가 직접 운영할 수 있도록 배포 자동화와 운영 문서까지 갖춰 계약 기간 안에 검수를 마쳤습니다.

작업 범위

  • 인증 연동: 회원가입·이메일 인증·로그인을 연결하고, 스팸으로 빠지지 않게 다듬은 인증 메일을 회사 메일 주소로 보내며, 세션이 만료돼도 작성하던 입력이 지워지지 않도록 처리
  • 진단 저장: 작성 중 진단 이어 쓰기, 여러 번 눌러도 한 건만 남는 제출, 결과 리포트 보관과 회차별 이력 비교를 새 저장 구조로 구현
  • 리포트 출력: 진단 리포트를 A4 인쇄 양식으로 정리해 브라우저에서 바로 인쇄하거나 기업명·날짜가 붙은 PDF로 저장
  • 배포·운영: 저장소 반영만으로 1분 안에 자동 게시되는 배포 체계와 보안 설정을 갖추고, 운영 매뉴얼·DB 구조 문서·점검 결과표를 함께 전달

주요 업무

  • 데이터 보호: 로그인한 기업은 자기 진단만 볼 수 있도록 데이터베이스 권한으로 막고, 제출한 진단은 누구도 고치거나 지울 수 없게 고정
  • 원본 결함 수정: 여러 창에서 동시에 제출하면 회차 번호가 겹치던 문제를 제출 순간 데이터베이스가 번호를 매기는 방식으로 근본 해결
  • 원본 보존: 진단 화면과 계산 방식은 손대지 않고 미리 시험한 연결 부품만 더해, 연동 뒤에도 결과가 원본과 같은지 자동으로 비교
  • 품질 검증: 240여 건의 자동 시험과 안드로이드·iOS·PC 브라우저별 점검으로 가입부터 인쇄까지 전 과정을 빠짐없이 확인하고, 휴대폰 입력 확대 같은 실기기 문제도 바로잡음
ESG 자가진단 SaaS
요구사항 정의

프로젝트 핵심 과제

프로젝트 진행 시 해결한 핵심 기술 과제입니다.

원본을 바꾸지 않는 연동

원본 화면 구조·디자인·진단 로직은 그대로 두고, 미리 만든 연동 부품과 연결 파일 하나로 인증·저장·인쇄를 붙였습니다. 원본 결과 정답지 대조 시험으로 계산이 바뀌지 않았음을 확인했습니다

DB가 지키는 규칙

회차 번호, 제출 후 불변, 결과 점수 범위, 기업명 정제, 계정당 상한을 모두 DB 제약과 트리거로 두어 화면 코드가 빠뜨려도 잘못된 값이 저장되지 않게 했습니다

원본 결함의 근본 수정

'조회 후 +1' 회차 계산이 연타·두 탭에서 겹치던 문제를 계정 단위 잠금으로 DB 한 곳에서 해결했습니다

입력 유실 방지

브라우저와 서버에 작성 중 사본을 함께 두고, 세션이 만료되면 입력을 지우지 않고 재로그인만 안내합니다

제약 안에서 배포

Netlify 무료 요금제가 비공개 저장소의 외부 커밋을 빌드하지 않는 제약을, 빌드 결과를 API로 올리는 배포 방식과 GitHub Actions로 풀었습니다

로컬에서만 실행되던 진단 웹앱을 참여 기업과 공공기관이 직접 가입해 쓰는 운영 서비스로 전환했습니다

구현 내용

핵심 기능 상세

핵심 기능 1

이메일 인증 가입·로그인 — 세션 만료에도 입력 보존

Supabase Auth로 가입·이메일 인증·로그인을 연결했습니다. 인증은 버튼을 눌러야 완료되고, 세션이 만료돼도 입력은 지우지 않습니다.

  • 인증 링크가 메일 보안 검사기에 의해 미리 소모되지 않도록 버튼 클릭형 확인 페이지 + 전용 CSP
  • 세션 만료를 감지하면 입력을 지우지 않고 재로그인만 안내 — 만료와 네트워크 오류를 구분
  • Supabase 오류 코드 전체를 한국어 문구로 바꾸는 메시지 모듈(단위 시험)
  • 가입 메일 제목·본문을 수신 메일함별 스팸 판정 실험으로 조정, 회사 메일 SMTP로 발송

로컬 Mailpit으로 실제 메일을 받아 링크를 여는 통합 시험을 만들어, 가입부터 인증 완료까지를 사람 손 없이 매번 검증했습니다.

이메일 인증 가입·로그인 — 세션 만료에도 입력 보존
이메일 인증 가입·로그인 — 세션 만료에도 입력 보존 실제 화면
핵심 기능 2

작성 중 진단 이어 쓰기 — 임시저장과 재시도 안전 제출

작성 중 진단을 브라우저와 서버에 함께 저장해 재로그인 뒤 이어 씁니다. 제출은 몇 번을 다시 보내도 한 건만 저장됩니다.

  • 진단 시작 때 id를 정해 끝까지 쓰는 멱등 제출 — 연타·재시도해도 중복 저장 없음
  • 브라우저·서버 임시저장을 합쳐 같은 id는 최신 쪽만 보여 주는 이어 쓰기 목록
  • 복원한 값은 그대로 믿지 않고 화면이 아는 영역·범위로 정리해 채움
  • 공용 PC를 고려해 로그아웃 때 이 기기 기록 삭제, 기간 지난 기록 자동 정리

iOS Safari가 7일 미방문 사이트 저장소를 지우는 점을 감안해 브라우저 임시저장만 믿지 않고 서버 사본을 함께 두었습니다.

작성 중 진단 이어 쓰기 — 임시저장과 재시도 안전 제출
작성 중 진단 이어 쓰기 — 임시저장과 재시도 안전 제출 실제 화면
핵심 기능 3

재진단과 회차 간 비교 — DB가 매기는 회차 번호

같은 기업을 다시 진단하면 회차가 쌓이고 영역별 변화를 비교합니다. 회차는 제출 순간 DB가 매겨 겹치지 않습니다.

  • 회차 번호를 BEFORE 트리거에서 계정 단위 advisory lock으로 부여 — 동시 제출에도 중복 없음
  • 제출된 진단은 트리거로 수정·삭제 불가, 작성 중 진단만 본인이 고치고 지울 수 있음
  • 계정당 작성 중 20건·24시간 50건·전체 1,000건 상한을 DB에서 강제(HTTP 429)
  • 기업명은 보이지 않는 문자·앞뒤 공백을 거부해 회차 묶음이 조용히 갈라지지 않게 함

받은 원본의 '조회 후 +1' 회차 계산이 두 탭에서 겹치던 결함을, 화면 코드가 아니라 DB 한 곳에서 해결했습니다.

재진단과 회차 간 비교 — DB가 매기는 회차 번호
재진단과 회차 간 비교 — DB가 매기는 회차 번호 실제 화면
핵심 기능 4

진단 리포트 저장·재조회와 A4 인쇄·PDF 저장

결과를 응답 원본과 함께 스냅샷으로 저장해 언제 열어도 같은 리포트가 나오고, A4 인쇄 스타일로 바로 인쇄·PDF 저장합니다.

  • 진단 1건 = 응답 원본 + 문항 버전 + 결과 스냅샷, 결과 점수 범위는 JSON 경로 CHECK로 검증
  • 인쇄 전용 CSS — 화면 요소 숨김, 차트 크기 고정, 스크롤 상자 펼침, 빈 마지막 쪽 제거
  • 인쇄 파일명을 기업명·날짜 규칙으로 자동 지정
  • 원본 정답지(입력→결과)를 고정해 연동 뒤에도 계산 결과가 원본과 같은지 시험

연동 과정에서 진단 로직이 조금도 바뀌지 않았다는 것을 원본 결과 정답지 대조 시험으로 증명했습니다.

진단 리포트 저장·재조회와 A4 인쇄·PDF 저장
진단 리포트 저장·재조회와 A4 인쇄·PDF 저장 실제 화면
핵심 기능 5

계정 격리·모바일 대응·배포 자동화

RLS로 본인 진단만 보이게 하고 휴대폰 브라우저에 맞춰 다듬었습니다. release 반영만으로 자동 배포됩니다.

  • RLS 정책 4종 — 이메일 인증을 마친 본인 명의로만 생성·조회, 두 계정 격리 시험 통과
  • 보안 헤더(CSP·HSTS·X-Frame-Options 등)를 빌드에 포함하고 배포 후 실측 점검
  • 빌드가 관리자용(secret) 키 혼입을 감지하면 중단, 사용자 입력 출력 지점 XSS 방지
  • 휴대폰 입력칸 16px로 자동 확대 방지, 안드로이드·iOS 브라우저 점검 결과표 납품

빌드 → 초안 게시 → 처리 확인 → 운영 게시 → 게시본 재확인까지를 스크립트 하나로 묶고 GitHub Actions에 연결했습니다.

계정 격리·모바일 대응·배포 자동화
계정 격리·모바일 대응·배포 자동화 실제 화면
구현 과정

프로젝트 진행 단계

STEP 1

연동 모듈 선제 구축·원본 인수 · 2026.10

원본을 받기 전에 인증·저장·인쇄·오류 안내·XSS 방지 모듈을 만들어 시험하고, 받은 웹앱을 수정 없이 반입해 위험 지점을 점검한 뒤 입력→결과 정답지를 고정합니다.

STEP 2

저장 구조 재설계·권한·화면 연결 · 2026.10

진단 저장 구조와 계정 단위 권한 정책을 마이그레이션으로 만들고, 가입·진단 입력·리포트·회차 이력 화면을 새 구조에 연결합니다.

STEP 3

운영 DB 적용·배포 자동화·메일 연결 · 2026.11

운영 DB에 구조를 적용하고 API 배포·GitHub Actions·보안 헤더를 구성하며, 회사 메일로 인증 메일을 연결합니다.

STEP 4

브라우저별 점검·문서 납품·검수 · 2026.11

휴대폰·PC 브라우저별 주요 기능을 점검하고 운영 매뉴얼·점검 결과표를 납품해 검수를 마칩니다.

개발 결과

화면 변경 없이 로컬 웹앱을 실서비스로 전환원본 화면·디자인·진단 로직은 그대로 두고 연동 모듈과 연결 파일만 더해, 가입부터 리포트 인쇄까지 운영 주소에서 동작하게 합니다.
원본 회차 결함을 DB 단에서 해결여러 창에서 동시에 제출하면 겹치던 회차 번호를, 제출 순간 DB가 계정 단위 잠금으로 매기도록 바꿉니다.
계정 단위 데이터 격리와 서버 측 검증RLS·CHECK 제약·트리거로 본인 진단만 보이고 제출분은 고칠 수 없게 하며, 계정 격리를 DB 시험으로 고정합니다.
자동 배포와 240여 건 자동 시험release 반영만으로 1분 안에 게시되는 배포 자동화와 단위·DB 권한·실메일 통합·원본 결과 대조 시험으로 검수를 지적 없이 마칩니다.

기술적 주안점

  • 원본 보존 — 화면·디자인·진단 로직은 건드리지 않고 연동 부품과 연결 파일만 더했습니다
  • 값의 출처 하나 — 화면이 읽는 값은 DB가 응답 원본에서 만들어 서로 어긋날 수 없습니다
  • 서버가 마지막 방어선 — 권한·형식·상한·불변 규칙을 화면이 아니라 DB가 강제합니다
  • 입력 유실 없음 — 세션 만료·네트워크 오류·저장 실패에도 작성 중 진단이 남습니다
  • 사람 손 없는 배포 — release 반영만으로 1분 안에 같은 절차로 게시됩니다

다양한 도메인 응용

  • 자가진단·설문형 평가 서비스 — 인증 진단, 컨설팅 사전 진단, 교육 성취도 평가처럼 응답과 결과 리포트를 계정별로 쌓는 서비스
  • 비개발자가 만든 프로토타입의 실서비스 전환 — AI 도구나 노코드로 만든 웹앱에 로그인·DB·배포를 붙이는 작업
  • 회차 이력 비교가 필요한 기록 서비스 — 정기 점검, 건강·역량 측정처럼 같은 대상의 변화를 추적하는 서비스
  • Supabase·정적 호스팅 기반 B2B SaaS — 별도 서버 없이 RLS로 고객 데이터를 격리하는 소규모 SaaS
  • 인쇄·PDF 제출이 필요한 리포트 서비스 — 브라우저에서 A4 양식으로 바로 내보내는 보고서·증빙 화면

유사한 프로젝트를 기획하고 계신가요?

필요한 기능과 일정을 알려주시면 개발 범위를 함께 정리하겠습니다.

프로젝트 문의