‹ 프로젝트

AI · 사내 시스템

사내 업무 시스템

노션에 흩어진 314개 DB를 팀이 더 이상 수기로 채우지 않아도 되도록. 대표가 음성으로 던진 지시를 AI가 과업으로 만들고, 검수하면 노션에 자동 반영된다.

기간
2026.04 – 2026.05
역할
기획·설계·구현 단독 (GM/PM)
상태
운영 중
규모
10,450줄

문제

복제 템플릿 200종에 서술형 양식 수십 개. 팀원은 포맷 채우기를 기피하고, 대표는 전화·카톡으로 구두 지시하니 아무것도 시스템에 남지 않았다.

해결

노션을 디스플레이 레이어로 강등하고 D1을 진실의 원천으로 삼았다. 음성·텍스트 지시를 LLM이 담당자·마감·결과물로 구조화하고, 중간관리자 검수를 통과한 과업만 노션에 단방향 push.

314개

정리 대상 노션 DB

운영 배포 완료

상태

음성 · 텍스트PWA홈 화면 설치Cloudflare WorkerHono · TypeScript라우팅 · 권한 · 크론D1 (SQLite)진실의 원천LLM · AI Gateway 경유Claude → OpenAI 폴백Whisper 음성 전사검수 큐사람이 통과시킨다노션디스플레이
  1. 대표가 말한다

    전화·카톡으로 흩어지던 구두 지시를 홈 화면에 깔린 앱에 대고 말합니다. Whisper가 받아 적습니다.

  2. AI가 과업으로 만든다

    담당자·프로젝트·마감·이유·결과물로 구조화합니다. 정보가 부족하면 되묻습니다. AI가 고른 담당자와 프로젝트는 DB에 실재하는지 검증합니다 — 환각 방어입니다.

  3. D1이 진실을 갖는다

    노션이 아니라 D1이 진실의 원천입니다. 노션 스키마에 도메인 모델을 묶으면 피보팅 때 전부 깨지니까요.

  4. 사람이 검수한다

    AI가 만든 과업은 곧바로 노출되지 않습니다. 중간관리자 검수함을 통과해야 합니다. 완전 자동보다 이 게이트가 실무에서 신뢰를 만듭니다.

  5. 노션에 자동 생성된다

    직원들은 노션을 계속 봅니다. 승인된 과업만 단방향으로 밀어 넣어 두 곳의 불일치를 없앱니다.

문제

광고대행사가 노션을 업무 허브로 쓰고 있었습니다. 다만 이런 상태였습니다.

입력 부담은 팀에, 가시성 부재는 경영진에. 둘 다 사람이 메우고 있었습니다.

설계 결정

결정 이유
노션은 디스플레이 레이어, D1이 진실의 원천 노션 스키마에 도메인 모델을 묶으면 피보팅 때 전부 깨진다. 코드 우선으로 분리
이중 궤도 기존 노션은 그대로 두고 [v2 staging]에서 실험 → 검증 후 승격. 운영 중단 0
경영진 슬라이스 먼저 가장 안정적인 니즈(대표 가시성)부터. 팀원 자동화는 후순위
검수 큐 AI·직원이 만든 과업은 전부 중간관리자 검수를 통과해야 노출. 품질과 책임을 한곳으로
앱 → 노션 단방향 push 직원은 노션을 계속 본다. 승인된 과업만 자동 생성해 불일치 제거

핵심 기능

  1. 대화·음성으로 과업 생성 — “팀원1한테 클라이언트D SNS 기획 다음주 금까지 시켜”라고 말하면 Whisper가 받아 적고, AI가 담당자·프로젝트·마감·이유·결과물로 구조화해 확인 카드를 냅니다. 정보가 부족하면 되묻습니다.
  2. 검수 큐 — 만들어진 과업은 중간관리자에게만 보이는 검수함으로. 수정·승인하면 대시보드·브리핑·노션에 동시 반영됩니다.
  3. 자동 일일 브리핑 — 하루 두 번 크론이 오늘 마감·지연·팀 로드·KPI를 모아 LLM이 요약하고, 검수를 거쳐 경영진에게 푸시로 갑니다.
  4. 프로젝트 보드 — 상태·클라이언트별 그룹핑에 진행률과 드릴다운. 노션을 열지 않아도 현황이 보입니다.
  5. 노션 양방향 동기화 — 노션에서 가져올 때는 reconciliation을 포함하고, 내보낼 때는 승인 과업만 단방향으로.
  6. 역할 기반 권한 — 경영진은 지시·조회, 중간관리자는 검수·삭제.

어려웠던 문제

LLM 지역 차단 — 가장 오래 막힌 문제

Worker에서 LLM을 부르면 간헐적으로 403이 났습니다. 처음엔 프롬프트 문제인 줄 알았는데, 세 제공사가 전부 막히는 게 이상했습니다.

원인은 Cloudflare Worker의 아웃바운드 IP였습니다. 사용자 IP와 무관하게, 제공사 입장에서 비지원 지역 풀로 분류되는 주소에서 나가고 있었습니다. 로컬에서 되는 게 Worker에서 안 되면 대개 출구 IP입니다.

Cloudflare AI Gateway를 경유시켜 해결했습니다. API 키도 요청 형식도 그대로 두고 URL만 게이트웨이로 바꿨더니 통과했고, 덤으로 로그·캐시·rate limit이 따라왔습니다. 안전분류기 오탐은 민감 인물명을 토큰화(클라이언트A → CLIENT_A)해서 없앴습니다.

노션 양방향 동기화의 함정

자연어를 구조로 바꾸기

Claude의 function calling으로 create_task와 ask_detail 두 도구만 줬습니다. 지시면 추출하고, 질문이면 그냥 답하고, 정보가 부족하면 되묻습니다 — 한 대화 흐름 안에서 분기합니다.

AI가 고른 project_id·user_id는 D1에 실재하는지 검증합니다. 환각 방어입니다. “나/내가”는 발화자 본인으로 매핑합니다.

배운 것

English Summary

A solo-built full-stack tool that turns an ad agency’s manual, Notion-based workflow into a voice/chat-driven system. A manager speaks a task, Whisper transcribes it, Claude (via tool use) structures it into assignee/project/deadline/spec, and a review queue lets a manager approve before it auto-syncs to Notion. Includes scheduled AI daily briefings with iOS push, role-based access, and bidirectional Notion sync.

Stack: Cloudflare Workers + D1 + Hono (TypeScript), React/Vite PWA, Claude + OpenAI via Cloudflare AI Gateway, Whisper STT, Web Push, Notion API. ~9.5k LOC, solo design and build.

Notable problems solved: edge-IP region-blocking of LLM providers (solved with AI Gateway), Notion trash reconciliation, harvesting member UUIDs the Notion API wouldn’t expose, and hallucination-guarded natural-language-to-task extraction.

광고대행사명과 클라이언트명은 전부 익명 처리

다른 프로젝트 보기 ›