Groselia

알아서 돌아가는 소셜 미디어

내 역할

공동 창업자
엔지니어링
제품 및 브랜드 디자인

설명

Groselia는 테크 스타트업을 시작으로, 다른 업종과 규모의 회사들의 소셜 미디어도 운영해요. 전략, 디자인, 게시, 댓글 답변, 리포트까지, 모든 채널을 하나의 플랫폼에서.

팀

Danilo Parmegiani공동 창업자
Pedro Critchi공동 창업자

배경

Groselia는 Pedro와 둘이서 시작했어요. 그는 마케팅, 영업, 운영을 맡고, 저는 브랜드와 제품을 디자인하고 그 기반이 되는 플랫폼을 데이터베이스부터 마지막 애니메이션까지 만들었어요. 셀프서브였던 시절에는 200명 넘게 가입해 사용했고, 지금은 고객들의 콘텐츠와 소셜 미디어를 운영하고 있어요. 2026년 6월에는 제가 졸업한 Link School of Business의 액셀러레이터 Link Vector로부터 R$100k 프리시드를 유치했고, 서비스로 피벗한 지 두 달 만에 Groselia는 월 R$15,000 이상의 매출을 내고 있어요.

도구

Codex
Claude Code
Figma
Adobe tools

기술 스택

  • React
  • Next.js
  • TypeScript
  • Tailwind
  • Supabase
  • Frontier LLMs
  • Trigger.dev
  • Stripe
  • Vercel

타임라인

2025–현재

숫자로 보기

R$180k+
연간 매출 런레이트
200+
생성된 계정
350
설정된 브랜드
9,700+
commits
520+
풀 리퀘스트
47
Edge Functions

과제

만드는 건 더 이상 병목이 아니다. 눈에 띄는 것이 병목이 됐다.

AI가 소프트웨어를 만드는 비용을 무너뜨렸어요. 엔지니어링 배경이 없는 창업자도 이제 주말 동안 제품을 출시할 수 있고, 다른 모두도 마찬가지예요. 싸지지 않은 건 누군가 알아봐 주게 만드는 일이었어요. 배포는 한 번의 작업이 아니라 끝없는 운영이에요. 매일 게시하고, 각자 다른 형식을 원하는 8개 네트워크를 챙기고, 모든 댓글에 답하고, 앱마다 다르게 보고하는 숫자를 읽어야 하죠.

스타트업은 셋 중 하나로 그 대가를 치러요. 아직 감당할 수 없는 팀을 고용하거나, 한 조각씩만 해결하는 도구 열두어 개를 이어 붙이거나, 아무것도 게시하지 않고 성장으로 대가를 치르거나. Groselia는 네 번째 선택지가 되려고 존재해요.

여기까지 온 길

Groselia는 지금의 모습을 찾기까지 네 번 모양을 바꿨어요. 매번 잘된 건 남기고 나머지는 버렸어요.

  1. 2025년 말 – 2026년 2월

    Argibee

    AI 브랜드 디자인 플랫폼. 2025년 말 프로토타입으로 시작해 2026년 2월에 정식 회사가 됐어요. 시장은 찾지 못했지만, 그 브랜드 키트 엔진이 이후 모든 것의 뼈대가 됐어요.

  2. 2026년 4월

    모션 영상

    Groselia는 After Effects 템플릿으로 만드는 Apple 스타일 런칭 영상으로 시작했어요. 파이프라인 전체를 손으로 검증해 봤고, 원하는 품질 수준으로는 확장할 수 없다는 걸 알게 됐어요.

  3. 2026년 6월

    Link Vector로부터 프리시드

    Link School of Business의 Startup School에 참여했어요. 창업자를 위한 100일 프로그램으로, 리얼리티 쇼처럼 촬영됐어요(시즌 보기). 마지막은 데모 데이였고, 제가 무대에서 Groselia를 피칭했고, 프리시드를 유치했어요. 제가 졸업한 Link School of Business의 액셀러레이터 Link Vector로부터 받은 R$100k 투자였어요.

    데모 데이에서의 제 피칭
  4. 2026년 8월

    마케팅을 위한 Lovable

    폼 대신 하나의 대화. 캠페인을 설명하면 Groselia가 계획하고, 쓰고, 게시해요. 봇 여러 개가 아니라 도구를 가진 하나의 채팅 에이전트.

  5. 2026년 9월

    소셜 미디어 매니저

    고객들은 AI가 콘텐츠를 만들어 주길 원하지 않았어요. 자기 사진이 잘 올라가고 댓글에 답이 달리길 원했죠. 그래서 생성 기능을 빼고 채널 운영에 깊이 집중했어요.

  6. 현재

    서비스 애즈 어 소프트웨어

    우리는 도구가 아니라 일을 팔아요. 우리 팀이 플랫폼에서 고객마다 소셜 미디어를 운영하고, 덕분에 예전엔 에이전시가 필요했던 일을 한 사람이 해낼 수 있어요.

