← Selected workCASE STUDY / 02 — WEB · ARCHIVE

INC 홈페이지:
자료를 찾고 관리하는
구조를 만들다

흩어진 발간물, 세미나, 워크숍과 보고서 자료를 한곳에서 조회하고 관리할 수 있는 권한 기반 웹사이트를 1인 개발했습니다.

역할웹 프론트엔드·서버 API·DB·배포 / 1인 개발기술Next.js, TypeScript, Supabase, R2운영Vercel · 2026.02 공개
관리 중인 자료
679건

게시판 11개 · 2022–2026 발간

행사 아카이브
11건

포스터·발표자료 등 연결 자료 157건

서버 API
23개

공개 조회 7개 · 관리자 16개

개발 기간
10개월

2025.11 — 2026.09 · 커밋 103회

자료·행사 수는 2026.10.20 운영 DB 기준이며 삭제 처리한 자료는 제외했습니다. API·화면 수(42개)는 저장소 코드 기준입니다. 공개 범위는 public / member / admin 3단계입니다.

01. 자료는 많지만, 일관된 접근 방식이 없었다

기관의 발간물·세미나·보고서가 서로 다른 경로와 형식으로 존재할 때, 이용자는 원하는 자료를 찾기 어렵고 관리자는 공개 범위와 업로드 상태를 일일이 확인해야 합니다.

자료 유형에 맞는 게시판과 검색 흐름을 만들고, 관리자가 직접 콘텐츠를 등록·수정·정리할 수 있는 환경을 구축했습니다.

02. 메타데이터와 파일을 분리한 구조

자료의 제목, 작성일, 게시판, 공개 범위는 PostgreSQL에서 관리하고 실제 문서·이미지·영상 파일은 Cloudflare R2에 저장했습니다. Next.js 서버 API에서 인증, 입력 검증, 공개 범위 판단과 업로드 흐름을 제어하도록 나누었습니다.

Next.js→Supabase / Metadata+Cloudflare R2 / Files

자료 정보와 객체 저장을 분리해 검색·목록 조회와 실제 파일 제공의 책임을 구분했습니다.

공개 범위를 public / member / admin으로 구분하고, 삭제 상태·검색어·카테고리·날짜 등을 조회 조건으로 반영했습니다.

526PDF104이미지24영상16문서9슬라이드

자료 삭제는 행을 지우지 않고 삭제 시각만 기록하는 방식으로 처리합니다. 목록과 검색에서는 빠지지만 기록은 남아, 지금까지 삭제한 37건도 언제 지웠는지 확인할 수 있습니다.

03. 정상 경로만 설계하지 않기

R2 업로드는 성공했지만 DB 저장이 실패한다면?

서로 다른 저장소는 하나의 데이터베이스 트랜잭션으로 묶이지 않습니다. 파일 업로드만 성공하고 자료 메타데이터 저장이 실패하면 저장소에는 조회되지 않는 객체가 남을 수 있습니다.

R2에 파일 업로드

자료의 실제 파일을 저장소에 기록합니다.

DB에 자료 메타데이터 등록

게시판·접근 범위·파일 키 등의 레코드를 저장합니다.

DB 저장 실패 시 업로드 객체 삭제

파일만 고립된 상태로 남지 않도록 보상 처리합니다.

이후 신규 콘텐츠만 고려하는 대신, 기존 자료를 새 분류와 날짜 기준에 맞춰 옮기기 위한 스크립트도 함께 만들었습니다. 재실행과 입력 검증을 고려해 관리 작업의 반복 부담을 줄이는 것이 목표였습니다.

04. 결과와 배운 점

이번 프로젝트에서는 웹 UI를 만드는 일 외에도 자료 저장 위치, 접근 권한, 업로드 실패, 기존 데이터 이관이라는 운영 영역을 직접 다뤘습니다. 특히 하나의 요청이 여러 외부 서비스에 걸쳐 있을 때 각 단계의 실패 상태를 어떻게 처리할지 고민하는 경험이었습니다.