Files
wms-app/scripts/sdlc-seed/docs-pm1.mjs
T
Thanakorn 087e7b3958 docs(sdlc): reformat work products to audited reference layout
Replace the PHP/Markdown seeding with a data-driven generator in
scripts/sdlc-seed and regenerate all 59 work products.
2026-09-09 08:09:54 +07:00

347 lines
49 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// PM work products 1–2: Statement of Work, Work Schedule, Software Project Plan, Customer Requirements.
import { P, TEAM, CODE, PROJECT_TH, COMPANY_TH, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, WPS, SCOPE, CR_GROUPS, CRS, DEV_START, TEST_FROM, TEST_TO } from './project.mjs';
import { TASKS } from './history.mjs';
import { bud, thLong, thRangeLong, thShort, table, bullets, numbered, daysBetween, doc } from './lib.mjs';
import { workProduct, head } from './format.mjs';
const DURATION = daysBetween(START, END);
const resp = (ids) => ids.map((i) => P[i].id).join(', ');
/** 1. Statement of Work — the meeting invitation that opened the project, as in the audited package. */
export function statementOfWork() {
const date = '2026-01-05';
return {
dir: '1-PM Process (10 Work Product)/1.Statement of Work',
name: `${CODE} Statement of Work ${bud(date)} V1.0 ApS`,
md: workProduct({
type: 'Statement of Work', footer: 'SoW',
rows: head('Statement of Work', `${bud(date)} V1.0 ApS`, [
['Title', 'ขอบเขตงานและหนังสือเชิญประชุมเปิดโครงการ'],
['Project Period', thRangeLong(START, END), 'Project Duration', `${DURATION} วัน`],
['Organizer', ORGANIZER_PM],
['Recorder', RECORDER],
]),
body: [
`วันที่ ${thLong(date)}`,
'**เรื่อง:** ขอบเขตงานโครงการพัฒนาระบบบริหารจัดการคลังสินค้า และนัดประชุมเปิดโครงการ',
'**เรียน:** ผู้บริหาร หัวหน้าฝ่าย และผู้เกี่ยวข้องทุกฝ่าย',
`ตามที่ ${COMPANY_TH} ได้ใช้การบันทึกข้อมูลคลังสินค้าด้วยกระบวนการที่กระจายอยู่หลายระบบและบางส่วนยังใช้เอกสารกระดาษ ซึ่งปัจจุบันพบว่ามีข้อจำกัดด้านความถูกต้องของยอดสินค้าคงคลัง ความรวดเร็วในการตรวจสอบ และการเชื่อมโยงกับงานขาย งานจัดซื้อ และงานบัญชี ผู้บริหารจึงเล็งเห็นความจำเป็นในการพัฒนาระบบบริหารจัดการคลังสินค้า (Warehouse Management System) ขึ้นใหม่ เพื่อให้การปฏิบัติงานมีความถูกต้อง ตรวจสอบย้อนกลับได้ และรองรับการเติบโตของธุรกิจ`,
'ดังนั้น จึงขอนัดประชุมเพื่อหารือร่วมกันระหว่างทุกฝ่ายที่เกี่ยวข้อง เพื่อ',
bullets(['รับฟังข้อเสนอแนะจากฝ่ายคลังสินค้า ฝ่ายขาย ฝ่ายจัดซื้อ และฝ่ายบัญชี', 'กำหนดแนวทางและกรอบความต้องการของระบบ', 'วางแผนดำเนินการพัฒนาและกำหนดผู้รับผิดชอบ']),
'## รายละเอียดการประชุม',
bullets([`วัน เวลา: ${thLong('2026-01-05')} เวลา 09.00 – 11.00 น.`, `สถานที่: ห้องประชุม ${COMPANY_TH}`, 'ผู้เข้าร่วม: ผู้บริหาร / ผู้จัดการ / หัวหน้าฝ่ายที่เกี่ยวข้อง และทีมพัฒนาระบบ']),
'## 1 วัตถุประสงค์ของโครงการ',
bullets([
'พัฒนาระบบบริหารจัดการคลังสินค้าแบบ Web-based รองรับหลายบริษัทและหลายคลังสินค้า',
'รองรับการรับเข้า จ่ายออก โอนย้าย ตรวจนับ พร้อมติดตาม Lot, Serial Number และวันหมดอายุ',
'ลดข้อผิดพลาดจากการทำงานด้วยมือ และเพิ่มความสามารถในการตรวจสอบย้อนกลับ',
'รองรับงานขาย งานจัดซื้อ งานการเงิน และการบันทึกบัญชีที่เกี่ยวข้อง',
'ควบคุมความปลอดภัย การแยกข้อมูลระหว่างบริษัท สิทธิ์การใช้งาน และการแจ้งเตือนแบบ Real-time',
]),
'## 2 ขอบเขตงาน (Scope of Work)',
table(['ลำดับ', 'ระบบ', 'ระบบย่อย'], SCOPE.map(([sys, subs], i) => [i + 1, sys, subs.join(' / ')]), ['c']),
'## 3 สิ่งส่งมอบ (Work Products)',
table(['รหัส', 'สิ่งส่งมอบ (Work Product)', 'รายละเอียด'], WPS),
'## 4 ข้อยกเว้นและข้อสมมติ',
bullets([
'ไม่รวมการจัดหาเครื่องแม่ข่าย อุปกรณ์เครือข่าย เครื่องอ่านบาร์โค้ด หรือบริการภายนอก เว้นแต่ได้รับอนุมัติแยกต่างหาก',
'การย้ายข้อมูลจากระบบเดิม การเชื่อมต่อ ERP หรือบริการภายนอก ต้องผ่านกระบวนการ Change Request',
'ผู้มีส่วนได้ส่วนเสียต้องให้ข้อมูล ตรวจสอบเอกสาร และร่วมทดสอบตามกำหนดเวลา',
]),
'## 5 แผนงานและหลักไมล์',
table(['ช่วงงาน', 'ระยะเวลา'], [
['เริ่มต้นและวางแผนโครงการ', thRangeLong(START, '2026-02-18')],
['พัฒนาและทดสอบภายใน', thRangeLong(DEV_START, '2026-05-29')],
['ตรวจสอบ ทดสอบ จัดทำเอกสาร และส่งมอบ', thRangeLong('2026-05-30', END)],
['วันสิ้นสุดโครงการอย่างเป็นทางการ', thLong(END)],
]),
'## 6 เกณฑ์การตรวจรับ',
bullets([
'ฟังก์ชันในขอบเขตผ่าน Test Case และเชื่อมโยงกับความต้องการใน Traceability Record',
'ไม่มีข้อบกพร่องระดับวิกฤตที่ขัดขวางการใช้งานคงค้าง',
'มีคู่มือติดตั้ง คู่มือผู้ใช้ คู่มือผู้ดูแลระบบ และคู่มือบำรุงรักษาครบถ้วน',
'ผลการตรวจสอบ (Verification) การทดสอบการยอมรับ (Validation) และการตรวจรับได้รับการลงนามโดยผู้มีอำนาจ',
]),
'## 7 การควบคุมการเปลี่ยนแปลง',
'การเปลี่ยนแปลงขอบเขต กำหนดเวลา หรือสิ่งส่งมอบ ต้องบันทึกใน Change Report ประเมินผลกระทบ และได้รับอนุมัติก่อนดำเนินการ ส่วนการแก้ไขข้อบกพร่องต้องบันทึกใน Correction Register และเชื่อมโยงกับหลักฐานการทดสอบที่เกี่ยวข้อง',
'จึงเรียนมาเพื่อโปรดพิจารณาและเข้าร่วมประชุมโดยพร้อมเพรียงกัน',
].join('\n\n'),
secretary: P.ApS, reviewer: P.YaB, approver: P.SeV,
}),
};
}
/** 2.1 Work Schedule — landscape task table with milestones. */
export function workSchedule() {
const date = '2026-02-13';
return {
dir: '1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule',
name: `${CODE} Work Schedule ${bud(date)} V1.0 ApS`,
md: workProduct({
type: 'Work Schedule', footer: 'WS',
rows: head('Work Schedule', `${bud(date)} V1.0 ApS`, [
['Title', 'แผนการดำเนินงานโครงการ (Work Schedule)'],
['Project Period', thRangeLong(START, END), 'Project Duration', `${DURATION} วัน`],
['Organizer', ORGANIZER_PM],
['Recorder', RECORDER],
]),
body: [
'## แผนการดำเนินงาน (Work Schedule)',
table(['No.', 'Phase', 'Task', 'รายละเอียด', 'ผู้รับผิดชอบ', 'Start', 'Finish', 'วัน', 'สิ่งส่งมอบ / หลักฐาน', 'Status', 'หมายเหตุ'],
TASKS.map((t) => [t[0], t[1], t[2], t[3], resp(t[4]), thShort(t[5]), thShort(t[6]), daysBetween(t[5], t[6]), t[7], t[8], t[9]]),
['c', '', '', '', 'c', 'r', 'r', 'r', '', 'c', '']),
'## หลักไมล์ของโครงการ (Milestones)',
table(['หลักไมล์', 'วันที่', 'เกณฑ์การบรรลุ'], [
['เปิดโครงการอย่างเป็นทางการ', thLong(START), 'ประชุม Kick-off และชี้แจงขอบเขตงาน'],
['อนุมัติกฎบัตรโครงการ', thLong('2026-01-23'), 'Project Sponsor อนุมัติ Project Charter'],
['ตั้ง Baseline ความต้องการและแผนงาน', thLong('2026-02-18'), 'อนุมัติ Customer Requirements และ Work Schedule'],
['เริ่มพัฒนาระบบ', thLong(DEV_START), 'เริ่ม Task 3.1 ตามแผน'],
['Baseline การพัฒนา', thLong('2026-05-29'), 'พัฒนาครบทุกโมดูล (Git a0677d6)'],
['ทดสอบระบบและ UAT', thRangeLong(TEST_FROM, TEST_TO), 'ทดสอบ 45 Test Case และ 12 สถานการณ์ UAT ผ่านทั้งหมด'],
['ตรวจรับส่งมอบระบบ', thLong('2026-08-17'), 'ผลการตรวจรับ Accepted'],
['อบรมผู้ใช้งาน', thLong('2026-08-22'), 'อบรมผู้ใช้งาน 6 คน'],
['ปิดโครงการ', thLong(END), 'ปิดโครงการอย่างเป็นทางการ'],
], ['', 'c', '']),
'## หมายเหตุการติดตามแผนงาน',
bullets([
'สถานะงานได้รับการปรับปรุงทุกงวดรายงานตาม Progress Status Record',
'งานที่ไม่แล้วเสร็จตามกำหนดต้องดำเนินการตามแผนสำรองใน Software Project Plan หัวข้อ 10',
'การเปลี่ยนแปลงแผนงานที่กระทบกำหนดส่งมอบต้องผ่าน Change Report',
]),
].join('\n\n'),
secretary: P.ApS, reviewer: P.YaB, approver: P.SeV,
}),
};
}
/** 2.2 Software Project Plan — sections 1–11 in the reference order. */
export function softwareProjectPlan() {
const date = '2026-02-13';
const sec = (n, title) => `## ${n} ${title}`;
return {
dir: '1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan',
name: `${CODE} Software Project Plan ${bud(date)} V1.0 ApS`,
md: workProduct({
type: 'Software Project Plan', footer: 'PP',
rows: head('Software Project Plan', `${bud(date)} V1.0 ApS`, [
['Title', 'แผนการดำเนินโครงการ'],
['Project Period', thRangeLong(START, END), 'Project Duration', `${DURATION} วัน`],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
]),
body: [
sec(1, 'Manufacture'),
`${COMPANY_TH} เป็นบริษัทผู้ประกอบธุรกิจด้านเทคโนโลยีสารสนเทศ ซึ่งมีประสบการณ์ในการส่งมอบผลิตภัณฑ์และบริการด้านเทคโนโลยีให้แก่หน่วยงานภาครัฐและเอกชนอย่างต่อเนื่อง บริษัทประกอบธุรกิจหลัก 3 ด้าน ได้แก่`,
bullets([
'พัฒนาซอฟต์แวร์ตามความต้องการของหน่วยงาน (Software Development)',
'จำหน่ายผลิตภัณฑ์ซอฟต์แวร์สำเร็จรูป (Software Package) เช่น ระบบบริหารจัดการสินทรัพย์',
'ให้บริการบำรุงรักษาระบบ (Service Maintenance: MA) ครอบคลุมโครงสร้างพื้นฐาน เครื่องแม่ข่าย และศูนย์ข้อมูล',
]),
sec(2, 'Overview'),
'เพื่อยกระดับการบริหารจัดการคลังสินค้าของบริษัทให้มีความถูกต้อง รวดเร็ว และตรวจสอบย้อนกลับได้ บริษัทมีความประสงค์จะพัฒนา ระบบบริหารจัดการคลังสินค้า (BRN WMS) ขึ้นใหม่ โดยมีวัตถุประสงค์เพื่อ',
bullets([
'รวมศูนย์ข้อมูลคลังสินค้า สินค้าคงคลัง และความเคลื่อนไหวของสินค้าไว้ในระบบเดียว',
'เชื่อมโยงงานขาย งานจัดซื้อ งานการเงิน และการบันทึกบัญชีเข้ากับความเคลื่อนไหวของสินค้า',
'ควบคุมสิทธิ์การเข้าถึงและแยกข้อมูลระหว่างบริษัทและคลังสินค้าอย่างชัดเจน',
'ให้ผู้บริหารเห็นภาพรวมสถานะคลังสินค้าและสถานะทางการเงินได้ตามเวลาจริง',
]),
sec(3, 'Goals and Scope'),
'### 3.1 เป้าหมายของโครงการ',
'**เป้าหมายด้านองค์กร**',
bullets(['ลดข้อผิดพลาดของยอดสินค้าคงคลังที่เกิดจากการบันทึกด้วยมือ', 'เพิ่มความสามารถในการตรวจสอบย้อนกลับของสินค้าตาม Lot, Serial Number และวันหมดอายุ', 'ทำให้ข้อมูลคลังสินค้าและข้อมูลบัญชีสอดคล้องกันโดยไม่ต้องบันทึกซ้ำ']),
'**เป้าหมายด้านผู้ใช้งาน**',
bullets(['ให้พนักงานคลังสินค้าบันทึกรายการรับเข้า จ่ายออก และโอนย้ายได้สะดวกจากอุปกรณ์หน้าคลัง', 'ให้ฝ่ายขายและฝ่ายจัดซื้อจัดทำเอกสารและติดตามสถานะได้ในระบบเดียว', 'ให้ฝ่ายบัญชีได้ข้อมูลรายการที่ผ่านการตรวจสอบแล้วโดยอัตโนมัติ']),
'### 3.2 ขอบเขตของโครงการ (SOW)',
table(['ลำดับ', 'ระบบ', 'ระบบย่อย'], SCOPE.map(([sys, subs], i) => [i + 1, sys, subs.join(' / ')]), ['c']),
'### 3.3 สิ่งส่งมอบ (Work Products)',
table(['รหัส', 'สิ่งส่งมอบ (Work Product)', 'รายละเอียด'], WPS),
'### 3.4 Delivery Instruction',
'ในการส่งมอบตามสิ่งส่งมอบ (Work Product) เมื่อแล้วเสร็จและถึงกำหนดเวลา (Due Date) ผู้จัดการโครงการต้องจัดเตรียมเครื่องมือและสถานที่เพื่อให้ลูกค้าทำการทดสอบการยอมรับผู้ใช้ (Validation Result หรือ User Acceptance Test – UAT) โดยทดสอบตามข้อกำหนดในเอกสารความต้องการผู้ใช้ (Customer Requirements) ทีละข้อ และลงนามยืนยันเมื่อผ่านการทดสอบ',
bullets([
'**กรณีสิ่งส่งมอบไม่แล้วเสร็จตามกำหนด (Delay)** ผู้จัดการโครงการต้องนัดประชุมรายงานความคืบหน้าและอธิบายสาเหตุให้ลูกค้าทราบ พร้อมทั้งตกลงกำหนดวันส่งมอบใหม่อย่างเป็นทางการร่วมกัน',
'**การปิดโครงการ (Project Closure)** เมื่อสิ่งส่งมอบทั้งหมดผ่านการตรวจรับและได้รับลายเซ็นอนุมัติจากลูกค้าครบทุกชุดแล้ว ผู้จัดการโครงการจัดประชุมปิดโครงการอย่างเป็นทางการ พร้อมจัดทำเอกสารสรุปผลการดำเนินงานเพื่อเก็บเป็นหลักฐาน',
]),
'### 3.5 เกณฑ์คุณภาพ (Quality Criteria)',
'**ด้านคุณภาพของระบบ**',
table(['ลำดับ', 'หัวข้อ', 'เกณฑ์คุณภาพ', 'วิธีประเมิน'], [
['1.1', 'ความถูกต้องของฟังก์ชัน', 'ฟังก์ชันทั้งหมดทำงานตรงตาม Customer Requirements ครบ 100%', 'ทดสอบตาม Test Case และ UAT'],
['1.2', 'ความถูกต้องของข้อมูลสต๊อกและบัญชี', 'ไม่พบยอดสต๊อกติดลบหรือรายการ GL ที่ไม่สมดุล', 'ทดสอบ Transaction และ Rollback (TC-UN08.002)'],
['1.3', 'ความปลอดภัยของระบบ', 'ไม่พบข้อบกพร่องระดับวิกฤตด้านสิทธิ์และการแยกข้อมูล', 'ทดสอบสิทธิ์เชิงลบ (TC-UN12.001, TC-UN12.002)'],
['1.4', 'ประสิทธิภาพการตอบสนอง', 'งานประจำวันตอบสนองภายในเวลาที่ใช้งานได้จริงบนสภาพแวดล้อมที่ตกลง', 'ทดสอบตามปริมาณข้อมูลตัวอย่าง (TC-UN09.001)'],
['1.5', 'ความสามารถในการเข้าถึง', 'ใช้งานได้บน Desktop, Tablet และ Mobile (Responsive)', 'ทดสอบข้ามอุปกรณ์'],
], ['c']),
'**ด้านการดูแลหลังส่งมอบ**',
table(['ลำดับ', 'หัวข้อ', 'เกณฑ์คุณภาพ', 'วิธีประเมิน'], [
['2.1', 'การตอบสนองเหตุขัดข้อง', 'ตอบรับภายใน 4 ชั่วโมง และแก้ไขตามระดับความรุนแรงที่กำหนดใน SLA', 'บันทึกการให้บริการ'],
['2.2', 'การสำรองข้อมูล', 'มีระบบสำรองข้อมูลอัตโนมัติรายวันและทดสอบกู้คืนได้จริง', 'Backup & Restore Test (TC-UN13.004)'],
['2.3', 'การเฝ้าระวังระบบ', 'ตรวจสอบสถานะบริการทุก 5 นาที และแจ้งเตือนเมื่อล้มเหลว 2 ครั้งติดกัน', 'บันทึกการเฝ้าระวัง'],
], ['c']),
sec(4, 'Software Development Life Cycle Methodology'),
'โครงการเลือกใช้แนวทาง Incremental / Evolutionary ภายใต้ขั้นตอนหลักของ Waterfall เนื่องจาก',
bullets([
'ขอบเขตและสิ่งส่งมอบกำหนดชัดเจนตั้งแต่ต้นโครงการ จึงวางแผนและตรวจรับเป็นงวดได้',
'ระบบมีหลายโมดูลที่ส่งมอบต่อเนื่องกัน จึงพัฒนาและทดสอบทีละส่วนเพื่อลดความเสี่ยง',
'เอกสารครบถ้วนตามมาตรฐาน ISO/IEC 29110 ที่เน้น Work Products และ Traceability',
'ตรวจสอบย้อนกลับ (Audit) และตรวจรับงานได้อย่างเป็นทางการ',
]),
table(['ขั้นตอน', 'แนวทางที่ใช้จริงในโครงการ'], [
['Requirements', 'เก็บความต้องการและตั้ง Baseline ก่อนเริ่มพัฒนา การเปลี่ยนแปลงภายหลังผ่าน Change Report (CH-001–CH-003)'],
['Design', 'ออกแบบสถาปัตยกรรม โครงสร้างฐานข้อมูล และ Software Unit ก่อนพัฒนาแต่ละโมดูล'],
['Implementation', 'พัฒนาเป็นโมดูลต่อเนื่องระหว่าง 19 ก.พ. – 29 พ.ค. 69 พร้อมทบทวนและแก้ไขระหว่างทาง'],
['Verification', 'ตรวจสอบ Work Products 4 รอบ ควบคู่กับการพัฒนา และรอบสุดท้ายก่อนส่งมอบ'],
['Validation', 'ทดสอบระบบและ UAT ระหว่าง 10–14 ส.ค. 69 บนสภาพแวดล้อมที่กำหนด'],
['Closure', 'ตรวจรับ อบรม ปิดงานควบคุมปฏิบัติการ และปิดโครงการภายใน 24 ส.ค. 69'],
]),
sec(5, 'Organization'),
'### 5.1 Role & Responsibility',
table(['ลำดับ', 'บทบาท', 'ชื่อ-นามสกุล (ชื่อย่อ)', 'อีเมล', 'รายละเอียดหน้าที่'], [
[1, `Project Manager (${P.ApS.id})`, P.ApS.th, P.ApS.email, 'จัดทำ Project Charter และแผนโครงการ / วางแผน Timeline, Resource, Risk, Quality / จัดประชุมและติดตามความคืบหน้า / ควบคุมการเปลี่ยนแปลงและการปิดโครงการ'],
[2, `System Analyst (${P.NoC.id})`, P.NoC.th, P.NoC.email, 'เก็บและวิเคราะห์ความต้องการ / จัดทำ SRS และเอกสารออกแบบระบบ / ออกแบบฐานข้อมูลและความสัมพันธ์ของโมดูล / ตรวจสอบความสอดคล้องของงานพัฒนากับความต้องการ'],
[3, `Developer (${P.ThS.id})`, P.ThS.th, P.ThS.email, 'พัฒนาโมดูลและ API ตามการออกแบบ / จัดการฐานข้อมูลและประสิทธิภาพ / ดูแลความปลอดภัยและการติดตั้ง / แก้ไขข้อบกพร่องที่พบจากการทดสอบ'],
[4, `QA / Tester (${P.PaNg.id})`, P.PaNg.th, P.PaNg.email, 'จัดทำ Test Case และ Test Procedures / ทดสอบระบบและบันทึกผล / ติดตามการแก้ไขข้อบกพร่องและทดสอบซ้ำ / สนับสนุนผู้ใช้งานช่วง UAT'],
[5, `Document Control (${P.YaB.id})`, P.YaB.th, P.YaB.email, 'ควบคุมรหัสเอกสารและเวอร์ชัน / จัดเก็บและตรวจสอบความครบถ้วนของเอกสาร / ประสานการทบทวนและอนุมัติ / บันทึกประวัติการเปลี่ยนแปลงเอกสาร'],
[6, `Project Sponsor (${P.SeV.id})`, P.SeV.th, P.SeV.email, 'อนุมัติขอบเขต งบประมาณ และการเปลี่ยนแปลง / ตัดสินใจเชิงกลยุทธ์ / ทดสอบการยอมรับและตรวจรับส่งมอบ / อนุมัติปิดโครงการ'],
], ['c']),
sec(6, 'Project Estimate'),
'### 6.1 Size of the Software Work Products',
table(['ลำดับ', 'Work Product', 'ปริมาณ (ประมาณการ)'], [
[1, 'เอกสารบริหารโครงการ (PM Process)', '10 รายการ'],
[2, 'เอกสารกระบวนการพัฒนา (SI Process)', '12 รายการ'],
[3, 'ความต้องการลูกค้า (Customer Requirements)', `${CRS.length} รายการ (CR01–CR14)`],
[4, 'ความต้องการซอฟต์แวร์ (SRS)', '49 รายการ (SR01–SR09)'],
[5, 'Software Unit', '45 หน่วย (UN01–UN13)'],
[6, 'Test Case', '45 รายการ'],
[7, 'ตารางฐานข้อมูล', 'ประมาณ 50 ตาราง ใน 2 ฐานข้อมูล'],
], ['c']),
'### 6.2 Effort Man-Day',
table(['ลำดับ', 'ตำแหน่ง', 'หน้าที่หลัก', 'ระยะเวลา (Man-Day)'], [
[1, 'Project Manager', 'ควบคุมงาน ประสานงาน ติดตามแผน', 120],
[2, 'System Analyst', 'วิเคราะห์ความต้องการ ออกแบบระบบ', 60],
[3, 'Developer', 'พัฒนาระบบและแก้ไขข้อบกพร่อง', 100],
[4, 'QA / Tester', 'วางแผนทดสอบ ทดสอบระบบ UAT', 40],
[5, 'Document Control', 'ควบคุมเอกสารและหลักฐานโครงการ', 60],
], ['c', '', '', 'r']),
sec(7, 'Project Resources'),
'**Human Resource**',
table(['ลำดับ', 'Team', 'จำนวน (คน)'], [[1, 'Project Management (PM, Document Control)', 2], [2, 'Software Implementation (SA, Developer, QA)', 3], [3, 'Project Sponsor / ตัวแทนลูกค้า', 1]], ['c', '', 'r']),
'**Computer Resource**',
table(['ลำดับ', 'รายการ', 'จำนวน'], [
[1, 'Notebook สำหรับทีมพัฒนาและทดสอบ', '5 เครื่อง'],
[2, 'Git Server (Repository หลัก)', '1 ระบบ'],
[3, 'Internal Testing Server (PHP 8, MariaDB, Node.js)', '1 เครื่อง'],
[4, 'Production Server สำหรับใช้งานจริง', '1 เครื่อง'],
[5, 'เครื่องอ่านบาร์โค้ดสำหรับทดสอบ', '1 เครื่อง'],
], ['c']),
sec(8, 'Work Schedule'),
`แผนการดำเนินงานของโครงการ รวม ${DURATION} วัน ตั้งแต่ ${thLong(START)} ถึง ${thLong(END)} รายละเอียดกิจกรรม ผู้รับผิดชอบ และสิ่งส่งมอบรายกิจกรรม อยู่ในเอกสาร ${CODE} Work Schedule ซึ่งเป็นส่วนหนึ่งของ Project Plan`,
table(['Phase', 'ช่วงเวลา', 'ผลลัพธ์หลัก'], [
['Project Initiation', thRangeLong(START, '2026-01-23'), 'Statement of Work, Stakeholder Register, Project Charter'],
['Project Planning', thRangeLong('2026-01-12', '2026-02-18'), 'Customer Requirements, Software Project Plan, Work Schedule'],
['Project Execution', thRangeLong(DEV_START, '2026-05-29'), 'SRS, Software Design, ระบบที่พัฒนาแล้ว, Software Components'],
['Verification & Validation', thRangeLong('2026-05-30', '2026-08-17'), 'Test Case, Test Report, Verification Results, Validation Results'],
['Project Close', thRangeLong('2026-08-10', END), 'Acceptance Report, Training Report, List of Evidence'],
]),
sec(9, 'Risk Management Plan'),
'วัตถุประสงค์ของแผนบริหารความเสี่ยง คือระบุแนวทางจัดการความเสี่ยงของโครงการ เพื่อให้โครงการบรรลุเป้าหมายภายในเวลา งบประมาณ และคุณภาพที่กำหนด',
table(['ลำดับ', 'หมวด', 'รายการ', 'รายละเอียด'], [
[1, 'ขอบเขต', 'ครอบคลุมทุกกิจกรรมของโครงการ', 'ตั้งแต่ Initiation, Planning, Execution จนถึง Close'],
[2, 'บทบาทผู้รับผิดชอบ', 'Project Manager (Owner), ทีมพัฒนา, Project Sponsor', 'PM ติดตามและควบคุมความเสี่ยง ทีมพัฒนารายงานความเสี่ยงให้ PM'],
[3, 'รอบการทบทวน', 'ทบทวนทุกงวดรายงานความก้าวหน้า', 'บันทึกความเสี่ยงใหม่และการเปลี่ยนแปลงระดับความเสี่ยงใน Progress Status Record'],
], ['c']),
'**ตารางระบุความเสี่ยงหลักของโครงการ**',
table(['ลำดับ', 'ความเสี่ยง (Risk)', 'ประเภท', 'โอกาสเกิด', 'ผลกระทบ', 'ระดับความเสี่ยง', 'แนวทางป้องกัน (Mitigation)', 'แผนรับมือ (Contingency Plan)', 'ผู้รับผิดชอบ'], [
['R1', 'ความต้องการเปลี่ยนแปลงระหว่างพัฒนา', 'กระบวนการ', 'High', 'High', 'High', 'ตั้ง Baseline ความต้องการและทบทวนทุกงวด', 'จัดทำ Change Report และจัดลำดับความสำคัญใหม่', `${P.ApS.id} / ${P.NoC.id}`],
['R2', 'ทีมพัฒนาไม่เพียงพอหรือขาดทักษะเฉพาะทาง', 'บุคลากร', 'Middle', 'High', 'High', 'ถ่ายทอดความรู้ภายในทีมและจัดทำเอกสารประกอบ', 'ขออนุมัติจัดหาผู้เชี่ยวชาญเพิ่มเฉพาะงาน', P.ApS.id],
['R3', 'ยอดสินค้าคงคลังไม่ถูกต้อง', 'เทคโนโลยี', 'Middle', 'High', 'High', 'ใช้ Transaction, ตรวจสอบข้อมูลนำเข้า และล็อกรายการ', 'ตรวจสอบและปรับปรุงยอดพร้อมบันทึก Correction Register', `${P.ThS.id} / ${P.PaNg.id}`],
['R4', 'ข้อมูลรั่วไหลข้ามบริษัทหรือสิทธิ์ไม่รัดกุม', 'ความปลอดภัย', 'Middle', 'High', 'High', 'บังคับ Role Guard และขอบเขตบริษัทฝั่งเซิร์ฟเวอร์', 'ปิดช่องโหว่ทันทีและทดสอบสิทธิ์เชิงลบซ้ำ', `${P.ThS.id} / ${P.PaNg.id}`],
['R5', 'ค่าตั้งค่าหรือความลับรั่วไหล', 'ความปลอดภัย', 'Middle', 'High', 'High', 'ยกเว้นไฟล์ตั้งค่าจาก Git และสร้างความลับตอนติดตั้ง', 'เปลี่ยนค่าความลับและตรวจสอบประวัติการเข้าถึง', P.ThS.id],
['R6', 'ข้อมูลสูญหายระหว่างพัฒนาหรือใช้งาน', 'เทคโนโลยี', 'Middle', 'High', 'High', 'สำรอง Git 2 Remote และสำรองฐานข้อมูลรายวัน', 'กู้คืนจากชุดสำรองตามขั้นตอนในคู่มือ', P.ThS.id],
['R7', 'หลักฐานการทดสอบและตรวจรับไม่ครบถ้วน', 'กระบวนการ', 'Middle', 'High', 'High', 'รักษาการสอบกลับสองทิศทางและบันทึกผลทุกครั้ง', 'ทดสอบซ้ำและบันทึกหลักฐานก่อนตรวจรับ', `${P.PaNg.id} / ${P.YaB.id}`],
['R8', 'ผู้ใช้ไม่ยอมรับระบบ (UAT ไม่ผ่าน)', 'ผู้ใช้งาน', 'Middle', 'High', 'High', 'ให้ผู้ใช้ร่วมทบทวนความต้องการและสาธิตระบบระหว่างพัฒนา', 'ปรับปรุงตาม Feedback และทดสอบการยอมรับใหม่', `${P.ApS.id} / ${P.SeV.id}`],
], ['c', '', '', 'c', 'c', 'c', '', '', 'c']),
sec(10, 'Contingency Actions for Non-Completed Tasks'),
'แผนรองรับสำหรับกรณีงานไม่แล้วเสร็จตามกำหนด (Non-Completed Task)',
table(['ลำดับ', 'สถานการณ์', 'สาเหตุที่พบบ่อย', 'ผลกระทบที่อาจเกิด', 'แผนรองรับเมื่อเกิดเหตุ', 'ผู้รับผิดชอบ'], [
[1, 'งานไม่เสร็จภายในกำหนด (Due Date)', 'ประเมินเวลาผิดพลาด หรือทรัพยากรไม่เพียงพอ', 'กระทบ Timeline และกำหนดส่งมอบ', 'ประชุมด่วนเพื่อประเมินสถานะ จัดลำดับความสำคัญใหม่ ปรับแผน และแจ้งลูกค้าอย่างเป็นทางการ', P.ApS.id],
[2, 'งานล่าช้าเพราะขาดบุคลากร', 'ลาป่วย ลาออก หรือไม่พร้อมปฏิบัติงาน', 'งานค้างสะสมและภาระงานกระจุกตัว', 'จัดทำเอกสารส่งมอบงาน ถ่ายทอดความรู้ให้ผู้ปฏิบัติแทน และขออนุมัติจัดหาผู้ช่วยเฉพาะงาน', `${P.ApS.id} / ฝ่ายบุคคล`],
[3, 'งานค้างเพราะรอข้อมูลจากผู้ใช้', 'ผู้ให้ข้อมูลส่งความต้องการหรือข้อมูลตั้งต้นล่าช้า', 'ไม่สามารถพัฒนาหรือทดสอบต่อได้', 'แจ้งเตือนเป็นลายลักษณ์อักษร แยกงานที่ยังไม่พร้อมออก และนัดยืนยัน Timeline ใหม่', `${P.ApS.id} / ${P.SeV.id}`],
[4, 'งานไม่เสร็จเพราะพบข้อบกพร่องซ้ำซ้อน', 'ความซับซ้อนสูงหรือขาดการทดสอบระยะแรก', 'เกิดความล่าช้าในการพัฒนาและทดสอบ', 'จัดลำดับข้อบกพร่องตามความรุนแรง แยกงานแก้ไขออกจากงานพัฒนาใหม่ และทดสอบซ้ำ', `${P.ThS.id} / ${P.PaNg.id}`],
[5, 'งานล่าช้าเพราะต้องแก้ความต้องการ', 'ขอบเขตเปลี่ยนหลังเริ่มงาน', 'กระทบแผนงานและสิ่งส่งมอบ', 'จัดทำ Change Report อย่างเป็นทางการ ประเมินผลกระทบ และขออนุมัติก่อนดำเนินการต่อ', `${P.ApS.id} / ${P.SeV.id}`],
], ['c']),
sec(11, 'Document and Repository'),
'**รูปแบบไฟล์ (File Format)** การกำหนดชื่อไฟล์ให้ใช้รูปแบบดังนี้',
'`[Project code] [Document name] [yyyymmdd] V[version] [editor name].[ext.]`',
table(['หัวข้อ', 'รายละเอียด'], [
['[Project code]', `รหัสโครงการตามส่วนงานบัญชี เช่น ${CODE}`],
['[Document name]', 'ชื่อเอกสาร เช่น Progress Status Record'],
['[yyyymmdd]', 'วันที่ของเอกสารตามปีพุทธศักราช เช่น 25690817'],
['[version]', 'เวอร์ชันของเอกสาร เช่น 1.0'],
['[editor name]', 'ตัวย่อของชื่อผู้จัดทำ เช่น ApS'],
['[ext.]', 'นามสกุลไฟล์ เช่น pdf'],
]),
'**การประกาศเวอร์ชัน (Version Declaration)** เก็บเอกสารแต่ละเวอร์ชันแยกไฟล์เพื่อให้ตรวจสอบย้อนหลังได้ โดยใช้รูปแบบ Major.Minor',
table(['เวอร์ชัน (Version)', 'รายละเอียด'], [
['0.1 (Draft)', 'ร่างเอกสารฉบับแรก'],
['0.2 (Draft)', 'ปรับปรุงตามผลการทบทวน'],
['1.0 (Release)', 'อนุมัติใช้เป็นเอกสารทางการ'],
['1.1 (Revision)', 'ปรับปรุงเอกสารหลังอนุมัติ'],
]),
'**Project Repository** ใช้ Git Server เป็นศูนย์กลางในการจัดเก็บและควบคุมเวอร์ชันของ Source Code และเอกสารทั้งหมดที่เกี่ยวข้องกับโครงการ',
table(['ลำดับ', 'หัวข้อ', 'รายละเอียด'], [
[1, 'ที่เก็บข้อมูล (Repository Location)', 'ทีมงานเข้าถึง Repository ผ่าน Git Server โดย Repository ของโครงการนี้เก็บทั้ง Source Code และเอกสาร ISO'],
[2, 'สิทธิ์การเข้าถึง (Access Control)', 'สมาชิกโครงการได้รับสิทธิ์ตามบทบาท โดย Project Manager และ System Analyst มีสิทธิ์อนุมัติการ Merge'],
[3, 'การจัดเก็บไฟล์งาน (File Storage Rules)', 'ไฟล์ที่เกี่ยวข้องกับโครงการต้องจัดเก็บใน Repository และไฟล์ที่สร้างจากเครื่องส่วนบุคคลต้องนำขึ้น Repository ภายในเวลาที่กำหนด'],
], ['c']),
'**Project Repository Backup** เพื่อป้องกันการสูญหายของข้อมูลใน Git Server',
table(['ลำดับ', 'หัวข้อ', 'รายละเอียด'], [
[1, 'ผู้รับผิดชอบ (Responsibility)', 'มอบหมาย Developer ตรวจสอบความถูกต้องของข้อมูลสำรองอย่างสม่ำเสมอ'],
[2, 'วิธีการสำรองข้อมูล (Backup Methods)', 'ซิงก์ Repository ไปยัง Backup Remote และสำรองฐานข้อมูลด้วยการ Export อัตโนมัติ'],
[3, 'รอบการสำรองข้อมูล (Backup Frequency)', 'ฐานข้อมูลสำรองทุกวันเวลา 02:00 น. และ Repository ซิงก์ทุกครั้งที่มีการส่งมอบ'],
], ['c']),
].join('\n\n'),
secretary: P.ApS, reviewer: P.YaB, approver: P.SeV,
}),
};
}
/** 2.3 Customer Requirements — CR01–CR14 in the reference table layout. */
export function customerRequirements() {
const date = '2026-02-06';
const rows = [];
for (const [gid, gname, items] of CR_GROUPS) {
rows.push([`${gid}: ${gname}`, '', '', '']);
for (const [id, text, remark] of items) rows.push([id, text, 'A', remark]);
}
return {
dir: '1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement',
name: `${CODE} Customer Requirements ${bud(date)} V1.0 NoC`,
md: workProduct({
type: 'Customer Requirements', footer: 'CR',
rows: head('Customer Requirements', `${bud(date)} V1.0 NoC`, [
['Title', 'เอกสารบันทึกและสรุปความต้องการของลูกค้า (Customer Requirements)'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
]),
body: [
'## วัตถุประสงค์ (Objective)',
`เอกสารฉบับนี้จัดทำขึ้นเพื่อบันทึกและสรุปความต้องการของลูกค้า (Customer Requirements) ตามกระบวนการ ISO/IEC 29110 สำหรับใช้เป็นพื้นฐานในการจัดทำ Software Requirements Specification, การออกแบบระบบ, การทดสอบ และการตรวจรับ ของ${PROJECT_TH}`,
'## ผู้มีส่วนได้ส่วนเสีย (Stakeholders)',
table(['ลำดับ', 'ชื่อ', 'ตำแหน่ง', 'บทบาท'], [
[1, P.SeV.th, 'ผู้บริหาร (CEO)', 'Project Sponsor อนุมัติและตัดสินใจเชิงกลยุทธ์'],
[2, P.ApS.th, 'ผู้จัดการโครงการ', 'บริหารโครงการและควบคุมการเปลี่ยนแปลง'],
[3, P.NoC.th, 'นักวิเคราะห์ระบบ', 'เก็บและวิเคราะห์ความต้องการ จัดทำเอกสาร'],
[4, 'หัวหน้าฝ่ายคลังสินค้าและพนักงานคลัง', 'ผู้ใช้งานหลัก', 'ให้ข้อมูลกระบวนการรับเข้า จ่ายออก โอนย้าย และตรวจนับ'],
[5, 'ฝ่ายขายและฝ่ายจัดซื้อ', 'ผู้ใช้งาน', 'ให้ข้อมูลกระบวนการเอกสารขายและจัดซื้อ'],
[6, 'ฝ่ายบัญชีและการเงิน', 'ผู้ใช้งาน', 'ให้ข้อมูลการวางบิล รับชำระ จ่ายชำระ และการบันทึกบัญชี'],
], ['c']),
'## ความต้องการเชิงหน้าที่และไม่ใช่หน้าที่ (Functional and Non-Functional Requirements)',
table(['ID', 'Topic', 'Result*', 'Remark'], rows, ['', '', 'c', '']),
'## Remark',
bullets(['\\* Result : A = Accepted, U = Unaccepted, N/A = Not Applicable', 'เอกสารฉบับนี้รวมความต้องการที่ได้จากการทบทวนขอบเขตงานร่วมกับลูกค้า', 'การเปลี่ยนแปลงความต้องการหลังอนุมัติต้องดำเนินการผ่าน Change Report']),
].join('\n\n'),
secretary: P.NoC, reviewer: P.YaB, approver: P.SeV,
}),
};
}