공개적으로 만들기

우리는 처음부터 만드는 과정을 공개했어요. 아직 Argibee였을 때부터 YouTube에 여정을 공유했고, Argibee 대기자 명단 오픈부터 Groselia를 처음 보여 준 영상까지 있어요. 그 뒤의 이야기는 영상 하나하나 우리 채널에 있어요.

Argibee 대기자 명단 오픈
Groselia를 처음 보여 준 영상

브랜드

Groselia의 브랜드는 대담하길 바랐어요. 웹사이트에서도, 앱에서도, 소셜 미디어의 모든 게시물에서도 사람들이 멈춰서 보게 만드는 것. 어디서 마주치든 감탄하게 하고, 조금은 동경하게 만들고, 방금 본 것 때문에 우리에게 일을 맡기고 싶어지게요. 무엇보다 우리가 속한 생태계이자 우리가 가장 먼저 만들어 주는 고객인 테크 스타트업에게 끝내주게 보여야 했어요.

브랜드 전체를 Codex 안의 Figma 플러그인으로 디자인했어요. 로고, 타이포그래피와 심볼을 올바른 비율로 결합하는 방식, 이미지, SVG 아이콘 라이브러리, 텍스트 스타일, 정리된 컬러 팔레트까지. 모든 결정을 수치와 함께 한 보드에 올려 비교하고 토론할 수 있게 했어요.

Figma의 Groselia 파일 옆에 띄운 Codex: 로고 시스템, 모든 배경색 위의 로고, 팔레트 전체에 놓인 심볼, 컬러 팔레트
Codex 안의 Figma 플러그인으로 Figma에서 만든 브랜드 보드.

심볼

심볼이 가장 먼저 있었고, 그대로 남았어요. 중심을 돌아가는 부드러운 꽃잎 세 장. 회사의 가장 첫 버전부터 이어진 것이고, 새 로고는 그 위에 덮어 그리지 않고 그 주위에 쌓아 올렸어요. 형태는 복사하고 크기만 바꿨지, 다시 그린 적은 없어요.

워드마크

워드마크는 TT Commons Pro Bold 소문자이고, 어디서든 똑같이 보이도록 벡터로 아웃라인 처리했어요. 기본 자간에서는 심볼 옆에서 느슨해 보여서, 160px 기준으로 글자마다 6.4유닛씩 왼쪽으로 당겨 −4% 트래킹으로 조였어요. 사소해 보이지만, 단어 폭이 564에서 520유닛이 되면서 하나의 형태로 읽히게 됐어요.

H 그리드

모든 건 워드마크의 눈에 보이는 높이인 H로 재고, H/10 그리드 위에 놓아요. 그래서 로고 크기를 바꿀 때 누구도 다시 눈대중할 필요가 없어요.

세로형 로고는 심볼 크기 세 가지(1.50H, 1.75H, 2.00H)와 간격 두 가지(0.15H, 0.25H)로 여섯 가지 안을 그렸고, B: 1.75H 심볼, 글자 위 0.15H를 골랐어요. 가로형은 0.20H부터 0.35H까지 간격을 비교해 1.10H 심볼에 0.35H 간격으로 정했어요.

1.75H0.15HH

구성 그리드 위의 세로형 로고. H는 워드마크의 높이, 그리드는 H/10이에요.

Groselia 가로형 로고

가로형

심볼 1.10H · 간격 0.35H

Groselia 세로형 로고

세로형

심볼 1.75H · 간격 0.15H

Groselia 심볼 로고

심볼

원래 비율, 0.93 : 1

Colour

The palette is fifteen colours, loud on purpose. But the logo only ever comes in four treatments: blue symbol with black text, blue with white, all black and all white. The other colours are grounds, never the symbol.

To prove that, I put the symbol and both lockups on twelve backgrounds, 24 studies each, and kept the ones where its silhouette survives. On blue grounds the symbol goes monochrome. Click a colour to copy it.

타이포그래피

TT Commons Pro가 모든 일을 해요. Light부터 ExtraBold까지 여섯 가지 굵기, 12px부터 96px까지 11단계 스케일, 그리고 진짜 이탤릭. 파일 안의 텍스트 레이어 688개를 모두 이 서체로 옮겨서, 이제 브랜드북과 앱과 웹사이트가 하나의 목소리로 말해요.

