หน้าหลัก All guides
ZYRA ClickUp & Figma ClickUp & Figma
Process · ClickUp + Figma Process · ClickUp + Figma

ทำงานกับ ClickUp และ Figma

งานทุกชิ้นของ Zyra เริ่มจาก task ใน ClickUp และ design ใน Figma หน้านี้บอกว่า status แต่ละตัวหมายถึงอะไร ใครมีสิทธิ์ขยับ มันแมปกับ branch/environment ของเราอย่างไร และต้องดึง spec จาก Figma ยังไงให้ UI ออกมาตรงแบบ

Working with ClickUp & Figma

Every piece of Zyra work starts as a ClickUp task and a Figma design. This page covers what each status means, who is allowed to move it, how it lines up with our branches and environments, and how to pull a spec out of Figma so the UI matches the design.

1โครงสร้าง boardBoard structure

Workspace  36898257
└─ Space   PM - Mos            90166731836
   └─ Folder  Zyra World       90169187867  ← status set ผูกที่ระดับ folder นี้
      └─ List                  901614367195  ← task ของ Zyra อยู่ที่นี่

Task ใช้ URL แบบ https://app.clickup.com/t/<task-id> เช่น 86d2wefft = [Module] Virtual Office — เอกสารใน zyra-doc/plan/ อ้าง task id ตรง ๆ แบบนี้ทั่วทั้งโปรเจกต์

status set ถูกกำหนดที่ folder “Zyra World” ไม่ใช่ที่ list — เพราะฉะนั้น list ใหม่ที่สร้างใน folder นี้จะได้ status ชุดเดียวกันอัตโนมัติ
Workspace  36898257
└─ Space   PM - Mos            90166731836
   └─ Folder  Zyra World       90169187867  ← the status set is defined here
      └─ List                  901614367195  ← Zyra tasks live here

Tasks use https://app.clickup.com/t/<task-id> — e.g. 86d2wefft is [Module] Virtual Office. Docs under zyra-doc/plan/ reference task ids exactly like that throughout.

The status set belongs to the “Zyra World” folder, not the list — so any new list created inside that folder inherits the same statuses automatically.

2Status ทั้ง 13 ตัวAll 13 statuses

#Statusหมายถึงเจ้าของ
1Openงานที่ได้รับมา ยังไม่ได้วางแผนPM
2pendingวางแผนแล้ว รอ dev หยิบไปทำPM
3in progressกำลังทำอยู่Dev
4waitdeploy-devdev เสร็จแล้วแต่ยังไม่ได้ deploy ขึ้น devDev
5completeddev เสร็จและอยู่บน dev แล้ว รอ QA หยิบไป testDev
6in reviewtester กำลัง testQA
7acceptedtest ผ่านQA
8rejectedtest ไม่ผ่าน — กลับไปหา devQA
9blockedhold ไว้ก่อน เพราะติดรออย่างอื่นPM Dev
10stagingอยู่บน UAT แล้ว กำลัง verifyQA
11waitdeployedUAT ผ่านแล้วแต่ยังไม่ได้ deploy prodPM
12deployedขึ้น production เรียบร้อยPM
13Closedอยู่บน production แล้วไม่มีปัญหา — ปิดงานPM
#StatusMeansOwner
1OpenWork received, not planned yetPM
2pendingPlanned, waiting for a dev to pick it upPM
3in progressBeing worked onDev
4waitdeploy-devDev work finished but not deployed to dev yetDev
5completedDone and live on dev — waiting for QA to pick it upDev
6in reviewTester is testing itQA
7acceptedTest passedQA
8rejectedTest failed — back to the developerQA
9blockedOn hold, waiting on something elsePM Dev
10stagingOn UAT, being verifiedQA
11waitdeployedUAT passed but not deployed to prod yetPM
12deployedLive on productionPM
13ClosedLive on production with no issues — work closedPM
!
ชื่อ status ที่ใช้จริงคือ waitdeployed — บนบอร์ดวางแผนเรียกว่า “Waitdeploy-Prod” แต่ค่าใน ClickUp คือ waitdeployed ตอนค้นหาหรือ filter ให้ใช้ชื่อนี้
!
The real status name is waitdeployed — the planning board calls it "Waitdeploy-Prod", but the value stored in ClickUp is waitdeployed. Use that when searching or filtering.

3ลำดับการทำงานThe flow

