getpersona.md를 이어가며 — AI 에이전트용 페르소나 플랫폼, Day 2 Foundation

Day 1에서 모노레포와 DESIGN.md를 잡았다면, Day 2는 Postgres·API·Web·Better Auth OAuth·Infisical까지 보이지 않는 바닥을 깔았습니다. 카탈로그는 아직 없지만 /dashboard가 텅 비어 보이는 이유와, 그래도 지금 Foundation을 먼저 닫아 둔 이유를 정리했습니다.

Share
getpersona.md를 이어가며 — AI 에이전트용 페르소나 플랫폼, Day 2 Foundation
AI 에이전트용 페르소나 플랫폼, Day 2 Foundation

이전 글: getpersona.md를 시작하며 — AI 에이전트용 페르소나 플랫폼, Day 1 Foundation


솔직히 말하면, 이번 주에 만든 화면을 친구에게 보여 주기는 좀 민망합니다.

/dashboard에 가면 워크스페이스 칸은 있는데, 채울 내용은 아직 “나중에 옵니다”에 가깝습니다. 카탈로그도 없고, 결제도 없고, 페르소나 런타임 데모도 없습니다. 대신 Postgres 스키마는 있고, API는 /ready로 DB 살았는지 물어보고, Google·GitHub로 로그인은 됩니다. 비밀번호는 Infisical에 넣어 두고, repo에는 이름만 남겼습니다.

겉보기엔 “아직 안 만든 것 같은데?”인데, 사실은 TASK-004부터 008까지 Day 2 Foundation을 한 번에 밀어 넣은 겁니다. Day 1에서 모노레포·제품 계약·DESIGN.md·SEO 골격을 잡았다면, 이번엔 제품이 돌아가려면 어쩔 수 없는 층—DB, API, Web, 인증, 시크릿—을 깔았습니다.


getPersona.md가 뭔지, 한 번만 더

getPersona.md는 AI 에이전트와 팀에게 말투·성향·판단 기준·지식 경계를 구조화해서 넘겨 주는 PERSONA.md 플랫폼입니다. getdesign.md가 DESIGN.md 모음이라면, getpersona.md는 PERSONA.md 모음을 목표로 합니다.

만드는 과정은 blog.goodtek.xyz에 그대로 올립니다. vibePulse 때처럼 Build in Public입니다. 예쁜 스크린샷 한 장보다, 왜 이 순서로 쌓는지를 남기는 쪽이 맞다고 봅니다.


TASK-004 — “personas 테이블은 어디 있나요?” “아직요”

페르소나, 구매 이력, 워크스페이스, 세션, 웹훅 로그. 나중에 말하게 될 것들은 거의 다 DB에 남습니다. 그래서 vibePulse 때 DB부터 깔았던 것처럼, getPersona도 packages/db에 Drizzle을 먼저 넣었습니다.

UUID 규칙, timestamptz, migrate·seed 파이프, foundation_checks 같은 스모크 테이블까지. personas 테이블은 TASK-015에서 옵니다. 지금은 “DB는 @getpersona/db 한곳에서만 건드린다”는 규칙만 정해 둔 상태입니다. 재미없어 보이죠. 맞습니다. 근데 나중에 테이블 이름이 사람마다 다르면 그때가 더 재미없습니다.


TASK-005 — DB 없어도 API는 뜹니다 (일부러 그렇게 했습니다)

NestJS API에 /health랑 /ready를 나눴습니다. 살아 있냐 vs 준비됐냐. 그리고 Postgres 없이도 서버는 켜집니다. DATABASE_URL 없으면 /ready가 “DB 아직 없어요”라고 솔직히 말합니다.

clone 받고 pnpm dev 쳤는데 서버가 안 뜨면, 그 순간부터 사람은 repo를 닫습니다. Docker로 Postgres 띄우는 건 TASK-012로 미뤘지만, “일단 구조는 볼 수 있게”는 지켰습니다. Pino, Swagger, Zod scaffold도 같이 넣었습니다. 기능 붙일 때마다 “로그는 어떻게 하죠?”부터 시작하고 싶지 않았습니다.


TASK-006 — 화면은 비어 있어도, fetch 패턴은 정해 뒀습니다