기본 서체

TT Commons
Pro

TT Commons Pro디스플레이 · 01
→Groselia@
Reels → Posts
Nº 128⅝ e

앱 아이콘

앱 아이콘은 브랜드가 유일하게 3D가 되는 곳이에요. 도자기 질감의 심볼을 겹겹이 쌓고, 위에서 빛을 비추고, 살짝 윤기를 줬어요. 나중에 리프레시하면서 타일 안에서 숨 쉴 수 있게 심볼을 10% 줄였어요. 워드마크와 함께 쓰는 전용 락업도 있고, 타일은 1.5H예요.

Groselia 앱 아이콘

3D 오브젝트의 세계

로고 주변에는 3D 오브젝트들이 살아요. 눈알 달린 하트, 말풍선, 해시태그, 반짝이. 웹사이트와 게시물에서 브랜드의 목소리가 되어 주고, 가만히 있는 법이 없어요. 둥둥 떠다니고, 사이트에서는 커서에 반응해요. 여기 있는 것들도 그래요. 밀어 보거나, 하나를 당겼다가 놓아 보세요.

Neo 두들

평면적인 것에는 모두 우리 아이콘 세트 Neo를 써요. 두꺼운 검은 외곽선, 팔레트의 채색, 하얀 하이라이트 하나. 웹사이트에서는 각 아이콘이 하얀 칩 안의 단순한 선 아이콘으로 시작했다가, 마우스를 올리면 낙서로 변해요. 부분들이 하나씩 나타나죠. 원이 톡 튀어나오고, 막대가 떨어지고, 하이라이트가 그려져요. 웹사이트의 낙서와 애니메이션을 그대로 가져왔어요. 하나 올려 보세요.

공식 연동
손 뗄 수 있어요
언제든 일시 정지
모든 기록 보관
데이터는 비공개로
언제든 해지
브랜드 말투로 답글
사람이 검토
리드 표시
유료 광고
랜딩 페이지
제품 리디자인
리브랜딩
스파크
하트
트로피

제품

Groselia에서는 모든 걸 하나의 채팅에 입력해서 해요. 무엇을 언제 올릴지 쓰면, 예약하고, 게시하고, 댓글에 답하고, 무엇이 잘됐는지 알려 줘요. 일은 다뤄야 할 열두어 개의 화면이 아니라, 오너가 승인하는 하나의 플랜으로 도착해요.

대시보드가 아니라 대화

지난주 어땠어?

6월 이후 최고의 한 주였어요.

  • 도달이 38% 늘었어요. 라테 아트 릴스 덕분이에요(Instagram 조회 4.1만, TikTok 6.4만).
  • 에스프레소 캐러셀은 저장이 두 배가 됐어요. 레시피는 다들 저장해 두더라고요.
  • 답을 기다리는 댓글이 있어요. 배송과 분쇄도 질문 14개, 대부분 아직 답이 없어요.

패턴은 분명해요. 영상은 오후 5~7시, 사진은 아침. 앞으로 2주는 이대로 가면 좋겠어요.

2일 전

좋은 아침이에요! 이번 주에 챙기셔야 할 게 두 가지 있어요.

  • Carmo de Minas 새 수확 원두가 금요일에 매대에 오르는데, 아직 아무 계획도 없어요.
  • 질문 14개가 게시물에 달려 있어요. 대부분 배송 관련이에요.

어디서부터 시작할까요?

하나 선택
8분 전

Groselia는 처음에 폼이었어요. 목표를 고르고, 칸을 채우고, 캠페인을 받는 거죠. 그런데 자기 사업에 대한 폼을 채우고 싶은 사람은 없어요. 그래서 이제 모든 브랜드에는 대신 하나의 대화가 있어요.

브랜드를 열고 입력하세요. 이번 주에 뭘 올려야 할지 묻거나, 폰에서 사진을 끌어다 놓거나, “어제 댓글에 답해 줘”라고 쓰면 돼요. 에이전트는 답하기 전에 먼저 봐요. 캘린더, 성과가 좋았던 것, 브랜드의 메모리를.

필요한 게 있으면 탭으로 답할 수 있는 짧은 질문을 한 번 해요. 그리고 하나의 플랜을 제안해요. 날짜와 시간이 정해진 게시물, 답글, 변경 사항. 원하는 걸 고치고 승인하면, 캘린더가 채워지는 걸 지켜보면 돼요.

여기 있는 카드는 진짜 채팅을 앱의 토큰으로 브라우저에서 다시 만든 거예요. 직접 써 보세요.

두 번 디자인했다: 먼저 오너를 위해, 그다음 우리를 위해

