Hướng dẫn CodePanel

Dành cho PO của EXO Studio · Cập nhật 2026-06-25

Tóm tắt 30 giây CodePanel là panel web cho PO quản lý + build + submit app iOS/Android từ xa qua URL panel.xuongapp.com. Mọi action upload/submit thật đều cần PO bấm xác nhận. Chat với Claude trong tab Lệnh & Build để Claude sửa code, install ads, submit App Store, v.v. — PO duyệt từng turn.
Mục lục
  1. Truy cập + đăng nhập
  2. Bố cục chung
  3. Tab Files
  4. Tab Status — pipeline + Version planner
  5. Tab Request — request + rejection + đính kèm file (mới 2026-06-25)
  6. Tab Lệnh & Build — terminal + chat Claude
  7. Tab Store listing — metadata + screenshots + AI gen
  8. Tab Policy — Privacy & Terms
  9. Tab Checklist — AdMob/SDK/Remote Config
  10. Workflow: thêm project mới từ GitLab (mới 2026-06-25)
  11. Workflow: tạo app mới từ đầu đến v1.0 live
  12. Workflow: tạo version mới đến submit
  13. Workflow: phản hồi rejection từ Apple
  14. Workflow: v1.1 — gắn Ads cho app v1.0 đã live
  15. Tips & Gotchas
  16. Khắc phục sự cố

1. Truy cập + đăng nhập

CodePanel chạy trên Mac mini của studio và expose ra ngoài qua Cloudflare tunnel:

2 cách đăng nhập

⚠ Bảo mật: KHÔNG share token qua chat/email công khai. Token = full access tới Mac build server. Mất token = phải re-generate ở .codepanel/config.json trên Mac.

2. Bố cục chung

Mở panel xong PO sẽ thấy:

Nút 🔄 trên cùng sidebar = refresh danh sách project (sau khi clone hoặc tạo thư mục mới).

3. Tab Files

Trình duyệt file của project. Click thư mục để mở; click file để xem với syntax highlight (highlight.js).

4. Tab Status — pipeline + Version planner

Tab tổng quan vòng đời app từ tạo project → release. Tab này có 2 phần:

Lưu ý 2026-06-25: Top button "🚀 Submit App Store…" đã BỎ. Path submit duy nhất hiện tại là nút "Nộp review qua ASC API" ở stage "Nộp & review" trong pipeline (xem 4.2 bên dưới) — spawn Claude session + Playwright xử lý App Privacy + Age Rating đầy đủ. Nếu chỉ muốn submit nhanh không cần Privacy (vd v1.1 resubmit không đổi data collection), curl trực tiếp: curl -X POST -H "Authorization: Bearer <token>" -d '{"releaseType":"MANUAL"}' http://localhost:8765/api/projects/<app>/submit.

4.1. Version planner panel iOS

Khi v live trên ASC đang ở trạng thái READY_FOR_SALE / READY_FOR_REVIEW và panel detect project.yml.marketing == live → hiển thị panel "💡 Bắt đầu version mới?":

Modal "Tạo version mới":

4.2. Pipeline stages

List dạng stepper dọc, mỗi dot màu theo state:

MàuStateÝ nghĩa
🟢doneHoàn thành
🟡doingĐang chạy / partial
🔴errorCó lỗi / sai sheet
⚪todoChưa làm
—unknownChưa kiểm tra được (vd ASC chưa cấu hình)

Mỗi stage có thể kèm nút action để hoàn thành bước đó:

4.3. Nộp review qua ASC API (Claude + Playwright)

Path submit DUY NHẤT trong UI hiện tại (top button "🚀 Submit App Store…" đã bỏ 2026-06-25). Truy cập qua nút "Nộp review qua ASC API" ở stage "Nộp & review" cuối pipeline.

Bấm nút → mở modal nhỏ chọn release type → spawn Claude session drive toàn bộ submit:

PO theo dõi từng turn ở tab Lệnh & Build (chat mode). Nếu Claude yêu cầu PO login ASC (lần đầu) → PO mở browser login → reply "ok tôi đã đăng nhập" → Claude resume.

Direct API path (không cần Privacy/Age Rating qua Playwright, vd v1.1 resubmit không đổi data): curl POST /submit trực tiếp với release type. Dùng cho resubmit nhanh.

5. Tab Lệnh & Build — chat Claude (Codex-style)

