Portfolio

소개와 연락

문제를 정의하고 구조를 설계한 뒤, 구현·검증·운영까지 연결한 프로젝트를 소개합니다.

대표 프로젝트

obsidian-custom-publish

Obsidian Vault를 Rust 전처리기와 Astro 정적 사이트로 변환해 rvnnt.dev에 게시하는 시스템을 구축했습니다.

문제

Obsidian Publish를 대체하면서 위키링크, 검색, 탐색 트리, 미리보기와 다이어그램을 정적 사이트에서 재현해야 했습니다.

역할

저장소 소유자로서 Rust 전처리기, Astro 렌더링 경로와 배포 구성을 설계·구현하고 운영했습니다.

핵심 결정

스캔→링크→변환→검색→출력의 5-pass 전처리와 Astro 렌더링을 분리하고, 생성물과 authored source의 경계를 명시했습니다.

구조

Rust CLI가 Vault를 가공해 콘텐츠와 검색·그래프·탐색 데이터를 만들고, Astro 6 사이트가 unified·rehype·Shiki·KaTeX 파이프라인으로 정적 HTML을 생성합니다.

결과

rvnnt.dev에서 운영되는 정적 블로그와 검색·그래프·탐색 데이터를 하나의 빌드 흐름으로 생성합니다.

배운 점

콘텐츠 문법 변환과 화면 렌더링의 책임을 분리하고 생성물을 직접 수정하지 않아야 재현 가능한 배포를 유지할 수 있음을 확인했습니다.

근거

mcp-local-reference

로컬 Zotero 라이브러리를 검색하고 PDF 텍스트·도판과 Harvard 인용을 제공하는 MCP 서버를 만들었습니다.

문제

연구 자료를 외부 서비스에 복제하지 않고 로컬 Zotero 데이터와 PDF에서 빠르게 찾고 인용 가능한 형태로 꺼낼 방법이 필요했습니다.

역할

저장소 소유자로서 MCP 도구, 로컬 데이터 접근, 인덱싱과 인용 출력 흐름을 설계·구현했습니다.

핵심 결정

Zotero SQLite와 로컬 파일을 읽고 메타데이터 검색과 semantic index를 결합하며, 조회·도판 crop·인용 생성을 별도 도구로 나눴습니다.

구조

Python MCP 서버가 Zotero 메타데이터, collections, PDF text·figures와 semantic index를 연결해 클라이언트 요청에 결과를 반환합니다.

결과

서지 메타데이터 검색, 컬렉션 탐색, PDF 본문·도판 추출, Harvard 인용과 라이브러리 인덱싱을 한 로컬 서버에서 제공합니다.

배운 점

로컬 데이터의 원본 구조를 보존하면서 검색 인덱스를 분리해야 정확한 참조와 재색인을 함께 관리할 수 있음을 배웠습니다.

근거

AdiuBear

음성·이미지·텍스트 입력을 처리하는 Flutter 앱과 Gemini 연동용 Cloud Run 미들웨어를 구현했습니다.

문제

모바일 앱에서 멀티모달 입력을 Gemini에 전달하면서 API 키를 클라이언트에 노출하지 않아야 했습니다.

역할

저장소 소유자로서 Flutter 클라이언트와 Gemini 연동 방식을 구현하고 통합 방향을 반복 검토했습니다.

핵심 결정

API 키 보호를 위해 Cloud Run 미들웨어를 두었고, Live API의 응답 파싱 문서가 충분하지 않아 서버 호출 방식으로 되돌렸습니다.

구조

Flutter 앱이 음성·이미지·텍스트 입력을 수집하고 Firebase·Vertex AI SDK 또는 Cloud Run 중계 계층을 통해 Gemini를 호출합니다.

결과

멀티모달 입력 흐름과 키 보호용 중계 계층을 구현했으며, Live API 실험 결과를 바탕으로 서버 호출 방식으로 전환했습니다.

배운 점

API 기능뿐 아니라 키 보안, 응답 파싱 문서와 운영 가능성을 함께 검토해야 통합 방식을 선택할 수 있음을 배웠습니다.

근거