← 블로그 목록

Manus로 만든 MVP, data.js만 바꿔 관리하도록 정리한 사례

Manus로 만들던 어린이 위인전 MVP를 예시로, 디자인 요구사항과 SVG 아이콘 제작, 다국어 입력 규칙, 공통 참조 구조를 data.js 하나로 정리한 실제 작업 사례를 익명화해 정리했습니다.

이 작업은 처음엔 "템플릿 제작"으로 들렸습니다. 그런데 저장소를 열어보니 핵심은 조금 달랐습니다. 고객은 Manus로 MVP를 만들고 있었고, 앞으로 직접 콘텐츠를 계속 늘려야 하는 상황이었습니다. 매번 AI에게 같은 구조를 다시 설명하거나 화면 코드를 뒤져가며 회차를 추가하기엔 금방 무거워질 수밖에 없었습니다.

작업 기간은 3일, 비용은 15만원이었습니다. 단순 문구 교체였다면 그 정도 비용이 나오지 않았을 겁니다. 실제 범위는 디자인 요구사항 반영, SVG 아이콘 제작, 다국어 데이터 입력 규칙 정리, 캐릭터와 회차를 계속 쌓을 수 있는 템플릿 구조화였습니다.

서비스명과 저장소명은 밝히지 않겠습니다. 대신 구조는 최대한 구체적으로 풀어보겠습니다. 이 글의 요지는 "비개발자도 코드를 만지게 하자"가 아니라, Manus로 만든 MVP를 운영하는 사람이 안전하게 바꿀 수 있는 영역을 따로 만들어주자에 가깝습니다.

처음부터 화면보다 데이터가 문제였다

콘텐츠는 어린이용 위인전 형태였습니다. 캐릭터가 있고, 각 캐릭터마다 여러 회차가 있고, 1화는 커버형 화면, 2화부터는 조금 더 압축된 화면을 씁니다. 본문에는 문단만 있는 게 아니라 삽화, 캡션, 하이라이트 문장도 섞입니다.

게다가 화면에 보이는 텍스트는 한국어, 영어, 중국어를 같이 입력해야 했습니다. 여기에 디자인 요구사항과 SVG 아이콘 제작까지 붙었습니다.

처음 떠올리기 쉬운 방식은 화면 가까이에 데이터를 하나씩 박아 넣는 겁니다.

js
const episode1Title = {
  ko: "1화 작은 집에서 자란 큰 마음",
  en: "Episode 1. A Big Heart in a Small Cabin",
  "zh-CN": "第1集 小木屋里的大胸怀",
};
const episode1Image = "/images/episodes/hero-01.webp";
const episode2Title = { ko: "2화 ...", en: "Episode 2 ...", "zh-CN": "第2集 ..." };

이 방식은 첫 화면을 빨리 만드는 데는 편합니다. 문제는 세 번째 캐릭터, 열 번째 회차가 들어올 때부터입니다. 고객 입장에서는 "어디를 복사해야 하지?", "이미지는 어디에 넣어야 하지?", "중국어 문구를 빼먹으면 화면이 어떻게 되지?" 같은 질문이 계속 생깁니다.

그래서 이번 작업에서는 화면을 하나 더 만드는 대신, 고객이 복사해서 확장할 수 있는 입력 구조부터 잡았습니다.

먼저 바뀌는 것과 고정되는 것을 나눴다

비개발자가 관리할 수 있는 구조를 만들 때 제일 중요한 건 "무엇을 바꿔도 되는지"입니다. 바꿔도 되는 영역과 건드리지 않는 영역이 섞이면, 결국 AI에게 다시 길게 설명해야 하거나 직접 수정 흐름이 멈춥니다.

영역고객이 바꾸는 것공통으로 고정한 것
캐릭터위인 이름, 관리자용 라벨원형 초상화 참조 위치
회차제목, 본문, 하이라이트 문장1화 cover, 2~12화 compact 구조
언어ko, en, zh-CN 문구모든 노출 텍스트의 언어 키 형식
삽화src, alt, caption이미지가 없을 때의 화면 처리
디자인콘텐츠 의도섹션별 프레임과 장식 규칙

이 표가 실제 구현의 기준이 됐습니다. 고객이 바꿀 데이터는 data.js에 모으고, 화면 레이아웃과 공통 스타일은 코드 쪽에 남겼습니다. 같은 정보가 여러 군데 흩어지지 않게 만든 것이고, 이게 이 작업에서 말하는 SSOT였습니다.

data.js를 고객용 입력면으로 만들었다