Đổi 2026-06-24: Action grid (git status/pull/xcodegen/schemes/build/...) + ô $ command tùy ý đã bỏ. Tab giờ tập trung 100% vào chat Claude. Các action xưa giờ:

5.1. Chat Claude (giao diện Codex-style)

Job Claude (từ tab Request, asc-submit, install-ads, auto-fix v.v.) hiện chat mode: bubble user/assistant đan xen, typography lớn (font system 15.5-16px), code block bo góc với header ngôn ngữ + nút Copy.

5.2. Soft guard "version trùng live"

Trước khi chạy Up TestFlight / Claude xử lý issue / Install Ads / Firebase Create, panel tự check: nếu project.yml.marketing == liveVersion và chưa có editable version → hiện confirm dialog cảnh báo:

⚠️ project.yml đang là v1.0 — trùng v live ASC. Khuyên Tạo version mới (v1.1) qua Status tab TRƯỚC khi tiếp tục — code change/upload không lẫn vào version đã live. (Apple sẽ reject upload trùng version, mất 5-15 phút processing.) Vẫn tiếp tục?

PO override được nếu chỉ dev test, không up TestFlight thật.

6. Tab Store listing — metadata + screenshots + AI gen

6.1. Header rõ version đang chỉnh

6.2. Sửa metadata

iOS có 6 field name/subtitle/promo/desc/keywords/whatsNew + Support URL + Marketing URL + Privacy Policy URL. Counter ký tự realtime (đỏ khi quá cap Apple).

Android có title (30), short description (80), full description (4000).

Bấm Lưu metadata → chỉ PATCH field nào thay đổi.

whatsNew khoá ở v1.0 đầu tiên: ASC trả 409 "Attribute 'whatsNew' cannot be edited". Panel auto bỏ qua field này và báo "đã lưu (bỏ qua: whatsNew)". Lần v1.1 trở đi sẽ sửa được.

6.3. Upload screenshots

6.4. AI gen ✨

Panel "✨ Tạo bằng Claude" trên cùng tab. Textarea brief mô tả app (1-3 câu), bấm:

Mọi gen job chạy async (poll mỗi 2s vì Cloudflare tunnel drop request dài 100s+).

7. Tab Policy — Privacy & Terms

Gen + deploy Privacy Policy / Terms of Service cho app, host miễn phí trên exo-pages.web.app.

  1. Form: chọn Privacy hoặc Terms, tên app, slug (auto-gen từ project), contact email, textarea practices mô tả app collect gì.
  2. Bấm Tạo — Claude gen HTML (60-180s), preview iframe.
  3. Bấm Lưu file — ghi local exo-pages/public/<slug>/<privacy|terms>.html.
  4. Bấm Deploy lên Firebase — chạy firebase deploy --only hosting push lên exo-pages.web.app. Mất ~20s.
  5. Bấm Đặt URL vào App Store Connect (iOS) — PATCH privacyPolicyUrl của appInfoLocalization.

URL kết quả: https://exo-pages.web.app/<slug>/privacy.

8. Tab Checklist — AdMob / SDK / Remote Config

8.1. Sheet cấu hình AdMob

Mỗi project iOS/Android có 1 Google Sheet config AdMob (1 dòng App ID + N dòng ad units + optional Facebook/TikTok IDs):

8.2. AdMob auto-create

Nếu cấu hình OAuth (config.json key admob_oauth_json): panel có nút 🤖 Tạo AdMob app + ad units chạy qua AdMob API v1beta — POST /apps + 21x POST /adUnits trong ~15s. Trả về IDs để fill Sheet generator.

⚠️ AdMob API không có DELETE — tạo nhầm chỉ archive được trên web. Cẩn thận!

8.3. Install Ads via Claude

Sau khi có sheet + AdMob IDs: panel hiện Install Ads panel (chỉ khi sheet có units):

Claude sẽ: consult skill install-exo-ads → curl sheet CSV → install SDK + gen Swift code (AdsBootstrap, AdManager, PaidImpressionLogger, per-placement loaders) → set Info.plist GADApplicationIdentifier + SKAdNetwork + ATT description → verify sim → re-gen Privacy Policy LOCAL → audit ios-review-policy skill → report 5-section.

