필기억 (inkrecall)
Apple Pencil로 쓴 풀이를 AI가 단계별로 채점하고, 약점을 분석해 유사문제를 만들고, 간격 반복(FSRS)으로 복습시키는 iPadOS 전용 AI 오답노트 - 얇은 SwiftUI 클라이언트 + 두꺼운 FastAPI 백엔드.
- SwiftUI (iPadOS)
- PencilKit
- FastAPI / Python
- Multimodal LLM
- FSRS (SRS)
Setup
- Problem
수험 공부의 핵심 자산은 "내가 틀린 문제와 그 이유"인데, 지금은 종이 오답노트에 흩어지거나 아예 안 만들어진다. 오답노트를 만드는 일 자체가 귀찮기 때문이다. 채점도 정답·오답 이분법이라 "어느 단계에서 왜 막혔는지"는 스스로 알아내야 하고, 약한 유형을 반복해 틀려도 본인은 패턴을 모른다.
- Context
iPad + Apple Pencil 사용자에게 가장 자연스러운 학습 행동은 "손으로 푸는 것"이다. 그 필기 풀이 자체를 1급 입력으로 받아, 오답노트 제작 -> 분석 -> 재학습 -> 복습의 전 과정을 앱이 자동화한다. 1차 코호트는 지불 의사가 분명한 자격증·공무원 준비생. 기획 문서(PRD·아키텍처·기능 IA)와 Figma 디자인을 먼저 확정하고 그 위에서 개발하는 "문서 -> Figma -> 코드" 순서로 진행한다.
Build
- What I did
- 제품 기획을 단일 소스로 먼저 확정 - PRD(비전·타겟·문제·MVP 범위·KPI·수익모델·리스크), 기능 IA(유저 플로우·9개 화면), 기술 아키텍처를 문서로 못박고 개발·디자인이 그 문서를 따르게
- Figma 디자인 시스템 완성 - 컬러 프리미티브 42 + 시맨틱 22(라이트/다크), 타입 램프·스페이싱·라운드·그림자 토큰, 컴포넌트(Button·Chip·VerdictBadge), 9개 화면
- 얇은 클라이언트 / 두꺼운 백엔드로 분리 - SwiftUI(iPadOS, PencilKit)는 캡처·필기·표시·캐시만, 채점·생성·SRS·과금검증은 전부 FastAPI. 공용 로직(InkrecallKit)은 SwiftUI/Foundation만 써서 swift test로 CI 검증되게 앱 타깃과 분리
- 핵심 오답 루프를 스캐폴딩으로 동작까지 - 등록 -> 필기 풀이 제출 -> 단계별 채점(구조화 출력 스키마 + Claude/mock) -> 약점 태그 누적 -> 유사문제 생성 -> FSRS 복습 큐. API 키가 없으면 mock 채점기로 전체 루프가 로컬에서 돈다
- 시험-불가지론 데이터 모델 - 시험/과목/유형을 마스터 데이터로 두어 새 시험 추가가 코드 변경이 아니라 데이터 삽입이 되게
- Product decisions
- 필기를 곁다리가 아니라 코어로 - 키보드 입력·객관식 체크가 아니라 손으로 쓴 풀이 과정 자체를 입력으로. iPad+Pencil 사용자에게 가장 자연스러운 학습 행동을 그대로 제품화하되, 그래서 필기 판독 정확도가 최대 리스크가 됨을 처음부터 리스크 표에 적어뒀다
- 채점이 아니라 진단 - "3번이 틀렸다"가 아니라 "2번째 줄에서 부호를 바꿔 적었고, 이건 2주간 4번 반복된 실수". 그래서 채점 출력을 단계별 구조(정오·오류유형·근거)로 강제
- 아키텍처만 멀티 시험, 론칭 콘텐츠는 1-2개 시험군에 집중 - "멀티 시험 지원"이 콘텐츠 폭을 무한정 넓힐 위험을 스코프 리스크로 인식하고, 코드가 아니라 데이터로 확장하도록 경계
- 월 구독 단일, 무료 티어 한도는 채점 원가 실측 후 결정 - 채점·생성당 LLM 비용이 원가의 핵심이라, 구독가·무료 한도를 감이 아니라 원가 실측 위에서 정하기로
- 시험이 끝난 코호트를 다음 목표로 이관 - 시험 종료 후 오답 자산과 SRS 스케줄을 다음 시험·상위 자격증으로 넘겨, 이탈 대신 리텐션으로
- QA considerations
- 채점 출력이 항상 구조화 스키마(단계별 정오·오류유형·근거)를 지키는가 - 근거 없는 판정을 파싱 단계에서 걸러냄
- 필기 판독 신뢰도(
transcription_confidence)가 낮을 때 바로 채점하지 않고 사용자 확인 상태로 보내는가 - 오채점 신고 → 프롬프트·평가셋 개선으로 이어지는 피드백 루프가 실제로 닫히는가
- API 키 없이 mock 채점기로 핵심 오답 루프(등록→풀이→채점→약점→유사문제→복습)가 끝까지 도는가
- InkrecallKit의 DTO 디코딩·모델을 단위 테스트로 고정해 백엔드 스키마 변경 시 회귀를 잡을 자리 확보
Outcome
- Metrics
- 기획 문서(PRD·기능 IA·아키텍처) + Figma 디자인(9개 화면·디자인 시스템) 완료
- 백엔드(FastAPI)·클라이언트(SwiftUI) 스캐폴딩 완료 - 핵심 오답 루프가 mock 채점기로 로컬에서 동작
- 미출시 - 프로덕션 LLM 연동·실기기·스토어 제출은 진행 예정
- North Star: 주간 채점된 풀이 수. 활성화·전환·리텐션 목표는 가설 단계(측정 전)
진행 과정 (기획 → 개발)
문제·가설에서 스코프·스펙(SSOT)·개발·QA 게이트·배포까지, 같은 틀로 이 앱을 어떻게 기획하고 끌고 갔는지.
진행 과정 (기획 → 개발)
문제 · 가설
수험생의 핵심 자산인 "틀린 문제와 그 이유"가 오답노트 제작 부담 때문에 흩어지거나 안 만들어진다는 문제에서 출발. "손으로 풀기만 하면 나머지는 앱이 한다"를 가설로 세우고, 필기 풀이 자체를 1급 입력으로 받는 iPadOS 전용으로 방향을 좁혔다.
역량 · 문제 정의 · 가설
스코프 · 우선순위
MVP를 "멀티 시험 아키텍처 위에서 핵심 오답 루프 완성"으로 정의. iPhone·Mac·웹, 소셜/랭킹, B2B 대시보드, 오프라인 완전지원, 마켓플레이스를 명시적 비목표로 잘라내고, 론칭 콘텐츠는 지불 의사가 분명한 자격증·공시 1-2개 군에 집중했다.
역량 · 스코핑 · 우선순위
스펙 우선 (SSOT)
PRD·기능 IA·아키텍처 문서를 개발과 Figma의 단일 소스로 두고 "문서 -> Figma -> 코드" 순서를 규칙으로 고정. 채점 출력 스키마, 데이터 모델(ERD), API까지 문서에서 먼저 확정했다.
역량 · 스펙 · 문서화
개발 · 이터레이션
얇은 SwiftUI 클라이언트(캡처·PencilKit 필기·표시·캐시) + 두꺼운 FastAPI 백엔드(채점 오케스트레이션·생성·SRS·과금검증)로 분리. 공용 로직을 InkrecallKit(SwiftUI/Foundation만)으로 떼어내 Xcode 없이 swift test로 검증되게 하고, 앱 타깃은 PencilKit이 필요한 부분만 담았다.
역량 · 실행 · 전달
검증 (QA 게이트)
핵심 오답 루프를 mock 채점기로 로컬에서 끝까지 돌려 스캐폴딩을 검증(등록 -> 풀이 -> 채점 -> 약점 -> 유사문제 -> 복습). InkrecallKit의 DTO 디코딩·모델을 단위 테스트로, 채점 출력은 구조화 스키마로 강제해 파싱·회귀를 잡을 자리를 만들었다.
역량 · 품질 · 리스크
배포
미출시. 다음은 필기 이미지 업로드·실제 LLM 채점 연동, Sign in with Apple·StoreKit 2 실연동, 나머지 화면 구현. 프로덕션 이전에 채점 정확도와 지불 의사를 먼저 검증하는 게 순서다.
역량 · 릴리스
- Tech stack
- SwiftUI (iPadOS 17+)
- PencilKit / SwiftData
- StoreKit 2 · Sign in with Apple
- FastAPI + Pydantic v2
- SQLAlchemy 2.x / Alembic
- Celery/RQ + Redis
- PostgreSQL
- Multimodal LLM (Claude tiering)
- FSRS
- Docker