핵심 파일은 고객이 직접 여는 data.js였습니다. 이 파일을 작업자만 알아보는 설정 파일처럼 두면 안 됐습니다. 그래서 맨 위에는 입력 방법을 적고, 아래에는 바로 복사할 수 있는 예시 데이터를 뒀습니다.

단순화하면 구조는 이런 느낌입니다.

js
window.BIOGRAPHY_TEMPLATE_DATA = {
  hero01: {
    adminLabel: "Hero 01",
    characterName: {
      ko: "위인 이름",
      en: "Hero Name",
      "zh-CN": "人物姓名",
    },
    episodes: {
      1: {
        template: "cover",
        heroTitle: {
          ko: "1화 제목",
          en: "Episode 1 Title",
          "zh-CN": "第1集标题",
        },
        bodyBlocks: [
          { type: "text", paragraphs: [{ ko: "문단", en: "Paragraph", "zh-CN": "段落" }] },
          { type: "image", align: "right", image: { src: "/images/example.webp" } },
        ],
      },
      2: {
        template: "compact",
        compactEpisodeTitle: { ko: "2화 제목", en: "Episode 2", "zh-CN": "第2集" },
        bodyBlocks: [],
      },
    },
  },
};

이런 구조의 장점은 고객이 '다음 회차를 만들 때 무엇을 복사해야 하는지' 바로 볼 수 있다는 점입니다. 1화는 cover, 2화부터는 compact. 본문은 bodyBlocks 배열 순서대로 쌓입니다. 텍스트 블록을 넣고, 필요하면 이미지 블록을 끼워 넣는 식입니다.

파일 상단에는 몇 가지 규칙도 같이 남겼습니다. 화면에 보이는 문구는 세 언어를 모두 입력한다, 이미지 src가 비어 있으면 어떤 슬롯은 placeholder를 보여주고 본문 삽화는 아예 숨긴다, 없는 캐릭터나 회차는 화면에서 기본 문구로 표시한다는 식입니다. 작은 규칙 같지만, 운영할 때는 이런 문장이 사고를 많이 줄입니다.

디자인 요구사항도 구조 안에 넣었다

이번 작업에는 디자인 요구사항도 꽤 있었습니다. 화면 장식, 프레임 느낌, SVG 아이콘 제작까지 같이 봐야 했습니다. 여기서 고민한 지점은 "고객이 매 회차마다 디자인을 고르게 할 것인가"였습니다.

저는 그렇게 하지 않는 쪽을 선택했습니다. 콘텐츠 입력자가 매번 프레임 종류까지 고르게 만들면, 자유도는 생기지만 관리 난도가 올라갑니다. 대신 섹션 역할별로 공통 스타일을 잡았습니다.

js
window.BIOGRAPHY_TEMPLATE_CONFIG = {
  frameStyles: {
    coverHero: { cornerStyle: "classic", borderStyle: "double" },
    heroOverlay: { cornerStyle: "deco", borderStyle: "single" },
    episodeBody: { cornerStyle: "regal", borderStyle: "double" },
    compactBar: { cornerStyle: "rococo", borderStyle: "double" },
    compactBody: { cornerStyle: "regal", borderStyle: "double" },
  },
};

이렇게 두면 디자인 요구사항은 반영되지만, 고객은 매번 "이번 회차에는 어떤 장식을 넣지?"를 고민하지 않아도 됩니다. 커버 히어로, 본문, 하이라이트, compact 헤더처럼 역할별 기준이 정해져 있으니까요.

SVG 아이콘도 같은 맥락이었습니다. 한 화면에서만 쓰고 버리는 장식이 아니라, 템플릿 톤 안에서 반복 사용될 수 있게 만들었습니다. 보기 좋은 것도 중요하지만, 반복될 때 덜 흔들리는 쪽이 더 중요했습니다.

고객이 실제로 만질 부분만 좁혔다

비개발자가 관리 가능한 템플릿에서 중요한 것은 "코드를 몰라도 됩니다"라는 말이 아닙니다. 그 말은 너무 넓고, 실제 운영에서는 별 도움이 안 됩니다. 더 중요한 건 "이 파일의 이 영역은 바꿔도 됩니다"라고 말할 수 있는 상태입니다.

이번 구조에서는 고객이 바꿔도 되는 부분을 데이터 입력으로 모았습니다. 반대로 화면 레이아웃, 공통 초상화 참조, 프레임 스타일, 누락 데이터 처리 같은 것은 공통 구조로 묶었습니다.