TASK-003에서 DESIGN.md, 헬스 홈, /design은 이미 있었습니다. TASK-006은 데이터 부르는 방식을 고정한 작업에 가깝습니다.

TanStack Query, apiFetch, 쿠키 대비한 credentials: "include"/dashboard 앱 셸. 공개 영역이랑 로그인 뒤 영역을 라우트로 미리 나눴습니다. 카탈로그는 밖, 워크스페이스는 안 — 나중에 헷갈리면 그때가 진짜 고생입니다.

vibePulse에서 “기능 붙이기 전에 화면 흐름부터” 했던 것과 비슷한데, getPersona는 fetch 패턴까지 같이 박아 둔 점이 다릅니다.


TASK-007 — 로그인 버튼 하나 붙인 게 아닙니다

인증을 나중에 끼우면, 만든 API·화면·마이그레이션을 한 번씩 뜯게 됩니다. vibePulse TASK-005에서 Google·GitHub만 먼저 했던 것처럼, getPersona도 OAuth 두 개로 시작했습니다. 이메일·비밀번호는 안 넣었습니다. 경로가 많아지면 운영만 피곤해집니다.

Better Auth, 세션은 Postgres, Web에는 React client. /dashboard에서 로그인·로그아웃이 됩니다. 다만 Postgres·migrate·시크릿이 없으면 auth는 꺼진 채로 API만 뜹니다. “로그인 버튼 눌렀는데 왜 안 되죠?” — TASK-012 전까지는 그게 정상일 수 있습니다. 구매, 워크스페이스, 관리자 화면은 전부 user.id가 있어야 의미가 생깁니다. 그 전제를 지금 맞춰 둔 겁니다.


TASK-008 — .env 복붙은 이제 그만 (습관부터 바꿉니다)

004~007까지는 README에 변수 이름만 있고, 값은 각자 export하거나 .env에 넣었습니다. 혼자 할 때는 됩니다. 둘이 되면 “어? 내 파일이랑 이름이 다른데?”가 시작됩니다.

vibePulse에서 이미 Infisical을 쓰고 있었고, getPersona도 처음부터 맞췄습니다. local / dev / prodpnpm dev는 예전처럼 시크릿 없이도 되고, 진짜 통합은 pnpm dev:secrets로 갑니다. repo에는 이름만, 값은 Infisical.

pnpm secrets:verify 돌렸을 때 “14개 주입됐다”고 나오면, 그때는 꽤 뿌듯합니다. 화면에 보이는 건 없어도, 바닥은 연결됐다는 뜻이니까요.


그래서 뭐가 달라졌나

Day 1이 말과 디자인의 기준이었다면, Day 2는 데이터·API·웹·인증·시크릿의 기준입니다.

다음은 TASK-012에서 Postgres를 compose로 묶고, TASK-011에서 CI를 붙입니다. 그다음에야 카탈로그 같은 겉모습이 “아, 제품이네” 싶게 보일 겁니다. 그때는 로그인한 사용자로 페르소나를 조회하는 게 당연한 전제가 되어 있을 테니까요.

지금 당장은 /dashboard가 텅 비어 보여도 괜찮습니다. 바닥이 튼튼하면, 위에 뭘 올려도 무너지지 않으니까요.

Read more

getpersona.md를 시작하며 — AI 에이전트용 페르소나 플랫폼, Day 1 Foundation

getpersona.md를 시작하며 — AI 에이전트용 페르소나 플랫폼, Day 1 Foundation

getpersona.md는 AI 코딩 에이전트와 팀에게 말투·성향·판단 기준·지식 경계를 구조화해서 전달하는 PERSONA.md 플랫폼입니다. getdesign.md가 “AI에게 디자인 감각을 주는 DESIGN.md 컬렉션”이라면, getpersona.md는 “AI에게 페르소나를 주는 PERSONA.md 컬렉션”을 목표로 합니다. 오늘은 카탈로그나 결제 UI 같은 겉모습은 거의 없습니다. 대신 모노레포, 제품 계약서, 디자인 시스템, SEO/AEO/GEO 골격까지 — 나중에 후회하지 않을 Foundation만 쌓았습니다.

By ● goodtek