첫 사용자는 직접 소셜 미디어를 운영하는 소상공인이었어요. 캠페인, 퍼널, 게시 주기로 생각하지 않고 “이번 주에 뭘 올리지?”를 생각하는 사람들이죠. 그래서 어려운 건 기계 장치를 숨기는 거였어요. 질문 네 개로 끝나는 온보딩, 링크 하나로 채워지는 브랜드 키트, 끌어서 옮기는 캘린더, 17개 언어로 휴대폰에서도 쓸 수 있는 모든 화면.

그 뒤 고객들은 아무리 단순해도 도구를 직접 다루고 싶어 하지 않는다는 걸 알았어요. 일이 끝나 있길 원했죠. 그래서 우리가 주 사용자가 됐어요. 팀의 한 사람이 많은 브랜드를 운영하니, 같은 앱에 멀티 브랜드 워크스페이스, 미팅으로 시작해 리포트로 끝나는 사이클, 모든 게시물의 승인 단계, 모든 네트워크를 모은 받은편지함이 필요해졌어요. 고객들은 여전히 로그인하지만, 이제 앱은 일을 하는 곳이 아니라 일을 지켜보는 곳이에요.

2026년 11월

월
103
화
113
수
123
목
133
금
143
토
152
일
162
8:00

우리가 시세보다 40% 더 내는 이유

가져옴
6
새 수확
49:00

새 수확: Carmo de Minas

게시됨
5
비하인드
17:30

POV: 로스터리 첫 근무

게시됨
레시피
9:00

에스프레소 세팅하는 법

게시됨
12:00

다크 로스트에 대한 비인기 의견

게시됨
실패
비하인드
1218:00

단골손님 주문 평가하기

게시됨
8:30

크루아상 타임

예약됨
3
채용
11:00

헤드 바리스타 Ana를 소개해요

수동
레시피새 수확+1
17:00

슬로모션 라테 아트

예약됨
9:00

생두 1kg이 무엇이 되는지

예약됨
7
비하인드
11:00

로스터리 안, 처음부터 끝까지

예약됨
레시피
18:30

60초 콜드브루

초안
영상 필요
새 수확프로모션
9:00

새 수확 원두가 매대에 올랐어요

예약됨
초안
채용
10:00

헤드 로스터를 채용해요

예약됨
17:00

아이스 라테, 처음부터 끝까지

초안
프로모션
10:00

당신의 토요일 식탁

예약됨
15:00

에스프레소 토닉의 계절이 왔어요

초안
레시피
11:00

4분 핸드드립 가이드

예약됨
프로모션
18:00

Oakline 원두 봉투를 소개해요

초안
4

에이전트가 읽도록 만들기

브랜드나 웹 페이지를 가장 먼저 읽는 건 점점 AI가 되고 있어요. 그래서 Groselia의 모든 건 사람만큼이나 에이전트를 위해 쓰여요. 브랜드의 메모리는 평범한 Markdown 문서 묶음이에요. 선호, 해야 할 것과 하지 말아야 할 것, 브랜드에 관한 사실. 에이전트는 답하기 전마다 이걸 읽고, AI 어시스턴트가 자기 기억을 관리하듯 도구 네 개로 직접 고쳐요. 사람도 브랜드 키트에서 똑같은 문서를 열고 고치고요.

인사이트는 대시보드와 에이전트가 함께 읽는 하나의 공유 코어를 거쳐서, “뭐가 잘되고 있어?”라고 물으면 답은 지금 보고 있는 숫자에서 나와요. 웹사이트도 사람들이 우리에 대해 묻는 어시스턴트를 위해 같은 일을 해요. groselia.com은 llms.txt, 더 긴 llms-full.txt, 비교 파일을 제공하고, 모두 코드 속 하나의 사실 출처에서 생성돼요. 그래서 AI가 우리 가격이나 보안에 대해 하는 말이 사이트와 어긋날 수 없어요.

시간에 따른 참여

주별, 최근 30일, 게시일 기준

참여율7.69%

