ทำงานกับ 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 ตรง ๆ แบบนี้ทั่วทั้งโปรเจกต์
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.
2Status ทั้ง 13 ตัวAll 13 statuses
| # | Status | หมายถึง | เจ้าของ |
|---|---|---|---|
| 1 | Open | งานที่ได้รับมา ยังไม่ได้วางแผน | PM |
| 2 | pending | วางแผนแล้ว รอ dev หยิบไปทำ | PM |
| 3 | in progress | กำลังทำอยู่ | Dev |
| 4 | waitdeploy-dev | dev เสร็จแล้วแต่ยังไม่ได้ deploy ขึ้น dev | Dev |
| 5 | completed | dev เสร็จและอยู่บน dev แล้ว รอ QA หยิบไป test | Dev |
| 6 | in review | tester กำลัง test | QA |
| 7 | accepted | test ผ่าน | QA |
| 8 | rejected | test ไม่ผ่าน — กลับไปหา dev | QA |
| 9 | blocked | hold ไว้ก่อน เพราะติดรออย่างอื่น | PM Dev |
| 10 | staging | อยู่บน UAT แล้ว กำลัง verify | QA |
| 11 | waitdeployed | UAT ผ่านแล้วแต่ยังไม่ได้ deploy prod | PM |
| 12 | deployed | ขึ้น production เรียบร้อย | PM |
| 13 | Closed | อยู่บน production แล้วไม่มีปัญหา — ปิดงาน | PM |
| # | Status | Means | Owner |
|---|---|---|---|
| 1 | Open | Work received, not planned yet | PM |
| 2 | pending | Planned, waiting for a dev to pick it up | PM |
| 3 | in progress | Being worked on | Dev |
| 4 | waitdeploy-dev | Dev work finished but not deployed to dev yet | Dev |
| 5 | completed | Done and live on dev — waiting for QA to pick it up | Dev |
| 6 | in review | Tester is testing it | QA |
| 7 | accepted | Test passed | QA |
| 8 | rejected | Test failed — back to the developer | QA |
| 9 | blocked | On hold, waiting on something else | PM Dev |
| 10 | staging | On UAT, being verified | QA |
| 11 | waitdeployed | UAT passed but not deployed to prod yet | PM |
| 12 | deployed | Live on production | PM |
| 13 | Closed | Live on production with no issues — work closed | PM |
waitdeployed — บนบอร์ดวางแผนเรียกว่า “Waitdeploy-Prod”
แต่ค่าใน ClickUp คือ waitdeployed ตอนค้นหาหรือ filter ให้ใช้ชื่อนี้
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
ทางแยกที่เจอบ่อย
- 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 progressand 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
acceptedstraight toclosed— PM's call
4ใครเปลี่ยน statusWho moves the status
Status คือ “ความจริงร่วม” ของทีม — คนที่เปลี่ยนต้องเป็นคนที่รู้จริงว่างานอยู่ขั้นไหน
- Dev ขยับได้ในช่วงของตัวเอง:
in progress→waitdeploy-dev→completed(และรับงานที่rejectedกลับมา) - QA เป็นเจ้าของ
in review/accepted/rejected/staging - PM เป็นเจ้าของช่วงต้น (
open/pending) และช่วงปล่อยของ (waitdeployed/deployed/closed)
.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 progress→waitdeploy-dev→completed(and picks work back up fromrejected) - QA owns
in review/accepted/rejected/staging - PM owns the front (
open/pending) and the release end (waitdeployed/deployed/closed)
.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 progress | branch feat/<name> (แตกจาก develop) | เครื่อง dev เอง |
waitdeploy-dev | PR เปิดแล้ว / รอ merge เข้า develop | ยังไม่ขึ้น env ไหน |
completed | merge เข้า develop แล้ว | dev (deploy อัตโนมัติ) |
in review / accepted | อยู่บน develop | dev — QA test ที่นี่ |
staging | merge develop → main | uat (deploy อัตโนมัติ) |
waitdeployed | อยู่บน main ยังไม่ตัด tag | uat — รอปล่อย prod |
deployed | tag v<x.y.z> บน main | prod (deploy อัตโนมัติ) |
| Status | Where the code is | Environment |
|---|---|---|
in progress | branch feat/<name> (off develop) | The developer's machine |
waitdeploy-dev | PR open / waiting to merge into develop | Not on any environment yet |
completed | Merged into develop | dev (auto deploy) |
in review / accepted | On develop | dev — QA tests here |
staging | develop merged into main | uat (auto deploy) |
waitdeployed | On main, no tag cut yet | uat — waiting for the prod release |
deployed | Tag v<x.y.z> on main | prod (auto deploy) |
main = deploy uat ทันที และ tag v* = deploy prod ทันที (ดู .claude/rules/17-git-branch-workflow.md) — ทั้งสองอย่างต้องขอ confirm จากผู้ใช้ก่อนทุกครั้ง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)
เวลาหยิบงาน
- อ่าน task ใน ClickUp ให้ครบ รวมตาราง scenario และ custom field
- หาเอกสารที่คู่กันใน
zyra-doc/plan/<Feature>/— spec, technical design, test plan, figma-nodes - แตก branch
feat/<name>จากdevelopแล้วทำตาม spec เท่านั้น - อัปเดตความคืบหน้าเป็น 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.
| Prefix | Means |
|---|---|
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
- Read the whole ClickUp task, including the scenario table and custom fields.
- Find its companion docs in
zyra-doc/plan/<Feature>/— spec, technical design, test plan, figma-nodes. - Branch
feat/<name>offdevelopand build exactly what the spec says. - 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-500instead oftext-[#8C99A6] - Eyeball spacing
- Skip
get_design_contextbecause "it looks guessable"
9ถามก่อนลงมือAsk before you build
ได้ Figma URL / node ใหม่มาแต่ยังไม่ชัดว่ามันอยู่ตรงไหนของ flow — ต้องถามก่อน ห้ามตีความเองแล้วสร้าง flow ใหม่ (.claude/rules/14-no-overreach.md) คำถามที่ต้องได้คำตอบ:
- node นี้อยู่ใน flow ไหน — หน้าไหน / modal ไหน / step ไหน
- ต่อจากอะไร — มาแทน component เดิม หรือเป็นของใหม่
- ใช้แทน หรือ เพิ่มเติม (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:
- Which flow does this node belong to — which page, which modal, which step?
- What comes before it — does it replace an existing component or is it new?
- 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.