You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
656 lines
62 KiB
Markdown
656 lines
62 KiB
Markdown
# 아리(Ari) — 포스트-MVP 개발 로드맵 & 횡단 아키텍처
|
|
|
|
> 한 줄 요약: MVP 3페이지(작업·인박스·대시보드) 위에 **나머지 10개 페이지 + 횡단 자율성 레이어**(자동화 엔진·승인 큐·커넥터·에이전트·RAG·멀티모달·이벤트 버스·스케줄러·인증)를 얹어, "적을 때는 분류하지 않는다 — 분류·배치·자동화는 아리가"라는 철학을 **실연동·능동 에이전트**까지 끌어올리는 포스트-MVP 진입 문서.
|
|
|
|
> **이 문서는 포스트-MVP 세트의 일부 — 먼저 `dev/overview.md`(MVP 정본)와 이 `dev/post-mvp-overview.md`를 읽으세요.** 이후 `phase-7-approvals-automation.md` → `phase-8-calendar-meetings.md` → `phase-9-mail-notifications.md` → `phase-10-research-travel.md` → `phase-11-life-care.md` → `phase-12-daily-narrative.md` → `phase-13-integrations.md` → `phase-14-proactive-agent.md` → `phase-15-production.md` 순서로 진행합니다.
|
|
|
|
이 문서의 모든 값(색 HEX, px, 클래스명, 한국어 UI 문구, 데이터 필드/시드 값)은 아래 원본에서 **그대로 인용**했습니다. 스택·토큰·데이터모델·API·환경변수·시드·명명 규약은 `dev/overview.md`와 `dev/phase-2-backend.md`를 **상속**하며 임의 변경하지 않습니다.
|
|
|
|
```
|
|
REF = /Users/kim1634/mycloud/personal/workspace/ari_assistant/workspace/design-reference
|
|
REF/PROJECT-README.md (제품·연합 가치 §5)
|
|
REF/결재함.html · REF/자동화.html · REF/일정.html · REF/메일.html · REF/알림.html
|
|
REF/리서치.html · REF/여행.html · REF/라이프.html · REF/여정.html · REF/하루 마감.html
|
|
REF/assets/approve-data.js (결재함: savedToday/autoCountNight/items[risk,cta,alt,undoLabel]/log)
|
|
REF/assets/auto-data.js (자동화: stats/examples/rules/suggests/log)
|
|
REF/assets/cal-data.js (일정: cals/events/focusBlocks/meets, today=8)
|
|
REF/assets/mail-data.js (메일: accounts/folders/people/emails[ai{...}]/sent/drafts)
|
|
REF/assets/notify-data.js (알림: stats/buckets{now,later,held}/guard/digests/senders)
|
|
REF/assets/research-data.js (리서치: collections/sources/report/qa/chart)
|
|
REF/assets/trip-data.js (여행: trip/route/stay/prep/days/check/expense/saved/planner)
|
|
REF/assets/life-data.js (라이프: sources/health/finance/knowledge)
|
|
REF/assets/journey-clean-data.js (여정: stages/cards/links/rows)
|
|
REF/assets/wrap-data.js (하루 마감: stats/highlights/rollover/tomorrow/prep/sleepNote)
|
|
REF/assets/shell.jsx (MAIN 13항목, Icon P 맵, Topbar/SubRail)
|
|
REF/assets/dash.css (디자인 토큰 :root — 상속)
|
|
```
|
|
|
|
---
|
|
|
|
## 0. 목차
|
|
|
|
1. [개요 & 목표](#1-개요--목표)
|
|
2. [선행 조건 / 산출물](#2-선행-조건--산출물)
|
|
3. [포스트-MVP 비전 — 3페이지 → 13페이지 + 연합 + 실연동 + 능동](#3-포스트-mvp-비전--3페이지--13페이지--연합--실연동--능동)
|
|
4. [무엇이 추가되나 — 10개 페이지 + 횡단 레이어](#4-무엇이-추가되나--10개-페이지--횡단-레이어)
|
|
5. [횡단 아키텍처 다이어그램](#5-횡단-아키텍처-다이어그램)
|
|
6. [연합(federation) 시나리오](#6-연합federation-시나리오)
|
|
7. [phase 7~15 로드맵 & 의존 그래프](#7-phase-715-로드맵--의존-그래프)
|
|
8. [신규 데이터 테이블 개요 (MVP 모델 확장)](#8-신규-데이터-테이블-개요-mvp-모델-확장)
|
|
9. [event_bus 이벤트 타입 & 연합 이벤트(발행/구독)](#9-event_bus-이벤트-타입--연합-이벤트발행구독)
|
|
10. [가정/결정 (assumptions) — 사용자가 조정 가능한 지점](#10-가정결정-assumptions--사용자가-조정-가능한-지점)
|
|
11. [비기능 목표(성능/접근성/관측성)의 포스트-MVP 상향선](#11-비기능-목표성능접근성관측성의-포스트-mvp-상향선)
|
|
12. [상태 처리 & 엣지 케이스 (포스트-MVP 전역)](#12-상태-처리--엣지-케이스-포스트-mvp-전역)
|
|
13. [테스팅 & 검증](#13-테스팅--검증)
|
|
14. [완료 기준 (Definition of Done)](#14-완료-기준-definition-of-done)
|
|
15. [이 문서 세트 사용법 + MVP 문서와의 관계](#15-이-문서-세트-사용법--mvp-문서와의-관계)
|
|
|
|
> (위 §번호는 본 진입 문서 내부의 절 번호입니다. CONTRACT 아웃라인 1~11 항목과 1:1 대응하며 일부 절은 통합되어 있습니다.)
|
|
|
|
---
|
|
|
|
## 1. 개요 & 목표
|
|
|
|
이 문서는 **아리 포스트-MVP**의 진입 문서이자 단일 출처(single source of truth)입니다. `dev/overview.md`가 MVP(작업·인박스·대시보드 3페이지)의 정본이라면, 이 문서는 그 **후속**으로서 나머지 10개 페이지와 **횡단 자율성 아키텍처**(automation/connectors/agents/rag/worker), **연합(event_bus)**, **실연동(mock→real 커넥터)**, **능동 에이전트/멀티모달**, **프로덕션 하드닝**까지 총괄합니다.
|
|
|
|
**이 문서가 끝나면 무엇이 동작하는가**: 직접 코드가 동작하지는 않습니다 — 이 문서는 *지도*입니다. 그러나 읽고 나면 개발자는 (1) MVP 위에 무엇을 더 만드는지, (2) 어떤 횡단 레이어(고정 명명)로, (3) 어떤 순서(phase 7→15)로, (4) 어떤 신규 테이블/이벤트/계약으로 만드는지를 완전히 이해하고 `phase-7-approvals-automation.md`로 바로 진입할 수 있습니다.
|
|
|
|
**포스트-MVP의 한 줄 정의**: 지우(PM)의 한 주(6/7~6/13, 오늘 6/8)에서, 아리가 **밤사이 자동으로 처리한 일**을 결재함에서 승인·되돌리고(`risk: low|high`), 자연어 한 문장이 자동화 규칙이 되며, 메일·회의의 액션이 작업으로 흐르고, 리서치·여행은 멀티스텝 **에이전트**가 종합하고, 라이프(건강·금융·지식)는 **커넥터**가 끌어오며, 여정·하루 마감이 전 페이지를 **집계**하고, 외부 제공자(Gmail/Calendar/Health/금융/Notion)는 **같은 인터페이스로 mock→real 교체**되는 — **연합으로 하나의 흐름을 이루는 Life OS**.
|
|
|
|
---
|
|
|
|
## 2. 선행 조건 / 산출물
|
|
|
|
### 2.1 선행 조건 (의존 문서)
|
|
|
|
| 의존 | 내용 |
|
|
|---|---|
|
|
| `dev/overview.md` | 스택·페르소나·데이터모델·API·디자인 토큰·연합 흐름의 MVP 정본. **상속**. |
|
|
| `dev/phase-2-backend.md` | 신규 테이블/엔드포인트가 따라야 할 패턴(SQLModel `models.py`, Pydantic `schemas.py`, 라우터 내부 prefix 없음 + `main.py` `include_router(prefix="/api", tags=...)`, `run_seed(session=None, reset=True)`, `LLMProvider`/`get_provider()`). **상속**. |
|
|
| `dev/phase-1-design-system.md` | 디자인 토큰(`tokens.css`)·`Icon`/`Topbar`(MAIN 13항목)/`SubRail`·라이트/다크·glass. 포스트-MVP 페이지가 셸을 **재사용**. |
|
|
| `dev/phase-3-tasks.md` | 트리/칸반 패턴·`useTasks`/`useTree` — 메일→작업, 회의→작업, 인박스→작업 federation 도착지. |
|
|
| MVP phase 0~6 완료 | phase 7은 MVP 직후 **최우선**(철학 실현). 나머지는 mock-first로 병렬화 가능하나 빌드 순서는 §7 권장. |
|
|
|
|
### 2.2 산출물 (Deliverables)
|
|
|
|
| 산출물 | 내용 | 절 |
|
|
|---|---|---|
|
|
| 포스트-MVP 비전 | 3→13페이지 + 연합 + 실연동 + 능동 | §3 |
|
|
| 추가물 카탈로그 | 10 페이지 + 9개 횡단 레이어(명명 고정) | §4 |
|
|
| 횡단 아키텍처 다이어그램 | FastAPI+SQLite+Ollama 위 automation/connectors/agents/rag/worker + event_bus | §5 |
|
|
| 연합 시나리오 표 | PROJECT-README §5 6대 흐름 → 이벤트/엔드포인트 매핑 | §6 |
|
|
| phase 7~15 로드맵 표 | 목표/산출물/의존성/주요 레이어/규모 + 의존 그래프 | §7 |
|
|
| 신규 테이블 개요 | 페이지별 테이블(원본 필드 이식) + autonomy/approval/automation 코어 | §8 |
|
|
| event_bus 타입 목록 | 발행/구독 매트릭스 | §9 |
|
|
| 가정/결정 | mock-first·모델 비종속·단일→멀티유저 + 조정 포인트 | §10 |
|
|
| 비기능 상향선 | 성능/접근성/관측성 목표치 | §11 |
|
|
| 테스팅 계약 | 실행 명령·케이스·수동 QA·통과 기준 | §13 |
|
|
| 문서 세트 사용법 | 읽는 순서 + MVP 관계 | §15 |
|
|
|
|
---
|
|
|
|
## 3. 포스트-MVP 비전 — 3페이지 → 13페이지 + 연합 + 실연동 + 능동
|
|
|
|
MVP는 **"적으면 분류된다"**(인박스→작업/일정/아이디어)와 **"작업이 위험을 알린다"**(리스크 레이더)를 증명했습니다. 포스트-MVP는 같은 철학을 **세 축**으로 확장합니다.
|
|
|
|
### 3.1 13페이지 완성 — "Life OS"의 표면
|
|
`shell.jsx`의 `MAIN` 13항목이 전부 *실제 페이지*가 됩니다. MVP에서 `/(placeholder)` "준비 중"이던 10개가 모두 동작합니다.
|
|
|
|
| MVP(3) | 포스트-MVP에서 추가되는 10 |
|
|
|---|---|
|
|
| 작업·인박스·대시보드 | 결재함 · 자동화 · 여정 · 일정 · 메일 · 알림 · 리서치 · 여행 · 라이프 · 하루 마감 |
|
|
|
|
### 3.2 연합(federation) — "끊김 없는 하나의 흐름"
|
|
MVP의 연합은 `인박스 capture→confirm→작업 등장` 한 줄기였습니다. 포스트-MVP는 **내부 이벤트 버스(`event_bus`)** 로 *모든* 페이지를 잇습니다(§6, §9). 예: `meeting.ended → action items → task.created`, `mail.received → extract → task/event`, `automation.matched → approval enqueue`, `approval.executed → wrap 집계`.
|
|
|
|
### 3.3 실연동(real integration) — "가정이 아니라 데이터"
|
|
MVP는 시드 목업입니다. 포스트-MVP는 **커넥터 추상화**(`backend/app/connectors/`)로 mail/calendar/chat/finance/health/knowledge 도메인을 추상화하고, phase 13에서 `CONNECTOR_<DOMAIN>=mock|real` 토글로 **같은 인터페이스에 실제 제공자**(Gmail/Workspace/HEY, Google Calendar, Apple Health, 금융 아그리게이터, Notion/Readwise)를 끼웁니다. 페이지는 phase 7~12에서 **mock-first**로 완성됩니다.
|
|
|
|
### 3.4 능동(proactive) — "할까요?가 아니라 이미 해뒀어요"
|
|
MVP의 분류는 *요청-응답*이었습니다. 포스트-MVP는 **백그라운드 스케줄러(`backend/app/worker/`)** 가 사용자가 묻기 전에 움직입니다: 자동화 평가·다이제스트/브리핑 생성·반복 패턴 탐지·심부름 에이전트 실행. 결과는 **결재함**에 쌓여 *읽고 탭 한 번*(승인/되돌리기)으로 끝납니다.
|
|
|
|
> 비전의 정수는 `approve-data.js` 주석 그대로입니다: *"아리는 '할까요?'라고 묻지 않고 미리 해둔다. risk: low → 자율성 '혼합' 이상에서 자동 실행(되돌리기 가능), risk: high → 보내기/결제/타인에게 전달 등은 승인 대기."*
|
|
|
|
---
|
|
|
|
## 4. 무엇이 추가되나 — 10개 페이지 + 횡단 레이어
|
|
|
|
### 4.1 10개 페이지 (담당 phase 문서)
|
|
|
|
| # | 라우트 | 라벨 | 원본 HTML / data | 핵심 | phase |
|
|
|---|---|---|---|---|---|
|
|
| 1 | `/approvals` | 결재함 | `결재함.html` / `approve-data.js` | 승인 큐(low=되돌리기, high=확인 실행), 자율성 설정 | phase-7 |
|
|
| 2 | `/automation` | 자동화 | `자동화.html` / `auto-data.js` | 자연어 한 문장→규칙, 아리 제안, 실행 기록 | phase-7 |
|
|
| 3 | `/calendar` | 일정 | `일정.html` / `cal-data.js` | 주/월/일 캘린더 + 회의 도우미(done/live/upcoming/1:1) | phase-8 |
|
|
| 4 | `/mail` | 메일 | `메일.html` / `mail-data.js` | 3계정 통합 + AI 요약·작업/일정 추출·회신 초안 | phase-9 |
|
|
| 5 | `/notifications` | 알림 | `알림.html` / `notify-data.js` | 트리아지(지금/나중에/아리가 처리) + 집중 보호 + 발신자 규칙 | phase-9 |
|
|
| 6 | `/research` | 리서치 | `리서치.html` / `research-data.js` | 멀티소스 종합 리포트 · 지식 Q&A · 시각화/예측 | phase-10 |
|
|
| 7 | `/trip` | 여행 | `여행.html` / `trip-data.js` | 출장 개요·이동·체크리스트·경비 + AI 여행 플래너 | phase-10 |
|
|
| 8 | `/life` | 라이프 | `라이프.html` / `life-data.js` | 건강·금융·지식(커넥터) | phase-11 |
|
|
| 9 | `/journey` | 여정 | `여정.html` / `journey-clean-data.js` | 4단계 흐름 + 협업 맵(베지어 링크) | phase-12 |
|
|
| 10 | `/wrap` | 하루 마감 | `하루 마감.html` / `wrap-data.js` | 이브닝 브리핑(집계, 풀스크린·상단메뉴 없음) | phase-12 |
|
|
|
|
> 라우트 슬러그는 영문 키(`approvals`/`automation`/`calendar`/`mail`/`notifications`/`research`/`trip`/`life`/`journey`/`wrap`)를 사용합니다. 상단 내비 `MAIN`의 id(`appr/auto/cal/mail/noti/research/trip/life/journey/wrap`)는 그대로 active 판정에 씁니다. `하루 마감`은 풀스크린(상단 메뉴 없음, `wrap-data.js` 컨셉) — 셸을 *적용하지 않는* 유일한 페이지.
|
|
|
|
### 4.2 9개 횡단 레이어 (명명 **고정** — 전 문서가 동일 참조)
|
|
|
|
| 레이어 | 디렉터리 | 역할 | 도입 phase |
|
|
|---|---|---|---|
|
|
| 자동화 엔진 | `backend/app/automation/` | `rule` 모델, `event_bus`, `evaluator`(이벤트→규칙 매칭→동작/승인 enqueue), `nl_parser`(자연어→규칙, LLM provider), `suggester`(반복 패턴→규칙 제안) | phase-7 |
|
|
| 승인 큐 | (모델 `approval`/`autonomy_setting`/`approval_log` + `/api/approvals`) | low+mixed이상=자동 실행(되돌리기), high=승인 대기. activity log | phase-7 |
|
|
| 커넥터 추상화 | `backend/app/connectors/` | 도메인 base 인터페이스 + `MockConnector`(시드) + `RealConnector`(phase-13). 도메인: mail/calendar/chat/finance/health/knowledge | phase-8~11(mock), phase-13(real) |
|
|
| 에이전트 오케스트레이션 | `backend/app/agents/` | LLM provider 위 멀티스텝 루프(plan→act(tool)→observe→reflect). 툴: web_search/rag_query/http_fetch/calendar_write/task_create/form_fill(stub) | phase-10 |
|
|
| RAG/지식베이스 | `backend/app/rag/` | ingest(pdf/web/note)→chunk→embed(Ollama embeddings 추상화)→vector store(SQLite + sqlite-vec 또는 코사인) | phase-10 |
|
|
| 멀티모달 캡처 | (`STTProvider`·`VisionProvider` 추상화, LLM Provider 패턴) | 음성→텍스트, 이미지→캡션/OCR. 인박스 voice/image 실구현 | phase-14 |
|
|
| 연합 이벤트 모델 | (`event_bus` 이벤트 타입) | capture.classified, task.created, meeting.ended, mail.received, automation.matched, approval.executed, notification.triaged … | phase-7~12 누적 |
|
|
| 능동 레이어/스케줄러 | `backend/app/worker/` | APScheduler류 백그라운드. 자동화 평가·다이제스트/브리핑·패턴 탐지·심부름 에이전트. 프로토타입은 수동 트리거 엔드포인트도 제공 | phase-14 |
|
|
| 인증/멀티유저 | (세션 인증 + per-user 스코프) | MVP는 단일 데모 사용자(지우). per-user 데이터 스코프 도입 | phase-15 |
|
|
|
|
---
|
|
|
|
## 5. 횡단 아키텍처 다이어그램
|
|
|
|
기존 `브라우저 ↔ FastAPI ↔ SQLite ↔ Ollama`(MVP, `overview.md` §6) 위에 **자율성 레이어**와 **event_bus**가 얹힙니다. 회색 박스는 MVP 상속, 굵은 박스는 포스트-MVP 신규.
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────────────────────┐
|
|
│ 브라우저 · Next.js (App Router, React, TS) · Topbar(MAIN 13 전부 라이브) │
|
|
│ /dashboard /inbox /tasks ←MVP │
|
|
│ /approvals /automation /calendar /mail /notifications │
|
|
│ /research /trip /life /journey /wrap ←포스트-MVP (mock-first → real) │
|
|
│ │ lib/api.ts (/api) · lib/types.ts (schemas.py 1:1) · lib/hooks/ │
|
|
└────────┼───────────────────────────────────────────────────────────────────────────┘
|
|
│ HTTP/JSON (prefix /api)
|
|
▼
|
|
┌──────────────────────────────────────────────────────────────────────────────────┐
|
|
│ FastAPI · app/main.py (CORS, include_router(prefix="/api", tags=...)) │
|
|
│ ┌──────────────────────────── routers/ (MVP) ───────────────────────────────┐ │
|
|
│ │ tree · tasks · inbox · dashboard · people · llm │ │
|
|
│ ├──────────────────────────── routers/ (포스트-MVP) ─────────────────────────┤ │
|
|
│ │ approvals · automation · calendar · meetings · mail · notifications │ │
|
|
│ │ research · trip · life · journey · wrap · connectors · agents · worker │ │
|
|
│ └────────────────────────────────────┬──────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌────────────────────────────── 횡단 자율성 레이어 (신규) ─────────────────────┐ │
|
|
│ │ │ │
|
|
│ │ ┌───────────────────────── event_bus ─────────────────────────────┐ │ │
|
|
│ │ │ publish/subscribe: capture.classified · task.created · │ │ │
|
|
│ │ │ meeting.ended · mail.received · automation.matched · │ │ │
|
|
│ │ │ approval.enqueued · approval.executed · notification.triaged ... │ │ │
|
|
│ │ └───────┬─────────────┬─────────────┬───────────────┬──────────────┘ │ │
|
|
│ │ ▼ ▼ ▼ ▼ │ │
|
|
│ │ ┌─────────────┐ ┌────────────┐ ┌───────────┐ ┌──────────────────────┐ │ │
|
|
│ │ │ automation/ │ │ agents/ │ │ rag/ │ │ worker/ (스케줄러) │ │ │
|
|
│ │ │ rule │ │ plan→act→ │ │ ingest→ │ │ APScheduler류: │ │ │
|
|
│ │ │ evaluator │ │ observe→ │ │ chunk→ │ │ 자동화 평가·다이제스트│ │ │
|
|
│ │ │ nl_parser │ │ reflect │ │ embed→ │ │ ·패턴 탐지·심부름 │ │ │
|
|
│ │ │ suggester │ │ (tools) │ │ vec store │ │ (+수동 트리거 EP) │ │ │
|
|
│ │ └──────┬──────┘ └─────┬──────┘ └─────┬─────┘ └──────────┬───────────┘ │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ approval 큐 tool calls: embed/query 주기 실행 │ │
|
|
│ │ (low 자동/ web_search, (knowledge) │ │
|
|
│ │ high 대기) rag_query, │ │
|
|
│ │ http_fetch, │ │
|
|
│ │ calendar_write, │ │
|
|
│ │ task_create, │ │
|
|
│ │ form_fill(stub) │ │
|
|
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────────────── connectors/ (도메인 추상화) ───────────────┐ │
|
|
│ │ base IF + MockConnector(시드) ──phase13──▶ RealConnector │ │
|
|
│ │ mail · calendar · chat · finance · health · knowledge │ │
|
|
│ │ env: CONNECTOR_<DOMAIN>=mock|real (기본 mock) │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ models.py (SQLModel) · schemas.py (Pydantic) · seed.py (run_seed) │
|
|
│ llm/ provider.py(LLMProvider) · ollama.py · heuristic.py + STTProvider/Vision │
|
|
│ │ │ │ │ │
|
|
│ ▼ ▼ ▼ ▼ │
|
|
│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
|
│ │ SQLite ari.db│ │ Ollama (LLM) │ │ Ollama embed │ │ 외부 제공자(real)│ │
|
|
│ │ +sqlite-vec? │ │ OLLAMA_MODEL 주입│ │ (embeddings) │ │ Gmail/Cal/Health │ │
|
|
│ │ (vector) │ │ 폴백:heuristic │ │ 폴백:코사인 │ │ 금융/Notion ... │ │
|
|
│ └──────────────┘ └──────────────────┘ └──────────────┘ └──────────────────┘ │
|
|
└──────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**설계 원칙(상속/고정)**:
|
|
- `event_bus`는 **내부 인메모리 pub/sub**(프로토타입). 핸들러가 동기 또는 worker 큐로 동작. 영속 이벤트가 필요하면 `automation_run_log`/`approval_log`에 기록.
|
|
- **event_bus 정본(단일 고정)**: 정본 모듈은 `backend/app/automation/event_bus.py` 하나뿐이다. `class EventBus { publish(event_type: str, payload: dict); subscribe(event_type: str, handler) }` + 전역 인스턴스 `bus = EventBus()`. 모듈 레벨 편의 export 로 `publish = bus.publish`, `subscribe = bus.subscribe`, `emit = bus.publish`(`emit` 은 `publish` 별칭)을 함께 제공한다. 따라서 `from app.automation.event_bus import bus`(`bus.publish('x', {...})`)와 `from app.automation.event_bus import publish`(`publish('x', {...})`, `emit` 동일) 둘 다 정상이다. `backend/app/events.py`·`backend/app/event_bus.py` 같은 다른 경로/심볼은 정본이 아니며 사용 금지.
|
|
- 모든 신규 라우터는 **내부 prefix 없음** → `main.py`에서 `include_router(prefix="/api", tags=...)`로만 `/api` 부착(phase-2 규약).
|
|
- 모든 모델/임베딩/STT/Vision은 **env 주입 + 폴백**(모델 비종속). Ollama 미가용·오프라인·CI에서도 `heuristic`/`scripted`/`코사인` 폴백으로 데모 결정성 보장.
|
|
|
|
---
|
|
|
|
## 6. 연합(federation) 시나리오
|
|
|
|
PROJECT-README §5의 6대 흐름을 포스트-MVP의 **이벤트/엔드포인트/도착지**로 매핑합니다. (`→`는 event_bus 발행, 굵은 한국어는 원본 UI 문구.)
|
|
|
|
| # | 흐름 | 트리거 → 처리 → 도착지 | 핵심 이벤트 | 관련 phase |
|
|
|---|---|---|---|---|
|
|
| F1 | 캡처 → 분류 → 실행 | 인박스 한 줄 → `POST /api/inbox/capture`(동기 분류) → confirm → 작업/일정/아이디어 | `capture.classified` → `task.created`/`calendar.updated` | MVP + phase-8 |
|
|
| F2 | 메일 → 작업/일정 | 메일 본문 `ai.tasks[]`/`ai.events[]` 추출 → "작업으로"/"캘린더로" → 작업 보드·캘린더 등장 | `mail.received` → `task.created`/`calendar.updated` | phase-9 |
|
|
| F3 | 회의 → 작업 | 끝난 회의(`meets.e3.phase="done"`) 액션 아이템 추출 → **"작업으로" 한 번에 전송** → 담당자 작업 | `meeting.ended` → `task.created` | phase-8 |
|
|
| F4 | 일정 ↔ 작업 ↔ 집중 모드 | 캘린더 빈 블록 읽어 `focusBlocks` 자동 배치 → 마감/쏠림은 리스크 레이더가 감시 | `calendar.updated` → `calendar.focus_scheduled` | phase-8 (+ MVP 리스크) |
|
|
| F5 | 위임 루프 | 일정 과부하 감지 → **"민서님께 '데이터 전처리' 위임 요청"**(결재함 high) → 1:1 도우미가 위임 과제 진행 추적(`meets.e7.promises`/`signals`) | `proactive.detected` → `approval.enqueued`(high) → `approval.executed` | phase-7 + phase-8 |
|
|
| F6 | 자동 처리 → 결재함 → 하루 마감 | 밤사이 자동 처리(`autoCountNight: 7`) → 결재함 승인/되돌리기 → 하루 마감 **"아리 자동 처리 12건 · 47분 아낌"** 합산 | `automation.matched` → `approval.enqueued` → `approval.executed` → `wrap.reflected` | phase-7 + phase-12 |
|
|
| F7 | 알림 트리아지 → 자동화 제안 | 알림 분류(`buckets.now/later/held`) → 반복 패턴(`suggests`) → 자동화 규칙 제안(레일 dot) | `notification.triaged` → `automation.suggested` | phase-9 + phase-7 |
|
|
| F8 | 공통 인물·프로젝트 | 지우·현우·민서·재호·수아 + 온보딩/분기 리포트가 전 페이지에 일관 등장(`person`/`project` 공유) | (정적 일관성) | 전 phase |
|
|
|
|
**대표 federation 데이터 경로 — F3 회의→작업 (cal-data.js `meets.e3`)**
|
|
```
|
|
회의 끝남(done) — actions:
|
|
[{ text:"온보딩 와이어프레임 피드백 정리", who:"나", when:"오늘", added:true },
|
|
{ text:"푸시 알림 QA 결과 공유", who:"수아", when:"내일", added:true },
|
|
{ text:"매출 데이터 전달", who:"현우", when:"오늘", added:false }]
|
|
│ POST /api/meetings/{id}/actions/to-tasks (added=false 항목을 task로 전송)
|
|
▼
|
|
event_bus.publish("meeting.ended", { event_id:"e3", actions:[...] })
|
|
▼ evaluator/handler
|
|
task 생성 (assignee=현우, title="매출 데이터 전달", project="경영 전략 · 분기 리포트")
|
|
▼
|
|
GET /api/tasks 에 즉시 등장 (작업 보드, phase-3 패턴) · 여정/하루마감 집계 갱신
|
|
```
|
|
|
|
**대표 federation 데이터 경로 — F6 자동 처리→결재함→하루 마감**
|
|
```
|
|
worker(스케줄러) 야간 실행 → automation.evaluator 가 rule 매칭
|
|
▼ approval enqueue: risk=low → 자동 실행 + undo_label; risk=high → status=pending
|
|
approve-data.js 시드 예: a1 "치과 예약을 16:00로 옮겼어요"(low, undoLabel:"원래 시간으로")
|
|
a4 "현우님께 회신 초안이 준비됐어요"(high, cta:"보내기", alt:"수정")
|
|
▼ 사용자: POST /api/approvals/{id}/approve | /undo
|
|
event_bus.publish("approval.executed", { id:"a4", saved_minutes:... })
|
|
▼ wrap.aggregator
|
|
하루 마감 stats: { n:"12", label:"아리 자동 처리", sub:"47분 아낌" } (wrap-data.js)
|
|
```
|
|
|
|
---
|
|
|
|
## 7. phase 7~15 로드맵 & 의존 그래프
|
|
|
|
### 7.1 로드맵 표
|
|
|
|
| Phase | 문서 | 목표(끝나면 동작) | 핵심 산출물 | 의존성 | 주요 신규 레이어 | 규모 |
|
|
|---|---|---|---|---|---|---|
|
|
| 7 | `phase-7-approvals-automation.md` | **자율성 코어**. 결재함(승인/되돌리기, 자율성 설정) + 자동화 엔진(자연어→규칙, 아리 제안, 실행 기록). low 자동/high 대기. | `approval`/`autonomy_setting`/`approval_log`, `automation_rule`/`automation_suggestion`/`automation_run_log`/`automation_stats`, `automation/`(event_bus·evaluator·nl_parser·suggester), `/api/approvals`·`/api/automation` | MVP(0~6) | automation, event_bus, 승인 큐 | L |
|
|
| 8 | `phase-8-calendar-meetings.md` | 일정(주/월/일) + 회의 도우미(done/live/upcoming/1:1). 액션→작업 연합, 집중 블록 자동 배치. | `calendar`/`event`/`focus_block`/`meeting`, `/api/calendar`·`/api/meetings`, calendar 커넥터(mock) | 7 | connectors(calendar mock), event_bus | L |
|
|
| 9 | `phase-9-mail-notifications.md` | 3계정 메일 + AI 요약/작업·일정 추출/회신 초안. 알림 트리아지(지금/나중에/아리가 처리) + 집중 보호 + 발신자 규칙. | `mail_account`/`email`/`mail_folder`/`sent`/`draft`, `notification`/`notification_guard`/`digest`/`sender_rule`/`notify_stats`, `/api/mail`·`/api/notifications`, mail/chat 커넥터(mock) | 7,8 | connectors(mail/chat mock) | L |
|
|
| 10 | `phase-10-research-travel.md` | 리서치(멀티소스 종합·지식 Q&A·시각화/예측) + 여행(출장·AI 플래너). 에이전트 오케스트레이션 + RAG + 웹검색. | `research_collection`/`research_source`/`research_report`/`knowledge_qa`/`research_chart`, `trip`/`trip_route`/`trip_stay`/`trip_prep`/`trip_day`/`trip_checklist`/`trip_expense`/`saved_trip`/`trip_plan`, `agents/`, `rag/`, `/api/research`·`/api/trip`·`/api/agents` | 7,9 | agents, rag, web_search | L |
|
|
| 11 | `phase-11-life-care.md` | 라이프 케어(건강·금융·지식). 커넥터(health/finance/knowledge mock). knowledge_item은 리서치와 공유. | `connector_source`, `health`, `finance`, `knowledge_item`, `/api/life`, health/finance/knowledge 커넥터(mock) | 7,10 | connectors(health/finance/knowledge mock) | M |
|
|
| 12 | `phase-12-daily-narrative.md` | 여정(4단계 + 협업 맵) + 하루 마감(이브닝 브리핑). 전 페이지 집계 narrative. | `journey_link`(최소), wrap 집계 서비스, `/api/journey`·`/api/wrap` | 7,8,9,10,11 | event_bus(집계 구독) | M |
|
|
| 13 | `phase-13-integrations.md` | 외부 연동 & 커넥터(mock→real). 같은 인터페이스로 실제 제공자 교체. | `RealConnector`(Gmail/Workspace/HEY, Google Calendar, Apple Health, 금융 아그리게이터, Notion/Readwise), OAuth/토큰 저장, `CONNECTOR_<DOMAIN>=real` | 8~11 | connectors(real) | L |
|
|
| 14 | `phase-14-proactive-agent.md` | 능동형 에이전트 + 멀티모달 캡처. 심부름 대행·능동 알림·음성/이미지. | `worker/`(APScheduler류 + 수동 트리거 EP), `STTProvider`/`VisionProvider`, 인박스 voice/image 실구현, 능동 다이제스트/브리핑 | 7~12 | worker, 멀티모달 | L |
|
|
| 15 | `phase-15-production.md` | 프로덕션 하드닝. 인증/멀티유저/배포/관측성/성능/보안. | 세션 인증 + per-user 스코프, 배포(Docker/compose), 로깅/메트릭/트레이싱, 성능·보안 점검 | 7~14 | 인증/멀티유저 | L |
|
|
|
|
> 규모 표기: M(보통)/L(큼) — 상대 추정. phase 7~10·13~15는 L, 11~12는 M.
|
|
|
|
### 7.2 빌드 순서 & 의존 그래프
|
|
|
|
```
|
|
빌드 순서: 7 → 8 → 9 → 10 → 11 → 12 → 13 → 14 → 15
|
|
(7은 MVP 직후 최우선 — 철학 실현, MVP에만 의존)
|
|
|
|
의존 그래프 (→ = 선행):
|
|
MVP(0~6) ──▶ 7(결재함·자동화) ──┬─▶ 8(일정·회의) ──┬─▶ 9(메일·알림) ──┐
|
|
│ │ │
|
|
│ └──────────────────┤
|
|
│ ▼
|
|
└────────────────────────────────▶ 10(리서치·여행)
|
|
│
|
|
11(라이프) ◀──────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
12(여정·하루마감) ◀── (7,8,9,10,11 집계)
|
|
│
|
|
▼
|
|
13(실연동 mock→real) ── 8~11 의 커넥터 인터페이스에 끼움
|
|
│
|
|
▼
|
|
14(능동·멀티모달) ── 7~12 위에 worker/STT/Vision
|
|
│
|
|
▼
|
|
15(프로덕션·인증/멀티유저)
|
|
```
|
|
|
|
- **페이지는 mock-first**: phase 7~12는 커넥터의 `MockConnector`(시드)로 완성. phase 13이 동일 인터페이스에 `RealConnector`를 끼워 *페이지 재작성 없이* 실연동 전환.
|
|
- **7이 최우선**: 결재함·자동화는 철학("이미 해뒀어요")의 실현이며 MVP에만 의존 → 가장 먼저.
|
|
- **12는 마지막 집계**: 여정·하루 마감은 작업·일정·결재·자동화·메일 등에서 계산되므로 페이지 phase 이후.
|
|
|
|
---
|
|
|
|
## 8. 신규 데이터 테이블 개요 (MVP 모델 확장)
|
|
|
|
> 규약(상속): 모든 PK는 **TEXT(str)**. `tone` enum 집합 `blue|violet|coral|green|amber|ink|faint`(+ 원본 일부 데이터에 `muted` 존재 — 알림/수면 stages — 는 시드 문자열 그대로 저장하되 표시 시 `--faint`로 매핑). 날짜/문구/금액 등 한국어 UI는 **원본 *-data.js 문구를 그대로** 사용. 신규 테이블/필드는 각 phase 문서가 원본에서 정밀 이식하며, 아래는 **개요**입니다.
|
|
|
|
### 8.1 횡단 코어 (phase-7) — autonomy / approval / automation
|
|
|
|
```python
|
|
# backend/app/models.py (발췌 — phase-7 가 확정)
|
|
|
|
class Approval(SQLModel, table=True): # approve-data.js: items[]
|
|
id: str = Field(primary_key=True) # 예 "a1".."a6"
|
|
icon: str # cal|mail|users|wallet (Icon P 맵 키)
|
|
tone: str # coral|blue|violet|green|amber
|
|
risk: str # "low" | "high"
|
|
status: str = "pending" # pending|approved|undone|executed
|
|
source: str = "automation" # 허용값: automation|agent|mail|calendar|finance|inbox|life|system
|
|
time: str # "07:42" | "보내기 대기" | "확인 필요"
|
|
title: str # "치과 예약을 16:00로 옮겼어요"
|
|
detail: str | None = None
|
|
cta: str | None = None # high: "보내기" | "전달" | "일시정지"
|
|
alt: str | None = None # high: "수정" | "내가 할게" | "유지"
|
|
undo_label: str | None = None # low: "원래 시간으로" | "되돌리기" | "블록 해제"
|
|
created_at: datetime
|
|
|
|
class AutonomySetting(SQLModel, table=True):
|
|
id: str = Field(default="default", primary_key=True) # PK=TEXT(str), 단일 row id="default"
|
|
level: str = "mixed" # approval_first | mixed | full_auto
|
|
# AutonomySetting 정본: PK 는 TEXT(str), 단일 row id="default".
|
|
# 조회 session.get(AutonomySetting, "default"); 시드 AutonomySetting(id="default", level=...).
|
|
# (briefing/automation_stats/notify_stats/guard 등 기존 단일 row 집계 테이블의 int id=1 은 MVP 상속 예외로 유지.)
|
|
|
|
class ApprovalLog(SQLModel, table=True): # approve-data.js: log[]
|
|
id: str = Field(primary_key=True)
|
|
time: str # "08:55" | "어제 23:10"
|
|
text: str # "스탠드업 직전 — 어제 진행 요약 노트 생성"
|
|
created_at: datetime
|
|
|
|
class AutomationRule(SQLModel, table=True): # auto-data.js: rules[]
|
|
id: str = Field(primary_key=True) # "r1".."r7"
|
|
on: bool = True # enabled
|
|
cat: str # mail|focus|cal|life
|
|
name: str # "수아님 메일은 바로"
|
|
trigger: str # "수아님 발신 메일"
|
|
cond: str | None = None # "긴급 표시가 아니면"
|
|
action: str # "즉시 알림 + 3줄 요약"
|
|
last: str | None = None # "오늘 09:12" | "어제 18:30"
|
|
runs: int = 0
|
|
|
|
class AutomationSuggestion(SQLModel, table=True): # auto-data.js: suggests[]
|
|
id: str = Field(primary_key=True) # 시드 id 규칙: asug-s1, asug-s2 (원본 s1/s2 에 asug- prefix)
|
|
pattern: str # "월요일 아침마다 주간 리포트 초안을 ..."
|
|
offer_name: str; offer_cat: str
|
|
offer_trigger: str; offer_cond: str | None; offer_action: str
|
|
|
|
class AutomationRunLog(SQLModel, table=True): # auto-data.js: log[]
|
|
id: str = Field(primary_key=True)
|
|
time: str; rule: str; text: str # "12:48" / "영수증 자동 정리" / "점심 결제 13,500원 → 식비로 분류"
|
|
```
|
|
|
|
> `automation_stats`(`auto-data.js: stats { active:7, runsWeek:31, saved:"1시간 40분" }`)와 결재함 헤더(`savedToday:"47분"`, `autoCountNight:7`)는 **집계 응답**(`GET /api/automation/stats`, `GET /api/approvals`)으로 계산 — 별도 테이블 대신 카운트/뷰 권장.
|
|
|
|
### 8.2 페이지별 신규 테이블 (개요 — 원본 *-data.js 기준)
|
|
|
|
| 페이지 | 테이블 (개요) | 원본 필드(인용) | 원본 |
|
|
|---|---|---|---|
|
|
| 결재함 | `approval`, `autonomy_setting`(PK str, 단일 row id="default"), `approval_log` | `risk`,`status`,`source`(automation\|agent\|mail\|calendar\|finance\|inbox\|life\|system),`cta`/`alt`/`undo_label`,`savedToday:"47분"`,`autoCountNight:7` | approve-data.js |
|
|
| 자동화 | `automation_rule`, `automation_suggestion`, `automation_run_log`, (`automation_stats`=뷰) | `trigger`/`cond`/`action`/`cat`/`on`/`last`/`runs`, `pattern`/`offer` | auto-data.js |
|
|
| 일정 | `calendar`(=cals), `event`, `focus_block`, `meeting` | `day`/`start`/`end`/`title`/`cal`/`loc`/`people`/`note`/`soon`/`actions`; meeting `phase: done|live|upcoming`, `summary`/`decisions`/`actions`/`agenda`/`lastMeeting`/`lastActions`/`insights`/`signals`/`talkingPoints`/`oneOnOne` | cal-data.js (today=8) |
|
|
| 메일 | `mail_account`(3), `email`, `mail_folder`, `sent`, `draft` | `account`/`from`/`to`/`subject`/`body`/`labels`/`read`/`starred`/`attachments` + `ai{summary,priority,category,tasks[],events[],replies[],file}` | mail-data.js |
|
|
| 알림 | `notification`, `notification_guard`, `digest`, `sender_rule`, (`notify_stats`=뷰) | `bucket: now|later|held`, `src`/`app`/`title`/`sum`/`time`/`why`/`tone`/`act`; guard `on`/`until`/`held`/`quiet` | notify-data.js |
|
|
| 리서치 | `research_collection`, `research_source`, `research_report`, `knowledge_qa`, `research_chart` | source `kind: pdf|web|note`, `learned`; report `synthesis`/`cross[]`/`counts`/`note`; qa `q`/`a`/`refs`; chart `bars`(+`forecast`)/`insight`/`caution` | research-data.js |
|
|
| 여행 | `trip`, `trip_route`(out/back), `trip_stay`, `trip_prep`, `trip_day`(items), `trip_checklist`, `trip_expense`, `saved_trip`(spark), `trip_plan` | `dday:"D-4"`, route `mode`/`seat`, prep `state: done\|doing`, expense `budget`/`planned`/`rows[state: paid\|hold\|est]`, planner `results[transport/stay/days/budget/checklist/sources]` | trip-data.js |
|
|
| 라이프 | `connector_source`, `health`, `finance`, `knowledge_item` | source `on`/`last`; health `rings`/`vitals`/`sleep`/`coach`/`habits`; finance `budget`/`cats`/`subs`/`coach`/`insights`; knowledge_item `type: article\|note\|idea\|highlight` + `ai` | life-data.js |
|
|
| 여정 | (집계 뷰 중심) `journey_link`(최소, 필요시) | `stages`(4) + `cards` + `links`(베지어, from/to/c/dash) + `rows` | journey-clean-data.js |
|
|
| 하루 마감 | (집계 중심, 상태 저장만) | `stats`/`highlights`/`rollover`/`tomorrow`/`prep`/`sleepNote`; 회고 한 줄·수면 모드는 상태 저장 | wrap-data.js |
|
|
|
|
> `knowledge_item`은 **리서치(research)와 라이프(life)가 공유** 가능(life-data.js `knowledge.items[]`의 `type: article|note|idea|highlight` ≈ research 컬렉션 소스). phase-11이 정본 테이블을 두고 phase-10이 참조.
|
|
|
|
> 라우터 등록(상속): 신규 라우터도 내부 prefix 없이 정의하고 `main.py`에서 `app.include_router(approvals.router, prefix="/api", tags=["approvals"])` 형태로만 `/api` 부착. 시드는 `run_seed(session=None, reset=True)` 안에서 `_seed_approvals(session)`·`_seed_automation(session)` 등 **내부 헬퍼**로 호출(공개 진입점 아님 — phase-2 `_seed_dashboard` 패턴).
|
|
|
|
### 8.3 신규 환경변수 (상속 + 추가)
|
|
|
|
상속(overview.md): `DATABASE_URL`, `OLLAMA_HOST`, `OLLAMA_MODEL`, `LLM_PROVIDER(auto|ollama|heuristic)`, `FRONTEND_ORIGIN`, `NEXT_PUBLIC_API_BASE`.
|
|
|
|
추가(포스트-MVP, 모두 폴백 기본값 보유):
|
|
|
|
| 변수 | 기본값 | 용도 | 도입 |
|
|
|---|---|---|---|
|
|
| `CONNECTOR_MAIL` | `mock` | 메일 커넥터 mock\|real | 9/13 |
|
|
| `CONNECTOR_CALENDAR` | `mock` | 캘린더 커넥터 | 8/13 |
|
|
| `CONNECTOR_CHAT` | `mock` | 메신저 커넥터 | 9/13 |
|
|
| `CONNECTOR_FINANCE` | `mock` | 금융 아그리게이터 | 11/13 |
|
|
| `CONNECTOR_HEALTH` | `mock` | Apple Health/Watch | 11/13 |
|
|
| `CONNECTOR_KNOWLEDGE` | `mock` | Notion/Readwise/웹클리퍼 | 11/13 |
|
|
| `EMBED_PROVIDER` | `ollama` | RAG 임베딩 ollama\|heuristic | 10 |
|
|
| `EMBED_MODEL` | (주입) | 임베딩 모델명(기본 예시만, 비종속) — `EMBED_PROVIDER` 와 반드시 함께 사용 | 10 |
|
|
| `WEB_SEARCH_PROVIDER` | `mock` | 웹검색 mock\|real … | 10 |
|
|
| `AGENT_PROVIDER` | (`LLM_PROVIDER` 따름) | 에이전트 루프 제공자(기본은 `LLM_PROVIDER` 상속) | 10 |
|
|
| `STT_PROVIDER` / `STT_MODEL` | `auto` / (주입) | 음성→텍스트(whisper류) | 14 |
|
|
| `VISION_PROVIDER` / `VISION_MODEL` | `auto` / (주입) | 이미지→캡션/OCR | 14 |
|
|
| `WORKER_ENABLED` | `false` | 스케줄러 on/off(프로토타입은 수동 트리거 EP) | 14 |
|
|
| `AUTH_ENABLED` | `false` | 세션 인증(단일 데모 사용자 기본) | 15 |
|
|
|
|
---
|
|
|
|
## 9. event_bus 이벤트 타입 & 연합 이벤트(발행/구독)
|
|
|
|
### 9.1 이벤트 타입 목록 (명명 고정 — 정본)
|
|
|
|
> 이벤트 이름은 아래가 정본이며 **이 이름만 사용**한다(발행/구독 짝 일치). 금지/교정: `approval.created`→`approval.enqueued`, `automation.suggestion_candidate`→`automation.suggested`. 발행은 정본 모듈 `backend/app/automation/event_bus.py` 의 `publish(event_type, payload)`(별칭 `emit`) 로만 한다.
|
|
|
|
| 이벤트 타입 | 페이로드(개요) | 첫 발행 phase |
|
|
|---|---|---|
|
|
| `capture.classified` | `{ item_id, type, sphere, project_id?, reason }` | MVP/7 |
|
|
| `task.created` | `{ task_id, assignee_id, project_id, source }` | MVP/8 |
|
|
| `meeting.ended` | `{ event_id, actions:[{text,who,when,added}] }` | 8 |
|
|
| `calendar.updated` | `{ event_id, day, start, end, cal, source }` | 8 |
|
|
| `calendar.focus_scheduled` | `{ id, day, start, end, type: light\|deep }` | 8 |
|
|
| `mail.received` | `{ email_id, account, ai:{tasks,events,replies} }` | 9 |
|
|
| `notification.triaged` | `{ id, bucket: now\|later\|held, why }` | 9 |
|
|
| `automation.matched` | `{ rule_id, event, action }` (규칙 매칭) | 7 |
|
|
| `automation.suggested` | `{ suggestion_id, pattern, offer }` (제안; `automation.suggestion_candidate` 금지) | 7/9 |
|
|
| `approval.enqueued` | `{ id, risk, source }` (결재 enqueue; `approval.created` 금지) | 7 |
|
|
| `approval.executed` | `{ id, risk, saved_minutes? }` (실행) | 7 |
|
|
| `approval.undone` | `{ id, risk }` (되돌리기) | 7 |
|
|
| `research.completed` | `{ collection_id, report_id }` | 10 |
|
|
| `knowledge.ingested` | `{ item_id, kind: pdf\|web\|note }` | 10/11 |
|
|
| `trip.plan.saved` | `{ plan_id, query }` | 10 |
|
|
| `price.target.hit` | `{ target_id, symbol, price }` | 11 |
|
|
| `errand.started` | `{ errand_id, kind }` | 14 |
|
|
| `errand.updated` | `{ errand_id, progress }` | 14 |
|
|
| `errand.completed` | `{ errand_id, result }` | 14 |
|
|
| `proactive.detected` | `{ pattern_id, kind, suggest }` | 14 |
|
|
| `weekly.reviewed` | `{ week, stats }` | 12 |
|
|
| `wrap.reflected` | `{ date, note }` | 12 |
|
|
| `finance.transaction` | `{ txn_id, amount, category }` | 11 |
|
|
| `health.sample` | `{ sample_id, metric, value }` | 11 |
|
|
|
|
> 체인: `notification.triaged` → (phase-7 suggester 구독) → `automation.suggested`. phase-7 suggester 는 `notification.triaged` 구독 + 수동 scan 둘 다 지원하며 `automation.suggested` 를 발행한다.
|
|
|
|
### 9.2 발행/구독 매트릭스 (페이지/레이어별)
|
|
|
|
| 발행자 → 이벤트 | 구독자(처리) |
|
|
|---|---|
|
|
| 인박스 `capture.classified` | 자동화 evaluator(규칙 매칭) · 대시보드 집계 |
|
|
| 일정 `meeting.ended` | 작업(`task.created`) · 여정/하루 마감 집계 |
|
|
| 일정 `calendar.updated` | worker → `calendar.focus_scheduled`(집중 블록 자동 배치) · 여정/하루 마감 집계 |
|
|
| 메일 `mail.received` | 작업/일정(추출, `task.created`/`calendar.updated`) · 알림 트리아지 · suggester |
|
|
| 알림 `notification.triaged` | suggester → `automation.suggested`(레일 dot) |
|
|
| 자동화 `automation.matched` | 승인 큐(`approval.enqueued`) · 실행 기록 |
|
|
| 승인 큐 `approval.enqueued` | low+mixed이상=자동 실행→`approval.executed` · high=대기(승인 시 `approval.executed`) |
|
|
| 승인 큐 `approval.executed` / `approval.undone` | 하루 마감(`wrap.reflected`/주간 `weekly.reviewed`) · 결재함 로그 · 대시보드 `saved_today` |
|
|
| 리서치/지식 `research.completed` / `knowledge.ingested` | 리서치 리포트 · RAG 인덱스 · 라이프 지식 |
|
|
| 라이프 `finance.transaction` / `health.sample` / `price.target.hit` | 금융/건강 집계 · 결재함(목표 도달 제안) |
|
|
| worker `proactive.detected` / `errand.started`/`errand.updated`/`errand.completed` | 결재함(능동 제안) · 알림(능동 브리핑) · 심부름 추적 |
|
|
|
|
> 각 페이지 phase 문서는 자신이 **발행/구독하는 이벤트를 §연합 이벤트 섹션에 명시**합니다(스타일 가이드 ⑦ 필수). 본 문서의 매트릭스가 전 phase의 참조 기준입니다.
|
|
|
|
---
|
|
|
|
## 10. 가정/결정 (assumptions) — 사용자가 조정 가능한 지점
|
|
|
|
| # | 가정/결정 | 기본값 | 조정 포인트 |
|
|
|---|---|---|---|
|
|
| A1 | **외부 연동은 mock-first + 커넥터 추상화** | `CONNECTOR_<DOMAIN>=mock` | phase-13에서 도메인별 `real`로 토글. 실제 제공자(Gmail/Workspace/HEY, Google Calendar, Apple Health export, 금융 아그리게이터, Notion/Readwise)는 **목표 예시이며 교체 가능**. |
|
|
| A2 | **에이전트/멀티모달/임베딩은 모델 비종속** | `*_PROVIDER`/`*_MODEL` env 주입(기본값은 §8.3 표 — `EMBED_PROVIDER=ollama`, `WEB_SEARCH_PROVIDER=mock`, `AGENT_PROVIDER`는 `LLM_PROVIDER` 상속, STT/Vision=`auto`) | tool-capable·STT·vision·embedding 모델은 env로 주입. 미가용 시 **scripted/heuristic/코사인 폴백**으로 데모 동작 보장(결정성). |
|
|
| A3 | **단일 데모 사용자(지우) 유지** | `AUTH_ENABLED=false` | 인증/멀티유저는 phase-15에서 세션 인증 + per-user 데이터 스코프 도입. |
|
|
| A4 | **능동 레이어는 프로토타입 수동 트리거 우선** | `WORKER_ENABLED=false` | phase-14에서 APScheduler류 백그라운드 활성. 프로토타입은 수동 트리거 엔드포인트(`POST /api/worker/run/{job}`) 제공. |
|
|
| A5 | **벡터 스토어는 단순 우선** | SQLite + 코사인 | sqlite-vec 가용 시 전환(같은 `rag/` 인터페이스). |
|
|
| A6 | **자율성 기본 레벨 = 혼합(mixed)** | `autonomy_setting.level="mixed"` | `approval_first`(전건 승인)·`full_auto`(저위험 자동). low+mixed이상=자동 실행(되돌리기), high=항상 승인 대기. |
|
|
| A7 | **데이터는 전부 목업/시드** | 지우 6/7~6/13, 오늘=6/8 | 원본 *-data.js 값을 그대로 이식. 날짜/문구/금액 변경 금지(픽셀 충실). |
|
|
|
|
> 모든 가정은 본 문서에 명시되어 **사용자가 조정 가능**합니다. 조정 시에는 이 문서를 먼저 갱신하고 영향 phase에 전파합니다(overview.md §19.2 작업 방식 상속).
|
|
|
|
---
|
|
|
|
## 11. 비기능 목표(성능/접근성/관측성)의 포스트-MVP 상향선
|
|
|
|
| 영역 | MVP 기준(상속) | 포스트-MVP 상향선 |
|
|
|---|---|---|
|
|
| **성능 — 동기 API** | `/api/*` 단건 응답 빠름 | 목록/집계 API p95 < 300ms(로컬 SQLite). 메일/알림 목록은 페이지네이션/지연 로드. |
|
|
| **성능 — 에이전트/RAG** | 해당 없음 | 에이전트 멀티스텝·RAG ingest는 **비동기/스트리밍**(진행 단계 애니메이션, trip planner `research[]` 단계 표시). 폴백 scripted는 즉시. |
|
|
| **성능 — 능동** | 해당 없음 | worker 잡은 백그라운드(메인 요청 비차단). 다이제스트 생성은 예약 시각(`digests`: 09:00/13:00/18:30) 기준. |
|
|
| **접근성(a11y)** | axe 위반 0(serious↑), 키보드/포커스 | 동일 + 드로어(회의 도우미)·탭·레일 ARIA(원본 `aria-current="page"`/`aria-label` 상속), 라이브 영역(능동 알림 `aria-live`), 차트 대체 텍스트(리서치 `chart.insight`/`caution`를 텍스트로 제공). |
|
|
| **접근성 — 한국어** | `word-break: keep-all`, `letter-spacing:-0.011em` | 전 페이지 상속. 긴 한국어 문구(메일 본문·회의 요약)도 어절 단위 줄바꿈. |
|
|
| **관측성(observability)** | (MVP 최소) | 구조적 로깅(요청 id·event_bus 이벤트·자동화 매칭·approval 전이), 메트릭(자동화 runs/주, approval 처리율, 절약 시간), phase-15에서 트레이싱. |
|
|
| **결정성(데모)** | heuristic 폴백 | 에이전트 scripted 파이프라인(trip planner 예시 2개 제주/도쿄 결과 고정, 자유 입력은 0번 폴백), RAG 코사인 폴백 — **오프라인/CI에서도 동일 결과**. |
|
|
| **보안/프라이버시** | 로컬 처리(Ollama) | 커넥터 토큰 저장 암호화(phase-13), per-user 스코프(phase-15), high-risk 동작은 항상 사용자 승인. |
|
|
|
|
---
|
|
|
|
## 12. 상태 처리 & 엣지 케이스 (포스트-MVP 전역)
|
|
|
|
overview.md §15 전역 원칙을 상속하며, 포스트-MVP 특화 케이스를 추가합니다.
|
|
|
|
| 상태/케이스 | 전역 처리 |
|
|
|---|---|
|
|
| **로딩** | 글래스 스켈레톤(카드 형태 유지). 에이전트/플래너는 **단계별 진행 애니메이션**(trip `research[]`, 원본 단계 표시). |
|
|
| **빈(empty)** | 결재함 빈: *"오늘은 아리가 처리한 게 없어요"* 류. 알림 빈 버킷: 버킷 라벨 유지 + placeholder. |
|
|
| **에러** | `lib/api.ts` 비2xx throw → 카드 단위 에러 + 재시도. 셸/테마 유지. 커넥터 real 실패 시 mock 폴백 또는 "연결 안 됨"(life `Google Fit: "연결 안 됨"` 패턴). |
|
|
| **오프라인/LLM 미가용** | 분류·에이전트·임베딩 폴백 동작, `model="heuristic"`/`"scripted"`/`"cosine"` 표기. UI는 "규칙 기반으로 처리했어요" 미세 힌트(선택). |
|
|
| **커넥터 mock↔real 전환** | 같은 인터페이스 → 페이지 무변경. real 미인증 시 mock 시드로 graceful degrade. |
|
|
| **승인 되돌리기(undo)** | low는 즉시 실행 후 `undo_label`로 되돌리기. `status: pending→approved→executed→undone` 전이를 `approval_log`에 기록. |
|
|
| **자율성 레벨 변경** | `approval_first`로 낮추면 자동 실행 중단·전건 대기. `full_auto`로 올리면 low 자동(되돌리기만). 변경은 즉시 반영. |
|
|
| **멀티모달 스텁→실구현** | MVP는 voice/image 스텁. phase-14에서 STT/Vision 실구현, 미가용 시 "텍스트로 적어주세요" 폴백. |
|
|
| **HTML 시드(notes/coach/insight/summary)** | 신뢰된 시드(`<b>` 등 포함, life `coach`·research `synthesis` 등). 사용자 입력 경로는 새니타이즈 후 렌더. |
|
|
|
|
---
|
|
|
|
## 13. 테스팅 & 검증
|
|
|
|
> 본 문서는 *지도*이므로 "검증" = **문서 정확성 + 각 phase 정합성 + 횡단 명명 일관성** 점검입니다. 동시에 포스트-MVP 전 phase가 공통으로 쓸 테스트 도구·실행 명령·통과 기준을 정의합니다(각 phase 문서가 재사용).
|
|
|
|
### 13.1 실행 명령 (포스트-MVP 공통 — overview.md §16.1 상속 + 추가)
|
|
|
|
```bash
|
|
# 백엔드 (backend/)
|
|
uv run pytest # 전건
|
|
uv run pytest -k "automation or approval" # phase-7 자율성 코어
|
|
uv run pytest -k "connector" # 커넥터 mock 인터페이스
|
|
uv run pytest -k "agent or rag" # 에이전트/RAG(폴백 결정성)
|
|
uv run pytest -k "event_bus" # 연합 이벤트 발행/구독
|
|
uv run uvicorn app.main:app --reload # 개발 서버 (:8000)
|
|
uv run alembic upgrade head # 신규 테이블 마이그레이션
|
|
uv run python -m app.seed # run_seed() — 지우 한 주 + 포스트-MVP 시드
|
|
curl -s localhost:8000/api/approvals | jq . # 결재함 응답 수동 확인
|
|
curl -s -X POST localhost:8000/api/worker/run/digest | jq . # 능동 수동 트리거(phase-14)
|
|
|
|
# 프론트엔드 (frontend/)
|
|
pnpm dev # Next dev (:3000, /api → :8000)
|
|
pnpm test # Vitest + RTL (컴포넌트)
|
|
pnpm playwright test # E2E (연합 흐름)
|
|
pnpm playwright test --grep @a11y # axe 접근성
|
|
pnpm build && pnpm start # 프로덕션 빌드 검증
|
|
```
|
|
|
|
### 13.2 이 문서(post-mvp-overview)의 검증 케이스
|
|
|
|
| # | 검증 항목 | 통과 기준 |
|
|
|---|---|---|
|
|
| PM-1 | 10페이지 매핑 | §4.1 라우트/라벨/원본/phase가 `MAIN`(shell.jsx)·로드맵과 일치 |
|
|
| PM-2 | 횡단 레이어 명명 | §4.2 디렉터리·모델명(automation/connectors/agents/rag/worker, approval/autonomy_setting/automation_rule …)이 CONTRACT 고정 명명과 1:1 |
|
|
| PM-3 | 시드 값 인용 | §8 `savedToday:"47분"`·`autoCountNight:7`·`stats{active:7,runsWeek:31,saved:"1시간 40분"}`·`risk low/high`·`cta/alt/undo_label`이 원본 *-data.js와 일치 |
|
|
| PM-4 | event_bus 타입 | §9.1 이벤트 타입이 CONTRACT 예시(capture.classified/task.created/meeting.ended/mail.received/automation.matched/approval.executed/notification.triaged)를 빠짐없이 포함 |
|
|
| PM-5 | 로드맵·의존 | §7 빌드 순서 `7→8→9→10→11→12→13→14→15`, 7 최우선, 페이지 mock-first/13 real 전환 명시 |
|
|
| PM-6 | 연합 시나리오 | §6이 PROJECT-README §5 6대 흐름(캡처→분류→실행/메일·회의→작업/일정↔작업↔집중/위임 루프/자동처리→결재함→하루마감/공통 인물·프로젝트)을 모두 포함 |
|
|
| PM-7 | 가정 명시 | §10 A1~A7이 mock-first·모델 비종속·단일→멀티유저·조정 포인트를 명시 |
|
|
| PM-8 | 환경변수 규약 | §8.3이 상속 6개 + 추가(CONNECTOR_*/EMBED_PROVIDER/EMBED_MODEL/WEB_SEARCH_PROVIDER/AGENT_PROVIDER/STT_*/VISION_*/WORKER_*/AUTH_*) 일관, `EMBEDDING_MODEL` 표기 없음, 기본 CONNECTOR_*=mock·EMBED_PROVIDER=ollama·WEB_SEARCH_PROVIDER=mock·AGENT_PROVIDER=LLM_PROVIDER 상속·WORKER/AUTH=false |
|
|
| PM-9 | 라우터/시드 패턴 | §8 신규 라우터 내부 prefix 없음 + `include_router(prefix="/api")`, `run_seed(session=None, reset=True)` + 내부 `_seed_*` 헬퍼(phase-2 상속) |
|
|
| PM-10 | 상호 참조 | 모든 phase 문서를 정확한 파일명(`phase-7-approvals-automation.md` … `phase-15-production.md`, MVP `phase-0~6`)으로 링크 |
|
|
|
|
### 13.3 전 phase 공통 통과 기준(요약, 상세는 각 문서)
|
|
|
|
- **백엔드**: `pytest` 전건 통과. 자동화 evaluator가 이벤트→규칙→approval enqueue를 정확히 수행(low 자동/high 대기). 커넥터 `MockConnector`가 base 인터페이스를 충족(real로 교체해도 동일 시그니처). 에이전트/RAG는 **폴백(scripted/cosine)으로도 결정적** 통과.
|
|
- **프론트**: `pnpm test` 컴포넌트 통과. `pnpm playwright test` 연합 E2E(F3 회의→작업, F6 자동처리→결재함→하루마감) 통과. axe 위반 0(serious↑).
|
|
- **디자인 충실도**: 라이트/다크 토큰 적용, 상단바 13항목 전부 라이브, 회의 도우미 드로어/레일/탭 동작, glass/라운드/그림자가 토큰과 일치, 한국어 문구가 원본 *-data.js와 동일.
|
|
|
|
### 13.4 수동 QA 체크리스트 (포스트-MVP 전체)
|
|
|
|
- [ ] 상단 내비 13항목 전부 **실제 페이지**로 이동(준비 중 없음). `하루 마감`은 풀스크린(상단 메뉴 없음).
|
|
- [ ] 결재함: low 항목 *되돌리기*만, high 항목 *cta/alt*(보내기/수정 등) 노출. `savedToday:"47분"`·자동 처리 건수 표시.
|
|
- [ ] 자율성 설정 변경(approval_first/mixed/full_auto) → 자동 실행 동작 변화.
|
|
- [ ] 자동화: 자연어 한 문장(예 *"출장 전날엔 저녁 일정 비워줘"*) → trigger/cond/action 미리보기 → 생성 → 토스트 후 목록 복귀. 아리 제안 레일 dot.
|
|
- [ ] 일정: 일(日) 뷰 회의 도우미 — done(요약·결정·**액션→작업**), live(기록 중), upcoming(브리핑·지난 액션 체크), 1:1(signals/talkingPoints).
|
|
- [ ] 메일: 3계정(회사/개인/사이드) 통합, AI 요약·우선순위·라벨, 본문에서 작업/일정 추출 → 작업 보드/캘린더 등장.
|
|
- [ ] 알림: 지금/나중에/아리가 처리 3버킷 + 이유 칩(why) + 되돌리기. 집중 보호(`guard.until:"16:00"`).
|
|
- [ ] 리서치: 멀티소스 종합 표(cross[]), 지식 Q&A(근거 refs), 시각화 + 예측(점선 forecast bar).
|
|
- [ ] 여행: 출장 D-4 개요·이동·체크리스트·경비, AI 플래너(제주/도쿄 결과 + 자유 입력 폴백, 체크 localStorage).
|
|
- [ ] 라이프: 건강(rings/sleep/habits)·금융(budget/subs/insights)·지식(items) + 커넥터 on/last·"연결 안 됨".
|
|
- [ ] 여정: 4단계 흐름 + 베지어 협업 링크 + 하단 작업 테이블.
|
|
- [ ] 하루 마감: stats(완료/딥워크/미팅/자동 처리 47분 아낌)·하이라이트·이월·내일 미리보기·수면 모드.
|
|
- [ ] 연합: 회의 액션 "작업으로" → 작업 등장 / 자동 처리 → 결재함 → 하루 마감 합산.
|
|
- [ ] 라이트/다크 토글 + 새로고침 유지. 한국어 `word-break: keep-all`.
|
|
|
|
---
|
|
|
|
## 14. 완료 기준 (Definition of Done)
|
|
|
|
이 진입 문서의 DoD:
|
|
|
|
- [x] 포스트-MVP 비전(3→13페이지 + 연합 + 실연동 + 능동) 서술(§3).
|
|
- [x] 추가물 카탈로그: 10페이지(라우트/원본/phase) + 9개 횡단 레이어(명명 고정)(§4).
|
|
- [x] 횡단 아키텍처 텍스트 다이어그램(FastAPI+SQLite+Ollama 위 automation/connectors/agents/rag/worker + event_bus)(§5).
|
|
- [x] 연합 시나리오 표(PROJECT-README §5 6대 흐름 → 이벤트/엔드포인트 매핑) + 대표 데이터 경로(§6).
|
|
- [x] phase 7~15 로드맵 표(목표/산출물/의존성/주요 레이어/규모) + 빌드 순서·의존 그래프(§7).
|
|
- [x] 신규 데이터 테이블 개요(횡단 코어 + 페이지별, 원본 필드 인용) + 환경변수(§8).
|
|
- [x] event_bus 이벤트 타입 목록 + 발행/구독 매트릭스(§9).
|
|
- [x] 가정/결정 A1~A7(mock-first·모델 비종속·단일→멀티유저·조정 포인트)(§10).
|
|
- [x] 비기능 목표 상향선(성능/접근성/관측성/결정성/보안)(§11).
|
|
- [x] 테스팅 & 검증(실행 명령·검증 케이스 PM-1~10·통과 기준·수동 QA)(§13).
|
|
- [x] 모든 phase 문서를 정확한 파일명으로 상호 참조(MVP phase-0~6 + 포스트-MVP phase-7~15).
|
|
- [x] 상속 규약(스택/토큰/데이터모델/API/환경변수/시드/명명) 준수, 임의 변경 없음.
|
|
|
|
---
|
|
|
|
## 15. 이 문서 세트 사용법 + MVP 문서와의 관계
|
|
|
|
### 15.1 MVP 문서와의 관계 (상속)
|
|
|
|
```
|
|
dev/overview.md (MVP 정본)
|
|
└─ phase-0-foundation.md → phase-1-design-system.md → phase-2-backend.md
|
|
→ phase-3-tasks.md → phase-4-inbox.md → phase-5-dashboard.md → phase-6-integration.md
|
|
▼ 상속(스택·토큰·데이터모델·API·환경변수·시드·명명)
|
|
dev/post-mvp-overview.md (이 문서 · 포스트-MVP 정본)
|
|
└─ phase-7 … phase-15
|
|
```
|
|
|
|
- 스택(Next.js+React+TS / FastAPI+SQLite(SQLModel+Alembic) / Ollama Provider 추상화), 디자인 토큰(dash.css), 데이터모델 규약(PK=TEXT, tone enum), API 규약(prefix /api, 라우터 내부 prefix 없음), 환경변수, 시드(`run_seed`)는 **MVP에서 그대로 상속** — 변경 금지.
|
|
- 포스트-MVP 신규 테이블/엔드포인트는 **phase-2-backend.md 패턴**을 따릅니다(SQLModel 모델 + Pydantic 스키마 + 라우터 + `_seed_*` 헬퍼).
|
|
|
|
### 15.2 읽는 순서
|
|
|
|
1. **`dev/overview.md`** — MVP 전체 그림·계약·로드맵(선행 필독).
|
|
2. **`dev/post-mvp-overview.md`(이 문서)** — 포스트-MVP 비전·횡단 아키텍처·phase 7~15 로드맵·의존성·가정.
|
|
3. **`phase-7-approvals-automation.md`** — 자율성 코어(결재함 + 자동화 엔진). MVP 직후 최우선.
|
|
4. **`phase-8-calendar-meetings.md`** — 일정 + 회의 도우미(액션→작업 연합).
|
|
5. **`phase-9-mail-notifications.md`** — 메일 + 알림 트리아지.
|
|
6. **`phase-10-research-travel.md`** — 리서치 + 여행(에이전트 + RAG + 웹검색).
|
|
7. **`phase-11-life-care.md`** — 라이프 케어(건강·금융·지식, 커넥터).
|
|
8. **`phase-12-daily-narrative.md`** — 여정 + 하루 마감(전 페이지 집계).
|
|
9. **`phase-13-integrations.md`** — 외부 연동 & 커넥터(mock→real).
|
|
10. **`phase-14-proactive-agent.md`** — 능동형 에이전트 + 멀티모달.
|
|
11. **`phase-15-production.md`** — 프로덕션 하드닝(인증/멀티유저/배포/관측성).
|
|
|
|
### 15.3 작업 방식 (overview.md §19.2 상속)
|
|
|
|
- 각 포스트-MVP phase 문서는 **10개 필수 섹션**을 가집니다: ①개요·목표 ②선행조건·산출물 ③상세 구현 ④데이터/타입/API 계약 ⑤디자인 충실도 노트 ⑥상태 처리·엣지케이스 ⑦연합 이벤트(발행/구독) ⑧테스팅 & 검증 ⑨완료 기준 ⑩다음 단계.
|
|
- 항상 **빌드 순서(§7.2)** 를 지키세요: `7→8→9→10→11→12→13→14→15`(7 최우선, 페이지 mock-first, 13에서 real 전환).
|
|
- 값(색·필드·문구)은 항상 **`REF/assets`의 원본 *-data.js를 단일 출처**로 삼고, 의심되면 이 문서의 표(§8)와 대조하세요.
|
|
- 계약(데이터 모델·API·토큰·스택·환경변수·명명)은 **변경 금지** — 변경이 필요하면 먼저 `overview.md`(MVP) 또는 이 `post-mvp-overview.md`(포스트-MVP)를 갱신하고 영향 phase에 전파합니다.
|
|
|
|
---
|
|
|
|
*끝. 다음 문서: `phase-7-approvals-automation.md`*
|