주요 기능

  • 링크 하나로 브랜드 키트

    웹사이트를 붙여 넣고 계정을 연결하세요. Groselia가 사이트를 수집하고 지난 게시물을 읽어서 로고, 색상, 폰트, 말투, 오디언스를 알아서 채워요.

  • 하나의 대화

    도구 41개를 가진 AI 에이전트가 미디어에 캡션을 달고, 직접 쌓은 참여 데이터로 시간을 고르고, 지표를 읽고, 답글 초안을 쓴 뒤 모든 걸 하나의 플랜으로 묶어요.

  • 8개 네트워크를 위한 캘린더

    Instagram, LinkedIn, TikTok, YouTube, X, Facebook, Threads, Reddit를 각자의 네이티브 형식으로. 지난 게시물도 가져와서 캘린더가 비어 있을 일이 없어요.

  • 모든 댓글에 답하기

    모든 네트워크의 댓글과 DM을 하나의 받은편지함에. 답글은 브랜드 말투로 초안이 잡히고, 민감한 건 사람이 볼 때까지 보류돼요.

  • 쉬운 말로 보는 인사이트

    모든 계정의 도달, 조회수, 참여. 플랫폼마다 무엇을 보고하고 무엇을 보고하지 않는지 솔직하게 보여 주고, “뭐가 잘되고 있어?”에도 답해요.

  • 사이클과 승인

    일은 사이클로 돌아가요. 각 사이클은 미팅으로 시작해 AI가 숫자로 쓰는 리포트로 끝나고, 모든 게시물은 고객의 승인을 기다릴 수 있어요.

AI 에이전트와 함께 만들기

Groselia는 AI 에이전트를 엔지니어링 팀 삼아 만들었어요. Codex와 Claude Code가 코드를 썼고, 변경마다 각자의 브랜치를 썼어요. 저는 디자인하고, 모든 풀 리퀘스트를 리뷰하고, 무엇을 출시할지 결정했어요.

그리고 프롬프트 대부분은 타이핑 대신 Wispr Flow로 말해서 입력했어요. 좋은 프롬프트는 길고 자세한 브리프인데, 말로 하니 생각하는 속도 그대로 전달할 수 있었어요.

  • Codex

    코딩 에이전트

  • Claude Code

    코딩 에이전트

  • Wispr Flow

    음성 받아쓰기

웹사이트

웹사이트는 브랜드가 가장 크게 외치는 곳이에요. Next.js로 디자인하고 만들었어요. 17개 언어를 지원하고, 방문자가 가입할 때 그 언어를 앱으로 그대로 넘겨줘요.

가지고 놀 수 있는 히어로

페이지가 로딩되는 동안 로고가 돌아 들어오고, 이어서 히어로. 둥둥 떠다니고, 마우스를 따라 기울고, 커서에 밀려나는 3D 소품들. 그리고 “Made for you”로 끝나는 스크롤 장면.

groselia.com
groselia.com 히어로: “We run your socials. You run your business.”, 하트 주위의 3D 소품들

진짜 앱을 다시 만들다

“Inside your Groselia”는 앱의 실제 화면을 데모 브랜드와 함께 코드로 다시 만들어, 플랫폼을 있는 그대로 보여 줘요.

groselia.com
“Inside your Groselia”: 플랫폼의 채널 연결 화면

블로그

소셜 미디어 운영에 관한 노트. 글은 언어마다 하나씩인 평범한 MDX 파일이고, CMS는 없어요. 각 글에 전용 피드와 구조화 데이터가 있어서 검색 엔진과 AI 어시스턴트가 제대로 읽어요.

groselia.com
groselia.com 블로그. 커서 아래 첫 글이 밝게 빛나고, 그 아래 다른 글들

리드를 선별하는 폼

모든 “Book a call”은 캘린더 전에 짧은 폼을 열어요. 누구인지, 어디에 게시하는지, 무엇이 필요한지, 예산은 얼마인지. 단계마다 입력하는 대로 데이터베이스에 저장돼서 중간까지만 쓴 답도 볼 수 있고, 폼을 끝내면 Slack으로 팀에 알림이 가요.

groselia.com
예약 페이지: “Let's talk about your social media.”, 세 단계 옆의 폼

언제나 반응형

모든 페이지는 그냥 줄여서 맞춘 게 아니라 휴대폰용으로도 디자인했어요. 호버가 없는 곳에서는 섹션이 화면 가운데에 오면 깨어나요.

휴대폰으로 본 홈페이지
휴대폰으로 본 “Always in sync with your team”, 첫 카드가 깨어난 모습
휴대폰으로 본 예약 폼, 필요한 것과 월 예산을 묻는 단계

엔지니어링

아키텍처

플랫폼은 AI를 페어 삼아 제가 직접 만들었어요. 앱은 React와 Vite, 랜딩은 Next.js이고, 둘 다 하나의 Supabase 프로젝트 위에 있어요. 행 수준 보안이 적용된 Postgres, 인증, 실시간, 스토리지, 그리고 Edge Functions 47개. 느리거나 예약된 작업은 Trigger.dev에서 돌고, 소셜 네트워크는 하나의 게시 API를 거치며, Stripe가 요금제, 카드, 브라질의 boleto를 처리해요.

