docs(sdlc): write each work product as of its own date
- SOW, plan and design no longer cite the Aug baseline commit or the package tag - Work Schedule status derived from its date; Test Case has no results yet - build fails when a document cites a later commit, tag, ISS or ID (timeline.mjs) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
be020e332b
commit
6c857005c0
@@ -1,9 +1,9 @@
|
||||
// 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 { P, CODE, PROJECT_TH, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, SCOPE, CRS, crTopic, TEST_FROM, TEST_TO, ACCEPT_DATE, DEV_BASELINE, BASELINE_COMMIT, TEST_STATE_COMMIT, ORIGIN, BACKUP } 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 { figure } from './figures.mjs';
|
||||
import { bud, thLong, thShort, thRangeLong, table, bullets, numbered } from './lib.mjs';
|
||||
import { bud, thLong, thShort, thRange, thRangeLong, table, bullets, numbered } from './lib.mjs';
|
||||
import { workProduct, head } from './format.mjs';
|
||||
|
||||
const D = '2026-08-17';
|
||||
@@ -131,20 +131,20 @@ export function softwareDesign() {
|
||||
figure('wfStockIn'),
|
||||
figure('wfReport'),
|
||||
'## Software Baseline',
|
||||
'หัวข้อนี้ระบุสิ่งที่ถูกกำหนดเป็น Baseline ของซอฟต์แวร์ วันที่กำหนด และผู้อนุมัติ เพื่อให้ตรวจสอบเส้นทาง Baseline → Configuration → Change ได้ในเอกสารชุดเดียวกัน',
|
||||
'หัวข้อนี้กำหนดสิ่งที่จะควบคุมเป็น Baseline ของซอฟต์แวร์ เวลาที่กำหนด Baseline และผู้อนุมัติ เพื่อให้ตรวจสอบเส้นทาง Baseline → Configuration → Change ได้ Commit ที่เป็น Baseline จริงจะบันทึกใน Software Configuration (WP 8) เมื่อกำหนด Baseline แต่ละครั้ง',
|
||||
table(['รายการที่กำหนดเป็น Baseline', 'ค่าที่ควบคุม', 'ที่จัดเก็บ'], [
|
||||
['Source Code ของแอปพลิเคชัน', `Git commit \`${BASELINE_COMMIT}\` บน branch \`main\``, `Repository หลัก \`${ORIGIN}\``],
|
||||
['Source Code ของแอปพลิเคชัน', 'Git commit บน branch `main` ณ วันที่กำหนด Baseline', `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}\``],
|
||||
['เอกสาร Work Products', 'Branch `sdlc`', `Repository หลักและ Remote สำรอง \`${BACKUP}\``],
|
||||
]),
|
||||
table(['หัวข้อ', 'รายละเอียด'], [
|
||||
['วันที่กำหนด Baseline', `${thLong('2026-08-17')} (Baseline ของระบบที่ส่งมอบ)`],
|
||||
['เวลาที่กำหนด Baseline', `เมื่อพัฒนาครบทุกโมดูล (Baseline การพัฒนา ตามแผน ${thLong(DEV_BASELINE)}) และเมื่อตรวจรับส่งมอบ (Baseline ของระบบที่ส่งมอบ ตามแผน ${thLong(ACCEPT_DATE)})`],
|
||||
['ผู้จัดทำ Baseline', `${P.ThS.th} (Developer)`],
|
||||
['ผู้ตรวจสอบ', `${P.NoC.th} (System Analyst) และ ${P.PaNg.th} (QA/Tester)`],
|
||||
['ผู้อนุมัติ', `${P.SeV.th} (Project Sponsor) พร้อมการตรวจรับเมื่อ ${thLong(ACCEPT_DATE)}`],
|
||||
['ผู้อนุมัติ', `${P.SeV.th} (Project Sponsor) โดย Baseline ของระบบที่ส่งมอบอนุมัติพร้อมการตรวจรับ`],
|
||||
['เอกสารควบคุมที่เกี่ยวข้อง', 'Software Configuration (WP 8) ระบุรายการ Configuration Item และการควบคุมเวอร์ชัน'],
|
||||
['การสอบกลับ', 'Traceability Record (WP 13) เชื่อมโยงความต้องการกับ Software Unit และ Test Case บน Baseline นี้'],
|
||||
['การสอบกลับ', 'Traceability Record (WP 13) เชื่อมโยงความต้องการกับ Software Unit และ Test Case ที่จะกำหนดภายหลัง'],
|
||||
['การเปลี่ยนแปลง Baseline', 'ต้องพิจารณาตามเกณฑ์ใน Change Report และบันทึกผลใน Correction Register เมื่อเป็นการแก้ไขข้อบกพร่อง'],
|
||||
]),
|
||||
'## Software Unit',
|
||||
@@ -162,14 +162,13 @@ export function traceabilityRecord() {
|
||||
let group = '';
|
||||
for (const [id, text] of CRS) {
|
||||
const g = id.slice(0, 4);
|
||||
if (g !== group) { group = g; const name = SCOPEGROUP(g); rows.push([`${g}: ${name}`, '', '', '', '', '', '', '']); }
|
||||
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, t.ev || '-']);
|
||||
rows.push([id, text, t.sr.join(', '), t.sr.map(srTopic).join(' / '), t.un.join(', ') || '-', t.un.map(unitTopic).join(' / ') || '-', t.ev || '-']);
|
||||
}
|
||||
const traced = CRS.map(([id]) => traceOf(id));
|
||||
const withUnits = traced.filter((t) => t.un.length).length;
|
||||
const withTests = traced.filter((t) => t.tcs.length).length;
|
||||
const byDocument = traced.filter((t) => !t.tcs.length).length;
|
||||
const byDocument = traced.filter((t) => !t.un.length).length;
|
||||
return {
|
||||
dir: '2-SI Process (12 Work Product)/13.Traceability record',
|
||||
name: `${CODE} Traceability Record ${bud(date)} V1.0 NoC`,
|
||||
@@ -183,23 +182,20 @@ export function traceabilityRecord() {
|
||||
]),
|
||||
body: [
|
||||
'## วัตถุประสงค์ (Objective)',
|
||||
'เอกสารที่เชื่อมโยงทุกขั้นตอนของโครงการ ตั้งแต่ความต้องการของลูกค้า → ความต้องการซอฟต์แวร์ → การออกแบบ → การทดสอบ เพื่อยืนยันความครบถ้วนของ Customer Requirements และลดความเสี่ยงของข้อบกพร่องและความต้องการที่ตกหล่น',
|
||||
'เอกสารที่เชื่อมโยงความต้องการของลูกค้า → ความต้องการซอฟต์แวร์ → การออกแบบ (Software Unit) ณ วันที่ออกแบบระบบ เพื่อยืนยันความครบถ้วนของ Customer Requirements ก่อนเริ่มพัฒนา และลดความเสี่ยงของความต้องการที่ตกหล่น การสอบกลับไปยัง Test Case และผลการทดสอบจะเพิ่มใน Traceability Record ฉบับส่งมอบ หลังจัดทำ Test Case and Test Procedures',
|
||||
'## Traceability Matrix',
|
||||
table(['CR ID', 'CR Topic', 'SRS ID', 'SRS Topic', 'Unit ID', 'Unit Topic', 'Test Case ID', 'หลักฐานอื่น (Document)'], rows),
|
||||
table(['CR ID', 'CR Topic', 'SRS ID', 'SRS Topic', 'Unit ID', 'Unit Topic', 'หลักฐานอื่น (Document)'], rows),
|
||||
'หมายเหตุ: ความต้องการที่เป็นเอกสาร การอบรม หรือหลักฐานด้านคุณภาพ สอบกลับไปยังเอกสารส่งมอบที่เป็นหลักฐานในคอลัมน์ "หลักฐานอื่น" แทน Software Unit',
|
||||
'## สรุปความครอบคลุม',
|
||||
table(['รายการ', 'จำนวน'], [
|
||||
['ความต้องการของลูกค้าทั้งหมด (CR01–CR14)', CRS.length],
|
||||
['เชื่อมโยงกับความต้องการซอฟต์แวร์ (SRS)', CRS.length],
|
||||
['เชื่อมโยงกับ Software Unit', withUnits],
|
||||
['เชื่อมโยงกับ Test Case', withTests],
|
||||
['ยืนยันด้วยเอกสารส่งมอบ (ไม่มี Software Unit)', byDocument],
|
||||
['มีหลักฐานยืนยันครบ (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)}`,
|
||||
'ความต้องการทุกรายการเชื่อมโยงกับความต้องการซอฟต์แวร์ และเชื่อมโยงกับ Software Unit หรือเอกสารส่งมอบที่เป็นหลักฐาน Test Case ของแต่ละ Software Unit จะกำหนดใน Test Case and Test Procedures (WP 6.0) ก่อนรอบทดสอบระบบ',
|
||||
].join('\n\n'),
|
||||
secretary: P.NoC, reviewer: P.YaB, approver: P.SeV,
|
||||
}),
|
||||
@@ -233,7 +229,7 @@ export function softwareComponents() {
|
||||
[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}\``],
|
||||
[7, 'Document Package', 'เอกสาร Work Products และชุด PDF ที่ส่งมอบ', '`sdlc/`, `sdlc-delivery/`', 'Branch `sdlc`'],
|
||||
], ['c']),
|
||||
'## รายการ Software Unit ที่พัฒนาแล้ว',
|
||||
table(['Module', 'Unit ID', 'Description', 'สถานะ'],
|
||||
@@ -260,7 +256,7 @@ export function softwareComponents() {
|
||||
/** 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)]);
|
||||
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], 'Ready', `ตามแผน ${thRange(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`,
|
||||
@@ -281,14 +277,14 @@ export function testCases() {
|
||||
['ทดสอบระบบตาม 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}\``,
|
||||
`การทดสอบระบบดำเนินการบน Internal Testing Server จึงสามารถทดสอบกรณีที่มีความเสี่ยงสูง เช่น การจำลองความล้มเหลวและ Rollback (TC-UN08.002) ได้โดยไม่กระทบข้อมูลของลูกค้า รอบทดสอบระบบกำหนดไว้ระหว่าง ${thRangeLong(TEST_FROM, TEST_TO)} และผลการทดสอบบันทึกใน Test Report`,
|
||||
'## ตาราง 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'],
|
||||
[1, 'Test Case', `กำหนด Test Case ทั้งหมด ${TEST_CASES.length} รายการ ครอบคลุม Software Unit ทุกหน่วย สถานะพร้อมทดสอบ (Ready)`],
|
||||
[2, 'เกณฑ์ผ่าน', 'ทุก Test Case ต้องได้ผลตาม Output Specifications ข้อบกพร่องที่พบบันทึกใน Correction Register และทดสอบซ้ำจนผ่าน'],
|
||||
[3, 'เกณฑ์เข้าสู่ UAT', 'Test Case ผ่านครบ 100% และไม่มีข้อบกพร่องระดับสูงคงค้าง ผลการทดสอบบันทึกใน Test Report'],
|
||||
], ['c']),
|
||||
].join('\n\n'),
|
||||
secretary: P.PaNg, reviewer: P.NoC, approver: P.SeV,
|
||||
|
||||
Reference in New Issue
Block a user