덕분에 운영 방식이 단순해졌습니다.

  • 새 캐릭터는 기존 캐릭터 블록을 복사해서 추가함
  • 새 회차는 1화 또는 2화 예시를 복사해서 내용만 바꿈
  • 다국어 문구는 같은 키 구조를 유지함
  • 본문 순서는 bodyBlocks 배열 순서로 조정함
  • 디자인 기준은 회차마다 다시 정하지 않음

이 정도만 돼도 고객이 느끼는 부담이 많이 줄어듭니다. "수정할 수 있다"보다 "잘못 건드릴 곳이 줄었다"가 더 정확한 표현일지도 모르겠습니다.

왜 단순 수정이 아니라 15만원 작업이 되었나

이 작업의 비용이 15만원이었던 이유는 결과물이 "화면 하나"가 아니었기 때문입니다. 손에 잡히는 결과만 보면 템플릿 화면과 데이터 파일이지만, 실제로 들어간 일은 조금 더 넓었습니다.

  • 고객 요구사항을 화면 구조와 데이터 구조로 분해
  • 디자인 요구사항에 맞춰 템플릿 화면 구현
  • 필요한 SVG 아이콘 제작
  • 캐릭터와 회차 데이터를 SSOT 형태로 정리
  • 다국어 입력 규칙 작성
  • 텍스트와 이미지가 섞이는 본문 블록 구조 설계
  • 고객이 복사해 쓸 수 있는 참고 데이터 작성
  • 누락 데이터와 빈 이미지의 화면 처리 정리

고객 입장에서는 마지막 항목들이 특히 중요합니다. 새 콘텐츠를 넣다가 이미지가 비었을 때 화면이 깨지면 곤란합니다. 중국어 문구가 빠졌을 때 어디가 빠졌는지 찾기 어려워도 곤란합니다. 그래서 템플릿 작업은 "처음 한 번 보이는 화면"보다 "두 번째, 세 번째 입력도 버티는 구조"가 더 중요했습니다.

비슷한 템플릿을 만들 때 먼저 정해야 하는 것

비슷한 템플릿을 만들 계획이라면, Manus나 AI 도구에 다시 요청하기 전에 아래 질문부터 정리하는 편이 좋습니다. 이건 기획서처럼 거창할 필요는 없습니다. 메모장에 적어도 됩니다.

  • 앞으로 반복해서 추가될 단위가 무엇인가
  • 그 단위마다 반드시 필요한 필드는 무엇인가
  • 선택 사항으로 비워둘 수 있는 필드는 무엇인가
  • 화면 종류가 몇 가지인지
  • 언어가 하나인지 여러 개인지
  • 공통으로 참조할 데이터가 있는지
  • 고객이 직접 바꿀 영역과 구조로 고정할 영역은 어디인지
  • 데이터가 비어 있을 때 화면은 어떻게 보여야 하는지

이 질문에 답이 없으면 템플릿은 금방 복잡해집니다. 반대로 이 기준만 잡혀도 AI로 만든 서비스나 초기 MVP를 훨씬 안정적으로 운영할 수 있습니다. AI에게 맡길 때도 "이 구조로 data.js를 만들어줘"라고 말할 수 있으니까요.

정리

비개발자도 관리 가능한 템플릿을 만든다는 것은 코드를 감추는 일이 아닙니다. 수정 가능한 영역을 좁히고, 반복되는 입력을 같은 규칙으로 쌓을 수 있게 만드는 일입니다.

이번 사례에서 중요했던 것은 세 가지였습니다.

  1. 디자인 요구사항을 화면에만 반영하지 않고 구조 안에 녹이는 것
  2. 고객이 복사해서 확장할 수 있는 실제 데이터 예시를 두는 것
  3. 공통 참조와 입력 규칙을 data.js 중심으로 정리하는 것

그래서 이 작업은 "템플릿 하나 제작"이라기보다 "앞으로 콘텐츠를 계속 쌓을 수 있는 운영 구조 만들기"에 가까웠습니다. LastFix가 단건 작업에서도 중요하게 보는 지점이 여기에 있습니다. 당장의 문제를 해결하되, 다음 수정이 더 쉬워지는 형태로 남기는 것.

관련 글: AI로 만든 MVP 화면이 흔들릴 때, 실제로 수정한 순서, 바이브코딩으로 만든 MVP 배포 전 체크리스트, AI가 만든 코드가 점점 복잡해질 때 멈춰야 하는 신호

LastFix 무료 진단

AI·바이브코딩으로 해결되지 않는 개발 이슈가 있다면 원인부터 확인하세요

배포 오류, UI 깨짐, 결제·예약 연동, 작은 기능 수정을 단건으로 진단하고 필요한 범위만 정리합니다.

무료 진단 신청