MCP 서버와 Codex 플러그인도 있어서 AI 에이전트 안에서 Groselia를 쓸 수 있어요. 같은 브랜드, 게시물, 초안을 도구로요.

쓰이는 곳

코어

Supabase

그 뒤에서

앱, 웹사이트, MCP 서버는 Vercel에서 호스팅해요.

상자에 마우스를 올리거나 탭하면 하는 일과 연결된 곳이 보여요.

게시물이 지나가는 길

부분들이 어떻게 맞물리는지 보려면 게시물 하나를 따라가는 게 가장 좋아요. 채팅 속 한 문장부터 인사이트의 숫자까지. 단계를 클릭해 보거나, 그냥 재생되게 두세요.

웹 앱

오너가 요청한다

“수확 사진을 금요일에 Instagram과 LinkedIn에 올려 줘.” 메시지는 에이전트의 Edge Function으로 가고, 답이 스트리밍으로 돌아와요.

ReactSSE 스트림

에이전트

에이전트는 Anthropic, OpenAI 등 여러 제공업체의 시장 최고 모델로 돌아가고, 도구 루프를 가진 하나의 스트리밍 Edge Function이에요. 모델에는 자체 도구 41개에 웹 검색과 웹 가져오기가 더해지고, 한 턴에 최대 8홉까지 가요. 어려운 건 모델이 아니었어요. 에이전트가 지금 이 순간 무엇이 사실인지 항상 알게 하는 거였죠.

그래서 매 턴, 모델이 메시지를 보기 전에 함수가 데이터베이스에서 컨텍스트를 다시 만들어요. 오너 시간대의 날짜와 시간, 브랜드의 메모리 문서, 실시간 캘린더, 진행 중인 플랜, 업로드된 문서, 이전 메시지의 누적 요약까지. 프롬프트의 안정적인 부분은 1시간 캐시하지만, 이 부분은 절대 캐시하지 않아서 낡을 수가 없어요.

나머지는 두 가지 규칙이 만들었어요. 공개되거나 되돌릴 수 없는 건 절대 바로 내보내지 않고 오너가 승인하는 플랜에 넣을 것. 그리고 게시물은 이번 턴에 도구가 만든 경우에만 존재할 것. 이걸로 에이전트가 하지도 않은 일을 설명하던 시절이 끝났어요. 에이전트는 한 모델에 묶여 있지도 않아요. 더 작고 저렴한 모델이 충분히 좋아졌을 때, 대화당 비용을 줄이려고 채팅을 그 모델로 옮겼어요.

매 턴 새로 만드는 컨텍스트

지시문과 도구1시간 캐시
날짜와 시간오너의 시간대
메모리 문서선호, 해야 할 것과 하지 말아야 할 것
실시간 캘린더모든 게시물과 그 상태
진행 중인 플랜제안됨, 승인됨
지금까지의 이야기계속 갱신되는 요약
→LLM최상위 모델 · 최대 8홉→

도구 호출

✓get_posting_times
✓get_insights
✓propose_plan

승인 대기 중인 플랜

수확 주간: 게시물 3개, 답글 4개

컨텍스트를 만드는 에이전트
// Volatile block: time + memory + live calendar + active plans + rolling summary.
// Rebuilt each turn (never cached) so the agent always sees current state.
const volatileSystem = () => {
  const parts = [
    nowBlock,
    renderMemories(memories),
    renderCalendar(calendar, todayISO),
    renderPlans(plans),
  ]
  if (documents.length) parts.push(renderDocuments(documents))
  if (rollingSummary) parts.push(`STORY SO FAR (summary of earlier messages in THIS conversation):\n${rollingSummary}`)
  // … then a line for each of the brand's other conversations
  return parts.join('\n\n')
}

데이터 모델

테이블은 약 55개이고, 몇 개의 명확한 그룹으로 나뉘어요. 워크스페이스에는 멤버와 브랜드가 있고, 나머지는 모두 브랜드에 매달려 있어서, 행 수준 보안은 어디서든 하나의 질문에만 답하면 돼요. 이 사람이 이 브랜드의 멤버인가?

누가

  • 워크스페이스
  • 멤버
  • 브랜드 역할
  • 프로필

브랜드

  • 브랜드
  • 색상, 폰트, 로고
  • 제품과 인물
  • 메모리 문서
  • 브랜드 문서

채팅

  • 대화
  • 메시지
  • 플랜
  • 플랜 항목

캘린더

  • 게시물
  • 네트워크마다 하나
  • 게시물 지표
  • 게시물 댓글

채널

  • 연결된 계정
  • 계정 일별 지표
  • 채널 설정

