Shopify UI 개발 전문가. Checkout UI Extensions(React), Liquid 테마 페이지, Polaris Admin 앱, Hydrogen/Remix 스토어프론트 개발과 폼 데이터 → n8n → PostgreSQL → Airtable → Shopify Metafields 데이터 파이프라인, E2E 테스트를 담당한다. Shopify UI, 체크아웃 확장, Liquid 페이지, 메타필드, 데이터 흐름, 폼 개발, 테마 배포, n8n 웹훅, 유저 데이터 저장, 스토어프론트, Polaris 관련 작업에 반드시 사용할 것. 새 페이지/폼 개발, 기존 UI 수정, 데이터 플로우 설계, E2E 테스트 작성 모두 이 스킬의 영역이다.
4개 UI 도메인(Checkout Extension, Liquid 테마, Polaris Admin, Hydrogen/Remix)과 공유 데이터 파이프라인을 통합 관리하는 스킬이다. UI에서 수집한 유저 데이터가 최종 저장소까지 도달하는 전체 흐름을 책임진다.
tools/deploy_*.py)tools/shopify_tester.py, tools/test_influencer_flow.py)[UI Layer] [Data Pipeline]
Checkout UI Extension ──metafield──> Shopify Order Metafields
(React, @shopify/ui-extensions-react) │
onzenna-survey-app/extensions/ │ Shopify Webhook
▼
Thank-You Extension ──POST──> n8n Orchestrator
(React, purchase.thank-you.*) │
┌──────┼──────┬──────┐
Liquid Pages ──fetch()──> │ │ │ │
(deploy_*.py, Theme Asset API) Postgres Airtable Slack Email
│
Admin App ──GraphQL──> Shopify Metafields (via n8n)
(Polaris, App Bridge)
Hydrogen/Remix ──Storefront API──>
(headless, SSR)
Influencer Pipeline ──n8n polling──>
(Airtable status → Shopify Draft Order → Fulfillment → Syncly)
React 컴포넌트 기반. @shopify/ui-extensions-react/checkout 패키지 사용.
위치: onzenna-survey-app/extensions/
onzenna-checkout-survey/ — 체크아웃 설문 (Q4~Q7)onzenna-thankyou-survey/ — 감사 페이지 크리에이터 폼 + 로열티 CTA핵심 패턴:
useApplyMetafieldsChange (메타필드 쓰기), useMetafield (읽기), useCustomer, useOrder, useSettingsapplyMetafieldsChange({ type: "updateMetafield", namespace, key, valueType, value })shopify.extension.toml에서 api_version, targeting, capabilities, metafields 선언shopify app dev (프리뷰) / shopify app deploy (프로덕션)메타필드 네임스페이스:
| Namespace | Key | 설명 |
|---|---|---|
onzenna_survey | journey_stage | 육아 단계 |
onzenna_survey | baby_birth_month | 아기 생년월 (YYYY-MM) |
onzenna_survey | has_other_children | 다른 자녀 유무 |
onzenna_survey | is_creator | 크리에이터 여부 |
onzenna_survey | signup_completed_at | 설문 완료 시각 |
onzenna_creator | creator_completed_at | 크리에이터 폼 완료 시각 |
상세 패턴은 references/ui-extensions.md 참조.
Python 스크립트가 Liquid 섹션 + JSON 템플릿을 Shopify Theme Asset API로 업로드하고, 페이지를 생성/업데이트한다.
기존 배포 스크립트:
| 스크립트 | 페이지 | 상태 |
|---|---|---|
deploy_core_signup_page.py | /pages/core-signup | 운영 |
deploy_loyalty_survey_page.py | /pages/loyalty-survey | 운영 |
deploy_creator_profile_page.py | /pages/creator-profile | 운영 |
deploy_creator_sample_form_page.py | /pages/creator-sample | 운영 |
deploy_influencer_page.py | /pages/influencer-gifting | 운영 |
deploy_influencer_gifting2_page.py | /pages/influencer-gifting2 | 운영 |
deploy_chaenmom_gifting_page.py | /pages/chaenmom-gifting | 운영 |
핵심 패턴:
PUT /themes/{id}/assets.json (Theme Asset)GET /themes.json → role == "main"templates/page.{handle}.jsonck-, igf-, cs-)fetch(WEBHOOK_URL, { method: "POST", ... })--dry-run, --unpublish, --rollback새 페이지 개발 시: 가장 유사한 기존 deploy 스크립트를 복사하여 시작한다.
상세 패턴은 references/liquid-themes.md 참조.
Shopify Admin에 임베딩되는 React 앱. 내부 대시보드, 설정 패널, 커스텀 워크플로우에 사용.
기술 스택:
@shopify/polaris — UI 컴포넌트 (Page, Card, Layout, DataTable, ResourceList 등)@shopify/app-bridge-react — Admin 임베딩tools/shopify_oauth.py 기존 패턴 재사용현재 상태: 설계 단계. 기존 구현 없음.
상세 패턴은 references/polaris-admin.md 참조.
헤드리스 커스텀 스토어프론트. Remix 기반 SSR.
기술 스택:
loader/action 패턴으로 데이터 페칭현재 상태: 계획 단계. 기존 구현 없음.
상세 패턴은 references/hydrogen-remix.md 참조.
인플루언서 협업의 전체 수명주기를 n8n 워크플로우 체인으로 자동화한다.
Not Started → Draft Ready → Sent → Replied → Needs Review
→ Accepted → Sample Sent → Sample Shipped → Sample Delivered → Posted
→ Sample Error
→ Declined
| 단계 | n8n 워크플로우 | 트리거 | 동작 |
|---|---|---|---|
| 0. AI 아웃리치 | Draft Generation (schedule) | 30분 폴링 | Airtable "Not Started" → Claude AI 초안 생성 → "Draft Ready" |
| 0.5 승인 발송 | Approval Send (schedule) | 5분 폴링 | "Approved" → Gmail 발송 → "Sent" |
| 1. 답장 처리 | Reply Handler (schedule) | 5분 폴링 | Gmail 답장 감지 → 분류(LT/HT) → AI 답장 초안 → "Replied" |
| 2. 신청 접수 | Gifting (webhook) | 폼 제출 | Shopify 고객 생성/조회 → Airtable 레코드 생성 (Needs Review) |
| 3. 수락 → 샘플 요청 | Gifting2 (webhook) | 크리에이터 폼 제출 | Draft Order 생성 (100% 할인) → Airtable + PG 업데이트 |
| 4. 샘플 발송 처리 | Fulfillment (schedule/webhook) | 폴링/이벤트 | Shopify fulfillment → Airtable "Sample Shipped" + 가이드라인 이메일 |
| 5. 샘플 발송 완료 | Sample Sent → Complete (polling) | 5분 간격 | Airtable "Sample Sent" → Draft Order Complete → "Sample Shipped" |
| 6. 배송 완료 | Shipped → Delivered (polling) | 30분 간격 | Shopify delivery 감지 → "Sample Delivered" |
| 7. 컨텐츠 게시 | Delivered → Posted (polling) | 6시간 간격 | Syncly D+60 시트 매칭 → "Posted" |
Production (17 workflows):
| ID | 이름 | 노드 | 상태 |
|---|---|---|---|
fwwOeLiDLSnR77E1 | Draft Generation | 42 | Active |
jf9uxkPww2xeCr82 | Approval Send | 16 | Active |
K99grtW9iWq8V79f | Reply Handler | 46 | Active |
F0sv8RsCS1v56Gkw | Gifting (Influencer Application) | - | Active |
KqICsN9F1mPwnAQ9 | Gifting2 (Sample Request → Draft Order) | 14 | Inactive |
ufMPgU6cjwuzLM0y | Shopify Fulfillment → Airtable | 34 | Active |
m89xU9RUbPgnkBy8 | Sample Sent → Complete Draft Order | - | Active |
FzBJVEOTvr6qJPAL | Syncly: Daily Content Metrics Sync | 5 | Active |
WJ TEST (18 workflows, 2026-03-13 마이그레이션 완료):
| ID | 이름 | 노드 | 상태 | 비고 |
|---|---|---|---|---|
0q9uJUYTpDhQFMfz | Draft Generation | 49 | Active | PROD +9 머지 |
mmkBpmvhzbgmSayh | Approval Send | 16 | Active | PROD +4 머지 |
nVtYmhU0InRqRn4K | Reply Handler | 50 | Active | PROD +7 머지 (HT Reply) |
4q5NCzMb3nMGYqL4 | Gifting | 12 | Active | |
734aqkcOIfiylExL | Gifting2 → Draft Order | 14 | Inactive | 검증 후 활성화 필요 |
UP1OnpNEFN54AOUn | Fulfillment → Airtable | 37 | Active | PROD +12 머지 |
Vd5NiKMwdLT7b9wa | Sample Sent → Complete | 7 | Active | |
2vsXyHtjo79hnFoD | Shipped → Delivered | 11 | Active | |
82t55jurzbY3iUM4 | Delivered → Posted | 8 | Active | |
FT70hFR6qI0mVc2T | Syncly Metrics Sync | 5 | Inactive | 검증 후 활성화 필요 |
wyttsPSZJlWLgy86 | Customer Lookup | 5 | Active | |
zKmOX0tEWi6EBT9h | Content Tracking | 23 | Active | |
6BNQRz57oCtdROlH | Syncly Data Processing | 64 | Active | |
CEWr3kQlDg07310Y | Full Pipeline (monolith) | 68 | Inactive | archive |
YCZuTAsHK2Ja6kIs | AI Outreach (archive) | 61 | Inactive | archive |
5BG7Qe7HtsbD4iP0 | Docusign Contracting | 14 | Inactive | |
k08R16VJIuSPdi6T | ManyChat Automation | 13 | Inactive | |
fJd4tZkBmmB2bdHJ | Fulfillment (archive) | 26 | Inactive | archive |
| 항목 | PROD | WJ TEST |
|---|---|---|
| Airtable Base | appNPVxj4gUJl9v15 | appT2gLRR0PqMFgII |
| 트리거 방식 | scheduleTrigger (폴링) | webhook (실시간) + schedule |
| Config 패턴 | Fetch Dashboard + Fetch Today Config + Wait for Config | Read Config Sheet (Google Sheets) |
| Shopify 스토어 | mytoddie.myshopify.com | toddie-4080.myshopify.com |
| PostgreSQL | 없음 | Django API 연동 (orbitools.orbiters.co.kr) |
| 테스트 인프라 | 없음 | Inject Test Record, Is Dry Run?, Manual Trigger |
Fetch Dashboard + Fetch Today Config + Wait for Config + Is Active? (중앙 Config 시트에서 on/off 제어)Stop: No Email, Stop: Missing Email, Update Creator: Error| ID | 이름 | 용도 |
|---|---|---|
rIJuzuN1C5ieE7dr | Shopify Admin API (Gifting) | mytoddie.myshopify.com Draft Order 관리 |
59gWUPbiysH2lxd8 | Airtable PAT (WJ Test) | Airtable HTTP Request 인증 |
| 환경 | Base ID | Table ID | 용도 |
|---|---|---|---|
| Production (William) | appNPVxj4gUJl9v15 | tblv2Jw3ZAtAMhiYY | Outbound CRM |
| WJ TEST | appT2gLRR0PqMFgII | tbl7zJ1MscP852p9N | 테스트 환경 |
| Inbound | appT2gLRR0PqMFgII | tbloYjIEr5OtEppT0 | 인플루언서 인바운드 |
fetch() 없음 — API 호출은 반드시 HTTP Request 노드 사용mytoddie.myshopify.com (n8n 크레덴셜, Draft Order 권한 있음) vs toddie-4080.myshopify.com (.wat_secrets 토큰, product scope만)상세는 references/influencer-pipeline.md 참조.
UI에서 수집한 데이터가 최종 저장소에 도달하는 경로.
패턴 A — Checkout Extension (메타필드 직접 쓰기):
체크아웃 폼 → useApplyMetafieldsChange → Order Metafield
→ Shopify Webhook (orders/create) → n8n → PostgreSQL + Airtable
→ n8n (sync) → Customer Metafield (via Admin API)
패턴 B — Thank-You / Liquid 페이지 (webhook POST):
폼 submit → fetch(n8n_webhook_url) → n8n
→ PostgreSQL (upsert) + Airtable (create/update)
→ Shopify Customer Metafield (via Admin API)
→ Slack 알림 / Email 확인
| 테이블 | 용도 |
|---|---|
customers | Shopify 고객 기본 정보 |
addresses | 배송 주소 (지역 분석) |
orders | 주문 이력 |
line_items | 제품별 주문 데이터 |
customer_metrics | LTV, RFM, 소비 패턴 (일일 enrichment) |
sync_log | 동기화 감사 추적 |
| 도구 | 용도 |
|---|---|
setup_n8n_core_signup.py | 코어 사인업 → 메타필드 |
setup_n8n_airtable_to_shopify_metafields.py | Airtable → Shopify 메타필드 동기화 |
setup_shopify_webhooks.py | Shopify 웹훅 등록 |
shopify_bulk_import.py | 기존 데이터 벌크 임포트 |
상세는 references/data-pipeline.md 참조.
tools/shopify_tester.py를 사용한 E2E 테스트.
shopify_tester.py --push --spec '...'shopify_tester.py --runshopify_tester.py --results| Type | 설명 |
|---|---|
http_post | 폼 제출 시뮬레이션 |
http_get | 페이지/API 응답 확인 |
verify_airtable | Airtable 레코드 확인 |
verify_postgres | PostgreSQL 쿼리 검증 |
verify_shopify | Shopify 메타필드/주문 확인 |
wait | 비동기 처리 대기 |
데이터 체인에서 어느 레이어가 깨졌는지 식별:
폼 제출 → webhook 수신 → n8n 처리 → DB 저장 → 메타필드 동기화
상세는 references/testing.md 참조.
| Tool | 페이지 |
|---|---|
deploy_core_signup_page.py | /pages/core-signup (Part 1) |
deploy_loyalty_survey_page.py | /pages/loyalty-survey (Part 3) |
deploy_creator_profile_page.py | /pages/creator-profile (Part 2) |
deploy_creator_sample_form_page.py | /pages/creator-sample |
deploy_influencer_page.py | /pages/influencer-gifting |
deploy_influencer_gifting2_page.py | /pages/influencer-gifting2 |
deploy_chaenmom_gifting_page.py | /pages/chaenmom-gifting |
| Tool | 용도 |
|---|---|
setup_n8n_core_signup.py | Core Signup → PG + Airtable + Shopify (PG-first) |
setup_n8n_loyalty_survey.py | Loyalty Survey → Discount Code + Metafields |
setup_n8n_creator_to_airtable.py | Creator Signup → PG + Airtable + IG Scrape |
setup_n8n_gifting2_order.py | Gifting2 → Shopify Draft Order + Airtable |
setup_n8n_sample_request_order.py | Sample Request → Draft Order (100% discount) |
setup_n8n_metafield_sync.py | Form survey data → Shopify customer metafields |
setup_n8n_airtable_to_shopify_metafields.py | Airtable → Shopify metafield sync (5min poll) |
setup_n8n_airtable_to_postgres.py | Airtable → PostgreSQL sync (5min poll) |
setup_n8n_airtable_sync.py | PostgreSQL → Airtable daily customer sync |
setup_n8n_customer_sync.py | Shopify Customer Webhook → PostgreSQL |
setup_n8n_order_sync.py | Shopify Order Webhook → PostgreSQL |
setup_n8n_customer_enrichment.py | Daily RFM + LTV + AOV calculation |
setup_n8n_accepted_email.py | Accepted creators → Send sample form email |
setup_n8n_syncly_daily.py | Syncly Daily Content Metrics Sync |
setup_n8n_signup_overview.py | Tag + overview workflow with flow diagram |
| Tool | 용도 |
|---|---|
shopify_tester.py | E2E 테스트 러너 (customer journey) |
shopify_bulk_import.py | 기존 데이터 벌크 임포트 to PG |
shopify_oauth.py | OAuth 토큰 발급 (local callback server) |
setup_survey_metafields.py | 메타필드 정의 등록 |
| Tool | 용도 |
|---|---|
test_influencer_flow.py | E2E flow tester (Pathlight pipeline) |
process_influencer_order.py | 폼 제출 → Shopify customer + draft order |
influencer_customer_lookup.py | Shopify 고객 검색 (n8n Execute Command용) |
fetch_influencer_orders.py | 인플루언서 주문 조회 (PR/supporter/sample) |
check_influencer_hashtag.py | IG 해시태그 포스팅 확인 (Meta Graph API) |
create_typeform_influencer.py | Typeform 기프팅 폼 생성 |
sync_influencer_notion.py | Google Sheets → Notion DB 동기화 |
| Tool | 용도 |
|---|---|
setup_airtable_customers.py | Shopify Customers 베이스 생성 |
setup_airtable_inbound.py | Inbound from ONZ 베이스 생성 |
setup_airtable_customers_table.py | Onzenna Customers 마스터 테이블 |
| 항목 | 값 |
|---|---|
| 인스턴스 | orbiters-n8n-server (i-0ddaa6796683e8043) |
| Private IP | 172.31.47.225 |
| Docker Compose | /home/ubuntu/n8n/docker-compose.yml |
| 컨테이너 | n8n-n8n-1 (n8n) + n8n-caddy-1 (Caddy reverse proxy) |
| 도메인 | https://n8n.orbiters.co.kr (Caddy SSL) |
| n8n 포트 | 5678 (Docker 내부, 호스트에 미노출) |
| 환경변수 | /home/ubuntu/n8n/.env |