open pending in progress waitdeploy-dev completed in review accepted staging waitdeployed deployed closed

ทางแยกที่เจอบ่อย

  • rejected — test ไม่ผ่าน งานเด้งกลับไป in progress แล้วเดินวนใหม่ตั้งแต่ dev
  • blocked — แขวนไว้ได้จากทุก status ถ้าติดรอของอื่น (design, decision, service อื่น) พอปลดล็อกก็กลับไป status เดิม
  • งานที่ไม่แตะ production (เช่น doc, spike) อาจปิดจาก accepted ไป closed ตรง ๆ — ให้ PM เป็นคนตัดสิน

Common branches off the happy path

  • rejected — the test failed; it bounces back to in progress and runs the loop again from dev
  • blocked — can be set from any status when something else is in the way (a design, a decision, another service); when unblocked it returns to where it was
  • Work that never reaches production (docs, spikes) may go from accepted straight to closed — PM's call

4ใครเปลี่ยน statusWho moves the status

Status คือ “ความจริงร่วม” ของทีม — คนที่เปลี่ยนต้องเป็นคนที่รู้จริงว่างานอยู่ขั้นไหน

  • Dev ขยับได้ในช่วงของตัวเอง: in progresswaitdeploy-devcompleted (และรับงานที่ rejected กลับมา)
  • QA เป็นเจ้าของ in review / accepted / rejected / staging
  • PM เป็นเจ้าของช่วงต้น (open / pending) และช่วงปล่อยของ (waitdeployed / deployed / closed)
!
AI (Claude) ห้ามเปลี่ยน status ทุกกรณี — ตาม .claude/rules/13-clickup-status.md AI ใช้ ClickUp ได้แบบอ่านอย่างเดียว (get / list / filter / search) เพิ่ม comment ได้ แต่ห้ามเรียก update เพื่อแก้ status แม้จะสั่งตรง ๆ ว่า “mark as done” หรืองาน deploy เสร็จแล้วก็ตาม เพราะ status เป็นสิทธิ์ของ PM/QA เท่านั้น

Status is the team's shared source of truth — whoever moves it must actually know where the work stands.

  • Dev owns their stretch: in progresswaitdeploy-devcompleted (and picks work back up from rejected)
  • QA owns in review / accepted / rejected / staging
  • PM owns the front (open / pending) and the release end (waitdeployed / deployed / closed)
!
The AI (Claude) never changes a status — no exceptions. Per .claude/rules/13-clickup-status.md it uses ClickUp read-only (get / list / filter / search) and may add comments, but must never call update to change a status, even when told "mark as done" or when a deploy has just finished. Status belongs to PM/QA only.

5แมปกับ git และ environmentMapping to git & environments

Statusโค้ดอยู่ไหนEnvironment
in progressbranch feat/<name> (แตกจาก develop)เครื่อง dev เอง
waitdeploy-devPR เปิดแล้ว / รอ merge เข้า developยังไม่ขึ้น env ไหน
completedmerge เข้า develop แล้วdev (deploy อัตโนมัติ)
in review / acceptedอยู่บน developdev — QA test ที่นี่
stagingmerge developmainuat (deploy อัตโนมัติ)
waitdeployedอยู่บน main ยังไม่ตัด taguat — รอปล่อย prod
deployedtag v<x.y.z> บน mainprod (deploy อัตโนมัติ)
StatusWhere the code isEnvironment
in progressbranch feat/<name> (off develop)The developer's machine
waitdeploy-devPR open / waiting to merge into developNot on any environment yet
completedMerged into developdev (auto deploy)
in review / acceptedOn developdev — QA tests here
stagingdevelop merged into mainuat (auto deploy)
waitdeployedOn main, no tag cut yetuat — waiting for the prod release
deployedTag v<x.y.z> on mainprod (auto deploy)
push เข้า main = deploy uat ทันที และ tag v* = deploy prod ทันที (ดู .claude/rules/17-git-branch-workflow.md) — ทั้งสองอย่างต้องขอ confirm จากผู้ใช้ก่อนทุกครั้ง
Pushing to main deploys uat instantly and a v* tag deploys prod instantly (see .claude/rules/17-git-branch-workflow.md) — both need explicit confirmation from the user first.

6รูปแบบ task และ SC idTask shape & SC ids