받은편지함과 사이클

  • 받은편지함 스레드
  • 받은편지함 메시지
  • 답글 초안
  • 사이클
  • 사이클 리포트

‘누가’ 아래의 모든 것은 브랜드 ID를 갖고, 행 수준 보안이 모든 읽기와 쓰기에서 이를 확인해요.

안정성과 보안

Groselia는 실제 계정에 게시해요. 그래서 치명적인 실패는 게시물이 두 번 나가거나, 아무도 모르게 끝내 안 나가는 거예요. 엔지니어링의 대부분이 거기에 들어가요.

1두 번 승인해도 실행은 한 번

플랜 러너는 조건부 업데이트로 플랜을, 이어서 각 항목을 선점하고, 모든 멱등성 키는 항목 자체의 ID에서 만들어요. 더블 클릭이나 재시도는 다시 게시하는 대신 재생돼요.

2웹훅은 서명되고 재생된다

게시 API에서 오는 모든 전송에는 유효한 HMAC 서명이 있어야 해요. 같은 전송이 여러 번 올 수 있어서 핸들러는 멱등하고, 놓친 이벤트는 10분마다 작업이 다시 재생해요.

3큐에 넣기 전에 거절하기

공유 규칙 파일 하나가 각 네트워크가 받는 걸 정해요(Instagram은 미디어 필수, YouTube는 영상 필수, Facebook은 혼합 불가). 스케줄러는 큐에 넣기 전에 이를 확인하고, 거절된 게시물은 캘린더에 ‘예약됨’으로 남는 대신 이유와 함께 ‘실패’로 돌아와요.

4모든 호출마다 접근 권한 확인

Postgres의 행 수준 보안, 모든 Edge Function의 역할 확인, 그리고 PKCE를 쓰는 OAuth로 MCP 접근. 브랜드별, 작업별로 범위를 정하고, 한 페이지에서 취소할 수 있어요.

한동안 로컬 앱과 라이브 앱이 하나의 프로덕션 데이터베이스를 같이 썼는데, 배포보다 먼저 실행된 마이그레이션이 라이브 Brand Kits 페이지를 텅 비게 만든 적이 있어요. 그 뒤로 백엔드 작업은 먼저 Supabase 브랜치에서 하고, 그게 필요한 코드와 함께 프로덕션에 병합해요.

품질과 워크플로

테스트 파일 140개에 걸친 약 1,000개의 테스트 케이스가 앱, MCP 서버, Edge Functions를 커버해요. 한 번 망가진 적이 있어서 생긴 검사도 있어요. 17개 언어 중 하나라도 키가 빠지면 빌드를 실패시키는 패리티 테스트, 합성 데이터로 돌고 끝나면 롤백하는 MCP 데이터베이스 테스트 같은 것들이요.

에이전트에는 전용 평가도 있어요. 브랜드 성과에 관한 정해진 질문들을 매번 새 대화에서 라이브 에이전트에게 묻고, 올바른 기간으로 인사이트를 읽었는지, 답에 인사이트 페이지와 같은 숫자가 들어 있는지 확인해요.

AI 에이전트를 팀처럼 다뤄서, 혼자 520개 넘는 풀 리퀘스트를 출시했어요. 모든 변경은 자기만의 git worktree 안의 자기 브랜치에서 이뤄져서, Claude Code와 Codex가 서로 부딪히지 않고 여러 일을 동시에 할 수 있어요. 각자 테스트와 타입 체크를 돌리고, 작은 풀 리퀘스트를 열고, 제가 읽기 전에는 아무것도 병합되지 않아요.

하나의 변경→전용 worktree→Claude Code 또는 Codex→테스트와 타입→작은 PR→내 리뷰→병합하고 배포

기술적 과제

모두 인터페이스 버그처럼 보였지만, 알고 보니 더 깊은 데 원인이 있었어요. 스트림의 형태, 타임스탬프, 네트워크가 실제로 보고하는 것, 그리고 시계.

생성을 실시간처럼 느끼게 · 실시간

한 달치 게시물을 생성하면 스피너가 돌다가 게시물 12개가 한꺼번에 튀어나왔어요. 느리게 느껴졌지만 문제는 모델이 아니었어요. 단위였죠.

모델 출력을 JSON Lines로 바꿔 스트리밍하고, 한 줄이 닫히는 순간 그 게시물을 삽입했어요. 캘린더는 Supabase Realtime으로 Postgres 변경을 구독하고 자리 표시자부터 그려서, 게시물이 하나씩 스스로 타이핑되듯 나타나요.

같은 기다림이 이제는 누군가 일하는 모습을 보는 것처럼 느껴져요.

절대 맞지 않던 두 타임스탬프 · 데이터

