ต่อยอดจาก spec v0.1 + mockup Workstation — ฉบับนี้สังเคราะห์จากการออกแบบ 6 มุมที่ไล่โค้ดจริงใน repo homeoffice ทุกจุด (migrations 32 ไฟล์ · operator-worker · workers · web) ของที่อ้างถึงตรวจแล้วว่ามีอยู่จริง จุดที่ของจริงขัดกับ mockup ชี้ไว้หมดแล้ว · ชื่อเคาะแล้ว: ConsultDesk (12 มิ.ย. — ตัวเลือกที่ตกรอบ: HQ/Desk, OpsDesk, Moster Desk, AgencyOS)
v0.2 = ConsultDesk ต้องยืนเองได้ไม่ต้องมี OS (ลูกค้า 2 โหมด: CONNECTED ดึงสด / MANUAL เราเปิดงานเอง · งานเข้า 3 ทาง: 🔗 auto · 🔁 ประจำตามสัญญา · ✍️ เปิดเอง · เมนู 8 ตัว) — ดูภาพรวม+จอใน Workstation · ฉบับนี้คือชั้นถัดไป: ทำให้ทุกอย่างข้างบนสร้างได้จริงโดยไม่ต้องเดา
5 ตารางใน mockup กางออกเป็นของจริง 14 ตาราง + ALTER 1 — พร้อมกฎ "จุดที่ตั้งใจไม่เก็บ" กันแหกกฎเหล็กระดับ DB
แคตตาล็อกงานสำนักงานบัญชีไทย 11 ชนิด · กติกาผลิตงาน idempotent · สูตร merge ปฏิทิน 3 แหล่ง · เงาใบงาน auto แบบ lazy
กลับด้านจาก v0.1: standalone มาก่อน connected · kill points 9 ข้อ · คำถามที่ต้องเคาะก่อนเริ่ม แยก "บล็อกเฟส 1" ชัด
HomeOffice = ซอฟต์แวร์ราคาเบา ใครก็ใช้เองได้ · บริการสำนักงาน = ชั้นเสริมที่เลือกจ้างได้ทีละเรื่อง — สองอย่างแยกขาดจากกัน ไม่บังคับพ่วง และไม่ล็อกว่าต้องใช้สำนักงานเรา (ลูกค้าเชิญสำนักบัญชีเจ้าไหนก็ได้ผ่านกลไกเชิญสมาชิกปกติ) · ค่า HomeOffice ลูกค้าจ่ายตรงกับแพลตฟอร์ม ไม่รวมในบิลบริการ (บิลสองโลกแยกกันอยู่แล้วใน schema: subscription ฝั่งแพลตฟอร์ม vs สัญญาบริการฝั่ง Desk)
| ขั้น | ลูกค้า | ระบบรองรับด้วย |
|---|---|---|
| 1 | ใช้ HomeOffice เองล้วน ไม่จ้างใคร | HomeOffice สมบูรณ์ในตัว (เลขา AI + เครื่องคำนวณภาษี/เงินเดือน) — ดีไซน์เดิมคือ "ระบบเตรียมให้ ผู้ใช้ยื่นเอง" |
| 2 | ใช้ระบบ + จ้างเราบางเรื่อง (แค่ภาษี / แค่เอกสาร HR) | สัญญาบริการเลือกขอบเขตเป็นรายการ — จ้างแค่ไหน งานเข้าโต๊ะแค่นั้น |
| 3 | ใช้ระบบ + จ้างเราเต็ม (เราเป็น สนง.บช.+HR ของเขา) | โหมด "เชื่อมระบบ" เต็มรูป |
| 4 | จ้างก่อน → เราวางระบบส่ง HomeOffice ให้ | งานวางระบบ (ด้านล่าง) — ส่งมอบเป็นระบบที่รันจริง |
| 5 | ใช้ระบบ + จ้างสำนักบัญชีอื่น | เขาเชิญสำนักบัญชีของเขาเป็น "บัญชีภายนอก" ได้ปกติ — ไม่มีอะไร hard-lock กับสำนักงานเรา |
จุดแข็งเชิงโครงสร้าง: เปลี่ยนผู้ให้บริการง่าย (สิทธิ์เชิญ-ถอนได้) แต่ย้ายออกจากระบบยาก — switching cost อยู่ฝั่งที่เป็นประโยชน์กับเรา
| รูปแบบ | ตัวอย่าง | ระบบทำยังไง |
|---|---|---|
| เหมาโปรเจกต์ (จบเป็นครั้ง) | วางระบบ HR ฿35,000 | สัญญาแบบครั้งเดียว + ชุดงานเรียงขั้น (ด้านล่าง) |
| เหมารายเดือน (retainer) | สนง.บช. ฿8,500/เดือน | สัญญารายเดือน → งานประจำเปิดเองทุกงวด (ส่วนที่ 5) |
| ตามเวลา — รายชั่วโมง/รายวัน | เข้าปรึกษา ฿1,500/ชม. · ประจำหน้างาน ฿8,000/วัน | สัญญาระบุเรท+หน่วย · ทุกครั้งที่เข้าปรึกษา = งาน 1 ใบ ปิดงานแล้วใส่จำนวนหน่วย (ช่องเดียว — ไม่มี timer ไม่มี timesheet) · สิ้นเดือนรายงานรวม "7 ชม. × ฿1,500 = ฿10,500" เป็นใบแนบเรียกเก็บ + หลักฐานว่าเข้าทำอะไรวันไหน · ไม่ขายแพ็กชั่วโมงล่วงหน้า (เคาะแล้ว) |
| ตามชิ้นงาน | ชุดเอกสาร ฿2,500/งาน | สัญญาผูกชิ้นงาน/เอกสารที่ออก — นับจากของจริง |
ลูกค้าหนึ่งรายผสมได้หลายแบบพร้อมกัน (เช่น retainer เงินเดือน + ปรึกษารายชั่วโมงเป็นครั้งๆ = สองสัญญาใต้ลูกค้าเดียว — schema รองรับอยู่แล้ว)
หลักคิดเดียวกับคลังแม่แบบเอกสาร: แม่แบบเอกสารมีหัวข้อ optional ติ๊กเลือก → แม่แบบชุดงานก็มีขั้น optional ติ๊กเลือก — เปิดสัญญาจากแม่แบบ "วางระบบ HR" → ติ๊กขั้นที่รายนี้ใช้ → ระบบเปิดงานทั้งชุดเรียงตามสัปดาห์ · progress โปรเจกต์ = นับงานเสร็จ/ทั้งหมดใต้สัญญา (ไม่ต้องมีตารางโปรเจกต์ใหม่) · "แต่ละรายต่างกันเล็กน้อย" = ติ๊กขั้น + แก้งานรายใบหลังเปิดได้อิสระ
| ขั้น | งาน | ผูกอะไร | สัปดาห์ |
|---|---|---|---|
| 1 | เก็บข้อมูล: สัมภาษณ์เจ้าของ + ทะเบียนพนักงาน + นโยบายปัจจุบัน | ไฟล์แนบในงาน | 1 |
| 2 | ออกแบบโครงสร้าง: ผังองค์กร/ตำแหน่ง + โครงสร้างเงินเดือน + เกณฑ์ ลา/OT/สวัสดิการ | — | 1-2 |
| 3 | ชุดเอกสาร: ข้อบังคับการทำงาน + สัญญาจ้าง×N + กฎระเบียบ | คลังแม่แบบ (1 งาน : N เอกสาร — เห็น "ลงนาม 5/8" ในตัว) | 2-3 |
| 4 | วางระบบเงินเดือน: รอบจ่าย เงินเพิ่ม-หัก ปกส./ภาษี + ทำเดือนแรกคู่ขนาน | checklist ในงาน | 3-4 |
| 5 | ขึ้นทะเบียน/นำส่งราชการ: นายจ้าง สปส. + แจ้งข้อบังคับ (≥10 คน) | หน้ากฎหมายแรงงานเตือนเกณฑ์ | 4 |
| 6 | ตั้งระบบจริงบน HomeOffice: ลงทะเบียนพนักงาน เปิดเช็คอิน ตั้งเงินเดือน — เป็นขั้น default ของลูกค้าใหม่ (ตัดได้เฉพาะรายที่ไม่เอาจริงๆ) | → ลูกค้ากลายเป็น "เชื่อมระบบ" ตั้งแต่วันส่งมอบ | 4-5 |
| 7 | ส่งมอบ + ชี้แจงพนักงาน + เล่ม HR Blueprint (โครงสร้าง+กติกา+เอกสารรวมเล่มเดียว — pattern Wizard+Blueprint) | เอกสารส่งมอบ | 5 |
ก่อนออกแบบ ทีมออกแบบไล่ migrations + worker ทั้งสองตัว + web จริง — เจอของที่ mockup คิดว่ามีแต่ไม่มี และช่องโหว่ที่ต้องอุดก่อนเริ่ม:
| # | ข้อค้นพบ | ผลต่อแผน |
|---|---|---|
| 1 🔴 | requireAdmin ไม่เช็ค role เลย — operator-worker/src/middleware/admin.js ตรวจแค่ JWT ถูกต้อง แล้วเกือบทุก route ของ Console (tenants/billing/impersonate) ใช้ตัวเดียวกันหมด | ถ้าสร้างบัญชี SERVICE ก่อนแก้ = SERVICE ทะลุ Console ทั้งใบ ผิดกฎเหล็ก "Console/Desk แยกเส้น" ตั้งแต่วันแรก → แยก requireConsole / requireDesk เป็นงานแรกของเฟส 1 + test case "SERVICE ยิงทุกเส้น /admin/* ต้อง 403" |
| 2 | audit_logs ฝั่ง tenant บังคับ tenant_id NOT NULL และฝั่ง platform ยังไม่มีตาราง audit เลย | log ชั้น Desk (กฎ audit สองชั้น) ใช้ของเดิมไม่ได้ → สร้าง desk_logs ใหม่ (metadata เท่านั้น) |
| 3 | กลไก deep link มีจริงเกือบครบ: signCustomerSession() มินต์ JWT ฝั่ง tenant ได้ (ใช้กับ impersonate อยู่) + web รับ token ทาง #lt=… อยู่แล้ว — แต่ JWT สองโลกคนละ secret และ web ล้าง hash ก่อนอ่านหน้าปลายทาง | deep link = เพิ่ม endpoint แลกเซสชัน + patch web boot ~1-3 บรรทัด (อ่าน param lp ก่อนล้าง hash) — ไม่ใช่ "ใช้ของเดิมเฉยๆ" อย่างที่ v0.1 เขียน แต่ก็เล็กกว่าที่กลัว |
| 4 | ตารางต้นทางใบงาน auto มีครบ 7 จาก 8 ชนิด (expenses · approvals · monthly_closes · tax_calendar+doc_submissions · payroll_runs · wht_certs · bank_txns) — ขาด expense_claim เพราะ HomeOffice ไม่มีตารางตั้งเบิกฝั่ง tenant เลย | เฟส connected เปิดได้ 7 ชนิดทันที · ตั้งเบิก = โมดูลฝั่ง Desk เอง (เฟส 4 รอ flow พี่กี้) |
| 5 | เกณฑ์ "ยื่นภาษีแล้ว" ของจริงคือ doc_submissions (มี flow เขียนจริง) — ส่วน tax_filings มีตารางแต่ไม่มีโค้ดเขียน (อ่านอย่างเดียว) | ใบงาน tax_due ใช้ doc_submissions เป็นเกณฑ์หาย — อย่าอ้าง tax_filings |
| 6 | cron ใช้ไป 3/5 slot ของ account (workers 2 + operator-worker 1 ตัวคือ 0 2 * * * = 09:00 ไทย) | เครื่องยนต์งานประจำเกาะ slot เดิมของ operator-worker — ไม่กิน slot ใหม่ |
| 7 | operator-worker ไม่มี KV binding (มีแต่ R2) และ pattern กันซ้ำทั้ง repo เป็น DB ไม่ใช่ KV | กันเตือนซ้ำ/กันผลิตงานซ้ำใช้ unique index + insert ก่อนทำ (แข็งกว่า KV) · ถ้าต้องการ cache ใบงาน ค่อย bind KV เมื่อลูกค้าเกิน ~15 ราย |
| 8 | tax_calendar มีแค่ 4 ฟอร์ม (ภพ.30, ภงด.1/3/53) ไม่มี e-filing / สปส. / ภงด.1ก / ภงด.50/51 — และ parser เดิมเจอ rule ที่ไม่รู้จักจะ "ข้ามเงียบ" | extend แบบ additive ได้ปลอดภัย: เพิ่มคอลัมน์ efiling_due_rule + แถวใหม่ — cron ฝั่ง tenant เดิมไม่พัง |
| 9 | แฟ้มเอกสาร HR ฝั่ง tenant ไม่มีตารางจริง — mockup เขียน "เก็บเข้าแฟ้ม HR ใน HomeOffice ของเขา" เหมือนมีอยู่แล้ว · และ expenses ไม่มี flag "รอตรวจ" (bill_review = status='recorded' + category is null; ร่างที่ลูกค้ายังไม่ยืนยันอยู่ใน KV — Desk มองไม่เห็น by design) | ต้องสร้าง hr_documents ฝั่ง tenant ในเฟสเอกสาร (โคลนโครง vendor_documents) · นิยามใบงาน bill_review ยึดตามของจริง |
ทุกตารางใหม่ใช้ prefix desk_ (เคาะแล้ว — กันสับสนกับ customers/tasks ฝั่ง tenant ใน Supabase เดียวกัน) · ทุกตัวเป็น platform table: เปิด RLS แบบ deny-all (ไม่มี policy) เข้าได้เฉพาะ operator-worker service role — pattern เดียวกับ platform_users เป๊ะ · migration เดียวจบ 20260612000033_consultdesk_core.sql
โลก tenant (มีอยู่แล้ว — ไม่แตะ) identities ──< tenant_members >── tenants
▲ สิทธิ์เห็นข้อมูลจริงมาจากตรงนี้เสมอ │ (เฉพาะ connected)
──────────────────────────────────────────────┼──────────────────────────────────┼──────────
โลก Desk (ใหม่ · RLS deny-all) │ identity_id (ALTER ใหม่) │ tenant_id
platform_users(+SERVICE) ──< desk_assignments >── desk_clients ── 2 โหมด ──────┘
│ (primary/backup) ├──< desk_agreements (สัญญาบริการ)
│ │ └──< desk_agreement_services ──> desk_task_catalog ──> tax_calendar
│ ├──< desk_jobs (งาน 3 ทาง) ──< desk_job_comments · desk_job_files
│ └──< desk_documents ──< desk_document_events
│ desk_doc_templates ──< desk_template_versions ──┘
└──< desk_logs (audit ชั้น Desk) · desk_notifications (กันเตือนซ้ำ)
desk_jobs(origin='auto') = "เงา" pointer 4 ฟิลด์: source + tenant_id + kind + ref_key
→ เนื้อหา (หัวเรื่อง/จำนวน/ยอด/กำหนด) คำนวณสดทุกครั้งจาก expenses · approvals ·
monthly_closes · tax_calendar+doc_submissions · payroll_runs · wht_certs · bank_txns
| ตาราง | บทบาท | จุดออกแบบสำคัญ |
|---|---|---|
desk_clients | ทะเบียนลูกค้าสำนักงาน 2 โหมด | CHECK บังคับ: connected ต้องมีปลายทาง (tenant_id สำหรับ HomeOffice / external_ref สำหรับ SiteOS เฟส 5) · manual ต้องสะอาด · unique tenant_id (1 tenant = 1 ลูกค้า desk) · ไม่มีฟิลด์ตัวเลขธุรกิจ (งานค้าง/ยอดเงิน = คำนวณสด) |
desk_agreements | สัญญาบริการที่ปรึกษา | ขอบเขต (บัญชี/ภาษี/เงินเดือน/HR/เอกสาร) · fee numeric(15,2) · starts/ends/auto_renew · คนละเรื่องกับ subscriptions (ค่า SaaS) ห้ามปน · ผูกตัวเอกสารสัญญาที่ลงนาม (desk_documents) · v0.3 รูปแบบคิดเงิน 4 แบบ: เหมาโปรเจกต์ / รายเดือน / ตามเวลา (เรท+หน่วย ชม./วัน) / ตามชิ้น — ไม่มีแพ็กชั่วโมง |
desk_agreement_services | งานประจำรายชนิดใน 1 สัญญา | 1 แถว = งานประจำ 1 ชนิด (ภงด.1 + ภพ.30 + เงินเดือน = 3 แถว) อ้าง catalog + override ได้: due_day (เงินเดือน 25/28) · lead · ใช้ e-filing ไหม · unique (agreement, code) |
desk_task_catalog | แคตตาล็อกงานมาตรฐานไทย (global seed 11 ชนิด) | SoT ของ "วิธีทำงานทีม" (lead/checklist/เตือน) · FK ชี้กลับ tax_calendar = SoT กำหนดกฎหมาย — แก้กำหนดกฎหมายที่เดียว ทั้ง tenant และ Desk ขยับพร้อมกัน |
desk_jobs | งาน 3 ทาง — หัวใจ migration | CHECK 3 ชุดบังคับตาม origin · เงา auto = pointer ล้วน (title/detail/due/checklist ต้องว่าง — DB ไม่ให้เก็บเนื้อหาแม้โค้ดพลาด) · กันซ้ำ 2 ชั้น: recurring unique (client, kind, period_key) + เงา unique (source, tenant, kind, ref_key) · v0.3 เพิ่ม billable_qty + billable_unit (nullable — ใส่ตอนปิดงานของสัญญาแบบตามเวลา ไม่มี timer) |
desk_job_comments · desk_job_files | คอมเมนต์ + ไฟล์แนบงาน | คอมเมนต์ใช้ได้ทุก origin (บทสนทนาทีมเรา) · ไฟล์แนบห้ามผูกงาน auto — กันคนเซฟสำเนาบิลจาก OS มาฝั่งเรา (เอกสารลูกค้า connected อยู่ใน tenant เขา) |
desk_doc_templates · desk_template_versions | คลังแม่แบบ + เวอร์ชัน | เวอร์ชัน append-only: draft → published (แก้ไม่ได้อีก) → retired · เอกสารที่ออกแล้วผูกเวอร์ชันเดิมตลอดชีพ (หลักเดียวกับ 50 ทวิ) · เนื้อหาเป็น sections + ตัวแปร (ดูส่วนที่ 7) |
desk_documents · desk_document_events | เอกสารที่ออกให้ลูกค้า + ประวัติ | สถานะ draft→…→filed (ส่วนที่ 7) · snapshot เนื้อหาเต็ม · share_token ลิงก์อ่าน · pointer ไป hr_documents ฝั่ง tenant (connected) · ทุกจุดเปลี่ยนสถานะ = 1 event |
desk_assignments | ใครดูแลลูกค้ารายไหน (ระดับ client) | จาก v0.1 — role primary/backup · partial unique: primary ได้คนเดียวต่อลูกค้า · assignment = routing งานเท่านั้น ไม่ใช่สิทธิ์เห็นข้อมูล (สิทธิ์มาจาก tenant_members เสมอ) |
desk_logs | audit ชั้น Desk (กฎเหล็กข้อ 3) | actor + action + client/job/tenant + detail metadata เท่านั้น ห้ามใส่เนื้อหา/ตัวเลขธุรกิจ (กฎเดียวกับ usage_events) |
desk_notifications | กันเตือนซ้ำ | unique (คน, ชนิด, อ้างอิง, วันไทย) — insert ก่อน push ชนแล้วข้าม (atomic, ไม่ใช้ KV) |
desk_work_snapshots เฟส 3 | สถิติใบงาน auto สำหรับรายงาน | ทางออก tension "ใบงาน auto คำนวณสดแล้วหายไป แต่รายงานเดือนหน้าต้องนับได้" — เก็บแค่ key + first/last_seen + resolved_at + count (int) = telemetry การทำงานของทีม ไม่ใช่ข้อมูลธุรกิจ |
desk_engagement_templates v0.3 · เฟส 2 | แม่แบบชุดงาน (งานวางระบบ) | รายการขั้นมาตรฐาน (ลำดับ + optional + สัปดาห์สัมพัทธ์ + ผูกแม่แบบเอกสาร) — เปิดสัญญาเหมาโปรเจกต์จากแม่แบบ → generate งานทั้งชุดใต้สัญญา · progress = นับงาน done/ทั้งหมดใต้สัญญา ไม่มีตารางโปรเจกต์แยก |
hr_documents เฟสเอกสาร · ฝั่ง tenant | แฟ้มเอกสาร HR ของลูกค้า connected | ตารางใหม่ฝั่ง tenant (RLS isolation ปกติ ไม่ใช่ deny-all) — ปลายทาง "เก็บเข้าแฟ้ม HR ให้พนักงานเขาเปิดดูเอง" ที่ mockup อ้างแต่ยังไม่มีจริง |
ALTER platform_users | เชื่อมสองโลก + บทบาท SERVICE | identity_id (nullable + unique partial + FK identities) · เพิ่ม 'SERVICE' ใน role check · status active/suspended · identity_id เป็น nullable จริงจัง — คนดูแลลูกค้า manual ล้วน (แบบ "คุณนภา" ใน mockup) ไม่ต้องมี ใช้ Desk ได้เต็ม ขาดแค่ deep link |
create table desk_jobs (
id uuid primary key default gen_random_uuid(),
client_id uuid not null references desk_clients(id) on delete cascade,
origin text not null check (origin in ('auto','recurring','manual')),
-- pointer เงางาน auto (สร้าง lazy เมื่อมีคน assign/comment ครั้งแรก)
source text, source_tenant_id uuid, kind text, ref_key text,
-- งานประจำ
agreement_service_id uuid, period_key text, -- '2026-06' / '2026-Q2' / '2026'
-- เนื้องาน (recurring/manual เท่านั้น)
title text, detail text, due_date date, -- date ล้วน คิดตามวันไทย
status text not null default 'open'
check (status in ('open','in_progress','waiting_client','done','skipped','cancelled')),
assignee_id uuid, checklist jsonb not null default '[]',
done_at timestamptz, done_note text, …
-- ★ กฎข้อ 1 ระดับ DB: เงา auto = pointer ล้วน ห้ามถือเนื้อหา/กำหนด/เช็คลิสต์
constraint jobs_auto_pointer_only check (origin <> 'auto' or (
source is not null and source_tenant_id is not null and kind is not null and ref_key is not null
and title is null and detail is null and due_date is null and checklist = '[]'::jsonb )),
constraint jobs_nonauto_no_pointer check (origin = 'auto' or (
title is not null and source is null and ref_key is null ))
);
-- กันซ้ำที่ DB ไม่ใช่ที่โค้ด — cron รันซ้ำกี่รอบ / สัญญาซ้อนกี่ฉบับ ก็ไม่เกิดงานคู่
create unique index uq_jobs_recurring on desk_jobs (client_id, kind, period_key) where origin='recurring';
create unique index uq_jobs_auto on desk_jobs (source, source_tenant_id, kind, ref_key) where origin='auto';
ทำไม unique recurring ผูก client_id ไม่ใช่ agreement: ต่อสัญญาแบบ "สร้างใหม่+ปิดเก่า" หรือสัญญาซ้อนที่มีงานชนิดเดียวกัน 2 ฉบับ — งวดเดียวกันต้องได้งานใบเดียวเสมอ กันที่ระดับ ลูกค้า × ชนิด × งวด จบทุกกรณี
homeoffice-docs เพิ่ม prefix ใหม่ desk/ แยกโลกชัด| ของ | path |
|---|---|
| ไฟล์แนบงาน | desk/clients/{client_id}/jobs/{job_id}/{uuid}.{ext} |
| เอกสารออกให้ลูกค้า (ร่าง/ส่ง · ฉบับลงนามสแกนกลับ) | desk/clients/{client_id}/documents/{doc_id}/… |
| ไฟล์แม่แบบต้นทาง | desk/templates/{template_id}/v{n}/… |
tenants/ = ทรัพย์สินลูกค้า (เข้าผ่าน worker ลูกค้า+สิทธิ์ tenant) · ทุกอย่างใต้ desk/ = ทรัพย์สินสำนักงาน (เข้าผ่าน operator-worker+requireDesk) — handler upload/download ตรวจ prefix เสมอ กันข้ามโลก · เก็บเอกสารเข้าแฟ้ม tenant = copy ไฟล์จริง ไม่ shared key (lifecycle สองโลกแยกขาด: เลิกใช้บริการแล้วลบฝั่งหนึ่ง อีกฝั่งต้องยังอยู่)เครื่องยนต์หลักของลูกค้า manual (และคนคุมจังหวะของ connected ด้วย) — หลักคิด: tax_calendar = ความจริงตามกฎหมาย · desk_task_catalog = วิธีทำงานของทีม สองชั้นนี้ไม่ยุบรวมกัน
| code | งาน | รอบ | กำหนด (กระดาษ) | e-filing | checklist ตั้งต้น |
|---|---|---|---|---|---|
pnd1 | ภงด.1 หัก ณ ที่จ่ายเงินเดือน | รายเดือน | วันที่ 7 เดือนถัดไป | วันที่ 15 | รับข้อมูล→คำนวณ→ยื่น→แนบใบเสร็จ |
pnd3 / pnd53 | ภงด.3 / ภงด.53 หัก ณ ที่จ่าย | รายเดือน | วันที่ 7 | วันที่ 15 | รวบรวม 50ทวิ→ยื่น→แนบใบเสร็จ |
vat30 | ภพ.30 ภาษีมูลค่าเพิ่ม | รายเดือน | วันที่ 15 | วันที่ 23 | กระทบยอดซื้อ-ขาย→ยื่น→ชำระ/ขอคืน |
sso | เงินสมทบ สปส. (สปส.1-10) | รายเดือน | วันที่ 15 | ~วันที่ 22 (แก้ได้ในตาราง — ประกาศต่ออายุเป็นช่วง) | ยอดค่าจ้าง→นำส่ง→ใบเสร็จ |
payroll | ทำเงินเดือน | รายเดือน | กำหนดเองต่อสัญญา (25/28) | — | รับข้อมูล→คำนวณ→ส่งสลิป→เก็บหลักฐาน |
month_close | ปิดเดือน | รายเดือน | วันที่ 15 (ปรับได้) | — | ตาม checklist ปิดเดือนของระบบ |
pnd1a / wht_annual | ภงด.1ก + ออก 50ทวิ ประจำปี | รายปี | 28 ก.พ. / 15 ก.พ. | 8 มี.ค. / — | กระทบยอด 12 เดือน→ยื่น / ออกครบ→ส่งมอบ |
pnd50 / pnd51 | ภงด.50 ประจำปี / ภงด.51 ครึ่งปี | รายปี / ครึ่งปี | 150 / 60 วันหลังสิ้น(ครึ่ง)รอบบัญชี — อ่านรอบบัญชีจริง ไม่ hardcode มกราคม | +8 วัน | งบเสร็จ→ผู้สอบลงนาม→ยื่น |
ไวยากรณ์กำหนด (superset ของ day:N เดิม): day:N · md:MM-DD (วันตายตัวรายปี) · fy_end+N / fy_half+N (อิงรอบบัญชี) · custom (บังคับใส่ due_day ต่อสัญญา) — parser ใหม่อยู่ฝั่ง operator-worker ไม่แตะของเดิมฝั่ง tenant (แถวใหม่ใน tax_calendar ถูก cron เดิมข้ามเงียบ = ปลอดภัย)
ภงด.1 ยื่น 7 ก.ค. = งวด 2026-06 — ตรงกับ period ของ payroll_runs / monthly_closes / doc_submissions ฝั่ง tenant ที่ใช้ "งวดข้อมูล" ทั้งหมด → join ตรงไม่ต้องแปลง และเป็นกุญแจกันซ้ำ
สัญญาจบ 30 มิ.ย. → ภงด.1 งวด มิ.ย. (ยื่น 7 ก.ค.) ยังเป็นงานของเรา — ธรรมเนียมจริงของสำนักงานบัญชี เดือนสุดท้ายของสัญญายังต้องยื่นให้ · เงื่อนไขนี้ทำให้ "สัญญาหมดอายุ" ไม่ต้องมี logic พิเศษ — เครื่องผลิตจนงวดสุดท้ายแล้วหยุดเอง
ไม่ pre-generate ทั้งปี — แก้สัญญากลางงวดง่าย ตารางไม่รกด้วยงานอนาคต · เดือนสั้น: due_day 31 → clamp วันสุดท้ายจริง · ตรงวันหยุด → เลื่อนวันทำการถัดไป (แนวสรรพากร — ทีมอยากเผื่อก่อนวันหยุดให้เพิ่ม lead แทน)
เดือนที่ไม่มียอด (ภงด.3 ไม่มีจ่าย): งานเกิดตามสัญญาเสมอ — สำนักงานต้อง "ยืนยันว่าไม่มี" ไม่ใช่ "ไม่รู้" → ทีมติ๊ก skipped "งวดนี้ไม่มียอด" · ประวัติคือหลักฐานเวลาลูกค้าถาม "เดือนนั้นทำไมไม่ยื่น"
โจทย์ชน: ลูกค้า connected ที่มีสัญญา "ยื่นภาษีรายเดือน" — งวดเดียวกันโผล่ทั้งจากข้อมูลจริง (live) และจากสัญญา (recurring job) ใครชนะ?
| กรณี | ผลในปฏิทิน/คิวงาน |
|---|---|
| มี recurring job + live ตรงงวด (connected) | แถวเดียว = job · live เติม badge สด: "เตรียม 80%" / "checklist 3/4" / "ยื่นแล้วในระบบ ✓" + deep link · auto-done: ข้อมูลจริงยืนยันงวดแล้ว (monthly_closes closed / payroll_runs approved / doc_submissions submitted) → cron ปิดงานเอง "อัตโนมัติ: ระบบลูกค้ายืนยันงวดนี้แล้ว" |
| มี recurring job · ลูกค้า manual | แถว job ล้วน — สถานะทีมติ๊กเอง · มาตรฐานการเตือนเดียวกับ connected ทุกอย่าง |
| live มี แต่ไม่มีสัญญาครอบชนิดนั้น | แถวจาง (ghost) badge "นอกสัญญา" — ไม่นับ workload ปิดได้ด้วย filter · default เปิดเพื่อกันพลาด + เป็นโอกาสชวนเซ็นเพิ่ม รอพี่ปุ้ยเคาะ |
| connected แต่ทีมยังไม่ถูกเชิญเข้า tenant | ไม่มี live (ไม่มีสิทธิ์ = ไม่เห็นแม้ชื่อใบงาน) — เห็นเฉพาะแถว job + badge "ยังไม่ได้รับเชิญเข้าระบบลูกค้า" |
หัวใจเมนู "งาน" + "หน้าแรก Today" — ใบงาน auto ต้องมี key เสถียร (ไม่แตกใบใหม่ทุกครั้งที่ query) เงาถึงผูกได้ และจอรวมถึงเรียงได้
(source, tenant, kind, ref_key) — key ห้ามมีส่วนผันแปร| ชนิด | ref_key | เหตุผล (อ้างตารางจริง) |
|---|---|---|
| บิลรอตรวจ · 50ทวิค้างออก · กระทบยอดค้าง · ปิดเดือน · เงินเดือน | งวดเดือน yyyy-mm | งานสะสม "เคลียร์ของงวดนี้ให้หมด" — ถ้าใช้ id รายใบ บิลเข้าจาก LINE วันละหลายใบ ใบงานจะเกิด/หายถี่ เงาบานเป็นร้อย และไม่ตรงวิธีมอบงานจริง ("ไปเคลียร์บิลเดือนนี้ของเจ้านี้") · เพดานธรรมชาติ 12 ใบ/ปี/ชนิด |
| รออนุมัติ | approvals.id (uuid) | เอกสารเดี่ยว ตัดสินรายใบ — status pending→approved/rejected ชัด |
| ภาษีใกล้ครบ | {form}:{yyyy-mm} เช่น ภพ.30:2026-05 | ต้องมีงวดใน key (ไม่งั้นเดือนถัดไปชนใบเดิม) · ใช้ชื่อฟอร์มไม่ใช่ uuid — อ่านรู้เรื่อง + SiteOS ใช้ตามได้โดยไม่ต้องมีตารางร่วม |
| เบิกรออนุมัติ | uuid ใบตั้งเบิก | เฟส 4 (ตารางฝั่ง Desk เอง) · เฟส 5 รับจาก SiteOS ผ่าน /work-items |
มอบหมาย · คอมเมนต์ · snooze ครั้งแรก → ค่อย insert แถวเงา · ใบงาน auto ที่ไม่มีใครแตะ = ไม่มีแถวเลย (คำนวณสดล้วนเหมือน v0.1) — eager ต้องมี sync engine คอยเปิด/ปิดแถว = ครึ่งทางไปสู่การ sync สำเนา
key 4 ฟิลด์ + ผู้รับผิดชอบ + snooze + คอมเมนต์ (ข้อความทีมพิมพ์เอง) — ห้าม: หัวเรื่อง/ยอดเงิน/ชื่อคู่ค้า/กำหนด ทั้งหมดคำนวณสดตอน render
ใบงานจริงหายจากผลคิวรีสด (งานเสร็จในระบบจริง) → เงาปิดเอง status done + closed_reason='auto_resolved' · key กลับมาโผล่อีก (เช่น reopen เดือน) → สร้างเงาใหม่ได้ ประวัติเก่าไม่ลบ
.in() ครั้งเดียว group ใน JSPOST /desk/enter-tenant { clientId, page }
1. ลูกค้าต้อง connected · ผู้กดต้องผูก identity แล้ว
2. เช็ค tenant_members (identity × tenant, active) ← กฎเหล็กข้อ 2 — Desk ไม่ใช่ทางลัด
3. gate เดียวกับ tenant switcher เดิมเป๊ะ: web_access (non-OWNER) + tenant ต้อง trial/active
4. มินต์ tenant JWT ด้วย signCustomerSession ที่มีอยู่ — ไม่ใส่ imp claim
(ที่ปรึกษาเป็นสมาชิกจริง เขียนได้ตาม role ACCOUNTANT/ADMIN ที่ลูกค้าให้ — ไม่ใช่การสวมรอย)
TTL 8 ชม. + claim via:{kind:'desk'} บอกที่มาของ session
5. audit สองชั้น: desk_logs 'enter_tenant' + audit_logs ฝั่ง tenant 'desk.enter' (actor = สมาชิกตัวจริง)
6. คืน URL: …/#lt={token}&lr={role}<n={tenant}&lp={page} → เปิดแท็บใหม่
(ฝั่ง web patch ~1 บรรทัด: อ่าน lp ก่อนล้าง hash — กลไก #lt มีอยู่แล้ว)
| ชนิดใบงาน | หน้าใน web ลูกค้า (page key จริง) |
|---|---|
บิลรอตรวจ → expenses | รายจ่าย & ผู้ขาย (ตั้งหมวด/แก้บิล) |
รออนุมัติ → approvals · 50ทวิ → whtCerts · กระทบยอด → reconcile | ใบให้ตรวจ&อนุมัติ · ใบ 50 ทวิ · กระทบยอดธนาคาร |
ปิดเดือน + ภาษี → monthlyClose · เงินเดือน → hr | ปิดเดือน (checklist+นำส่ง) · พนักงาน·เงินเดือน |
{source}:{tenant}:{kind}:{ref_key} + product + api_base + title/status/due/age/count + can_complete_here + deep_link — ไม่มีฟิลด์เงิน (metadata-only by design จำนวนเงินไปดูในระบบจริง) · SiteOS แค่ทำ GET /work-items ตอบตามนี้ ใส่ไว้ใน backbone ของ os-starter ทีเดียวทุก OS ได้ฟรีHomeOffice เดิมออกแบบทิศ "รวบกองเอกสารส่งออกไปให้สำนักบัญชีข้างนอก แล้วจบ" (ตาราง doc_submissions คอมเมนต์ไว้ตรงๆ ว่า "ทะเบียนคุมการนำส่งเอกสารให้สำนักบัญชี") — ขารับจึงครบเกือบหมด แต่ขา "สำนักงานบัญชีตอบกลับเข้ามาในระบบ" ไม่เคยมีใครสร้าง เพราะตอนนั้นเรายังไม่ใช่ สนง.บช. — v0.3 เติมขานี้ให้ครบ
| ของ | ลูกค้าเชื่อมระบบ | ลูกค้าดูแลเอง |
|---|---|---|
| บิลซื้อ-ขาย | พนักงานเขาถ่ายเข้า LINE ระบบเขา → OCR → ลงบัญชี → ใบงาน "บิลรอตรวจ" ที่โต๊ะเรา ✓ ครบแล้ว | ส่ง LINE ส่วนตัว → แนบเข้างานของงวด → เข้าแฟ้มลูกค้าเอง ✓ |
| สัญญาณ "เอกสารครบ เริ่มทำได้" | G2: ปุ่ม "รวบกองส่งสำนักบัญชี" (doc_submissions) ที่ลูกค้ามีอยู่แล้ว — เปลี่ยนความหมายเป็น "ส่งมอบงวดให้ที่ปรึกษา": ลูกค้ากด → โต๊ะเราเกิดงาน "เริ่มทำงวด" + รู้ว่ามีบิลกี่ใบ | งานประจำมีขั้น "รับข้อมูล" + สถานะ "รอลูกค้าส่ง" → ระบบช่วยทวง (G4) |
| statement ธนาคาร | นำเข้าในระบบเขา → ใบงานกระทบยอด ✓ | ลูกค้าส่งไฟล์ → แนบเข้างาน |
| เงินเดือน/เวลาทำงาน | อยู่ในระบบเขาอยู่แล้ว (เช็คอิน/ลา/OT) ✓ | ลูกค้าส่งไฟล์ → แนบเข้างานทำเงินเดือน |
| เอกสารงวดอื่น (สัญญาเช่า ฯลฯ) | G5: ยังไม่มีที่ลงชัดฝั่ง tenant — "แฟ้มงวด" เป็นงานเฟสหลัง ไม่บล็อกอะไร | |
| # | ช่องว่าง | เติมที่ไหน | เฟส |
|---|---|---|---|
| G1 | ปุ่มบันทึกยื่นภาษี + แนบใบเสร็จ (เขียน tax_filings ที่ว่างอยู่) | ฝั่ง HomeOffice เพิ่มเล็ก | 3 |
| G2 | เปลี่ยนบทบาท doc_submissions → "ส่งมอบงวดให้ที่ปรึกษา" trigger งานที่โต๊ะเรา | แก้ป้าย/ความหมาย + connector | 3 |
| G3 | รายงานปิดงวดจากที่ปรึกษา (ตัวเลข+คำแนะนำ → inbox+LINE ลูกค้า) | ใหม่ | 3-4 |
| G4 | ปุ่มทวงเอกสาร: เชื่อมระบบ = เตือนผ่าน LINE ระบบเขา · ดูแลเอง = copy ข้อความทวง | Desk | 2 |
| G5 | แฟ้มงวดสำหรับเอกสารที่ไม่ใช่บิล | ฝั่ง tenant | หลัง ไม่บล็อก |
| G6 | ปุ่ม "จ้างสำนักงานบัญชี/ที่ปรึกษา" ใน HomeOffice (funnel ทิศ product → service): ลูกค้า self-serve ที่เหนื่อยกับการยื่นเอง/ทำเอกสารเอง กดแล้วเด้งเป็น "ลูกค้าใหม่ + คำขอจ้าง" เข้าโต๊ะเรา → เสนอสัญญา → เชิญทีม (กลไกที่มีครบแล้ว ขาดแค่ปุ่มต้นทาง) — วางแบบ generic ทีมเราเป็น default ไม่ล็อก | ฝั่ง HomeOffice (จุดวาง: หน้า ภาษี/ปิดเดือน/เอกสาร + first-run) | 3-4 |
| เมนู | เส้นทางหลัก | จุดบังคับ |
|---|---|---|
| หน้าแรก Today | GET /desk/summary · GET /desk/work-items?scope=… | endpoint เดียวกับเมนูงาน + filter ฝั่ง server — ไม่ทำตรรกะแยก |
| ลูกค้า + สัญญา | /desk/clients CRUD + /connect (manual→connected) + /assign · /desk/agreements CRUD + /terminate + /generate-now | POST สร้าง = idempotency · คนสร้างเป็น primary อัตโนมัติ · generate-now กันซ้ำด้วย unique index |
| งาน | /desk/jobs CRUD + /assign + /comments + /files · POST /desk/work-items/adopt (สร้างเงา) | แนบไฟล์เฉพาะงานไม่ใช่ auto · PATCH เงา+status → 409 |
| เอกสาร & แม่แบบ | /desk/templates + versions/publish · /desk/documents + เดินสถานะ/send/signed-file/file/void | publish เวอร์ชัน = PLATFORM_ADMIN · ผู้รีวิว ≠ ผู้สร้าง · เดินสถานะหน้าเดียว ย้อนได้เฉพาะแอดมิน |
| ปฏิทินงวด | GET /desk/calendar?month= | merge 3 แหล่งตามกฎส่วนที่ 4 — อ่านอย่างเดียว ไม่มีตารางปฏิทินแยก |
| ทีม | GET /desk/team + workload · POST /desk/team/invite-to-tenant | คำขอเชิญ = ขยาย member_invites เดิม (status 'requested') → OWNER ลูกค้ากดยืนยันในเว็บเขา → ระบบ insert tenant_members — สิทธิ์มาจากลูกค้าเสมอ Desk แค่ยื่นคำขอ |
| รายงาน | GET /desk/reports/overview · /clients/:id · /export?format=csv | เริ่มจากตารางดิบ export ได้ — dashboard KPI ไว้เมื่อมีข้อมูลสะสม ≥3 เดือน |
| Deep link | POST /desk/enter-tenant | rate limit 30 ครั้ง/10 นาที/คน · audit สองชั้นทุกครั้ง |
SPA แยกไฟล์ ใช้ styles.css + token เดิมร่วมกัน (login ครั้งเดียวเข้าได้สองประตู) — แตะ app.js ของ Console แค่ 2 จุด: login แล้ว role SERVICE เด้งไป /desk + ปุ่มสลับประตูสำหรับ PLATFORM_ADMIN · _redirects เพิ่ม /desk → desk.html
response {ok,data}/{ok,error,code} · เพิ่ม RATE_LIMITED + TENANT_SUSPENDED ใน response.js ฝั่ง operator (เดิมไม่มี) · idempotency POST สำคัญ (ต้อง bind KV ก่อน) · rate limit /admin/login (เดิมไม่มี!) · เงิน numeric(15,2) · เวลา UTC แสดงไทย · UI copy ไทยง่ายไม่ทับศัพท์
เคาะรูปแบบ: HTML แตกเป็น section + ตัวแปร {{placeholder}} → render เป็นหน้าพิมพ์ (พิมพ์/Save as PDF) — ตรง pattern ที่ระบบใช้จริงอยู่แล้ว (printDoc + Sarabun) dependency ใหม่เป็นศูนย์ · ไม่เอา DOCX (หลุด version control + render ไทยเพี้ยน) ไม่เอา PDF lib (จัดหน้าไทยยาวหลายหน้าด้วยมือ = งานมหาศาล)
optional = ติ๊กเลือกตอนสร้าง (กฎระเบียบ 8 หัวข้อเลือกเฉพาะที่ใช้) · locked = ถ้อยคำตามกฎหมายบังคับ แก้รายลูกค้าไม่ได้ (แก้ที่แม่แบบ→ออกเวอร์ชันใหม่เท่านั้น){{client.*}} เติมอัตโนมัติจากทะเบียนลูกค้า · {{doc.*}} ระบบใส่ให้ (เลขที่/วันที่) · {{var.*}} {{emp.*}} กรอกตอนสร้าง — ฟอร์มกรอก generate จากนิยามตัวแปร ไม่ hardcodedraft ──▶ in_review ──▶ approved ──▶ sent ──▶ viewed ──▶ signed ──▶ filed ▲ │ (ลูกค้าเปิดลิงก์) (อัปสแกน) (เก็บแฟ้ม + สำเนา tenant) └── ตีกลับ ──┘ ทางแยก: voided (ก่อน signed) · superseded (ถูกฉบับใหม่แทน)
| ใบงานสดชนิดใหม่ | เกิดเมื่อ | หายเมื่อ |
|---|---|---|
doc_unsigned ส่งแล้วไม่ลงนาม | ส่งแล้วเกิน X วัน (ตั้งต่อแม่แบบ default 7) | ลงนาม/ยกเลิก — ไม่ insert งานจริง โผล่ใน work queue แบบเดียวกับ 8 ชนิดเดิม |
doc_review ถึงรอบทบทวน | แม่แบบออกรุ่นใหม่ (กฎหมายเปลี่ยน) หรือครบรอบทบทวนรายปี (ข้อบังคับ = 12 เดือน) | กด "ออกฉบับใหม่" (ฉบับเก่า superseded) หรือ "ยังใช้ฉบับเดิม" (stamp รับทราบถึงรุ่นนี้ — มีร่องรอยใครตัดสินเมื่อไหร่) |
R2 desk/clients/{id}/docs/… + แถว metadata — จบ · งานผูกเอกสาร 1 งาน : N ใบ (สัญญาจ้าง ×8 คน = งานเดียว เอกสาร 8 ใบ เห็น progress "ลงนามแล้ว 5/8") · งานปิดเองเมื่อเอกสารทุกใบถึง filed/voided
① เช็ค membership ผู้กดก่อนเสมอ (ไม่เป็นสมาชิก = ปุ่ม disabled — service role ไม่ใช่ทางลัด) ② copy ไฟล์จริงเข้า tenants/{id}/hr-docs/… ③ insert hr_documents (ตารางใหม่ฝั่ง tenant — พนักงานเขาเปิดดูเองได้ผ่าน /hr/documents) ④ audit สองชั้น: ฝั่ง tenant "บัญชีภายนอกเก็บเอกสารเข้าแฟ้ม" + event ฝั่ง Desk ⑤ stamp pointer + filed · แยก signed/filed เพราะขั้น copy อาจติดสิทธิ์ — ให้มองเห็นค้าง
เหตุผลที่กลับด้าน: พี่ปุ้ยมีลูกค้า manual จริงอยู่แล้ววันนี้ ส่วนลูกค้า connected ที่ทีมดูแลจริงยังต้องเคาะรายชื่อ · เฟส connected มีงานแฝงที่ v0.1 ประเมินต่ำ (แลกเซสชันข้าม JWT สองโลก, ผูก identity, OWNER ต้องเปิด web_access) · และโหมด manual ต้องการตาราง clients+jobs+agreements ตั้งแต่วันแรกอยู่ดี — งาน auto ค่อยมาเกาะทีหลัง
| ชิ้นงาน | เนื้อหา | ขนาด |
|---|---|---|
| Migration ชุดเดียว | desk_clients · desk_agreements (+services+catalog) · desk_jobs (+comments/files) · desk_assignments · desk_logs · desk_notifications · ALTER platform_users — additive ล้วน role เดิม 4 ค่าผ่านหมด | M |
| 🔴 แยก middleware สิทธิ์ | requireConsole ครอบ /admin/* เดิมทั้งหมด + requireDesk สำหรับ /desk/* — ต้องเสร็จก่อน insert บัญชี SERVICE คนแรก | M |
| API กลุ่ม desk | clients/agreements/jobs CRUD + มอบหมาย + แนบไฟล์ + คอมเมนต์ — ทุก endpoint เขียน desk_logs | M |
| เครื่องยนต์งานประจำ | เกาะ scheduled() เดิม 09:00 ไทย — ผลิต/sync/เตือน idempotent ทุกขั้น | M |
| UI 4 เมนูแรก | Today · ลูกค้า · งาน · ปฏิทินงวด (= view จาก jobs.due_date ไม่มีตารางแยก) — desk.html/desk.js แยกไฟล์ | L |
| # | คำถาม | คนเคาะ | กระทบ |
|---|---|---|---|
| Q1 | รายชื่อลูกค้า manual จริงวันนี้ + บริการที่ทำให้แต่ละราย (ยื่นภาษี? เงินเดือน? เอกสาร?) | พี่ปุ้ย | ชุดงานประจำรุ่นแรก + seed ข้อมูลจริง |
| Q2 | ทีมที่ได้บัญชี SERVICE มีใครบ้าง — ทุกคนสิทธิ์เท่ากันหมดได้ไหม (เสนอ: เท่ากันก่อน ไม่ทำ sub-role) และเห็นลูกค้าร่วมกันทั้งทีม หรือเฉพาะรายที่ถูก assign | พี่กี้+พี่ปุ้ย | โมเดลสิทธิ์ + หน้าเมนูลูกค้า |
| Q3 | งานประจำต้องมี checklist ขั้นย่อย ("4 ขั้น" ใน mockup) หรือใบเดียวติ๊กเสร็จพอ — ถ้าไม่จำเป็นจริงตัดทิ้ง (กัน K5) | พี่กี้ | schema jobs + ความซับซ้อน UI |
| Q4 | กำหนดยื่นภาษีใช้เกณฑ์กระดาษ (7/15) หรือ e-filing (+8 วัน) ต่อลูกค้า · ค่า สปส. e-Payment ที่ทีมใช้จริงตอนนี้ | พี่กี้ | สูตรคำนวณ due ของเครื่องยนต์ |
| Q5 | แจ้งเตือนทีมเฟส 1: in-app พอ หรือต้อง LINE push เลย — ถ้า push ใช้ OA กลาง platform ตามดีไซน์ใช่ไหม | พี่ปุ้ย | scope เฟส 1 |
| เคาะก่อน | คำถาม |
|---|---|
| เฟส 2 | เมนูเอกสารเริ่มระดับไหน — ไฟล์ master + สถานะลงนาม (เสนอ) หรือ section+ตัวแปรเต็มรูปเลย · ตำแหน่งหน้าอ่านลิงก์สาธารณะ: operator-worker มีคอมเมนต์ "ห้ามรับ traffic ลูกค้า" → ยกเว้นจำกัด read-only หรือ worker เล็กตัวที่สาม (เสนอ: worker แยก สะอาดสุด) |
| เฟส 3 | ลูกค้า connected รายแรกที่ทีมดูแลจริงคือใคร + OWNER ยอมเชิญทีมเป็น ACCOUNTANT + เปิด web_access ไหม (ไม่มีรายจริง = เฟส 3 ยังไม่เริ่ม) · งวด live "นอกสัญญา" โชว์เป็นแถวจางหรือซ่อน (เสนอ: โชว์) · cron auto-done อ่านสถานะ tenant ด้วย service role แบบ existence-check 3 ตาราง — ตีความผ่านกฎเหล็กข้อ 2 ไหม หรือให้ปิดเฉพาะตอนคนที่มี membership เปิดจอ · token เข้าเว็บลูกค้า TTL 8 ชม.+localStorage หรือ in-memory ปิดแท็บแล้วหลุด |
| เฟส 2 | v0.3 ขั้นมาตรฐานจริงของงานวางระบบ HR (ร่าง 7 ขั้นในส่วนที่ 2 ถูกกี่ % — ใช้ทำ seed แม่แบบชุดงาน) · งวดเก็บเงินโปรเจกต์ (เช่น มัดจำ 50 / ส่งมอบ 50) ให้ระบบช่วยตามทวงไหม หรือคุมเองนอกระบบ |
| เฟส 4 | นัดฟัง flow ตั้งเบิกจริงทั้งวงจรจากพี่กี้ (ค้างจาก v0.1) รวม "จับคู่ statement กับลูกค้า manual ที่เราไม่มี statement นิยามยังไง" · SLA ลูกค้า manual นับจากทีมติ๊ก — ยอมรับความแม่นระดับนี้ หรือบังคับแนบหลักฐานก่อนติ๊กเสร็จ เคาะแล้ว: ฐานคิดค่าบริการสัญญาแบบเวลา = หน่วยที่ใส่ตอนปิดงาน ไม่ใช่ time tracking |
| นโยบาย | EXPERT/SUPPORT/SALES เห็น Desk ไหม (เสนอ: ไม่เห็น) · prefill รายชื่อพนักงาน tenant ตอน batch สัญญาจ้าง = อ่าน PII มาฝั่ง Desk (เฟสแรกพิมพ์มือ — เคาะนโยบายทีหลัง) |