Task ระดับโมดูลตั้งชื่อว่า [Module] <ชื่อ> ข้างในมีตาราง scenario ที่ทุก scenario มี id ของตัวเอง — id ชุดนี้ถูกอ้างต่อทั้งใน spec, test plan และชื่อ commit

Prefixหมายถึง
SC-VO-*Scenario ของ Virtual Office
SC-SB-*Scenario ของ Space Builder
SC-PROFILE-*Scenario ของ Profile / Settings
SC-UG-*Scenario ของ User Guide / Help Center
TC-*Test case ที่คู่กับ scenario นั้น

แต่ละ scenario ระบุ type ไว้: Happy Path (flow ปกติ), Alternate Path (แยกออกไปแต่ยังสำเร็จ), Error Path (error หรือถูก block)

เวลาหยิบงาน

  1. อ่าน task ใน ClickUp ให้ครบ รวมตาราง scenario และ custom field
  2. หาเอกสารที่คู่กันใน zyra-doc/plan/<Feature>/ — spec, technical design, test plan, figma-nodes
  3. แตก branch feat/<name> จาก develop แล้วทำตาม spec เท่านั้น
  4. อัปเดตความคืบหน้าเป็น comment ใน task ได้ตลอด — แต่ status ให้ PM/QA ขยับ

Module-level tasks are named [Module] <name> and contain a scenario table where every scenario has its own id. Those ids are referenced again in specs, test plans and commits.

PrefixMeans
SC-VO-*Virtual Office scenarios
SC-SB-*Space Builder scenarios
SC-PROFILE-*Profile / Settings scenarios
SC-UG-*User Guide / Help Center scenarios
TC-*The test cases paired with a scenario

Each scenario declares a type: Happy Path (the normal flow), Alternate Path (diverges but still succeeds), Error Path (errors or gets blocked).

When you pick up a task

  1. Read the whole ClickUp task, including the scenario table and custom fields.
  2. Find its companion docs in zyra-doc/plan/<Feature>/ — spec, technical design, test plan, figma-nodes.
  3. Branch feat/<name> off develop and build exactly what the spec says.
  4. Post progress as comments on the task any time — but leave the status to PM/QA.

7Figma — ไฟล์และ nodeFigma — file & nodes

ไฟล์เดียวของโปรเจกต์: Zyra design (More Organised ver.)
file key: Map8gX0L2hk7HnkaFRfhtj

ทุกหน้าจอถูกอ้างด้วย node id ที่อยู่ท้าย URL:

https://www.figma.com/design/Map8gX0L2hk7HnkaFRfhtj/Zyra-design...?node-id=1805-285771
                                                                          ^^^^^^^^^^^^^^
                                                       node id — ใน MCP ใช้เป็น 1805:285771

node id ของแต่ละฟีเจอร์ถูกจดไว้ในเอกสาร เช่น zyra-doc/plan/UserGuide/figma-nodes.md ที่แมป SC-UG-01 → 2286:623285 ไปจนถึงระดับ modal ทีละหน้า — ก่อนทำงานให้เช็กว่าฟีเจอร์นั้นมีไฟล์ figma-nodes อยู่แล้วหรือยัง

One file for the whole project: Zyra design (More Organised ver.)
file key: Map8gX0L2hk7HnkaFRfhtj

Every screen is addressed by the node id at the end of the URL:

https://www.figma.com/design/Map8gX0L2hk7HnkaFRfhtj/Zyra-design...?node-id=1805-285771
                                                                          ^^^^^^^^^^^^^^
                                                        node id — written 1805:285771 in MCP

Per-feature node ids are recorded in docs such as zyra-doc/plan/UserGuide/figma-nodes.md, which maps SC-UG-01 → 2286:623285 down to individual modals. Check whether your feature already has a figma-nodes file before you start.

8Figma fidelity 95–100%Figma fidelity 95–100%

ก่อนเขียนหรือแก้ UI ทุกครั้ง ต้องดึง spec จาก Figma MCP ก่อน — ห้ามเดา (.claude/rules/10-figma-fidelity.md)

1. get_design_context(nodeId)   → layout, spacing, สี, typography, padding, gap
2. get_screenshot(nodeId)       → ภาพอ้างอิงยืนยันภาพรวม
3. get_variable_defs()          → design token
4. get_metadata(nodeId)         → child tree เพื่อแตก component