Supabase가 데이터베이스 디스크 IO가 곧 바닥난다고 경고했어요. 읽기는 괜찮았어요. 무언가가 같은 행을 계속 다시 쓰고 있었죠. 메시지 8.3만 개를 저장하는 데 insert가 34.4만 번.

받은편지함 동기화는 저장한 타임스탬프와 다시 읽은 타임스탬프를 비교했어요. Postgres는 +00:00으로 돌려주고 우리는 Z로 썼으니, 모든 대화가 바뀐 것처럼 보였고 매번 다시 내려받았던 거예요. 문자열 대신 시각 자체를 비교하자 해결됐어요.

두 타임스탬프 비교하기
export function sameInstant(a: string | null | undefined, b: string | null | undefined): boolean {
  if (a == null && b == null) return true;
  if (a == null || b == null) return false;
  if (a === b) return true;
  const ta = Date.parse(a);
  const tb = Date.parse(b);
  return Number.isFinite(ta) && Number.isFinite(tb) && ta === tb;
}

메시지 8.3만 개 저장에 든 insert

34.4만→새 메시지당 한 번

동기화마다 다시 읽는 대화

전부→바뀐 것만

불필요한 쓰기가 멈췄고, 한 번도 끝나지 않던 받은편지함 기록이 처음으로 동기화를 마쳤어요.

0이 항상 0은 아니다 · 분석

분석 제공업체는 모든 네트워크에 같은 형식으로 응답하고, 네트워크가 보고하지 않는 값은 0으로 채워요. Instagram은 모든 게시물의 클릭이 0“이었죠”. 차트가 정중하게 거짓말을 하고 있었어요.

플랫폼별 지표 레지스트리를 만들어 각 네트워크가 실제로 보고하는 걸 기록하고, 나머지는 수집할 때 null로 처리했어요. 그래서 모든 차트가 지표를 정직하게 보여 주거나, 낮춰 보여 주거나, 숨길 수 있어요.

8개 네트워크에 걸친 인사이트에서, 아무도 측정하지 않은 숫자는 절대 보이지 않아요.

빠른 시계 때문에 로그아웃 · 인증

공동 창업자가 로그인하자마자 로그아웃됐어요. 1초에 토큰 갱신 15번, 그리고 레이트 리밋. 다른 누구도 재현할 수 없었어요.

그의 컴퓨터 시계가 한 시간 넘게 빨랐고, 그래서 새로 받은 토큰이 전부 만료된 것처럼 보였던 거예요. 세션 스토리지를 감싸서, 세션을 쓸 때 만료 시각을 로컬 시계 기준으로 다시 맞추게 했어요.

초당 토큰 갱신

15→0

기기 시계가 어떻든 로그인되고, 시계가 어긋나 있으면 콘솔이 알려 줘요.

배운 점

취향이 해자다

AI로 만드는 비용이 싸지면 누구나 출시할 수 있고, 대부분은 비슷해 보여요. 여전히 귀한 건 판단력이에요. 무엇을 뺄지, 화면이 어떤 느낌이어야 할지, 어떤 애니메이션이 하나 더 많은지 아는 것. 누구보다 돈을 더 쓸 수 없는 두 명의 팀에게, 취향은 Groselia를 훨씬 큰 무언가처럼 보이고 작동하게 만드는 거예요. 그리고 제가 절대 모델에게 넘기지 않을 부분이기도 하고요.

도구가 아니라 결과를 팔아라

아무리 좋아도 마케팅 소프트웨어를 직접 다루고 싶은 사람은 없었어요. 사람들은 눈에 띄고 싶었죠. 앱 대신 일 자체를 팔자 제품은 덜 중요해진 게 아니라 더 중요해졌어요. 우리가 매일 돌리는 엔진이 됐으니, 거친 부분은 모두 고쳐졌어요.

영리함보다 컨텍스트

에이전트가 좋아진 건 프롬프트가 똑똑해졌을 때가 아니라 더 많이 알게 됐을 때였어요. 매 턴 실시간 캘린더, 메모리, 진행 중인 플랜을 주고, 행동하기 전에 묻게 한 것이 어떤 모델 업그레이드보다 효과가 컸어요.

AI는 팀의 크기를 바꾼다

에이전트가 코드 대부분을 병렬로 쓰면서, 제 일은 무엇을 만들지 정하고, 모든 변경을 리뷰하고, 기준을 높게 유지하는 쪽으로 옮겨 갔어요. 이제 한 사람이 예전엔 팀이 필요했던 일을 운영할 수 있어요. 그 사람이 편집자로 남아 있는 한요.

다음 프로젝트

모든 프로젝트