PO theo dõi qua chat Lệnh & Build. Privacy Policy CHỈ ghi file local — PO mở tab Policy bấm Deploy tay.

8.4. SDK checks

Section liệt kê SDK Claude detect trong dependency manifest:

State todo = "không cài" — có thể intentional (app không cần SDK đó), không phải lỗi.

8.5. AdMob App ID + Ad units check

Đối chiếu code với sheet:

8.6. Remote Config check + tạo param qua CLI

Mỗi ad-unit row có sub-line nhỏ phía dưới ID (chỉ row RC-gated theo EXO_PLACEMENTS):

RC: code ✓ · Firebase ✓ true

Decode:

Tạo qua CLI: panel chạy firebase remoteconfig:get → inject params thiếu với default true → firebase deploy --only remoteconfig. Không cần SA, dùng firebase login sẵn có.

8.7. Event-logging checks

Section "Ad impression — log gửi về đâu" + "Purchase — log gửi về đâu" — pattern match code có gọi Analytics.logEvent / paidEventHandler / TikTokAdRevenueEvent / ADJAdRevenue / v.v.:

9. Tab Request — request + rejection + đính kèm file đổi 2026-06-25

Tab cũ tên "Log issue" → đổi tên Request và chuyển sang trái tab "Lệnh & Build". Workflow PO log request → Claude propose plan → PO duyệt → Claude implement → bấm build & up TestFlight.

9.1. Form tạo request gọn vào modal mới

9.2. Auto-detect loại request từ text mới

Backend chạy 10 regex pattern khi PO submit:

Auto-extract: guideline (vd "5.2.1"), version (vd "1.1 (11)"), store (apple/google). PO vẫn có thể paste freetext — server không bắt buộc structure.

9.3. Claude 2-Phase: LUÔN propose + hỏi PO trước action mới

Khi PO tạo request mới, Claude bắt buộc chạy 2 phase:

Phase 1 — DIAGNOSE & PROPOSE (turn này, KHÔNG edit code):

Phase 2 — IMPLEMENT (turn sau, khi PO reply):

Ngoại lệ duy nhất skip Phase 1: typo cực kỳ tầm thường (vd "sửa setttings → settings") và Claude 100% chắc chắn không có cách hiểu khác.

9.4. Rejection vẫn dùng diagnose mode A/B/C

Rejection có flow riêng (đã có từ trước, không đổi):

9.5. Issue card đơn giản (3 nút)

3 nút "Gửi Claude xử lý" / "Build & Up" / "Trả lời" của bản cũ đã bỏ — auto-spawn Claude khi tạo request + reply qua chat thread.

9.6. Multi-turn session Claude

Mỗi request có 1 sessionId UUID — Claude lưu context full conversation ở ~/.claude/projects/:

9.7. Claude tự action ASC qua API

Cho project iOS: prompt có ASC API capabilities block liệt kê endpoint Claude tự gọi:

Claude propose action + curl command → PO duyệt "ok" trong chat → Claude execute. KHÔNG dump TODO "@store/@asc-web" cho PO làm tay.

Web-only thật chỉ còn: App Privacy questionnaire, Age Rating, Pricing — Claude dùng Playwright MCP click ASC web.

10. Workflow: thêm project mới từ GitLab mới 2026-06-25

PO có project trên GitLab exostudio24 nhưng chưa clone về máy local (vd: bạn dev khác đã tạo, hoặc PO muốn pull code về máy mới). Workflow này cho phép clone qua UI, không cần mở terminal.

Bước 1 — Mở modal Add Project:
Bước 2 — Chọn repo:
Bước 3 — Đợi clone xong:
Bước 4 — Setup local nếu cần:
Caveat về security:

11. Workflow: tạo app mới từ đầu đến v1.0 live

Áp dụng khi PO bắt đầu 1 app iOS hoàn toàn mới — chưa có record trên ASC, chưa có code, chưa có icon. Mục tiêu: từ tay trắng đến v1.0 ready trên App Store.

Bước 1 — Bundle ID + App Store Connect record (làm tay 1 lần):
Bước 2 — Tạo project iOS (local, qua Xcode hoặc XcodeGen):
Bước 3 — Setup Firebase + Privacy Policy:
Bước 4 — Code MVP qua tab Request:
Bước 5 — Set Privacy URL trên ASC:
Bước 6 — Metadata + Screenshots:
Bước 7 — Up TestFlight:
Bước 8 — Submit App Store qua ASC API:
Bước 9 — Đợi Apple review:
Bước 10 — Release:

v1.0 đã live → tiếp tục workflow 14 để làm v1.1 gắn Ads.

12. Workflow: tạo version mới đến submit

Bước 1. v1.0 live trên store. Mở project trong panel → Status tab → panel "💡 Bắt đầu version mới?" tự hiện.
Bước 2. Bấm 🆕 Tạo v1.1… → modal → confirm. Panel bump project.yml + tạo ASC version 1.1 + seed metadata.
Bước 3. Code thay đổi: mở Xcode sửa, hoặc tạo request "Add feature X" trong tab Request → Claude sửa code + verify sim.
Bước 4. Tab Lệnh & Build → ⬆ Up TestFlight. Đợi 5-15 phút Apple process build.
Bước 5. Tab Store listing → header xanh "Đang chỉnh v1.1". Viết whatsNew (release notes). Upload screenshot mới nếu UI đổi.
Bước 6. Tab Status → stage "Nộp & review" → Nộp review qua ASC API → modal chọn release type → spawn Claude submit.
Bước 7. Theo dõi Claude turn ở chat. Reply "ok" khi Claude propose actions. Khi submit xong → toast success + Status tab refresh.
Bước 8. Apple review 24-48h. State chuyển WAITING_FOR_REVIEW → IN_REVIEW → READY_FOR_SALE (nếu MANUAL: PENDING_DEVELOPER_RELEASE đợi PO Release).

13. Workflow: phản hồi rejection từ Apple

Bước 1. Apple gửi email reject. PO copy reviewer note.
Bước 2. Tab Request → bấm ➕ Tạo request mới → modal → paste nguyên email từ Apple/Google vào textarea (chứa "Guideline X.Y.Z" hoặc tương đương). Server auto-detect rejection + extract guideline + version + store. Có thể đính kèm screenshot reviewer gửi qua drop zone.
Bước 3. Bấm Tạo request → modal đóng → Claude auto-spawn ngay, switch tab Lệnh & Build, bắt đầu Phase 1 diagnose.
Bước 4. Claude turn 1: diagnose mode (Read/Grep, KHÔNG Edit). Output structured: Root cause + Phương án A/B/C + Checklist + Recommendation + Estimate. ~3-5 phút.
Bước 5. Panel parse output → hiện Resubmit Checklist + button Chọn Phương án X trên card.
Bước 6. PO bấm Phương án (vd "A — De-brand"). Followup textarea pre-fill template. Bấm Gửi tiếp Claude.
Bước 7. Claude turn 2: Apply code/metadata changes qua ASC API (Claude tự curl các endpoint, propose + duyệt + execute). Verify sim. Báo cáo file modified.
Bước 8. PO review code (mở Xcode) → bấm Build & Up trên card → up TestFlight build mới → submit lại.

14. Workflow: v1.1 — gắn Ads cho app v1.0 đã live

Áp dụng khi app v1.0 (no-ads) đã live ổn định ≥ 1 tuần và muốn bật monetization. Workflow này chạy song song với workflow 12 (tạo version mới).

Bước 1 — Bump version: v1.0 đã live. Status tab → panel "💡 Bắt đầu version mới?" → bấm 🆕 Tạo v1.1… → confirm. Panel bump MARKETING_VERSION 1.0 → 1.1 + tạo ASC version 1.1.
Bước 2 — Tạo AdMob app + ad units:
Bước 3 — Remote Config (optional nhưng recommend):
Bước 4 — Install Ads via Claude:
Bước 5 — Privacy Policy update (bắt buộc khi thêm ads):
Bước 6 — App Privacy questionnaire trên ASC:
Bước 7 — Up TestFlight + test on device:
Bước 8 — Submit App Store:
Bước 9 — Monitor revenue (sau release):

15. Tips & Gotchas

16. Khắc phục sự cố

16.1. "Lỗi tải metadata" / "App chưa có trên ASC"

16.2. "Phiên bản đang ở trạng thái READY_FOR_SALE — có thể không sửa được"

16.3. "Build chưa processed" trong preflight

16.4. Claude không respond

16.5. "Server đã restart, log job đã mất"

16.6. "Lỗi gọi /api/projects/.../listing"

16.7. Token bị mất / lộ