ถ้า node เป็น instance ให้ขยาย main component ด้วย · spec ที่ต้องได้ครบ: layout (direction, gap, padding, align), size, สี (hex + alpha), typography (size, weight, line-height, letter-spacing), border-radius ทีละมุมถ้าไม่เท่ากัน, effect (shadow, opacity) และ state (hover / active / disabled)

แปลง Figma → Tailwind

px      → arbitrary value:  p-[16px]  gap-[13px]  w-[368px]
hex     → exact:            bg-[#242B32]  text-[#58D68D]
opacity → rgba:             bg-[rgba(255,255,255,0.05)]
border  → border border-[rgba(255,255,255,0.2)]
font    → text-[14px] leading-[18px] font-bold
radius  → rounded-[8px]  rounded-[16px]

ทำ

  • ใช้ค่า exact จาก Figma ทุกตัว
  • ดึง screenshot มาเทียบก่อนบอกว่าเสร็จ
  • ทำ state ให้ครบตามที่ออกแบบไว้

ห้าม

  • ใช้ Tailwind default (p-4, text-sm) แทนค่าจริง
  • ใช้ text-gray-500 แทน text-[#8C99A6]
  • เดา spacing จากสายตา
  • ข้าม get_design_context เพราะ “น่าจะเดาได้”

Before writing or changing any UI you must pull the spec from the Figma MCP — never guess (.claude/rules/10-figma-fidelity.md).

1. get_design_context(nodeId)   → layout, spacing, colours, typography, padding, gap
2. get_screenshot(nodeId)       → a visual reference to confirm the whole
3. get_variable_defs()          → design tokens
4. get_metadata(nodeId)         → the child tree, for breaking out components

If the node is an instance, expand the main component too. You need the full spec: layout (direction, gap, padding, align), size, colours (hex + alpha), typography (size, weight, line-height, letter-spacing), per-corner border-radius when they differ, effects (shadow, opacity), and states (hover / active / disabled).

Figma → Tailwind

px      → arbitrary value:  p-[16px]  gap-[13px]  w-[368px]
hex     → exact:            bg-[#242B32]  text-[#58D68D]
opacity → rgba:             bg-[rgba(255,255,255,0.05)]
border  → border border-[rgba(255,255,255,0.2)]
font    → text-[14px] leading-[18px] font-bold
radius  → rounded-[8px]  rounded-[16px]

Do

  • Use the exact values from Figma, every time
  • Pull a screenshot and compare before calling it done
  • Build every state the design specifies

Don't

  • Substitute Tailwind defaults (p-4, text-sm) for real values
  • Use text-gray-500 instead of text-[#8C99A6]
  • Eyeball spacing
  • Skip get_design_context because "it looks guessable"

9ถามก่อนลงมือAsk before you build

ได้ Figma URL / node ใหม่มาแต่ยังไม่ชัดว่ามันอยู่ตรงไหนของ flow — ต้องถามก่อน ห้ามตีความเองแล้วสร้าง flow ใหม่ (.claude/rules/14-no-overreach.md) คำถามที่ต้องได้คำตอบ:

  1. node นี้อยู่ใน flow ไหน — หน้าไหน / modal ไหน / step ไหน
  2. ต่อจากอะไร — มาแทน component เดิม หรือเป็นของใหม่
  3. ใช้แทน หรือ เพิ่มเติม (replace หรือ add)
// ผิด
ดู node แล้วเดาว่าเป็น step ใหม่ → สร้างเลย

// ถูก
"node 1554-286010 นี้ใช้แทน modal เดิมของ BuildWorkspace step 1 หรือเปล่า?"
→ รอคำตอบ → implement ตาม spec เท่านั้น ไม่เพิ่ม field / step เอง

คำสั่งที่ spec ครบและชัดแล้ว ให้ทำตรง ๆ ไม่ต้องถาม — และไม่ต้องเติมของที่ไม่ได้สั่ง

Got a new Figma URL or node but it isn't clear where it sits in the flow? Ask first — never interpret it into a flow of your own invention (.claude/rules/14-no-overreach.md). The questions you need answered:

  1. Which flow does this node belong to — which page, which modal, which step?
  2. What comes before it — does it replace an existing component or is it new?
  3. Replace, or add?
// wrong
look at a node, assume it's a new step, build it

// right
"Does node 1554-286010 replace the existing BuildWorkspace step 1 modal?"
→ wait for the answer → build exactly the spec, adding no fields or steps

When the request is already complete and unambiguous, just build it — and don't add anything that wasn't asked for.