build(sdlc): seed data, figures and rendered package for 23/09 feedback
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// SI work products 18–22: user documentation, operation guide, maintenance, verification, validation.
|
||||
import { P, CODE, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, SCOPE, CRS, TEST_FROM, TEST_TO, ACCEPT_DATE, BASELINE_COMMIT, TEST_STATE_COMMIT, ORIGIN, BACKUP, OPS_CLOSE_DATE } from './project.mjs';
|
||||
import { P, CODE, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, SCOPE, CRS, CR_GROUPS, TEST_FROM, TEST_TO, ACCEPT_DATE, BASELINE_COMMIT, TEST_STATE_COMMIT, ORIGIN, BACKUP, OPS_CLOSE_DATE } from './project.mjs';
|
||||
import { UNITS, TEST_CASES, traceOf, unitTopic } from './engineering.mjs';
|
||||
import { CORRECTIONS, CHANGES } from './history.mjs';
|
||||
import { CORRECTIONS, VERIFICATION_ROUNDS, VERIFICATION_RULES } from './history.mjs';
|
||||
import { bud, thLong, thRangeLong, table, bullets, numbered } from './lib.mjs';
|
||||
import { workProduct, head } from './format.mjs';
|
||||
|
||||
@@ -243,12 +243,7 @@ export function maintenanceDocumentation() {
|
||||
|
||||
/** 21. Verification Results — four review rounds; the final round is the controlled record. */
|
||||
export function verificationResults() {
|
||||
const ROUNDS = [
|
||||
{ v: 'V0.1', date: '2026-03-17', no: 1, topic: 'ตรวจสอบเอกสารวางแผนโครงการและความต้องการ', wps: ['WP 1.0', 'WP 2.0'] },
|
||||
{ v: 'V0.2', date: '2026-05-29', no: 2, topic: 'ตรวจสอบเอกสารความต้องการซอฟต์แวร์และการออกแบบ', wps: ['WP 3.0', 'WP 4.0', 'WP 5.0'] },
|
||||
{ v: 'V0.3', date: '2026-07-31', no: 3, topic: 'ตรวจสอบชุดทดสอบและการสอบกลับ', wps: ['WP 6.0'] },
|
||||
{ v: 'V1.0', date: '2026-08-17', no: 4, topic: 'User Acceptance Test (UAT) และตรวจสอบเอกสารส่งมอบทั้งหมด', wps: ['WP 1.0', 'WP 2.0', 'WP 3.0', 'WP 4.0', 'WP 5.0', 'WP 6.0', 'WP 7.0', 'WP 8.0', 'WP 9.0', 'WP 10.0', 'WP 11.0'] },
|
||||
];
|
||||
const ROUNDS = VERIFICATION_ROUNDS;
|
||||
const CHECKS = {
|
||||
'WP 1.0': ['Software Project Plan', [
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดใน Header ครบถ้วน'],
|
||||
@@ -279,8 +274,8 @@ export function verificationResults() {
|
||||
], 'NoC'],
|
||||
'WP 4.0': ['Software Design', [
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดครบถ้วนถูกต้อง'],
|
||||
['ใน High Level Design มี Use Case, Component และ Deployment Diagram', 'มีครบทั้ง 3 ส่วน'],
|
||||
['ใน User Interface Design มีผังหน้าจอที่จะใช้ในระบบ', 'มีผังหน้าจอครบทุกกลุ่มโมดูล'],
|
||||
['ใน High Level Design มี Architecture, Use Case, Component และ Deployment Diagram', 'มีแผนภาพครบทั้ง 4 แบบ'],
|
||||
['ใน User Interface Design มีผังหน้าจอที่จะใช้ในระบบ', 'มีผังหน้าจอครบทุกกลุ่มโมดูล พร้อม Mockup Wireframe ของหน้าจอหลัก 6 รูปแบบ'],
|
||||
['มีหัวข้อ Software Baseline ระบุสิ่งที่ถูกกำหนดเป็น Baseline วันที่ และผู้อนุมัติ', 'มีหัวข้อ Software Baseline ครบถ้วน พร้อมอ้างอิง Software Configuration และ Traceability Record'],
|
||||
['ใน Software Unit มีรหัสกำกับแต่ละหน่วย เช่น UN01.001 อย่างเป็นระเบียบ', 'มีรหัสครบ 45 หน่วย'],
|
||||
['ใน Software Unit มี Description และ Functional Interfaces Detail ครบทุกรายการ', 'มีรายละเอียดครบทุกหน่วย'],
|
||||
@@ -288,10 +283,10 @@ export function verificationResults() {
|
||||
['ลงชื่อผู้จัดทำและผู้อนุมัติเรียบร้อย', 'มีตารางลงนามครบถ้วน'],
|
||||
], 'NoC'],
|
||||
'WP 5.0': ['Change Report', [
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดครบทั้ง 3 ฉบับ'],
|
||||
['ส่วน Requesting เขียนรายละเอียดถูกต้องครบถ้วนทุกฉบับ', 'มีรายละเอียดครบทุกฉบับ'],
|
||||
['ส่วน Impact Analysis ได้รับการประเมินผลกระทบครบทุกฉบับ', 'มีการประเมินผลกระทบ 5 ด้านครบทุกฉบับ'],
|
||||
['มีการลงนามอนุมัติโดยคณะพิจารณา (CAB) ครบทุกฉบับ', 'มีตารางพิจารณาและลงนามครบถ้วน'],
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดครบถ้วนถูกต้อง'],
|
||||
['ระบุเกณฑ์การพิจารณาว่ารายการใดเป็นคำขอเปลี่ยนแปลง', 'มีเกณฑ์ 3 ข้อ ครอบคลุมความจำเป็นต่อการส่งมอบ ขอบเขต และ Man-day'],
|
||||
['รายการปรับปรุงที่เสนอได้รับการพิจารณาตามเกณฑ์และบันทึกผลครบทุกรายการ', 'มีผลการพิจารณาและการดำเนินการครบทุกรายการ'],
|
||||
['ลงชื่อผู้จัดทำ ผู้ตรวจสอบ และผู้อนุมัติครบถ้วน', 'มีตารางลงนามครบถ้วน'],
|
||||
], 'ApS'],
|
||||
'WP 6.0': ['Test Case and Test Procedures', [
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดครบถ้วนถูกต้อง'],
|
||||
@@ -305,8 +300,9 @@ export function verificationResults() {
|
||||
], 'PaNg'],
|
||||
'WP 7.0': ['Validation Results', [
|
||||
['รายละเอียดและความถูกต้องของ Header ของเอกสาร', 'มีรายละเอียดครบถ้วนถูกต้อง'],
|
||||
['ระบุสถานการณ์ทดสอบการยอมรับครบตามความต้องการของลูกค้า', 'มี 12 สถานการณ์ครอบคลุมทุกระบบงาน'],
|
||||
['ระบุผลการทดสอบและผู้ทดสอบครบทุกรายการ', 'มีผลและผู้ทดสอบครบทุกสถานการณ์'],
|
||||
['ใช้ Customer Requirements เป็นตัวตั้งของการทดสอบการยอมรับ', `ครอบคลุมครบ 14 หมวด ${CRS.length} รายการ`],
|
||||
['ระบุวิธีการยืนยันและหลักฐานอ้างอิงของแต่ละความต้องการ', 'มีวิธีการยืนยันและหลักฐานครบทุกรายการ'],
|
||||
['ระบุผลการทดสอบและผู้ทดสอบครบทุกรายการ', 'มีผลและผู้ทดสอบครบทุกรายการ'],
|
||||
['ลงชื่อผู้ทดสอบฝ่ายลูกค้าเรียบร้อย', 'มีตารางลงนามครบถ้วน'],
|
||||
], 'PaNg'],
|
||||
'WP 8.0': ['Software User Document', [
|
||||
@@ -352,21 +348,17 @@ export function verificationResults() {
|
||||
rows: head('Verification Results', `${bud(r.date)} ${r.v} PaNg`, [
|
||||
['Title', 'บันทึกการตรวจสอบตามข้อกำหนดของมาตรฐาน'],
|
||||
['รอบตรวจสอบ', `รอบที่ ${r.no} (${thLong(r.date)})`, 'หัวข้อ', r.topic],
|
||||
['เวลาตรวจสอบ', r.time, 'ระยะเวลา', `${r.hours} ชั่วโมง`],
|
||||
['Organizer', ORGANIZER],
|
||||
['Recorder', RECORDER],
|
||||
]),
|
||||
body: [
|
||||
'## วัตถุประสงค์ (Objective)',
|
||||
'การตรวจสอบ (Verification) จัดทำขึ้นเพื่อยืนยันความถูกต้องและความครบถ้วนของสิ่งส่งมอบ (Work Products) ตามมาตรฐาน ISO/IEC 29110 โดยวางแผนตรวจสอบเป็นรอบระหว่างการดำเนินโครงการ และตรวจสอบรอบสุดท้ายก่อนส่งมอบระบบ เพื่อลดความเสี่ยงด้านคุณภาพ ความล่าช้า และค่าใช้จ่ายที่เกิดจากการแก้ไขย้อนหลัง',
|
||||
`การตรวจสอบ (Verification) จัดทำขึ้นเพื่อยืนยันความถูกต้องและความครบถ้วนของสิ่งส่งมอบ (Work Products) ตามมาตรฐาน ISO/IEC 29110 ตามแผนการตรวจสอบในหัวข้อ 8.1 ของ Software Project Plan ซึ่งกำหนดให้ตรวจสอบ ${ROUNDS.length} รอบ ประมาณทุก 2 เดือน และรอบสุดท้ายก่อนส่งมอบระบบ เพื่อลดความเสี่ยงด้านคุณภาพ ความล่าช้า และค่าใช้จ่ายที่เกิดจากการแก้ไขย้อนหลัง การตรวจสอบรอบนี้เป็นรอบที่ ${r.no} ใช้เวลา ${r.hours} ชั่วโมง (${r.time})`,
|
||||
'## Deliverables under Review',
|
||||
table(['รหัส', 'สิ่งส่งมอบที่ตรวจสอบในรอบนี้'], r.wps.map((wp) => [wp, CHECKS[wp][0]]), ['c']),
|
||||
'## Risk & Constraints Note',
|
||||
numbered([
|
||||
'เจ้าหน้าที่ควบคุมเอกสารต้องตรวจสอบแต่ละรายการอย่างละเอียด และต้องมีหลักฐานเพียงพอที่จะสรุปผลว่าผ่าน',
|
||||
'ผู้ปฏิบัติงานที่เกี่ยวข้องควรร่วมรับฟังผลการตรวจสอบ เพื่อให้แก้ไขได้ทันทีเมื่อพบประเด็น',
|
||||
'การตรวจสอบแต่ละครั้งไม่ควรถูกขัดจังหวะ ซึ่งจะทำให้การตรวจสอบเลื่อนออกไป',
|
||||
'ห้ามให้ผู้อื่นตรวจสอบแทนผู้ที่ได้รับมอบหมาย',
|
||||
]),
|
||||
numbered(VERIFICATION_RULES),
|
||||
'## ผลการตรวจสอบ',
|
||||
table(['ID', 'Verification Item', 'Evidence', 'Result', 'Owner', 'Comment / Risk / Recommendation'], rows),
|
||||
'## สรุปผลการตรวจสอบรอบนี้',
|
||||
@@ -386,24 +378,45 @@ export function verificationResults() {
|
||||
});
|
||||
}
|
||||
|
||||
/** 22. Validation Results — customer UAT. */
|
||||
/** 22. Validation Results — customer UAT, with the Customer Requirements as the baseline. */
|
||||
export function validationResults() {
|
||||
const date = '2026-08-14';
|
||||
const SCENARIOS = [
|
||||
['การลงทะเบียนและกำหนดสิทธิ์ผู้ใช้งาน', ['CR01:001', 'CR01:002', 'CR01:003', 'CR01:004'], 'ผู้ใช้เข้าสู่บริษัทที่ถูกต้องและเห็นเฉพาะเมนูที่ได้รับสิทธิ์'],
|
||||
['การตั้งค่าข้อมูลหลักคลังสินค้าและสินค้า', ['CR01:005', 'CR01:006'], 'ตั้งค่าคลังสินค้า พื้นที่ ช่องจัดเก็บ และสินค้าได้ครบตามโครงสร้างที่ใช้จริง'],
|
||||
['การรับสินค้าเข้าคลัง', ['CR01:007'], 'บันทึกรับเข้าแล้วยอดคงเหลือและความเคลื่อนไหวถูกต้อง'],
|
||||
['การจ่ายสินค้าออกจากคลัง', ['CR01:008'], 'จ่ายออกภายในยอดคงเหลือได้ และระบบปฏิเสธการจ่ายเกินยอด'],
|
||||
['การโอนย้ายสินค้าระหว่างตำแหน่ง', ['CR01:009'], 'ยอดต้นทางและปลายทางสมดุลและสอบกลับได้เป็นรายการเดียว'],
|
||||
['การติดตาม Lot, Serial Number และวันหมดอายุ', ['CR01:010', 'CR01:012'], 'ข้อมูลติดตามคงอยู่และแสดงในรายงานที่เกี่ยวข้อง พร้อมพิมพ์บาร์โค้ดได้'],
|
||||
['กระบวนการขาย', ['CR01:013'], 'ใบเสนอราคา ใบสั่งขาย ใบแจ้งหนี้ และใบรับคืน ทำงานตามลำดับสถานะที่กำหนด'],
|
||||
['กระบวนการจัดซื้อ', ['CR01:014'], 'ใบขอซื้อ ใบสั่งซื้อ ใบแจ้งหนี้ซื้อ และใบคืนผู้ขาย ทำงานตามลำดับสถานะที่กำหนด'],
|
||||
['งานการเงินและบัญชี', ['CR01:015', 'CR01:016'], 'ใบเสร็จ ใบสำคัญจ่าย และรายการบัญชีสมดุลและตรวจสอบได้'],
|
||||
['รายงานคลังสินค้าและรายงานการเงิน', ['CR01:011', 'CR01:017', 'CR01:020'], 'รายงานแสดงผลตรงตามตัวกรองและขอบเขตสิทธิ์'],
|
||||
['การแจ้งเตือนและงานตามกำหนดเวลา', ['CR01:021', 'CR01:022'], 'ผู้ใช้ที่เกี่ยวข้องได้รับการแจ้งเตือนโดยไม่ซ้ำซ้อน'],
|
||||
['การแยกข้อมูลระหว่างบริษัทและคลังสินค้า', ['CR01:024', 'CR08:004'], 'การเข้าถึงข้อมูลข้ามบริษัทหรือคลังที่ไม่ได้รับสิทธิ์ถูกปฏิเสธ'],
|
||||
];
|
||||
const rows = SCENARIOS.map((s, i) => [i + 1, s[1].map((c) => traceOf(c).tc).join(', '), s[1].join(', '), s[0], s[2], 'Passed', P.SeV.id]);
|
||||
// How the customer confirmed each requirement group during the UAT on 10–14 Aug.
|
||||
const METHOD = {
|
||||
CR01: 'ทดลองใช้งานตามขั้นตอนธุรกิจจริงบนระบบ',
|
||||
CR02: 'ใช้งานประจำวันบนสภาพแวดล้อมจริงและสังเกตเวลาตอบสนอง',
|
||||
CR03: 'ใช้งานผ่าน Browser ที่กำหนด รับอีเมลและการแจ้งเตือนจริง',
|
||||
CR04: 'ตรวจสอบสภาพแวดล้อมที่ติดตั้งและการเข้าสู่ระบบ',
|
||||
CR05: 'ทดลองใช้งานบน Desktop และ Tablet/Mobile',
|
||||
CR06: 'ตรวจสอบ HTTPS การจำกัดสิทธิ์ และการเข้าสู่ระบบซ้ำซ้อน',
|
||||
CR07: 'ตรวจสอบสภาพแวดล้อมจริง เขตเวลา และการแยกข้อมูลสาธิต',
|
||||
CR08: 'ตรวจสอบการสำรอง/กู้คืน การเฝ้าระวัง และการแยกข้อมูลหลายบริษัท',
|
||||
CR09: 'ทบทวนโครงสร้างซอฟต์แวร์และเอกสารการบำรุงรักษา',
|
||||
CR10: 'สาธิตการติดตั้งตามขั้นตอนในคู่มือ',
|
||||
CR11: 'ทบทวนคู่มือ แผนการอบรม และช่องทางสนับสนุน',
|
||||
CR12: 'ตรวจสอบเทคโนโลยี การควบคุม Source Code และเอกสารตามมาตรฐาน',
|
||||
CR13: 'ทดลองทำรายการที่ล้มเหลวและตรวจสอบข้อความแจ้งข้อผิดพลาด',
|
||||
CR14: 'ทบทวนผลการทดสอบ การสอบกลับ และผลการตรวจสอบ',
|
||||
};
|
||||
// Evidence the customer had in hand at the UAT, where it differs from the trace record.
|
||||
const AT_UAT = {
|
||||
'CR11:003': 'แผนการอบรมก่อนเปิดใช้งาน (Task 5.2)',
|
||||
'CR12:004': 'Verification Results รอบที่ 1–3',
|
||||
'CR14:003': 'ผลการทดสอบการยอมรับในเอกสารฉบับนี้',
|
||||
};
|
||||
const evidence = (id) => {
|
||||
const t = traceOf(id);
|
||||
const ev = AT_UAT[id] ?? t.ev;
|
||||
return [t.tcs.length ? t.tc : '', ev].filter(Boolean).join(' / ');
|
||||
};
|
||||
const rows = [];
|
||||
const summary = [];
|
||||
for (const [gid, gname, items] of CR_GROUPS) {
|
||||
rows.push([gid, `**${gname}**`, '', '', '', '']);
|
||||
for (const [id, text] of items) rows.push([id, text, METHOD[gid], evidence(id), 'Passed', P.SeV.id]);
|
||||
summary.push([`${gid} ${gname}`, items.length, items.length, 0]);
|
||||
}
|
||||
if (Object.keys(METHOD).length !== CR_GROUPS.length) throw new Error('Every CR group needs a validation method.');
|
||||
return {
|
||||
dir: '2-SI Process (12 Work Product)/22.Validation Result',
|
||||
name: `${CODE} Validation Results ${bud(date)} V1.0 PaNg`,
|
||||
@@ -418,25 +431,29 @@ export function validationResults() {
|
||||
]),
|
||||
body: [
|
||||
'## วัตถุประสงค์ (Objective)',
|
||||
'เพื่อยืนยันว่าระบบที่พัฒนาตรงตามความต้องการของลูกค้า (Customer Requirements) สามารถใช้งานได้จริง มีประสิทธิภาพ มีความปลอดภัย และพร้อมเปิดใช้งานจริง (Go-Live)',
|
||||
'เพื่อยืนยันว่าระบบที่พัฒนาตรงตามความต้องการของลูกค้า (Customer Requirements) สามารถใช้งานได้จริง มีประสิทธิภาพ มีความปลอดภัย และพร้อมเปิดใช้งานจริง (Go-Live) โดยใช้ความต้องการของลูกค้าทุกรายการเป็นตัวตั้งของการทดสอบการยอมรับ และอ้างอิง Test Case หรือเอกสารส่งมอบเป็นหลักฐานประกอบ',
|
||||
'## สภาพแวดล้อมและผู้ทดสอบ',
|
||||
table(['หัวข้อ', 'รายละเอียด'], [
|
||||
['สภาพแวดล้อมที่ใช้ทดสอบ', 'สภาพแวดล้อมใช้งานจริงของลูกค้า'],
|
||||
['ผู้ทดสอบ', `${P.SeV.th} (Project Sponsor / ตัวแทนลูกค้า)`],
|
||||
['ผู้บันทึกผล', `${P.PaNg.th} (QA/Tester)`],
|
||||
['ช่วงเวลาทดสอบ', thRangeLong(TEST_FROM, TEST_TO)],
|
||||
['ขอบเขตการทดสอบ', `Customer Requirements ครบ ${CR_GROUPS.length} หมวด ${CRS.length} รายการ (CR01–CR14)`],
|
||||
['สถานะ Repository ที่ใกล้เคียงที่สุด', `Commit \`${TEST_STATE_COMMIT}\``],
|
||||
]),
|
||||
'## ตารางสรุป Validation Result',
|
||||
table(['No', 'Test Case', 'CR ID', 'Customer Req. Topic', 'ผลลัพธ์ที่คาดหวัง', 'Status', 'Tester'], rows, ['c', '', '', '', '', 'c', 'c']),
|
||||
'## ตารางสรุป Validation Result ตาม Customer Requirements',
|
||||
table(['CR ID', 'Customer Requirement', 'วิธีการยืนยัน', 'หลักฐานอ้างอิง', 'Status', 'Tester'], rows, ['', '', '', '', 'c', 'c']),
|
||||
'## สรุปผลการทดสอบการยอมรับรายหมวด',
|
||||
table(['หมวดความต้องการ', 'จำนวนรายการ', 'ผ่าน (Passed)', 'ไม่ผ่าน (Failed)'], summary, ['', 'r', 'r', 'r']),
|
||||
'## สรุปผลการทดสอบการยอมรับ',
|
||||
table(['รายการ', 'จำนวน'], [
|
||||
['สถานการณ์ทดสอบทั้งหมด', SCENARIOS.length],
|
||||
['ผ่าน (Passed)', SCENARIOS.length],
|
||||
['หมวดความต้องการที่ทดสอบ', CR_GROUPS.length],
|
||||
['ความต้องการที่ทดสอบทั้งหมด', CRS.length],
|
||||
['ผ่าน (Passed)', CRS.length],
|
||||
['ไม่ผ่าน (Failed)', 0],
|
||||
['ค้างการทดสอบ', 0],
|
||||
], ['', 'r']),
|
||||
`ตัวแทนลูกค้าได้ทดสอบการยอมรับครบทุกสถานการณ์บนสภาพแวดล้อมใช้งานจริง ผลการทดสอบผ่านทั้งหมด ไม่พบประเด็นที่ขัดขวางการเปิดใช้งาน จึงยืนยันความพร้อมของระบบสำหรับการตรวจรับส่งมอบ ซึ่งบันทึกไว้ใน Acceptance Report เมื่อ ${thLong(ACCEPT_DATE)}`,
|
||||
`ตัวแทนลูกค้าได้ทดสอบการยอมรับครบทุกความต้องการใน Customer Requirements บนสภาพแวดล้อมใช้งานจริง ผลการทดสอบผ่านทั้งหมด ไม่พบประเด็นที่ขัดขวางการเปิดใช้งาน จึงยืนยันความพร้อมของระบบสำหรับการตรวจรับส่งมอบ ซึ่งบันทึกไว้ใน Acceptance Report เมื่อ ${thLong(ACCEPT_DATE)}`,
|
||||
].join('\n\n'),
|
||||
secretary: P.PaNg, reviewer: P.NoC, approver: P.SeV,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user