Files
wms-app/scripts/sdlc-seed/docs-si.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

376 lines
33 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.
// SI work products 11–22.
import { P, CODE, PROJECT_TH, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, SCOPE, CRS, crTopic, TEST_FROM, TEST_TO, ACCEPT_DATE, BASELINE_COMMIT, TEST_STATE_COMMIT, ORIGIN, BACKUP, TAG } from './project.mjs';
import { SR_GROUPS, SRS, srTopic, UNIT_GROUPS, UNITS, unitTopic, unitModule, TEST_CASES, traceOf } from './engineering.mjs';
import { CORRECTIONS } from './history.mjs';
import { bud, thLong, thShort, thRangeLong, table, bullets, numbered } from './lib.mjs';
import { workProduct, head } from './format.mjs';
const D = '2026-08-17';
/** 11. Software Requirements Specification. */
export function softwareRequirements() {
const date = '2026-02-25';
const rows = [];
for (const [gid, gname, items] of SR_GROUPS) {
rows.push([`${gid}: ${gname}`, '', '', '']);
for (const [id, text, refs] of items) rows.push([id, text, 'A', refs]);
}
return {
dir: '2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)',
name: `${CODE} Software Requirements ${bud(date)} V1.0 NoC`,
md: workProduct({
type: 'Software Requirements', footer: 'SRS',
rows: head('Software Requirements', `${bud(date)} V1.0 NoC`, [
['Title', 'เอกสารบันทึกและสรุปความต้องการซอฟต์แวร์ (Software Requirements Specification)'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
]),
body: [
'## วัตถุประสงค์ (Objectives)',
'เพื่อแปลงความต้องการของลูกค้าที่ได้รับอนุมัติแล้วให้เป็นความต้องการเชิงเทคนิคของซอฟต์แวร์ ครอบคลุมมาตรฐาน โครงสร้าง ส่วนประกอบ ความสัมพันธ์ ประสิทธิภาพ ส่วนเชื่อมต่อ ความปลอดภัย ฐานข้อมูล และการจัดการข้อผิดพลาด เพื่อใช้เป็นเอกสารอ้างอิงหลักในการออกแบบระบบ พัฒนา และทดสอบ',
'## ผู้มีส่วนได้ส่วนเสีย (Stakeholders)',
table(['ลำดับ', 'ชื่อ', 'หน่วยงาน/ตำแหน่ง', 'บทบาท'], [
[1, P.SeV.th, 'ผู้บริหาร (CEO)', 'Project Sponsor อนุมัติความต้องการ'],
[2, P.ApS.th, 'ผู้จัดการโครงการ', 'บริหารจัดการโครงการ'],
[3, P.NoC.th, 'นักวิเคราะห์ระบบ', 'จัดทำและควบคุมความต้องการซอฟต์แวร์'],
[4, P.ThS.th, 'นักพัฒนาระบบ', 'พัฒนาระบบตามความต้องการ'],
[5, P.PaNg.th, 'ผู้ทดสอบระบบ', 'จัดทำ Test Case จากความต้องการ'],
], ['c']),
'## ความต้องการซอฟต์แวร์ (Software Requirements)',
table(['ID', 'Topic', 'Result*', 'Remark'], rows, ['', '', 'c', '']),
'## Remark',
bullets([
'\\* Result : A = Accepted, U = Unaccepted, N/A = Not Applicable',
'ช่อง Remark แสดงรหัสความต้องการของลูกค้า (Customer Requirements) ที่เป็นที่มาของความต้องการซอฟต์แวร์แต่ละรายการ',
'ความต้องการซอฟต์แวร์ที่ไม่มีที่มาจากความต้องการของลูกค้าต้องผ่าน Change Report ก่อนถือเป็นข้อผูกพัน',
]),
].join('\n\n'),
secretary: P.NoC, reviewer: P.YaB, approver: P.SeV,
}),
};
}
/** 12. Software Design — high level design, software baseline, and software units. */
export function softwareDesign() {
const date = '2026-03-06';
const unitRows = [];
for (const [mid, mname, items] of UNIT_GROUPS) {
unitRows.push([`${mid} — ${mname}`, '', '', '', '']);
for (const [id, desc, detail, refs, files] of items) unitRows.push([id, desc, detail, refs, files]);
}
return {
dir: '2-SI Process (12 Work Product)/12.Software design',
name: `${CODE} Software Design ${bud(date)} V1.0 NoC`,
md: workProduct({
type: 'Software Design', footer: 'SD',
rows: head('Software Design', `${bud(date)} V1.0 NoC`, [
['Title', 'เอกสารการออกแบบระบบ (System Design Document)'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
]),
body: [
'## HIGH LEVEL DESIGN',
'### Use Case Diagram',
'ผู้ใช้งานของระบบและกลุ่มการใช้งานหลัก',
table(['Actor', 'คำอธิบาย', 'การใช้งานหลัก'], [
['Owner', 'เจ้าของบริษัท สิทธิ์สูงสุดภายในบริษัท', 'ตั้งค่าบริษัท จัดการผู้ใช้ และใช้งานทุกโมดูล'],
['Admin', 'ผู้ดูแลระบบภายในบริษัท', 'จัดการข้อมูลหลัก ผู้ใช้ สิทธิ์ และใช้งานทุกโมดูลปฏิบัติการ'],
['Staff', 'ผู้ปฏิบัติงาน', 'บันทึกรายการคลังสินค้า ขาย จัดซื้อ และการเงินตามสิทธิ์'],
['Viewer', 'ผู้ใช้แบบอ่านอย่างเดียว', 'ดูหน้าจอและรายงานที่ได้รับสิทธิ์'],
['System Scheduler', 'ผู้กระทำอัตโนมัติ (Node.js)', 'สรุปยอดสต๊อก/GL และแจ้งเตือนตามกำหนดเวลา'],
['SMTP Service', 'ผู้กระทำภายนอก', 'ส่งอีเมล Onboarding กู้คืนรหัสผ่าน และแจ้งเตือน'],
]),
'### Component Diagram',
'โครงสร้างส่วนประกอบของระบบแบ่งตามชั้นการทำงาน',
table(['ชั้น (Layer)', 'ส่วนประกอบ', 'อ้างอิง SR'], [
['Presentation', 'หน้าจอ PHP ในแต่ละโมดูล (`app/<module>/`), JavaScript และ CSS ที่รองรับ Responsive', 'SR02:002, SR06:002, SR06:003'],
['Business Logic', 'Manager/Service Classes ใน `app/assets/utils/classes/` เรียกใช้จาก Page Controller', 'SR02:003, SR03:001–SR03:011'],
['Data Access', 'Manager Classes เข้าถึงฐานข้อมูล MariaDB โดยตรง พร้อม Trait รวมตรรกะที่ใช้ร่วมกัน', 'SR02:004, SR06:001, SR08:001–SR08:005'],
['Real-time / Scheduler', 'บริการ Node.js (`server.js`, `scheduler.js`) ควบคุมด้วย pm2', 'SR03:011, SR06:004, SR06:005'],
['External', 'บริการ SMTP สำหรับส่งอีเมล และ Socket.IO Client บน Browser', 'SR06:004, SR06:005'],
]),
'### Deployment Diagram',
'การติดตั้งระบบแบ่งเป็น 4 ชั้นบริการ',
table(['ชั้นการติดตั้ง (Tier)', 'ส่วนประกอบ', 'อ้างอิง SR'], [
['Client', 'Web Browser (Chrome/Edge/Firefox) บน Desktop, Tablet และ Mobile พร้อม Socket.IO Client', 'SR06:002, SR06:003, SR06:005'],
['Web Tier', 'PHP 8 บน Apache ติดตั้งแบบ Manual หรือ Container `docker/php`', 'SR01:003, SR02:005'],
['Data Tier', 'MariaDB ฐานข้อมูล `wms` (ผู้ใช้/บริษัท) และ `wms2` (คลัง/บัญชี)', 'SR06:001, SR08:001–SR08:004'],
['Service Tier', 'Node.js `server.js` และ `scheduler.js` ควบคุมด้วย pm2', 'SR03:011, SR06:004'],
]),
'### User Interface Design',
'ผังหน้าจอหลักของระบบแบ่งตามโมดูลการใช้งาน',
table(['กลุ่มหน้าจอ', 'หน้าจอ'], [
['Login & Onboarding', 'เข้าสู่ระบบ / ลงทะเบียนบริษัท / รับคำเชิญเข้าร่วมบริษัท / ลืมรหัสผ่าน / ยืนยัน OTP'],
['Dashboard', 'แดชบอร์ดคลังสินค้า / แดชบอร์ดบัญชีและการเงิน'],
['Master Data', 'คลังสินค้า / พื้นที่จัดเก็บ / ช่องจัดเก็บ / หมวดสินค้า / สินค้า / ประเภทผู้ติดต่อ / ผู้ติดต่อ'],
['Inventory Control', 'รับสินค้าเข้า / จ่ายสินค้าออก / โอนย้ายสินค้า / ยอดคงเหลือ / Lot & Serial / พิมพ์บาร์โค้ด'],
['Sales', 'ใบเสนอราคา / ใบสั่งขาย / ใบแจ้งหนี้ / ใบรับคืนและใบลดหนี้'],
['Purchasing', 'ใบขอซื้อ / ใบสั่งซื้อ / ใบแจ้งหนี้ซื้อ / ใบคืนสินค้าผู้ขาย'],
['Finance', 'ใบวางบิลรับ / ใบเสร็จรับเงิน / ใบวางบิลจ่าย / ใบสำคัญจ่าย'],
['Accounting', 'ผังบัญชี / แผนก / สูตรบัญชี / สมุดรายวัน / บัญชีแยกประเภท'],
['Reports', 'รายงานสต๊อก / ความเคลื่อนไหว / ความจุคลัง / สินค้าใกล้หมด / สินค้าหมดอายุ / รายงานการเงิน'],
['Settings', 'ข้อมูลบริษัท / SMTP / ผู้ใช้งานและสิทธิ์ / การตั้งค่าระบบ'],
]),
'## Software Baseline',
'หัวข้อนี้ระบุสิ่งที่ถูกกำหนดเป็น Baseline ของซอฟต์แวร์ วันที่กำหนด และผู้อนุมัติ เพื่อให้ตรวจสอบเส้นทาง Baseline → Configuration → Change ได้ในเอกสารชุดเดียวกัน',
table(['รายการที่กำหนดเป็น Baseline', 'ค่าที่ควบคุม', 'ที่จัดเก็บ'], [
['Source Code ของแอปพลิเคชัน', `Git commit \`${BASELINE_COMMIT}\` บน branch \`main\``, `Repository หลัก \`${ORIGIN}\``],
['โครงสร้างฐานข้อมูล', 'Schema ที่สร้างโดย `setup.php` และ `docker/mariadb/init-wms2.sql`', 'ควบคุมใน Repository เดียวกัน'],
['ค่าตั้งค่าและชุดติดตั้ง', '`docker-compose.yml`, `docker/`, `.env.example` (ไม่รวมค่าความลับ)', 'ควบคุมใน Repository เดียวกัน'],
['เอกสาร Work Products', `Branch \`sdlc\` และ Tag \`${TAG}\``, `Repository หลักและ Remote สำรอง \`${BACKUP}\``],
]),
table(['หัวข้อ', 'รายละเอียด'], [
['วันที่กำหนด Baseline', `${thLong('2026-08-17')} (Baseline ของระบบที่ส่งมอบ)`],
['ผู้จัดทำ Baseline', `${P.ThS.th} (Developer)`],
['ผู้ตรวจสอบ', `${P.NoC.th} (System Analyst) และ ${P.PaNg.th} (QA/Tester)`],
['ผู้อนุมัติ', `${P.SeV.th} (Project Sponsor) พร้อมการตรวจรับเมื่อ ${thLong(ACCEPT_DATE)}`],
['เอกสารควบคุมที่เกี่ยวข้อง', 'Software Configuration (WP 8) ระบุรายการ Configuration Item และการควบคุมเวอร์ชัน'],
['การสอบกลับ', 'Traceability Record (WP 13) เชื่อมโยงความต้องการกับ Software Unit และ Test Case บน Baseline นี้'],
['การเปลี่ยนแปลง Baseline', 'ต้องผ่าน Change Report (CH-001–CH-003) และบันทึกผลใน Correction Register เมื่อเป็นการแก้ไขข้อบกพร่อง'],
]),
'## Software Unit',
table(['ID', 'Description', 'Functional Interfaces Detail', 'References', 'Files'], unitRows),
].join('\n\n'),
secretary: P.NoC, reviewer: P.YaB, approver: P.SeV,
}),
};
}
/** 13. Traceability Record. */
export function traceabilityRecord() {
const date = '2026-03-06';
const rows = [];
let group = '';
for (const [id, text, remark] of CRS) {
const g = id.slice(0, 4);
if (g !== group) { group = g; const name = SCOPEGROUP(g); rows.push([`${g}: ${name}`, '', '', '', '', '', '']); }
const t = traceOf(id);
rows.push([id, text, t.sr.join(', '), t.sr.map(srTopic).join(' / '), t.un.join(', '), t.un.map(unitTopic).join(' / '), t.tc]);
}
return {
dir: '2-SI Process (12 Work Product)/13.Traceability record',
name: `${CODE} Traceability Record ${bud(date)} V1.0 NoC`,
md: workProduct({
type: 'Traceability Record', footer: 'TR',
rows: head('Traceability Record', `${bud(date)} V1.0 NoC`, [
['Title', 'เอกสารบันทึกการสอบกลับได้ของระบบ (Traceability Matrix)'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
]),
body: [
'## วัตถุประสงค์ (Objective)',
'เอกสารที่เชื่อมโยงทุกขั้นตอนของโครงการ ตั้งแต่ความต้องการของลูกค้า → ความต้องการซอฟต์แวร์ → การออกแบบ → การทดสอบ เพื่อยืนยันความครบถ้วนของ Customer Requirements และลดความเสี่ยงของข้อบกพร่องและความต้องการที่ตกหล่น',
'## Traceability Matrix',
table(['CR ID', 'CR Topic', 'SRS ID', 'SRS Topic', 'Unit ID', 'Unit Topic', 'Test Case ID'], rows),
'## สรุปความครอบคลุม',
table(['รายการ', 'จำนวน'], [
['ความต้องการของลูกค้าทั้งหมด (CR01–CR14)', CRS.length],
['เชื่อมโยงกับความต้องการซอฟต์แวร์ (SRS)', CRS.length],
['เชื่อมโยงกับ Software Unit', CRS.length],
['เชื่อมโยงกับ Test Case', CRS.length],
['ความต้องการซอฟต์แวร์ทั้งหมด (SR01–SR09)', SRS.length],
['Software Unit ทั้งหมด', UNITS.length],
['Test Case ทั้งหมด', TEST_CASES.length],
], ['', 'r']),
`ความต้องการทุกรายการมีเส้นทางการสอบกลับที่ครบถ้วนตั้งแต่ความต้องการของลูกค้าจนถึง Test Case และผลการทดสอบ โดยผลการทดสอบทั้งหมดผ่านในรอบทดสอบระหว่าง ${thRangeLong(TEST_FROM, TEST_TO)}`,
].join('\n\n'),
secretary: P.NoC, reviewer: P.YaB, approver: P.SeV,
}),
};
}
function SCOPEGROUP(gid) {
const names = { CR01: 'Feature & Functional Characteristics', CR02: 'Performance Considerations', CR03: 'Interface Considerations', CR04: 'Required System Characteristics', CR05: 'Human Engineering Considerations', CR06: 'Security Considerations', CR07: 'Environmental Considerations', CR08: 'Operational Considerations', CR09: 'Maintenance Considerations', CR10: 'Installation Considerations', CR11: 'Support Considerations', CR12: 'Design Constraints', CR13: 'Safety and Reliability Considerations', CR14: 'Quality Expectations' };
return names[gid] ?? '';
}
/** 14. Software Components. */
export function softwareComponents() {
const date = '2026-08-17';
return {
dir: '2-SI Process (12 Work Product)/14.Software Components',
name: `${CODE} Software Components ${bud(date)} V1.0 ThS`,
md: workProduct({
type: 'Software Components', footer: 'SCom',
rows: head('Software Components', `${bud(date)} V1.0 ThS`, [
['Title', 'เอกสารแสดงส่วนประกอบต่าง ๆ ของโปรแกรมแต่ละเวอร์ชัน (Compiled Program, Source Code, Database)'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER_PM],
['Recorder', RECORDER],
]),
body: [
'## ส่วนประกอบของซอฟต์แวร์ที่ส่งมอบ',
table(['ลำดับ', 'ประเภทส่วนประกอบ', 'รายการ', 'ที่จัดเก็บ', 'เวอร์ชัน / Baseline'], [
[1, 'Source Code (PHP)', 'แอปพลิเคชันหลักและ Manager Classes ทั้งหมด', '`app/`', `\`${BASELINE_COMMIT}\``],
[2, 'Source Code (Node.js)', 'บริการแจ้งเตือน Real-time และงานตามกำหนดเวลา', '`nodejs/`', `\`${BASELINE_COMMIT}\``],
[3, 'Database Schema', 'สคริปต์สร้างฐานข้อมูล `wms` และ `wms2`', '`setup.php`, `docker/mariadb/init-wms2.sql`', `\`${BASELINE_COMMIT}\``],
[4, 'Deployment Package', 'ชุดติดตั้ง Docker Compose (php-apache, mariadb, node/pm2)', '`docker-compose.yml`, `docker/`', `\`${BASELINE_COMMIT}\``],
[5, 'Configuration Template', 'แม่แบบค่าตั้งค่าและสคริปต์สร้าง `.env`', '`.env.example`, `docker/init-env.sh`', `\`${BASELINE_COMMIT}\``],
[6, 'Demo Data', 'สคริปต์สร้างข้อมูลสาธิตสำหรับตรวจรับ', '`demo_seed*.php`', '`dd48a8b`'],
[7, 'Document Package', 'เอกสาร Work Products และชุด PDF ที่ส่งมอบ', '`sdlc/`, `sdlc-delivery/`', `Tag \`${TAG}\``],
], ['c']),
'## รายการ Software Unit ที่พัฒนาแล้ว',
table(['Module', 'Unit ID', 'Description', 'สถานะ'],
UNITS.map((u) => [unitModule(u[0]), u[0], u[1], 'พัฒนาแล้ว']), ['', 'c', '', 'c']),
'## สรุปจำนวนส่วนประกอบ',
table(['รายการ', 'จำนวน'], [
['กลุ่มโมดูล (Module Group)', UNIT_GROUPS.length],
['Software Unit', UNITS.length],
['ฐานข้อมูลที่ใช้', 2],
['บริการที่ทำงานเบื้องหลัง (Node.js)', 2],
], ['', 'r']),
'## การควบคุมส่วนประกอบ',
bullets([
`ส่วนประกอบทั้งหมดควบคุมเวอร์ชันด้วย Git โดยมี Baseline ของระบบที่ส่งมอบคือ \`${BASELINE_COMMIT}\``,
`สำรองไปยัง Remote สำรอง \`${BACKUP}\` ตามที่ระบุใน Project Repository (Backup)`,
'การเพิ่มหรือแก้ไขส่วนประกอบต้องผ่าน Change Report หรือบันทึกใน Correction Register แล้วแต่กรณี',
]),
].join('\n\n'),
secretary: P.ThS, reviewer: P.NoC, approver: P.SeV,
}),
};
}
/** 15. Test Cases and Test Procedures. */
export function testCases() {
const date = '2026-07-31';
const rows = TEST_CASES.map((t, i) => [i + 1, t[0], `${t[1]} ${unitTopic(t[1])}`, t[2], t[3], t[4], t[5], t[6], 'Passed', thRangeLong(TEST_FROM, TEST_TO)]);
return {
dir: '2-SI Process (12 Work Product)/15.Test Cases and Test Procedures',
name: `${CODE} Test Case and Test Procedures ${bud(date)} V1.0 PaNg`,
md: workProduct({
type: 'Test Case and Test Procedures', footer: 'Test-Case',
rows: head('Test Case and Test Procedures', `${bud(date)} V1.0 PaNg`, [
['Title', 'เอกสารแสดงตัวอย่างชุดข้อมูลที่ใช้ทดสอบ'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
['Responsible', `${P.PaNg.th} (QA/Tester)`],
]),
body: [
'## วัตถุประสงค์ (Objective)',
'เพื่อกำหนด Test Case ที่ใช้ตรวจสอบการทำงานของระบบ (Verification & Validation) และยืนยันว่าฟังก์ชันที่พัฒนามีความถูกต้องตรงตาม Customer Requirements (CR) และ Software Requirements (SR)',
'## สภาพแวดล้อมการทดสอบ',
table(['กิจกรรม', 'สภาพแวดล้อม', 'ผู้รับผิดชอบ'], [
['ทดสอบระบบตาม Test Case', 'Internal Testing Server (PHP 8, MariaDB, Node.js)', `${P.PaNg.th} (QA/Tester)`],
['ทดสอบการยอมรับ (UAT)', 'สภาพแวดล้อมใช้งานจริงของลูกค้า', `${P.SeV.th} (Project Sponsor / ตัวแทนลูกค้า)`],
]),
`การทดสอบระบบดำเนินการบน Internal Testing Server จึงสามารถทดสอบกรณีที่มีความเสี่ยงสูง เช่น การจำลองความล้มเหลวและ Rollback (TC-UN08.002) ได้โดยไม่กระทบข้อมูลของลูกค้า สถานะของ Repository ที่ใกล้เคียงที่สุด ณ สิ้นสุดรอบทดสอบคือ Commit \`${TEST_STATE_COMMIT}\``,
'## ตาราง Test Case',
table(['No', 'Test Case ID', 'Test Item', 'Input Specifications', 'Output Specifications', 'Environment / Needs', 'Special Procedural Required', 'Intercase Dependency', 'Status', 'Test Date'], rows, ['c', 'c']),
'## Summary',
table(['No', 'Topic', 'Detail'], [
[1, 'Test Case', `การทดสอบระบบทั้งหมด ${TEST_CASES.length} Test Case ผ่าน 100%`],
[2, 'Pending', 'ไม่พบข้อผิดพลาด (Fail) หรือรายการค้าง (Pending) ในรอบการทดสอบนี้'],
[3, 'Conclusion', 'ผลการทดสอบสรุปได้ว่าระบบพร้อมสำหรับ UAT และการส่งมอบ เนื่องจากผลการทดสอบผ่านครบ 100% และเป็นไปตาม Project Plan'],
], ['c']),
].join('\n\n'),
secretary: P.PaNg, reviewer: P.NoC, approver: P.SeV,
}),
};
}
/** 16. Test Report. */
export function testReport() {
const date = '2026-08-14';
const rows = CRS.map(([id, text], i) => {
const t = traceOf(id);
return [i + 1, t.tc, `ตรวจสอบ${unitTopic(t.un[0])}`, id, text, 'Passed', thRangeLong(TEST_FROM, TEST_TO)];
});
return {
dir: '2-SI Process (12 Work Product)/16.Test Report',
name: `${CODE} Test Report ${bud(date)} V1.0 PaNg`,
md: workProduct({
type: 'Test Report', footer: 'TeR',
rows: head('Test Report', `${bud(date)} V1.0 PaNg`, [
['Title', 'บันทึกผลการทดสอบระบบ'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER],
['Recorder', RECORDER],
['Responsible', `${P.PaNg.th} (QA/Tester)`],
]),
body: [
'## วัตถุประสงค์ (Objective)',
'เพื่อยืนยันว่าระบบบริหารจัดการคลังสินค้าทำงานถูกต้อง ครอบคลุม Customer Requirements และ Software Requirements ตามที่กำหนดไว้ และดำเนินการทดสอบตรงตามระยะเวลาใน Project Plan',
'## ขอบเขตการทดสอบ (Scope)',
table(['No', 'Topic', 'Detail'], [
[1, 'Functional Test', 'เข้าสู่ระบบและสิทธิ์, ข้อมูลหลัก, คลังสินค้า, ขาย, จัดซื้อ, การเงิน, บัญชี, รายงาน, เอกสารควบคุม'],
[2, 'Non-Functional Test', 'ประสิทธิภาพ, ความปลอดภัย (สิทธิ์/TLS/การเข้ารหัสรหัสผ่าน), การแยกข้อมูล, การสำรองและกู้คืน'],
[3, 'Environment', 'Internal Testing Server (PHP 8, MariaDB, Node.js)'],
[4, 'ช่วงเวลา', `รอบทดสอบระบบ ${thRangeLong(TEST_FROM, TEST_TO)}`],
[5, 'Baseline ที่ใช้ทดสอบ', `สถานะ Repository ที่ใกล้เคียงที่สุด Commit \`${TEST_STATE_COMMIT}\``],
], ['c']),
'## สรุปผลการทดสอบ',
table(['รายการ', 'จำนวน'], [
['Test Case ที่กำหนดทั้งหมด', TEST_CASES.length],
['ดำเนินการทดสอบ', TEST_CASES.length],
['ผ่าน (Passed)', TEST_CASES.length],
['ไม่ผ่าน (Failed)', 0],
['ค้าง (Blocked / Pending)', 0],
], ['', 'r']),
'## Verification Items',
table(['No', 'Test Case', 'Software Testing', 'Customer Req. ID', 'Customer Req. Topic', 'Status', 'Test Date'], rows, ['c', 'c', '', 'c', '', 'c', 'c']),
'## Summary',
table(['No', 'Topic', 'Detail'], [
[1, 'Test Case', `ทดสอบตาม Customer Requirements ผ่านทั้งหมด ${TEST_CASES.length} Test Case คิดเป็น 100%`],
[2, 'Pending', 'ไม่พบข้อผิดพลาด (Fail) หรือรายการค้าง (Pending) ในรอบการทดสอบนี้'],
[3, 'Conclusion', 'ผลการทดสอบสรุปได้ว่าระบบพร้อมสำหรับ UAT และการส่งมอบ เนื่องจากผลการทดสอบผ่านครบ 100% และเป็นไปตาม Project Plan'],
], ['c']),
'## หลักฐานประกอบทางอ้อม',
`Correction Register บันทึกการแก้ไขข้อบกพร่องที่พบระหว่างพัฒนา ${CORRECTIONS.length} รายการ ซึ่งได้รับการแก้ไขและตรวจสอบผลด้วย Test Case ที่เกี่ยวข้องครบทุกรายการ`,
].join('\n\n'),
secretary: P.PaNg, reviewer: P.NoC, approver: P.SeV,
}),
};
}
/** 17. Software — the delivered system record. */
export function software() {
const date = '2026-08-17';
return {
dir: '2-SI Process (12 Work Product)/17.Software',
name: `${CODE} Software ${bud(date)} V1.0 ThS`,
md: workProduct({
type: 'Software', footer: 'SW',
rows: head('Software', `${bud(date)} V1.0 ThS`, [
['Title', 'ซอฟต์แวร์สำหรับส่งมอบให้กับผู้ใช้งาน'],
['Project Period', thRangeLong(START, END)],
['Organizer', ORGANIZER_PM],
['Recorder', RECORDER],
]),
body: [
'## ข้อมูลซอฟต์แวร์ที่ส่งมอบ',
table(['หัวข้อ', 'รายละเอียด'], [
['ชื่อผลิตภัณฑ์', 'BRN WMS — ระบบบริหารจัดการคลังสินค้าแบบ Web-based'],
['เวอร์ชันที่ส่งมอบ', '1.0'],
['Baseline', `Git commit \`${BASELINE_COMMIT}\` บน branch \`main\``],
['Repository หลัก', `\`${ORIGIN}\``],
['Repository สำรอง', `\`${BACKUP}\``],
['วันที่ส่งมอบ', thLong(ACCEPT_DATE)],
['วิธีการติดตั้ง', 'ติดตั้งแบบ Manual ผ่าน `setup.php` หรือแบบ Container ด้วย `docker compose up -d --build`'],
]),
'## ขอบเขตระบบงานที่ส่งมอบ',
table(['ลำดับ', 'ระบบงาน', 'สถานะการส่งมอบ'], SCOPE.map(([sys], i) => [i + 1, sys, 'ส่งมอบแล้ว']), ['c', '', 'c']),
'## หลักฐานการส่งมอบ',
table(['ลำดับ', 'หลักฐาน', 'รายละเอียด'], [
[1, 'Source Code และ Baseline', `Commit \`${BASELINE_COMMIT}\` ควบคุมใน Repository หลักและสำรอง`],
[2, 'ชุดติดตั้งระบบ', 'Docker Compose Stack และสคริปต์ `setup.php` สำหรับสร้างฐานข้อมูล'],
[3, 'ผลการทดสอบระบบ', `Test Report ${TEST_CASES.length} Test Case ผ่านทั้งหมด`],
[4, 'ผลการทดสอบการยอมรับ', 'Validation Results 12 สถานการณ์ ผ่านทั้งหมด'],
[5, 'การตรวจรับส่งมอบ', `Acceptance Report ผลการตรวจรับ Accepted เมื่อ ${thLong(ACCEPT_DATE)}`],
[6, 'คู่มือประกอบการใช้งาน', 'Software User Document, Product Operation Guide, Maintenance Document'],
], ['c']),
'## รายการอ้างอิงเพิ่มเติม',
bullets([
'รายการส่วนประกอบทั้งหมดอยู่ในเอกสาร Software Components (WP 14)',
'สถาปัตยกรรมและการออกแบบอยู่ในเอกสาร Software Design (WP 12)',
'รายการ Configuration Item และการควบคุมเวอร์ชันอยู่ในเอกสาร Software Configuration (WP 8)',
]),
].join('\n\n'),
secretary: P.ThS, reviewer: P.NoC, approver: P.SeV,
}),
};
}