diff --git a/scripts/build-sdlc-delivery.sh b/scripts/build-sdlc-delivery.sh index 96bc370..9d266bf 100755 --- a/scripts/build-sdlc-delivery.sh +++ b/scripts/build-sdlc-delivery.sh @@ -8,17 +8,22 @@ SOURCE_DIR="$ROOT_DIR/sdlc" DELIVERY_ROOT="$ROOT_DIR/sdlc-delivery" STAGING_DIR="$ROOT_DIR/.sdlc-delivery.staging" -# sdlc/ is generated output: the seed rebuilds every work product from the -# controlled project data in scripts/sdlc-seed/ before anything is rendered. -echo "Seeding work products from project data..." -node "$SCRIPT_DIR/sdlc-seed/build.mjs" - if [[ ! -d "$TOOL_DIR/node_modules/playwright" ]]; then echo "Installing the local PDF renderer..." npm install --prefix "$TOOL_DIR" npx --prefix "$TOOL_DIR" playwright install chromium fi +# The Software Design figures are drawn in scripts/sdlc-seed/figures.mjs and +# rasterised with the document font before the seed copies them into sdlc/. +echo "Rendering Software Design figures..." +node "$TOOL_DIR/render-figures.mjs" + +# sdlc/ is generated output: the seed rebuilds every work product from the +# controlled project data in scripts/sdlc-seed/ before anything is rendered. +echo "Seeding work products from project data..." +node "$SCRIPT_DIR/sdlc-seed/build.mjs" + rm -rf "$STAGING_DIR" mkdir -p "$STAGING_DIR" diff --git a/scripts/sdlc-delivery/assets/sdlc-delivery.css b/scripts/sdlc-delivery/assets/sdlc-delivery.css index e73ecc5..1a2ca94 100644 --- a/scripts/sdlc-delivery/assets/sdlc-delivery.css +++ b/scripts/sdlc-delivery/assets/sdlc-delivery.css @@ -144,3 +144,8 @@ table.signature-table th:nth-child(4), table.signature-table td:nth-child(4) { w reference package, so they take a smaller face to fit the text block. */ table.dense { font-size: 7.2pt; } table.dense th, table.dense td { padding: 1mm 1.2mm; } + +/* Figures in the Software Design: full column width, caption under the image. */ +.delivery-document figure.figure { margin: 8pt 0 12pt; text-align: center; break-inside: avoid; page-break-inside: avoid; } +.delivery-document figure.figure img { max-width: 100%; max-height: 225mm; border: .5pt solid #bfbfbf; } +.delivery-document figure.figure figcaption { margin-top: 4pt; font-size: 9.5pt; font-weight: 700; } diff --git a/scripts/sdlc-delivery/convert-to-docx.py b/scripts/sdlc-delivery/convert-to-docx.py index 6e45b91..70abe15 100644 --- a/scripts/sdlc-delivery/convert-to-docx.py +++ b/scripts/sdlc-delivery/convert-to-docx.py @@ -188,15 +188,19 @@ LOGO_MIN_PX = 100 def strip_logo_images(document): """Drop the letterhead logo left loose in the body. - The work products carry no figures of their own, but the converter draws - each bullet as a small image, so only the logo is removed - anything that - size would be furniture, anything smaller is a list marker. + The converter draws each bullet as a small image, so only the logo is + removed: it is square and at least LOGO_MIN_PX, whereas anything smaller is + a list marker. The Software Design figures are wider than they are tall, + so they are kept. """ + def is_logo(image): + width, height = image.px_width, image.px_height + return max(width, height) >= LOGO_MIN_PX and 0.8 <= width / max(height, 1) <= 1.25 + logos = { relationship_id for relationship_id, part in document.part.related_parts.items() - if getattr(part, 'image', None) is not None - and max(part.image.px_width, part.image.px_height) >= LOGO_MIN_PX + if getattr(part, 'image', None) is not None and is_logo(part.image) } removed = 0 diff --git a/scripts/sdlc-delivery/render-figures.mjs b/scripts/sdlc-delivery/render-figures.mjs new file mode 100644 index 0000000..725b284 --- /dev/null +++ b/scripts/sdlc-delivery/render-figures.mjs @@ -0,0 +1,34 @@ +// Rasterise the Software Design figures (scripts/sdlc-seed/figures.mjs) to PNG with the +// document font, so Thai labels print the same in the PDF and survive the Word conversion. +// Usage: node scripts/sdlc-delivery/render-figures.mjs +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { chromium } from 'playwright'; +import { FIGURES } from '../sdlc-seed/figures.mjs'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const output = path.resolve(here, '../sdlc-seed/figures'); + +async function main() { + const font = await fs.readFile(path.join(here, 'assets/LeelawadeeUI.ttf')); + const fontFace = `@font-face { font-family: "BRN Thai"; src: url(data:font/ttf;base64,${font.toString('base64')}) format("truetype"); font-weight: 400 700; }`; + await fs.mkdir(output, { recursive: true }); + const browser = await chromium.launch({ headless: true }); + try { + const page = await (await browser.newContext({ deviceScaleFactor: 2 })).newPage(); + for (const [file, , draw] of Object.values(FIGURES)) { + const svg = draw(); + const [, w, h] = svg.match(/width="(\d+)" height="(\d+)"/); + await page.setViewportSize({ width: Number(w), height: Number(h) }); + await page.setContent(`${svg}`); + await page.evaluate(() => document.fonts.ready); + await page.locator('svg').first().screenshot({ path: path.join(output, `${file}.png`) }); + console.log(`Rendered figures/${file}.png`); + } + } finally { + await browser.close(); + } +} + +main().catch((error) => { console.error(error); process.exit(1); }); diff --git a/scripts/sdlc-delivery/render-sdlc.mjs b/scripts/sdlc-delivery/render-sdlc.mjs index 1b4142a..16d7ea8 100644 --- a/scripts/sdlc-delivery/render-sdlc.mjs +++ b/scripts/sdlc-delivery/render-sdlc.mjs @@ -1,4 +1,5 @@ import fs from 'node:fs/promises'; +import { readFileSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { chromium } from 'playwright'; @@ -101,7 +102,7 @@ function renderParagraph(lines) { }).join(''); } -function markdownToHtml(markdown) { +function markdownToHtml(markdown, baseDir) { const lines = markdown.replaceAll('\r\n', '\n').split('\n'); const output = []; let index = 0; @@ -110,6 +111,15 @@ function markdownToHtml(markdown) { const line = lines[index]; if (!line.trim()) { index += 1; continue; } + // A figure: ![caption](relative/path.png), embedded so the PDF needs no external files. + const image = line.match(/^!\[([^\]]*)\]\(([^)]+)\)\s*$/); + if (image) { + const data = readFileSync(path.resolve(baseDir, image[2])).toString('base64'); + output.push(`
${renderInline(image[1])}
`); + index += 1; + continue; + } + if (isTableLine(line)) { const table = []; while (index < lines.length && isTableLine(lines[index])) table.push(lines[index++]); @@ -149,7 +159,7 @@ function markdownToHtml(markdown) { } const paragraph = []; - while (index < lines.length && lines[index].trim() && !isTableLine(lines[index]) && !/^(#{1,3})\s+/.test(lines[index]) && !/^[-*]\s+/.test(lines[index]) && !/^\d+\.\s+/.test(lines[index])) paragraph.push(lines[index++]); + while (index < lines.length && lines[index].trim() && !isTableLine(lines[index]) && !/^!\[/.test(lines[index]) && !/^(#{1,3})\s+/.test(lines[index]) && !/^[-*]\s+/.test(lines[index]) && !/^\d+\.\s+/.test(lines[index])) paragraph.push(lines[index++]); const isApproval = paragraph.some((line) => /^(Name|Role|Signature|Date|Position|Company|Project roles|Decision):/.test(line.trimEnd())); const html = `${renderParagraph(paragraph)}

`; // Keep a signatory's heading and fields on one page. @@ -226,7 +236,7 @@ async function main() { ? '@page { size: A4 landscape; margin: 32mm 15mm 24mm 15mm; }' : ''; const templateFont = ``; - const html = `
${markdownToHtml(body)}
`; + const html = `
${markdownToHtml(body, path.dirname(source))}
`; await fs.mkdir(path.dirname(destination), { recursive: true }); const browser = await chromium.launch({ headless: true }); diff --git a/scripts/sdlc-delivery/verify-content.mjs b/scripts/sdlc-delivery/verify-content.mjs index 1881217..e3b798c 100644 --- a/scripts/sdlc-delivery/verify-content.mjs +++ b/scripts/sdlc-delivery/verify-content.mjs @@ -12,6 +12,8 @@ function extractDocumentContent(markdown) { .slice((titleMatch?.index ?? 0) + (titleMatch?.[0].length ?? 0)) .replace(/^\s*$/m, '') .replace(//gi, ' ') // markup, not document text + // A figure prints its caption; the image path is markup. + .replace(/^!\[([^\]]*)\]\([^)]*\)\s*$/gm, '$1') // List markers are drawn by the renderer, not stored as text: the browser // paints them from
    /
      and Word from numbering.xml, so they are // markup here too and must not be expected in the extracted text. diff --git a/scripts/sdlc-seed/README.md b/scripts/sdlc-seed/README.md index 634b43f..f6e47cf 100644 --- a/scripts/sdlc-seed/README.md +++ b/scripts/sdlc-seed/README.md @@ -16,6 +16,7 @@ Approval signature tables on every document. | `history.mjs` | Work Schedule, reporting periods, meetings, Correction Register, Change Reports | | `lib.mjs` | Buddhist-calendar dates, Markdown tables, signature blocks | | `format.mjs` | The shared work-product scaffold | +| `figures.mjs` | Software Design diagrams and wireframes, drawn as SVG; `scripts/sdlc-delivery/render-figures.mjs` rasterises them into `figures/*.png` | | `docs-*.mjs` | One generator per work product | | `build.mjs` | Writes all documents and checks no folder is left empty | diff --git a/scripts/sdlc-seed/build.mjs b/scripts/sdlc-seed/build.mjs index d40a498..64c6679 100644 --- a/scripts/sdlc-seed/build.mjs +++ b/scripts/sdlc-seed/build.mjs @@ -11,6 +11,7 @@ import * as other from './docs-other.mjs'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); const target = path.join(root, 'sdlc'); +const figureSource = path.join(path.dirname(fileURLToPath(import.meta.url)), 'figures'); // Folders that must exist even when a work product is evidence rather than a document. const FOLDERS = [ @@ -71,7 +72,16 @@ async function main() { await fs.rm(target, { recursive: true, force: true }); for (const folder of FOLDERS) await fs.mkdir(path.join(target, folder), { recursive: true }); - for (const d of docs) await fs.writeFile(path.join(target, d.dir, `${d.name}.md`), d.md, 'utf8'); + for (const d of docs) { + await fs.writeFile(path.join(target, d.dir, `${d.name}.md`), d.md, 'utf8'); + // Figures referenced as ![caption](figures/x.png) are copied next to the document. + for (const [, file] of d.md.matchAll(/^!\[[^\]]*\]\(figures\/([^)]+)\)$/gm)) { + const from = path.join(figureSource, file); + try { await fs.access(from); } catch { throw new Error(`${d.name} references missing figure ${file}; run scripts/sdlc-delivery/render-figures.mjs`); } + await fs.mkdir(path.join(target, d.dir, 'figures'), { recursive: true }); + await fs.copyFile(from, path.join(target, d.dir, 'figures', file)); + } + } const empty = []; for (const folder of FOLDERS) { diff --git a/scripts/sdlc-seed/docs-other.mjs b/scripts/sdlc-seed/docs-other.mjs index 2af5c85..66df14d 100644 --- a/scripts/sdlc-seed/docs-other.mjs +++ b/scripts/sdlc-seed/docs-other.mjs @@ -1,7 +1,7 @@ // 3-Other Document: Stakeholder Register, Project Charter, Traceability Record Table, Training Report, List of Evidence. import { P, TEAM, CODE, PROJECT_TH, COMPANY_TH, ORGANIZER_PM, RECORDER, START, END, SCOPE, CRS, TRAINING_DATE, ACCEPT_DATE, TEST_FROM, TEST_TO, BASELINE_COMMIT, ORIGIN, BACKUP, TAG, DEV_START } from './project.mjs'; import { SRS, UNITS, TEST_CASES, traceOf, srTopic, unitTopic } from './engineering.mjs'; -import { CORRECTIONS, CHANGES, PERIODS, MEETINGS, TASKS } from './history.mjs'; +import { CORRECTIONS, PERIODS, MEETINGS, TASKS } from './history.mjs'; import { bud, thLong, thRangeLong, table, bullets, numbered, daysBetween } from './lib.mjs'; import { workProduct, head } from './format.mjs'; @@ -119,8 +119,9 @@ export function traceabilityTable() { const date = '2026-08-17'; const rows = CRS.map(([id, text]) => { const t = traceOf(id); - return [id, text, t.sr.join(', '), t.un.join(', '), t.tc, 'Passed', 'Passed']; + return [id, text, t.sr.join(', '), t.un.join(', ') || '-', t.tc, t.ev || '-', 'Passed', 'Passed']; }); + const traced = CRS.map(([id]) => traceOf(id)); return { dir: OTHER, name: `${CODE} TRACEABILITY-RECORD ${bud(date)} V1.0 NoC`, @@ -136,14 +137,15 @@ export function traceabilityTable() { '## วัตถุประสงค์', 'ตารางนี้สรุปเส้นทางการสอบกลับของความต้องการทุกรายการ ตั้งแต่ความต้องการของลูกค้าจนถึงผลการทดสอบและผลการทดสอบการยอมรับ เพื่อใช้ตรวจสอบความครบถ้วนได้ในหน้าเดียว โดยรายละเอียดหัวข้อของแต่ละรหัสอยู่ในเอกสาร Traceability Record (WP 13)', '## ตารางสรุปการสอบกลับ', - table(['CR ID', 'Customer Requirement', 'SRS ID', 'Unit ID', 'Test Case ID', 'ผลการทดสอบ', 'ผล UAT'], rows, ['', '', '', '', 'c', 'c', 'c']), + table(['CR ID', 'Customer Requirement', 'SRS ID', 'Unit ID', 'Test Case ID', 'หลักฐานอื่น (Document)', 'ผลการทดสอบ', 'ผล UAT'], rows, ['', '', '', '', 'c', '', 'c', 'c']), '## สรุปความครอบคลุม', table(['รายการ', 'จำนวน'], [ ['ความต้องการของลูกค้าทั้งหมด', CRS.length], ['เชื่อมโยงกับความต้องการซอฟต์แวร์', CRS.length], - ['เชื่อมโยงกับ Software Unit', CRS.length], - ['เชื่อมโยงกับ Test Case', CRS.length], - ['ผลการทดสอบผ่าน', CRS.length], + ['เชื่อมโยงกับ Software Unit', traced.filter((t) => t.un.length).length], + ['เชื่อมโยงกับ Test Case', traced.filter((t) => t.tcs.length).length], + ['ยืนยันด้วยเอกสารส่งมอบ (ไม่มี Software Unit)', traced.filter((t) => !t.tcs.length).length], + ['ผลการทดสอบหรือการตรวจสอบเอกสารผ่าน', CRS.length], ['ผลการทดสอบการยอมรับผ่าน', CRS.length], ], ['', 'r']), ].join('\n\n'), diff --git a/scripts/sdlc-seed/docs-pm1.mjs b/scripts/sdlc-seed/docs-pm1.mjs index 89238e9..5479f85 100644 --- a/scripts/sdlc-seed/docs-pm1.mjs +++ b/scripts/sdlc-seed/docs-pm1.mjs @@ -1,6 +1,6 @@ // 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 { TASKS, VERIFICATION_ROUNDS, VERIFICATION_RULES } from './history.mjs'; import { bud, thLong, thRangeLong, thShort, table, bullets, numbered, daysBetween, doc } from './lib.mjs'; import { workProduct, head } from './format.mjs'; @@ -97,7 +97,7 @@ export function workSchedule() { ['ตั้ง 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 ผ่านทั้งหมด'], + ['ทดสอบระบบและ UAT', thRangeLong(TEST_FROM, TEST_TO), `ทดสอบ 45 Test Case และ UAT ครบ 14 หมวดความต้องการ (${CRS.length} รายการ) ผ่านทั้งหมด`], ['ตรวจรับส่งมอบระบบ', thLong('2026-08-17'), 'ผลการตรวจรับ Accepted'], ['อบรมผู้ใช้งาน', thLong('2026-08-22'), 'อบรมผู้ใช้งาน 6 คน'], ['ปิดโครงการ', thLong(END), 'ปิดโครงการอย่างเป็นทางการ'], @@ -185,11 +185,11 @@ export function softwareProjectPlan() { 'ตรวจสอบย้อนกลับ (Audit) และตรวจรับงานได้อย่างเป็นทางการ', ]), table(['ขั้นตอน', 'แนวทางที่ใช้จริงในโครงการ'], [ - ['Requirements', 'เก็บความต้องการและตั้ง Baseline ก่อนเริ่มพัฒนา การเปลี่ยนแปลงภายหลังผ่าน Change Report (CH-001–CH-003)'], + ['Requirements', 'เก็บความต้องการและตั้ง Baseline ก่อนเริ่มพัฒนา การเปลี่ยนแปลงภายหลังต้องพิจารณาตามเกณฑ์ใน Change Report ก่อนดำเนินการ'], ['Design', 'ออกแบบสถาปัตยกรรม โครงสร้างฐานข้อมูล และ Software Unit ก่อนพัฒนาแต่ละโมดูล'], ['Implementation', 'พัฒนาเป็นโมดูลต่อเนื่องระหว่าง 19 ก.พ. – 29 พ.ค. 69 พร้อมทบทวนและแก้ไขระหว่างทาง'], - ['Verification', 'ตรวจสอบ Work Products 4 รอบ ควบคู่กับการพัฒนา และรอบสุดท้ายก่อนส่งมอบ'], - ['Validation', 'ทดสอบระบบและ UAT ระหว่าง 10–14 ส.ค. 69 บนสภาพแวดล้อมที่กำหนด'], + ['Verification', 'ตรวจสอบ Work Products 4 รอบ ประมาณทุก 2 เดือน และรอบสุดท้ายก่อนส่งมอบ ตามแผนในหัวข้อ 8.1'], + ['Validation', 'ทดสอบระบบและ UAT ระหว่าง 10–14 ส.ค. 69 บนสภาพแวดล้อมที่กำหนด โดยใช้ Customer Requirements ทุกรายการเป็นตัวตั้ง'], ['Closure', 'ตรวจรับ อบรม ปิดงานควบคุมปฏิบัติการ และปิดโครงการภายใน 24 ส.ค. 69'], ]), sec(5, 'Organization'), @@ -241,6 +241,19 @@ export function softwareProjectPlan() { ['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'], ]), + '### 8.1 แผนการตรวจสอบ (Verification Plan)', + `โครงการมีระยะเวลา ${DURATION} วัน จึงกำหนดให้ตรวจสอบ Work Products ทั้งหมด ${VERIFICATION_ROUNDS.length} ครั้ง ประมาณทุก 2 เดือน (ทุก 60–75 วัน) ครั้งละ 3 ชั่วโมง และรอบสุดท้ายก่อนส่งมอบระบบ 6 ชั่วโมง เพื่อให้พบประเด็นตั้งแต่เนิ่น ๆ และแก้ไขได้ก่อนเริ่มงานขั้นถัดไป ผลการตรวจสอบแต่ละรอบบันทึกใน Verification Results และประเด็นที่พบบันทึกใน Correction Register`, + table(['รอบ', 'วันที่ตรวจสอบ', 'เวลา', 'ชั่วโมง', 'หัวข้อการตรวจสอบ', 'Deliverables under Review'], + VERIFICATION_ROUNDS.map((r) => [r.no, thLong(r.date), r.time, r.hours, r.topic, r.wps.join(', ')]), ['c', '', 'c', 'r', '', '']), + table(['หัวข้อ', 'รายละเอียด'], [ + ['ผู้ตรวจสอบ', `${P.PaNg.th} (QA/Tester) ร่วมกับ ${P.YaB.th} (Document Control)`], + ['ผู้เข้าร่วมรับฟังผล', 'ผู้จัดทำ Work Product ที่ตรวจในรอบนั้น เพื่อแก้ไขได้ทันทีเมื่อพบประเด็น'], + ['ผู้อนุมัติผลการตรวจสอบ', `${P.SeV.th} (Project Sponsor)`], + ['รวมเวลาตรวจสอบตลอดโครงการ', `${VERIFICATION_ROUNDS.reduce((a, r) => a + r.hours, 0)} ชั่วโมง`], + ['บันทึกผล', 'Verification Results แยกฉบับตามรอบ (V0.1–V1.0) และ Correction Register'], + ]), + '**Risk & Constraints Note**', + numbered(VERIFICATION_RULES), sec(9, 'Risk Management Plan'), 'วัตถุประสงค์ของแผนบริหารความเสี่ยง คือระบุแนวทางจัดการความเสี่ยงของโครงการ เพื่อให้โครงการบรรลุเป้าหมายภายในเวลา งบประมาณ และคุณภาพที่กำหนด', table(['ลำดับ', 'หมวด', 'รายการ', 'รายละเอียด'], [ @@ -309,8 +322,8 @@ 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]); + rows.push([`${gid}: ${gname}`, '', '']); + for (const [id, text] of items) rows.push([id, text, 'A']); } return { dir: '1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement', @@ -336,7 +349,7 @@ export function customerRequirements() { [6, 'ฝ่ายบัญชีและการเงิน', 'ผู้ใช้งาน', 'ให้ข้อมูลการวางบิล รับชำระ จ่ายชำระ และการบันทึกบัญชี'], ], ['c']), '## ความต้องการเชิงหน้าที่และไม่ใช่หน้าที่ (Functional and Non-Functional Requirements)', - table(['ID', 'Topic', 'Result*', 'Remark'], rows, ['', '', 'c', '']), + table(['ID', 'Topic', 'Result*'], rows, ['', '', 'c']), '## Remark', bullets(['\\* Result : A = Accepted, U = Unaccepted, N/A = Not Applicable', 'เอกสารฉบับนี้รวมความต้องการที่ได้จากการทบทวนขอบเขตงานร่วมกับลูกค้า', 'การเปลี่ยนแปลงความต้องการหลังอนุมัติต้องดำเนินการผ่าน Change Report']), ].join('\n\n'), diff --git a/scripts/sdlc-seed/docs-pm2.mjs b/scripts/sdlc-seed/docs-pm2.mjs index 9584b62..6a5cd99 100644 --- a/scripts/sdlc-seed/docs-pm2.mjs +++ b/scripts/sdlc-seed/docs-pm2.mjs @@ -1,7 +1,7 @@ // PM work products 3–10: Progress Status Record, Correction Register, Acceptance Report, // Change Report, Meeting Record, Software Configuration, Project Repository (+ Backup). -import { P, CODE, PROJECT_TH, COMPANY_TH, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, WPS, TEAM, ORIGIN, BACKUP, TAG, BASELINE_COMMIT, TEST_FROM, TEST_TO, ACCEPT_DATE, OPS_CLOSE_DATE } from './project.mjs'; -import { TASKS, taskById, CORRECTIONS, CHANGES, PERIODS, MEETINGS } from './history.mjs'; +import { P, CRS, CODE, PROJECT_TH, COMPANY_TH, ORGANIZER, ORGANIZER_PM, RECORDER, START, END, WPS, TEAM, ORIGIN, BACKUP, TAG, BASELINE_COMMIT, TEST_FROM, TEST_TO, ACCEPT_DATE, OPS_CLOSE_DATE } from './project.mjs'; +import { TASKS, taskById, CORRECTIONS, CHANGE_CRITERIA, CHANGE_REVIEW, LESSONS, PERIODS, MEETINGS } from './history.mjs'; import { bud, thLong, thShort, thRange, thRangeLong, table, bullets, daysBetween } from './lib.mjs'; import { workProduct, head } from './format.mjs'; @@ -22,10 +22,8 @@ export function progressStatusRecords() { const c = CORRECTIONS.find((x) => x[0] === iid); return [n + 1, `${c[0]} : ${c[4]}`, `${c[5]} จึงดำเนินการ${c[6]} แล้วเสร็จ ${thShort(c[2])}`, P[c[7]].id, 'เสร็จสิ้น']; }); - const changes = changeIds.map((cid) => { - const c = CHANGES.find((x) => x.id === cid); - return [c.id, c.titleTh, 'อนุมัติ', c.impact[0][1]]; - }); + if (changeIds.length) throw new Error(`Progress record ${date} lists change requests, but the project has none.`); + const changes = []; return { dir: dir3, name: `${CODE} Progress Status Record ${bud(date)} V1.0 ApS`, @@ -88,6 +86,10 @@ export function correctionRegister() { ['คงค้าง', 0], ], ['', 'r']), `ปัญหาทุกรายการได้รับการแก้ไขและตรวจสอบผลด้วย Test Case ที่เกี่ยวข้อง โดยผลการทดสอบผ่านทั้งหมดในรอบทดสอบระหว่าง ${thRangeLong(TEST_FROM, TEST_TO)} ไม่มีข้อบกพร่องระดับวิกฤตคงค้าง ณ วันตรวจรับ`, + '## บทเรียนและแนวทางป้องกันสำหรับโครงการถัดไป (Lessons Learned)', + 'เมื่อปิดโครงการ ทีมงานทบทวนปัญหาทั้งหมดในทะเบียนนี้ จัดกลุ่มตามสาเหตุ และกำหนดแนวทางป้องกันเพื่อไม่ให้ปัญหาลักษณะเดียวกันเกิดซ้ำในโครงการถัดไป', + table(['ลำดับ', 'กลุ่มปัญหา', 'เลขที่ปัญหา', 'จำนวน', 'สิ่งที่เกิดขึ้น', 'แนวทางป้องกัน (Preventive Action)'], + LESSONS.map(([theme, issueIds, what, action], i) => [i + 1, theme, issueIds.join(', '), issueIds.length, what, action]), ['c', '', '', 'r', '', '']), '## การเชื่อมโยงกับหลักฐานการทดสอบ', table(['เลขที่', 'การแก้ไขอ้างอิง (Commit)', 'Test Case ที่ใช้ตรวจสอบ', 'ผลการทดสอบ'], CORRECTIONS.map((c) => [c[0], `\`${c[8]}\``, c[9], 'Passed']), ['c', '', 'c', 'c']), ].join('\n\n'), @@ -118,7 +120,7 @@ export function acceptanceReport() { table(['ลำดับ', 'เกณฑ์การตรวจรับ', 'หลักฐานอ้างอิง', 'ผลการตรวจสอบ'], [ [1, 'ฟังก์ชันในขอบเขตทำงานตรงตาม Customer Requirements ครบทุกรายการ', 'Traceability Record, Test Report', 'ผ่าน'], [2, 'ทดสอบระบบตาม Test Case ครบถ้วน', `Test Report 45 Test Case ผ่านทั้งหมด (${thRangeLong(TEST_FROM, TEST_TO)})`, 'ผ่าน'], - [3, 'ทดสอบการยอมรับโดยผู้ใช้ (UAT)', 'Validation Results 12 สถานการณ์ ผ่านทั้งหมด', 'ผ่าน'], + [3, 'ทดสอบการยอมรับโดยผู้ใช้ (UAT)', `Validation Results ครบ 14 หมวดความต้องการ (${CRS.length} รายการ) ผ่านทั้งหมด`, 'ผ่าน'], [4, 'ไม่มีข้อบกพร่องระดับวิกฤตคงค้าง', `Correction Register ${CORRECTIONS.length} รายการ แก้ไขและตรวจสอบครบ`, 'ผ่าน'], [5, 'เอกสารคู่มือผู้ใช้ ผู้ดูแลระบบ และการบำรุงรักษาครบถ้วน', 'Software User Document, Product Operation Guide, Maintenance Document', 'ผ่าน'], [6, 'Source Code และเอกสารจัดเก็บใน Repository พร้อมชุดสำรอง', 'Project Repository, Project Repository (Backup)', 'ผ่าน'], @@ -139,65 +141,50 @@ export function acceptanceReport() { }; } -/** 6. Change Report — one document per change request. */ +/** 6. Change Report — the change-control register. No adjustment in this project met the criteria. */ export function changeReports() { - return CHANGES.map((c) => ({ + const date = ACCEPT_DATE; + return [{ dir: '1-PM Process (10 Work Product)/6.Change Report', - name: `${CODE} Change Report ${bud(c.date)} V1.0 ${c.requester.id}`, + name: `${CODE} Change Report ${bud(date)} V1.0 ApS`, md: workProduct({ type: 'Change Report', footer: 'CR', - rows: head('Change Report', `${bud(c.date)} V1.0 ${c.requester.id}`, [ - ['Change ID', c.id, 'วันที่ร้องขอ', thLong(c.date)], - ['ผู้ร้องขอ (Requester)', `${c.requester.th} (${c.requester.role})`], - ['หน่วยงาน/ฝ่าย', c.unit], - ['ประเภทการเปลี่ยนแปลง', `☒ ${c.type} ☒ ${c.typeChecked} ☐ Schedule ☐ Cost ☐ Resource ☐ Other`], - ['ความเร่งด่วน (Priority)', `☐ High ☒ ${c.priority} ☐ Low`], + rows: head('Change Report', `${bud(date)} V1.0 ApS`, [ + ['Title', 'ทะเบียนการควบคุมการเปลี่ยนแปลง (Change Control Register)'], + ['Project Period', thRangeLong(START, END)], + ['Organizer', ORGANIZER_PM], + ['Recorder', RECORDER], ]), body: [ - '## ส่วนที่ 1 : ข้อมูลทั่วไป', - table(['หัวข้อ', 'รายละเอียด'], [ - ['ชื่อการเปลี่ยนแปลง', c.titleTh], - ['โครงการ', PROJECT_TH], - ['ระยะที่เกิดการเปลี่ยนแปลง', `ช่วงดำเนินโครงการ (${thLong(c.date)})`], - ['เอกสารที่เกี่ยวข้อง', 'Customer Requirements, Software Project Plan, Traceability Record'], - ]), - '## ส่วนที่ 2 : รายละเอียดการเปลี่ยนแปลง', - table(['ลำดับ', 'รายการ', 'รายละเอียด'], [ - [1, 'คำอธิบายการเปลี่ยนแปลงที่ต้องการ (Description)', c.description], - [2, 'เหตุผลของการเปลี่ยนแปลง (Justification)', c.justification], - ], ['c']), - '## ส่วนที่ 3 : การประเมินผลกระทบ (Impact Analysis)', - table(['ลำดับ', 'รายการ', 'รายละเอียด'], c.impact.map((r, i) => [i + 1, r[0], r[1]]), ['c']), - '## ส่วนที่ 4 : การพิจารณาอนุมัติ (Change Advisory Board Approval)', - table(['ลำดับ', 'ชื่อผู้พิจารณา', 'ตำแหน่ง', 'ความคิดเห็น / ลงนาม'], [ - [1, P.ApS.th, 'Project Manager', 'เห็นควรอนุมัติ ผลกระทบอยู่ในวิสัยที่ควบคุมได้'], - [2, P.NoC.th, 'System Analyst', 'สอดคล้องกับความต้องการและการออกแบบ'], - [3, P.PaNg.th, 'QA / Tester', 'ต้องทดสอบซ้ำในส่วนที่ได้รับผลกระทบ'], - [4, P.SeV.th, 'Project Sponsor', 'อนุมัติ'], - ], ['c']), - '## ส่วนที่ 5 : สรุปผลการพิจารณา', - table(['หัวข้อ', 'รายละเอียด'], [ - ['สถานะ', '☒ อนุมัติ (Approved) ☐ ไม่อนุมัติ (Rejected)'], - ['การอ้างอิงการดำเนินการ', `Commit \`${c.commit}\``], - ['ผลการดำเนินการ', c.result], - ]), - '## ภาคผนวก A : เกณฑ์การประเมินระดับความรุนแรงของการเปลี่ยนแปลง (Change Criteria)', - 'ตารางนี้ใช้เป็นแนวทางประเมินระดับความรุนแรง (Priority Level) ของการเปลี่ยนแปลง เพื่อให้คณะพิจารณา (Change Advisory Board – CAB) กำหนดระดับผลกระทบและความเร่งด่วนได้ชัดเจนตามมาตรฐาน ISO/IEC 29110', - table(['ระดับ (Level)', 'คำจำกัดความ (Definition)', 'ตัวอย่างสถานการณ์ (Examples)', 'ผลกระทบ (Impact Scope)'], [ - ['High', 'การเปลี่ยนแปลงที่มีผลกระทบอย่างมีนัยสำคัญต่อระบบหลัก งบประมาณ หรือแผนโครงการ ซึ่งต้องได้รับอนุมัติจาก Project Manager และ Project Sponsor', 'ปรับสถาปัตยกรรมหลักของระบบ / เพิ่มฟังก์ชันหลักใหม่ / ต้องปรับงบประมาณหรือระยะเวลาโครงการ', 'กระทบ Scope, Schedule และ Cost โดยตรง'], - ['Medium', 'การเปลี่ยนแปลงที่มีผลกระทบต่อส่วนติดต่อผู้ใช้งานหรือฟังก์ชันย่อยบางส่วน แต่ไม่กระทบโครงสร้างหลัก', 'ปรับปรุงหน้าจอ / ปรับข้อความหรือตรรกะบางส่วน / เพิ่มการตรวจสอบข้อมูล', 'กระทบ Quality หรือ Deliverables บางส่วน'], - ['Low', 'การเปลี่ยนแปลงขนาดเล็กที่ไม่ส่งผลต่อการทำงานหลักของระบบ', 'แก้ไขคำสะกดหรือข้อความแสดงผล / เปลี่ยนโลโก้หรือรูปภาพ / ปรับฟอนต์หรือสี', 'ผลกระทบเล็กน้อยต่อ Deliverables'], - ]), - '**แนวทางการใช้งาน**', - bullets([ - 'ผู้ร้องขอ (Requester) ระบุระดับความรุนแรงตามตารางนี้ในส่วน "ความเร่งด่วน (Priority)"', - 'คณะพิจารณา (CAB) ใช้ตารางนี้ประกอบการพิจารณาในส่วน "การประเมินผลกระทบ (Impact Analysis)"', - 'หากมีข้อสงสัยในระดับผลกระทบ ให้ใช้ระดับที่สูงกว่าเพื่อความปลอดภัยของโครงการ', + '## วัตถุประสงค์ (Objective)', + 'เอกสารนี้บันทึกการควบคุมการเปลี่ยนแปลงของโครงการ ตั้งแต่ตั้ง Baseline ความต้องการเมื่อ 18 กุมภาพันธ์ 2569 จนถึงการตรวจรับส่งมอบ โดยพิจารณาทุกรายการปรับปรุงที่มีการเสนอตามเกณฑ์ในส่วนที่ 1 รายการที่เข้าเกณฑ์ต้องจัดทำคำขอเปลี่ยนแปลง ประเมินผลกระทบ และขออนุมัติก่อนดำเนินการ ส่วนรายการที่ไม่เข้าเกณฑ์ดำเนินการเป็นมติที่ประชุมหรืองานในแผน', + '## ส่วนที่ 1 : เกณฑ์การพิจารณาคำขอเปลี่ยนแปลง (Change Criteria)', + 'รายการใดจะถือเป็นคำขอเปลี่ยนแปลงเมื่อเข้าเกณฑ์ทั้ง 3 ข้อ หากตัดรายการนั้นออกแล้วยังส่งมอบงานได้ตามที่ตกลงไว้ จะไม่ถือเป็นคำขอเปลี่ยนแปลง', + table(['ลำดับ', 'เกณฑ์', 'คำอธิบาย'], CHANGE_CRITERIA.map(([name, detail], i) => [i + 1, name, detail]), ['c']), + '## ส่วนที่ 2 : ทะเบียนคำขอเปลี่ยนแปลง (Change Request Log)', + table(['Change ID', 'หัวข้อ', 'ผู้ร้องขอ', 'ผลกระทบ', 'สถานะ'], [['-', 'ไม่มีคำขอเปลี่ยนแปลงที่เข้าเกณฑ์ตลอดโครงการ', '-', '-', '-']], ['c', '', 'c', '', 'c']), + '## ส่วนที่ 3 : รายการปรับปรุงที่พิจารณาแล้วไม่เข้าเกณฑ์', + table(['ลำดับ', 'วันที่พิจารณา', 'รายการ', 'ผู้เสนอ', 'ผลการพิจารณา', 'การดำเนินการ', 'อ้างอิง'], + CHANGE_REVIEW.map(([when, topic, who, assessment, handled, ref], i) => [i + 1, thShort(when), topic, P[who].id, `ไม่เข้าเกณฑ์ — ${assessment}`, handled, ref]), ['c', 'c', '', 'c', '', '', '']), + '## ส่วนที่ 4 : สรุปผลการควบคุมการเปลี่ยนแปลง', + table(['รายการ', 'จำนวน'], [ + ['รายการปรับปรุงที่เสนอและพิจารณา', CHANGE_REVIEW.length], + ['คำขอเปลี่ยนแปลงที่เข้าเกณฑ์', 0], + ['คำขอเปลี่ยนแปลงที่อนุมัติ', 0], + ['ผลกระทบต่อ Man-day กำหนดส่งมอบ และค่าใช้จ่าย', 'ไม่มี'], + ], ['', 'r']), + 'ขอบเขตงาน สิ่งส่งมอบ และ Customer Requirements ที่ตั้ง Baseline ไม่มีการเปลี่ยนแปลงตลอดโครงการ รายการปรับปรุงที่พิจารณาทั้งหมดดำเนินการภายในแผนงานเดิมโดยไม่กระทบ Man-day และกำหนดส่งมอบ', + '## ภาคผนวก A : เกณฑ์การประเมินระดับความรุนแรงของการเปลี่ยนแปลง', + 'ใช้ประเมินระดับความรุนแรง (Priority Level) เมื่อมีคำขอเปลี่ยนแปลงที่เข้าเกณฑ์ในส่วนที่ 1', + table(['ระดับ (Level)', 'คำจำกัดความ (Definition)', 'ตัวอย่างสถานการณ์ (Examples)'], [ + ['High', 'กระทบระบบหลัก งบประมาณ หรือแผนงานอย่างมีนัยสำคัญ', 'เพิ่มโมดูลใหม่ เปลี่ยนโครงสร้างฐานข้อมูลหลัก'], + ['Medium', 'กระทบฟังก์ชันย่อยหรือส่วนติดต่อผู้ใช้งานบางส่วน และกระทบ Man-day', 'รองรับ 2 ภาษา เพิ่มรายงานใหม่'], + ['Low', 'กระทบเล็กน้อยต่อ Man-day ไม่เปลี่ยนการทำงานหลัก', 'เพิ่มฟิลด์ในเอกสาร'], ]), ].join('\n\n'), - secretary: c.requester, reviewer: P.ApS, approver: P.SeV, + secretary: P.ApS, reviewer: P.YaB, approver: P.SeV, }), - })); + }]; } /** 7. Meeting Record — Minutes of Meeting per checkpoint. */ @@ -266,7 +253,7 @@ export function softwareConfiguration() { ['**เอกสารส่งมอบครั้งที่ 2 (พัฒนาและทดสอบ)**', '', ''], ['WP 3.0', `เอกสาร ${CODE} Software Requirements Specification`, '1.0'], ['WP 4.0', `เอกสาร ${CODE} Software Design`, '1.0'], - ['WP 5.0', `เอกสาร ${CODE} Change Report (CH-001–CH-003)`, '1.0'], + ['WP 5.0', `เอกสาร ${CODE} Change Report`, '1.0'], ['WP 6.0', `เอกสาร ${CODE} Test Case and Test Procedures`, '1.0'], ['WP 7.0', `เอกสาร ${CODE} Validation Results`, '1.0'], ['WP 8.0', `เอกสาร ${CODE} Software User Document`, '1.0'], @@ -296,7 +283,7 @@ export function softwareConfiguration() { ['สิทธิ์การเข้าถึง', 'ยืนยันตัวตนด้วย SSH Key ตามบทบาทของสมาชิกโครงการ'], ]), '## การเชื่อมโยงกับการเปลี่ยนแปลง', - `การเปลี่ยนแปลง Configuration Item ต้องผ่าน Change Report (CH-001–CH-003) และการแก้ไขข้อบกพร่องต้องบันทึกใน Correction Register (${CORRECTIONS[0][0]}–${CORRECTIONS[CORRECTIONS.length - 1][0]}) โดยทุกรายการเชื่อมโยงกับ Commit ที่ตรวจสอบได้ใน Repository`, + `การเปลี่ยนแปลง Configuration Item ต้องพิจารณาตามเกณฑ์ใน Change Report และการแก้ไขข้อบกพร่องต้องบันทึกใน Correction Register (${CORRECTIONS[0][0]}–${CORRECTIONS[CORRECTIONS.length - 1][0]}) โดยทุกรายการเชื่อมโยงกับ Commit ที่ตรวจสอบได้ใน Repository`, ].join('\n\n'), secretary: P.ThS, reviewer: P.ApS, approver: P.SeV, }), diff --git a/scripts/sdlc-seed/docs-si.mjs b/scripts/sdlc-seed/docs-si.mjs index 103c735..66cfaa3 100644 --- a/scripts/sdlc-seed/docs-si.mjs +++ b/scripts/sdlc-seed/docs-si.mjs @@ -2,6 +2,7 @@ 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 { figure } from './figures.mjs'; import { bud, thLong, thShort, thRangeLong, table, bullets, numbered } from './lib.mjs'; import { workProduct, head } from './format.mjs'; @@ -72,8 +73,12 @@ export function softwareDesign() { ]), body: [ '## HIGH LEVEL DESIGN', + '### High Level Architecture Diagram', + 'ภาพรวมสถาปัตยกรรมของระบบ แบ่งเป็นผู้ใช้งาน ชั้น Client, Web, Data, Service และบริการภายนอก พร้อมช่องทางการเชื่อมต่อระหว่างกัน ทุกคำขอจากหน้าจอผ่านการตรวจสอบของ db_auth ก่อนถึงตรรกะธุรกิจ', + figure('architecture'), '### Use Case Diagram', - 'ผู้ใช้งานของระบบและกลุ่มการใช้งานหลัก', + 'ผู้ใช้งานของระบบและกลุ่มการใช้งานหลัก บทบาทที่สูงกว่าได้รับสิทธิ์การใช้งานของบทบาทที่ต่ำกว่าทั้งหมด (Viewer → Staff → Admin → Owner)', + figure('useCase'), table(['Actor', 'คำอธิบาย', 'การใช้งานหลัก'], [ ['Owner', 'เจ้าของบริษัท สิทธิ์สูงสุดภายในบริษัท', 'ตั้งค่าบริษัท จัดการผู้ใช้ และใช้งานทุกโมดูล'], ['Admin', 'ผู้ดูแลระบบภายในบริษัท', 'จัดการข้อมูลหลัก ผู้ใช้ สิทธิ์ และใช้งานทุกโมดูลปฏิบัติการ'], @@ -83,6 +88,8 @@ export function softwareDesign() { ['SMTP Service', 'ผู้กระทำภายนอก', 'ส่งอีเมล Onboarding กู้คืนรหัสผ่าน และแจ้งเตือน'], ]), '### Component Diagram', + 'โมดูลของระบบ (Software Unit กลุ่ม UN01–UN13) และความสัมพันธ์การเรียกใช้ระหว่างโมดูล', + figure('component'), 'โครงสร้างส่วนประกอบของระบบแบ่งตามชั้นการทำงาน', table(['ชั้น (Layer)', 'ส่วนประกอบ', 'อ้างอิง SR'], [ ['Presentation', 'หน้าจอ PHP ในแต่ละโมดูล (`app//`), JavaScript และ CSS ที่รองรับ Responsive', 'SR02:002, SR06:002, SR06:003'], @@ -92,6 +99,8 @@ export function softwareDesign() { ['External', 'บริการ SMTP สำหรับส่งอีเมล และ Socket.IO Client บน Browser', 'SR06:004, SR06:005'], ]), '### Deployment Diagram', + 'การติดตั้งบนสภาพแวดล้อมใช้งานจริงด้วย Docker Compose และทางเลือกการติดตั้งแบบ Manual', + figure('deployment'), 'การติดตั้งระบบแบ่งเป็น 4 ชั้นบริการ', table(['ชั้นการติดตั้ง (Tier)', 'ส่วนประกอบ', 'อ้างอิง SR'], [ ['Client', 'Web Browser (Chrome/Edge/Firefox) บน Desktop, Tablet และ Mobile พร้อม Socket.IO Client', 'SR06:002, SR06:003, SR06:005'], @@ -100,7 +109,7 @@ export function softwareDesign() { ['Service Tier', 'Node.js `server.js` และ `scheduler.js` ควบคุมด้วย pm2', 'SR03:011, SR06:004'], ]), '### User Interface Design', - 'ผังหน้าจอหลักของระบบแบ่งตามโมดูลการใช้งาน', + 'ผังหน้าจอหลักของระบบแบ่งตามโมดูลการใช้งาน ทุกหน้าจอใช้โครงร่างเดียวกัน ได้แก่ เมนูด้านซ้ายที่แสดงตามสิทธิ์ของผู้ใช้ แถบด้านบนสำหรับเลือกบริษัทและบัญชีผู้ใช้ และพื้นที่ทำงานด้านขวา', table(['กลุ่มหน้าจอ', 'หน้าจอ'], [ ['Login & Onboarding', 'เข้าสู่ระบบ / ลงทะเบียนบริษัท / รับคำเชิญเข้าร่วมบริษัท / ลืมรหัสผ่าน / ยืนยัน OTP'], ['Dashboard', 'แดชบอร์ดคลังสินค้า / แดชบอร์ดบัญชีและการเงิน'], @@ -113,6 +122,14 @@ export function softwareDesign() { ['Reports', 'รายงานสต๊อก / ความเคลื่อนไหว / ความจุคลัง / สินค้าใกล้หมด / สินค้าหมดอายุ / รายงานการเงิน'], ['Settings', 'ข้อมูลบริษัท / SMTP / ผู้ใช้งานและสิทธิ์ / การตั้งค่าระบบ'], ]), + '### Mockup Wireframe', + 'Wireframe แสดงโครงร่างหน้าจอหลักที่ใช้เป็นแม่แบบในการพัฒนา หน้าจอเอกสารขาย จัดซื้อ และการเงินใช้รูปแบบหน้ารายการ (รูปที่ 7) และหน้าบันทึก (รูปที่ 8) เดียวกัน', + figure('wfLogin'), + figure('wfDashboard'), + figure('wfList'), + figure('wfDocument'), + figure('wfStockIn'), + figure('wfReport'), '## Software Baseline', 'หัวข้อนี้ระบุสิ่งที่ถูกกำหนดเป็น Baseline ของซอฟต์แวร์ วันที่กำหนด และผู้อนุมัติ เพื่อให้ตรวจสอบเส้นทาง Baseline → Configuration → Change ได้ในเอกสารชุดเดียวกัน', table(['รายการที่กำหนดเป็น Baseline', 'ค่าที่ควบคุม', 'ที่จัดเก็บ'], [ @@ -128,7 +145,7 @@ export function softwareDesign() { ['ผู้อนุมัติ', `${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 เมื่อเป็นการแก้ไขข้อบกพร่อง'], + ['การเปลี่ยนแปลง Baseline', 'ต้องพิจารณาตามเกณฑ์ใน Change Report และบันทึกผลใน Correction Register เมื่อเป็นการแก้ไขข้อบกพร่อง'], ]), '## Software Unit', table(['ID', 'Description', 'Functional Interfaces Detail', 'References', 'Files'], unitRows), @@ -143,12 +160,16 @@ export function traceabilityRecord() { const date = '2026-03-06'; const rows = []; let group = ''; - for (const [id, text, remark] of CRS) { + 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]); + rows.push([id, text, t.sr.join(', '), t.sr.map(srTopic).join(' / '), t.un.join(', ') || '-', t.un.map(unitTopic).join(' / ') || '-', t.tc, 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; return { dir: '2-SI Process (12 Work Product)/13.Traceability record', name: `${CODE} Traceability Record ${bud(date)} V1.0 NoC`, @@ -164,13 +185,16 @@ export function traceabilityRecord() { '## วัตถุประสงค์ (Objective)', 'เอกสารที่เชื่อมโยงทุกขั้นตอนของโครงการ ตั้งแต่ความต้องการของลูกค้า → ความต้องการซอฟต์แวร์ → การออกแบบ → การทดสอบ เพื่อยืนยันความครบถ้วนของ Customer Requirements และลดความเสี่ยงของข้อบกพร่องและความต้องการที่ตกหล่น', '## Traceability Matrix', - table(['CR ID', 'CR Topic', 'SRS ID', 'SRS Topic', 'Unit ID', 'Unit Topic', 'Test Case ID'], rows), + table(['CR ID', 'CR Topic', 'SRS ID', 'SRS Topic', 'Unit ID', 'Unit Topic', 'Test Case ID', 'หลักฐานอื่น (Document)'], rows), + 'หมายเหตุ: ความต้องการที่เป็นเอกสาร การอบรม หรือหลักฐานด้านคุณภาพ สอบกลับไปยังเอกสารส่งมอบที่เป็นหลักฐานในคอลัมน์ "หลักฐานอื่น" แทน Software Unit', '## สรุปความครอบคลุม', table(['รายการ', 'จำนวน'], [ ['ความต้องการของลูกค้าทั้งหมด (CR01–CR14)', CRS.length], ['เชื่อมโยงกับความต้องการซอฟต์แวร์ (SRS)', CRS.length], - ['เชื่อมโยงกับ Software Unit', CRS.length], - ['เชื่อมโยงกับ Test Case', 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], @@ -275,9 +299,11 @@ export function testCases() { /** 16. Test Report. */ export function testReport() { const date = '2026-08-14'; - const rows = CRS.map(([id, text], i) => { + const tested = CRS.filter(([id]) => traceOf(id).tcs.length); + const byDocument = CRS.length - tested.length; + const rows = tested.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 [i + 1, t.tc, `ตรวจสอบ ${t.un.map(unitTopic).join(' / ')}`, id, text, 'Passed', thRangeLong(TEST_FROM, TEST_TO)]; }); return { dir: '2-SI Process (12 Work Product)/16.Test Report', @@ -312,6 +338,7 @@ export function testReport() { ], ['', 'r']), '## Verification Items', table(['No', 'Test Case', 'Software Testing', 'Customer Req. ID', 'Customer Req. Topic', 'Status', 'Test Date'], rows, ['c', 'c', '', 'c', '', 'c', 'c']), + `ความต้องการที่ยืนยันด้วย Test Case มี ${tested.length} รายการ ส่วนอีก ${byDocument} รายการเป็นความต้องการด้านเอกสาร การอบรม และหลักฐานด้านคุณภาพ ซึ่งยืนยันด้วยเอกสารส่งมอบตามที่ระบุใน Traceability Record และได้รับการยืนยันจากลูกค้าใน Validation Results`, '## Summary', table(['No', 'Topic', 'Detail'], [ [1, 'Test Case', `ทดสอบตาม Customer Requirements ผ่านทั้งหมด ${TEST_CASES.length} Test Case คิดเป็น 100%`], @@ -358,7 +385,7 @@ export function software() { [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 สถานการณ์ ผ่านทั้งหมด'], + [4, 'ผลการทดสอบการยอมรับ', `Validation Results ครบ 14 หมวด ${CRS.length} รายการ ผ่านทั้งหมด`], [5, 'การตรวจรับส่งมอบ', `Acceptance Report ผลการตรวจรับ Accepted เมื่อ ${thLong(ACCEPT_DATE)}`], [6, 'คู่มือประกอบการใช้งาน', 'Software User Document, Product Operation Guide, Maintenance Document'], ], ['c']), diff --git a/scripts/sdlc-seed/docs-si2.mjs b/scripts/sdlc-seed/docs-si2.mjs index b142bb9..e76def6 100644 --- a/scripts/sdlc-seed/docs-si2.mjs +++ b/scripts/sdlc-seed/docs-si2.mjs @@ -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, }), diff --git a/scripts/sdlc-seed/engineering.mjs b/scripts/sdlc-seed/engineering.mjs index 4b20b3c..0f8a275 100644 --- a/scripts/sdlc-seed/engineering.mjs +++ b/scripts/sdlc-seed/engineering.mjs @@ -206,7 +206,11 @@ export const TEST_CASES = [ ]; export const tcByUnit = (unitId) => TEST_CASES.find((t) => t[1] === unitId)?.[0] ?? ''; -/** Traceability: CR id -> { sr: [...], un: [...] }. The test case is the one owned by the first unit. */ +/** + * Traceability: CR id -> { sr: [...], un: [...], ev? }. + * Every unit brings its own test case. Requirements met by a delivered document or record + * (manuals, training, SLA, quality evidence) name it in `ev`, with or without software units. + */ export const TRACE = { 'CR01:001': { sr: ['SR03:001', 'SR08:001'], un: ['UN01.001'] }, 'CR01:002': { sr: ['SR03:001', 'SR04:001', 'SR07:005'], un: ['UN01.002'] }, @@ -261,43 +265,45 @@ export const TRACE = { 'CR07:004': { sr: ['SR01:003'], un: ['UN13.001'] }, 'CR08:001': { sr: ['SR01:003'], un: ['UN13.004'] }, 'CR08:002': { sr: ['SR01:003'], un: ['UN13.004'] }, - 'CR08:003': { sr: ['SR05:004'], un: ['UN11.002'] }, + 'CR08:003': { sr: ['SR05:004'], un: [], ev: 'Product Operation Guide (การเฝ้าระวังระบบ)' }, 'CR08:004': { sr: ['SR04:003'], un: ['UN12.001'] }, 'CR08:005': { sr: ['SR05:002'], un: ['UN11.002'] }, - 'CR09:001': { sr: ['SR02:003', 'SR02:004'], un: ['UN13.001'] }, + 'CR09:001': { sr: ['SR02:003', 'SR02:004'], un: [], ev: 'Software Design (Software Unit), Software Components' }, 'CR09:002': { sr: ['SR01:005'], un: ['UN13.003'] }, - 'CR09:003': { sr: ['SR01:001'], un: ['UN13.004'] }, + 'CR09:003': { sr: ['SR01:001'], un: [], ev: 'Maintenance Document, Correction Register' }, 'CR09:004': { sr: ['SR08:005', 'SR08:004'], un: ['UN13.001'] }, 'CR10:001': { sr: ['SR01:003', 'SR08:005'], un: ['UN13.001'] }, 'CR10:002': { sr: ['SR02:005'], un: ['UN13.002'] }, 'CR10:003': { sr: ['SR01:005'], un: ['UN13.003'] }, - 'CR10:004': { sr: ['SR01:001'], un: ['UN13.001'] }, - 'CR11:001': { sr: ['SR01:001'], un: ['UN01.002'] }, - 'CR11:002': { sr: ['SR01:001'], un: ['UN13.001'] }, - 'CR11:003': { sr: ['SR01:001'], un: ['UN01.002'] }, - 'CR11:004': { sr: ['SR01:001'], un: ['UN13.004'] }, + 'CR10:004': { sr: ['SR01:001'], un: ['UN13.001', 'UN13.002'], ev: 'Product Operation Guide (ขั้นตอนติดตั้ง)' }, + 'CR11:001': { sr: ['SR01:001'], un: [], ev: 'Software User Document (WP 8.0)' }, + 'CR11:002': { sr: ['SR01:001'], un: [], ev: 'Product Operation Guide (WP 10.0)' }, + 'CR11:003': { sr: ['SR01:001'], un: [], ev: 'Training Report' }, + 'CR11:004': { sr: ['SR01:001'], un: [], ev: 'Maintenance Document (SLA)' }, 'CR12:001': { sr: ['SR01:002'], un: ['UN13.001'] }, - 'CR12:002': { sr: ['SR01:001'], un: ['UN13.001'] }, + 'CR12:002': { sr: ['SR01:001'], un: [], ev: 'Software Configuration, Project Repository' }, 'CR12:003': { sr: ['SR01:004'], un: ['UN01.003'] }, - 'CR12:004': { sr: ['SR01:001'], un: ['UN13.001'] }, + 'CR12:004': { sr: ['SR01:001'], un: [], ev: 'List of Evidence, Verification Results' }, 'CR13:001': { sr: ['SR09:003'], un: ['UN08.002'] }, 'CR13:002': { sr: ['SR09:003'], un: ['UN04.002'] }, 'CR13:003': { sr: ['SR01:003'], un: ['UN13.004'] }, 'CR13:004': { sr: ['SR09:002'], un: ['UN10.002'] }, - 'CR14:001': { sr: ['SR01:001'], un: ['UN01.002'] }, - 'CR14:002': { sr: ['SR01:001'], un: ['UN01.002'] }, - 'CR14:003': { sr: ['SR01:001'], un: ['UN01.002'] }, - 'CR14:004': { sr: ['SR07:002'], un: ['UN12.001'] }, + 'CR14:001': { sr: ['SR01:001'], un: [], ev: 'Test Report' }, + 'CR14:002': { sr: ['SR01:001'], un: [], ev: 'Traceability Record' }, + 'CR14:003': { sr: ['SR01:001'], un: [], ev: 'Validation Results, Acceptance Report' }, + 'CR14:004': { sr: ['SR07:002'], un: ['UN12.001', 'UN12.002'], ev: 'Test Report, Correction Register' }, }; export const traceOf = (crId) => { const t = TRACE[crId]; if (!t) throw new Error(`No traceability entry for ${crId}`); - return { ...t, tc: tcByUnit(t.un[0]) }; + const tcs = [...new Set(t.un.map(tcByUnit))]; + return { sr: t.sr, un: t.un, ev: t.ev ?? '', tcs, tc: tcs.join(', ') || '-' }; }; -// Sanity: every CR is traced and every trace target exists. +// Sanity: every CR is traced, every trace target exists, and each CR ends in a test case or named evidence. for (const [id] of CRS) { const t = traceOf(id); for (const s of t.sr) if (!srTopic(s)) throw new Error(`${id} references unknown ${s}`); for (const u of t.un) if (!unitTopic(u)) throw new Error(`${id} references unknown ${u}`); - if (!t.tc) throw new Error(`${id} has no test case`); + if (t.tcs.some((tc) => !tc)) throw new Error(`${id} has a unit without a test case`); + if (!t.tcs.length && !t.ev) throw new Error(`${id} has neither a test case nor evidence`); } diff --git a/scripts/sdlc-seed/figures.mjs b/scripts/sdlc-seed/figures.mjs new file mode 100644 index 0000000..2a2bdd5 --- /dev/null +++ b/scripts/sdlc-seed/figures.mjs @@ -0,0 +1,337 @@ +// Figures for the Software Design work product: high-level diagrams and low-fidelity wireframes. +// Each figure is an SVG drawn here; scripts/sdlc-delivery/render-figures.mjs rasterises them to +// PNG with the document font (scripts/sdlc-seed/figures/*.png), which build.mjs copies next to +// the Markdown that references them. + +const FONT = "'BRN Thai', 'Leelawadee UI', sans-serif"; +const BLUE = '#0797d5'; +const BLUE_BG = '#e8f5fb'; +const INK = '#222'; +const GREY = '#8e8e8e'; +const LINE = '#595959'; +const WF_FILL = '#f2f2f2'; +const WF_DARK = '#d9d9d9'; + +const esc = (s) => String(s).replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>'); + +function text(x, y, value, { size = 15, weight = 400, anchor = 'middle', fill = INK, lh = 1.3 } = {}) { + const lines = Array.isArray(value) ? value : [value]; + const top = y - ((lines.length - 1) * size * lh) / 2; + return lines.map((l, i) => `${esc(l)}`).join(''); +} +function rect(x, y, w, h, { fill = '#fff', stroke = LINE, sw = 1.5, rx = 6, dash = '' } = {}) { + return ``; +} +/** A labelled box: title centred, optional smaller subtitle lines. */ +function box(x, y, w, h, title, sub = [], opts = {}) { + const { fill = '#fff', stroke = LINE, titleSize = 15, subSize = 12.5, dash = '', rx = 6 } = opts; + const subs = Array.isArray(sub) ? sub : [sub]; + const total = subs.length ? titleSize * 1.4 + subs.length * subSize * 1.35 : 0; + const cy = y + h / 2; + const titleY = subs.length ? cy - total / 2 + titleSize * 0.7 : cy; + const body = subs.length ? text(x + w / 2, titleY + titleSize * 0.75 + (subs.length * subSize * 1.35) / 2, subs, { size: subSize, fill: '#444', lh: 1.35 }) : ''; + return rect(x, y, w, h, { fill, stroke, rx, dash }) + text(x + w / 2, titleY, title, { size: titleSize, weight: 700 }) + body; +} +/** A container with its title in the top-left corner. */ +function frame(x, y, w, h, title, { fill = BLUE_BG, stroke = BLUE, dash = '', bottom = false } = {}) { + return rect(x, y, w, h, { fill, stroke, sw: 2, rx: 10, dash }) + text(x + 14, bottom ? y + h - 18 : y + 20, title, { size: 15, weight: 700, anchor: 'start', fill: stroke === BLUE ? '#05618a' : INK }); +} +function cylinder(x, y, w, h, title, sub = []) { + const ry = 12; + return `` + + `` + + text(x + w / 2, y + h / 2 + 6, [title, ...sub].length > 1 ? [title, ...sub] : title, { size: 13.5 }); +} +const defs = ` + + + +`; +/** Straight or elbowed connector with an optional label. `points` is [[x,y], ...]. */ +function link(points, { label = '', head = 'arr', tail = '', dash = '', lx, ly, size = 12.5 } = {}) { + const d = points.map(([x, y], i) => `${i ? 'L' : 'M'}${x},${y}`).join(' '); + const path = ``; + if (!label) return path; + const mid = Math.floor((points.length - 1) / 2); + const x = lx ?? (points[mid][0] + points[mid + 1][0]) / 2; + const y = ly ?? (points[mid][1] + points[mid + 1][1]) / 2; + const lines = Array.isArray(label) ? label : [label]; + const width = Math.max(...lines.map((l) => l.length)) * size * 0.56 + 12; + const height = lines.length * size * 1.3 + 6; + return path + `` + text(x, y, lines, { size, fill: '#333' }); +} +function actor(x, y, label) { + return `` + + text(x, y + 50, label, { size: 14, weight: 700 }); +} +function usecase(cx, cy, label, w = 230, h = 50) { + return `` + text(cx, cy, label, { size: 13.5 }); +} +const svg = (w, h, body) => `${defs}${body}`; + +// ─── High-level diagrams ────────────────────────────────────────────────────── + +function architecture() { + const b = []; + b.push(frame(20, 40, 190, 300, 'ผู้ใช้งาน')); + b.push(actor(70, 140, 'Owner'), actor(160, 140, 'Admin'), actor(70, 270, 'Staff'), actor(160, 270, 'Viewer')); + b.push(frame(250, 40, 220, 300, 'Client Tier')); + b.push(box(270, 80, 180, 110, 'Web Browser', ['Chrome / Edge / Firefox', 'Desktop · Tablet · Mobile', 'หน้าจอ Responsive'])); + b.push(box(270, 215, 180, 95, 'Socket.IO Client', ['รับการแจ้งเตือน', 'แบบ Real-time'])); + b.push(frame(510, 20, 420, 420, 'Web Tier — Apache + PHP 8')); + b.push(box(530, 55, 380, 58, 'Page Controllers', 'app//*.php — หน้าจอและฟอร์ม')); + b.push(box(530, 125, 380, 58, 'API Engines', 'app/*/api/engine/*.php — รับคำสั่งจากหน้าจอ (JSON)')); + b.push(box(530, 195, 380, 70, 'db_auth (ประตูตรวจสอบทุกคำขอ)', ['Session · CSRF · OTP · Role Guard', 'ขอบเขตบริษัท/คลัง (Tenant Scope)'], { fill: '#fff8e5' })); + b.push(box(530, 277, 380, 70, 'Manager / Service Classes', ['ตรรกะธุรกิจ: สต๊อก ขาย จัดซื้อ การเงิน บัญชี', 'ทำงานภายใน Database Transaction'])); + b.push(box(530, 359, 380, 60, 'Report / ETL Managers', 'รายงาน แดชบอร์ด และตารางสรุปยอด')); + b.push(frame(970, 40, 210, 300, 'Data Tier — MariaDB')); + b.push(cylinder(995, 80, 160, 105, 'wms', ['ผู้ใช้ / บริษัท / สิทธิ์'])); + b.push(cylinder(995, 205, 160, 115, 'wms2', ['คลัง · ขาย · จัดซื้อ', 'การเงิน · บัญชี'])); + b.push(frame(510, 480, 420, 190, 'Service Tier — Node.js (pm2)', { bottom: true })); + b.push(box(530, 495, 185, 130, 'server.js', ['Socket.IO', 'ส่งการแจ้งเตือน', 'ไปยังผู้ใช้ที่เกี่ยวข้อง'])); + b.push(box(725, 495, 185, 130, 'scheduler.js', ['สรุปยอดสต๊อก/GL', 'แจ้งเตือนตามเวลา', 'Asia/Bangkok'])); + b.push(frame(970, 480, 210, 190, 'External', { fill: '#f5f5f5', stroke: GREY })); + b.push(box(985, 515, 180, 65, 'Backup', ['Git Backup Remote', 'mysqldump รายวัน'])); + b.push(box(985, 595, 180, 60, 'SMTP Server', 'อีเมล Onboarding / แจ้งเตือน')); + b.push(link([[210, 190], [250, 190]])); + b.push(link([[450, 135], [530, 135]], { label: 'HTTPS (TLS)', ly: 120 })); + b.push(link([[910, 300], [950, 300], [950, 190], [995, 190]], { label: 'PDO', lx: 950, ly: 245 })); + b.push(link([[620, 440], [620, 495]], { label: 'Emit + Secret', lx: 620, ly: 465 })); + b.push(link([[820, 495], [820, 440]], { label: 'เรียก app/cron', lx: 820, ly: 465 })); + b.push(link([[530, 590], [360, 590], [360, 310]], { label: 'WebSocket', lx: 420, ly: 590 })); + b.push(link([[910, 400], [950, 400], [950, 625], [985, 625]], { label: 'SMTP', lx: 950, ly: 470 })); + b.push(link([[1075, 320], [1075, 515]], { label: 'สำรองข้อมูล', lx: 1075, ly: 420, dash: '5 4' })); + return svg(1200, 690, b.join('')); +} + +function useCase() { + const b = []; + b.push(rect(270, 20, 680, 800, { fill: '#fafcfd', stroke: BLUE, sw: 2, rx: 12 })); + b.push(text(610, 44, 'ระบบ BRN WMS', { size: 16, weight: 700, fill: '#05618a' })); + const A = { Viewer: [100, 150], Staff: [100, 400], Admin: [100, 610], Owner: [100, 765] }; + // Generalisation: each role inherits the use cases of the role above it. + b.push(link([[100, 352], [100, 214]], { head: 'tri' }), link([[100, 562], [100, 464]], { head: 'tri' }), link([[100, 718], [100, 674]], { head: 'tri' })); + for (const [name, [x, y]] of Object.entries(A)) b.push(actor(x, y, name)); + const UC = { + login: [460, 95, 'เข้าสู่ระบบ / กู้คืนรหัสผ่าน'], + report: [460, 165, 'ดูแดชบอร์ดและรายงาน'], + stock: [460, 255, 'รับ / จ่าย / โอนสินค้า'], + sales: [460, 320, 'จัดการเอกสารขาย'], + purchase: [460, 385, 'จัดการเอกสารจัดซื้อ'], + finance: [460, 450, 'รับชำระ / จ่ายชำระ'], + gl: [460, 515, 'สมุดรายวันและบัญชีแยกประเภท'], + master: [460, 595, 'จัดการข้อมูลหลัก'], + users: [460, 660, 'จัดการผู้ใช้และสิทธิ์'], + company: [460, 765, 'ตั้งค่าบริษัทและ SMTP'], + etl: [790, 205, 'สรุปยอดสต๊อก / GL ตามเวลา'], + alert: [790, 280, 'แจ้งเตือนสินค้าใกล้หมด / ค้างชำระ'], + notify: [790, 385, 'แจ้งเตือนแบบ Real-time'], + email: [790, 660, 'ส่งอีเมล'], + }; + for (const [cx, cy, label] of Object.values(UC)) b.push(usecase(cx, cy, label)); + const assoc = (actorKey, ucKey) => { const [ax, ay] = A[actorKey]; const [ux, uy] = UC[ucKey]; return link([[ax + 28, ay - 10], [ux - 115, uy]], { head: '' }); }; + b.push(assoc('Viewer', 'login'), assoc('Viewer', 'report')); + for (const k of ['stock', 'sales', 'purchase', 'finance', 'gl']) b.push(assoc('Staff', k)); + b.push(assoc('Admin', 'master'), assoc('Admin', 'users'), assoc('Owner', 'company')); + b.push(actor(1090, 260, 'System Scheduler'), actor(1090, 680, 'SMTP Service')); + b.push(link([[1060, 240], [905, 205]], { head: '' }), link([[1060, 250], [905, 280]], { head: '' }), link([[1060, 660], [905, 660]], { head: '' })); + b.push(link([[575, 660], [675, 660]], { dash: '6 4', head: 'open', label: '«include»', ly: 645 })); + b.push(link([[575, 95], [930, 95], [930, 660], [905, 660]], { dash: '6 4', head: 'open', label: '«include»', lx: 755, ly: 95 })); + b.push(link([[575, 320], [700, 370]], { dash: '6 4', head: 'open', label: '«include»', lx: 640, ly: 330 })); + return svg(1200, 850, b.join('')); +} + +function components() { + const b = []; + const comp = (x, y, w, h, id, name, fill = '#fff') => { + const icon = ``; + return rect(x, y, w, h, { fill, rx: 4 }) + icon + text(x + w / 2 - 8, y + h / 2 - 9, `«component» ${id}`, { size: 12, fill: GREY }) + text(x + w / 2 - 8, y + h / 2 + 12, name, { size: 14, weight: 700 }); + }; + b.push(frame(20, 20, 1160, 120, 'ส่วนกลางที่ทุกโมดูลเรียกใช้ (Cross-cutting)')); + b.push(comp(45, 55, 350, 70, 'UN01', 'Identity & Access', '#fff'), comp(425, 55, 350, 70, 'UN12', 'Security & Tenant Scope'), comp(805, 55, 350, 70, 'UN02', 'Company Settings')); + const W = 255, H = 80, X = [45, 330, 615, 900]; + b.push(frame(20, 165, 1160, 360, 'โมดูลธุรกิจ (Manager / Service Classes)', { fill: '#fff', stroke: BLUE })); + b.push(comp(X[0], 205, W, H, 'UN03', 'Master Data'), comp(X[1], 205, W, H, 'UN04', 'Inventory Control'), comp(X[2], 205, W, H, 'UN05', 'Sales'), comp(X[3], 205, W, H, 'UN06', 'Purchasing')); + b.push(comp(X[0], 420, W, H, 'UN10', 'Document Control'), comp(X[1], 420, W, H, 'UN07', 'Finance'), comp(X[2], 420, W, H, 'UN08', 'Accounting / GL'), comp(X[3], 420, W, H, 'UN09', 'Reports & Dashboard')); + b.push(frame(20, 550, 1160, 130, 'บริการและโครงสร้างพื้นฐาน', { fill: '#f5f5f5', stroke: GREY })); + b.push(comp(45, 585, 350, 75, 'UN11', 'Notification & Scheduler'), comp(425, 585, 350, 75, 'UN13', 'Deployment & Backup')); + b.push(cylinder(840, 575, 290, 95, 'MariaDB wms / wms2')); + const dep = (pts, label) => link(pts, { dash: '6 4', head: 'open', label, size: 12 }); + b.push(dep([[X[1], 245], [X[0] + W, 245]], 'ใช้ข้อมูลหลัก')); + b.push(dep([[X[2], 230], [X[1] + W, 230]], 'ตัดสต๊อก')); + b.push(dep([[X[3] + 60, 205], [X[3] + 60, 180], [X[1] + W - 60, 180], [X[1] + W - 60, 205]], 'รับสินค้าเข้า')); + b.push(dep([[X[2] + 128, 285], [X[2] + 128, 420]], 'บันทึก GL')); + b.push(dep([[X[3] + 60, 285], [X[3] + 60, 360], [X[2] + 200, 360], [X[2] + 200, 420]], '')); + b.push(dep([[X[1] + W, 460], [X[2], 460]], 'บันทึก GL')); + b.push(dep([[X[3] + 180, 420], [X[3] + 180, 330], [X[1] + 200, 330], [X[1] + 200, 285]], 'อ่านยอดสต๊อก')); + b.push(dep([[X[2] + 60, 285], [X[2] + 60, 390], [X[0] + 200, 390], [X[0] + 200, 420]], 'ออกเลขที่เอกสาร')); + b.push(dep([[X[1], 480], [X[0] + W, 480]], '')); + b.push(dep([[220, 585], [220, 540], [X[3] + 128, 540], [X[3] + 128, 500]], 'ตารางสรุปยอด')); + return svg(1200, 700, b.join('')); +} + +function deployment() { + const b = []; + const node = (x, y, w, h, title) => `` + text(x + 14, y + 36, title, { size: 15, weight: 700, anchor: 'start' }); + b.push(node(20, 70, 220, 250, '«device» Client')); + b.push(box(40, 125, 180, 80, 'Web Browser', ['Desktop / Tablet', 'Mobile'])); + b.push(box(40, 220, 180, 80, 'เครื่องสแกนบาร์โค้ด', ['(ทำงานเป็นคีย์บอร์ด)'])); + b.push(node(290, 20, 600, 620, '«execution environment» Production Server — Linux + Docker Compose')); + b.push(box(320, 80, 250, 150, '«container» php', ['Apache + PHP 8', 'แอปพลิเคชัน wms-app', 'config.php สร้างจาก .env', 'พอร์ต 80 / 443 (TLS)'], { fill: BLUE_BG, stroke: BLUE })); + b.push(box(610, 80, 250, 150, '«container» node', ['pm2', 'server.js (Socket.IO :3000)', 'scheduler.js', '(ETL และแจ้งเตือน)'], { fill: BLUE_BG, stroke: BLUE })); + b.push(box(320, 290, 250, 150, '«container» db', ['MariaDB', 'ฐานข้อมูล wms และ wms2', 'Volume ข้อมูลถาวร'], { fill: BLUE_BG, stroke: BLUE })); + b.push(box(610, 290, 250, 150, 'ไฟล์ตั้งค่า', ['.env (ไม่อยู่ใน Git)', 'docker/init-env.sh', 'docker-compose.yml'], { fill: '#fff8e5' })); + b.push(box(320, 500, 540, 110, 'ทางเลือกติดตั้งแบบ Manual (LAMP)', ['Apache + PHP 8 + MariaDB บนเครื่องเดียว', 'สร้างฐานข้อมูลด้วย setup.php และรัน Node.js ผ่าน pm2'], { dash: '6 4' })); + b.push(node(950, 40, 230, 150, '«external» SMTP')); + b.push(box(965, 80, 200, 90, ' ', ['ส่งอีเมลของแต่ละบริษัท'], { stroke: 'none', fill: 'none' })); + b.push(node(950, 230, 230, 170, '«external» Git Server')); + b.push(box(965, 275, 200, 100, ' ', ['Repository หลัก (origin)', 'และ Backup Remote'], { stroke: 'none', fill: 'none' })); + b.push(node(950, 440, 230, 170, '«storage» Backup')); + b.push(box(965, 485, 200, 100, ' ', ['mysqldump รายวัน 02:00 น.', 'เก็บนอกเครื่องแม่ข่าย'], { stroke: 'none', fill: 'none' })); + b.push(link([[220, 165], [320, 165]], { label: 'HTTPS', ly: 150 })); + b.push(link([[240, 110], [270, 110], [270, 12], [735, 12], [735, 80]], { label: 'WebSocket', lx: 500, ly: 12 })); + b.push(link([[570, 150], [610, 150]], { label: 'Emit', ly: 135, size: 11.5 })); + b.push(link([[445, 230], [445, 290]], { label: 'PDO', lx: 445, ly: 260 })); + b.push(link([[860, 110], [950, 110]], { label: 'SMTP', ly: 95 })); + b.push(link([[860, 330], [950, 330]], { label: 'git push', ly: 315, dash: '5 4' })); + b.push(link([[445, 440], [445, 470], [920, 470], [920, 525], [950, 525]], { label: 'สำรองข้อมูล', lx: 700, ly: 470, dash: '5 4' })); + return svg(1200, 660, b.join('')); +} + +// ─── Wireframes ────────────────────────────────────────────────────────────── + +const MENU = ['แดชบอร์ด', 'ข้อมูลหลัก', 'คลังสินค้า', 'ขาย', 'จัดซื้อ', 'การเงิน', 'บัญชี', 'รายงาน', 'ตั้งค่า']; +/** Browser window + sidebar + top bar; returns the SVG and the content area. */ +function shell(title, active, content) { + const W = 1200, H = 760; + const b = []; + b.push(rect(10, 10, W - 20, H - 20, { fill: '#fff', stroke: '#9a9a9a', rx: 10 })); + b.push(rect(10, 10, W - 20, 36, { fill: WF_DARK, stroke: '#9a9a9a', rx: 10 }), rect(10, 30, W - 20, 16, { fill: WF_DARK, stroke: 'none', rx: 0 })); + b.push(...[30, 50, 70].map((x) => ``)); + b.push(rect(100, 18, 520, 20, { fill: '#fff', stroke: '#b5b5b5', rx: 10 }), text(115, 28, 'https://wms.brn.co.th/app/…', { size: 12, anchor: 'start', fill: GREY })); + b.push(rect(10, 46, 200, H - 56, { fill: '#e9e9e9', stroke: 'none', rx: 0 })); + b.push(rect(28, 62, 120, 30, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(88, 77, 'โลโก้บริษัท', { size: 12, fill: GREY })); + MENU.forEach((m, i) => { + const y = 116 + i * 40; + if (m === active) b.push(rect(18, y - 15, 184, 30, { fill: '#fff', stroke: BLUE, rx: 4 })); + b.push(rect(32, y - 7, 14, 14, { fill: m === active ? BLUE : '#bdbdbd', stroke: 'none', rx: 3 }), text(56, y, m, { size: 14, anchor: 'start', weight: m === active ? 700 : 400 })); + }); + b.push(rect(210, 46, W - 220, 50, { fill: '#fff', stroke: WF_DARK, rx: 0 })); + b.push(text(232, 71, title, { size: 18, weight: 700, anchor: 'start' })); + b.push(rect(W - 330, 58, 150, 26, { fill: WF_FILL, stroke: '#b5b5b5', rx: 4 }), text(W - 255, 71, 'บริษัท ▾', { size: 12.5 })); + b.push(``, text(W - 90, 71, 'ผู้ใช้ ▾', { size: 12.5 })); + b.push(content); + return svg(W, H, b.join('')); +} +const btn = (x, y, w, label, primary = false) => rect(x, y, w, 32, { fill: primary ? BLUE : '#fff', stroke: primary ? BLUE : '#9a9a9a', rx: 5 }) + text(x + w / 2, y + 16, label, { size: 13.2, fill: primary ? '#fff' : INK, weight: primary ? 700 : 400 }); +const field = (x, y, w, label, hint = '') => text(x, y, label, { size: 12.5, anchor: 'start', fill: '#444' }) + rect(x, y + 10, w, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }) + (hint ? text(x + 10, y + 26, hint, { size: 12, anchor: 'start', fill: '#aaa' }) : ''); +function grid(x, y, cols, rowCount, { rowH = 34, headFill = WF_DARK } = {}) { + const w = cols.reduce((a, c) => a + c[1], 0); + const b = [rect(x, y, w, rowH, { fill: headFill, stroke: '#b5b5b5', rx: 0 })]; + let cx = x; + for (const [label, cw, align] of cols) { b.push(text(align === 'r' ? cx + cw - 10 : cx + 10, y + rowH / 2, label, { size: 12.5, weight: 700, anchor: align === 'r' ? 'end' : 'start' })); cx += cw; } + for (let r = 1; r <= rowCount; r += 1) { + b.push(rect(x, y + r * rowH, w, rowH, { fill: r % 2 ? '#fff' : '#fafafa', stroke: '#d0d0d0', rx: 0 })); + let px = x; + for (const [, cw, align] of cols) { const bw = Math.min(cw - 20, 40 + ((r * 37 + cw) % 60)); b.push(rect(align === 'r' ? px + cw - 10 - bw : px + 10, y + r * rowH + rowH / 2 - 5, bw, 10, { fill: WF_DARK, stroke: 'none', rx: 3 })); px += cw; } + } + return b.join(''); +} +const tile = (x, y, w, label) => rect(x, y, w, 82, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }) + text(x + 16, y + 24, label, { size: 13.2, anchor: 'start', fill: '#555' }) + rect(x + 16, y + 44, 80, 22, { fill: WF_DARK, stroke: 'none', rx: 4 }) + rect(x + w - 50, y + 22, 32, 32, { fill: WF_FILL, stroke: '#c8c8c8', rx: 6 }); + +function wfLogin() { + const b = []; + b.push(rect(10, 10, 1180, 740, { fill: '#f4f6f8', stroke: '#9a9a9a', rx: 10 })); + b.push(rect(400, 110, 400, 520, { fill: '#fff', stroke: '#b5b5b5', rx: 10 })); + b.push(rect(530, 140, 140, 50, { fill: WF_FILL, stroke: '#b5b5b5', rx: 6 }), text(600, 165, 'โลโก้', { size: 13.2, fill: GREY })); + b.push(text(600, 225, 'เข้าสู่ระบบ BRN WMS', { size: 20, weight: 700 })); + b.push(field(440, 265, 320, 'ชื่อผู้ใช้ / อีเมล', 'username'), field(440, 335, 320, 'รหัสผ่าน', '••••••••')); + b.push(rect(440, 405, 16, 16, { fill: '#fff', stroke: '#9a9a9a', rx: 3 }), text(465, 413, 'จดจำการเข้าสู่ระบบ', { size: 12.5, anchor: 'start' })); + b.push(btn(440, 440, 320, 'เข้าสู่ระบบ', true)); + b.push(text(600, 500, 'ลืมรหัสผ่าน? · ลงทะเบียนบริษัทใหม่', { size: 13.2, fill: BLUE })); + b.push(rect(440, 530, 320, 70, { fill: '#fff8e5', stroke: '#e0c070', rx: 6, dash: '5 4' }), text(600, 565, ['ขั้นตอน OTP (ถ้าเปิดใช้งาน):', 'กรอกรหัส 6 หลักที่ส่งทางอีเมล'], { size: 12.5 })); + return svg(1200, 760, b.join('')); +} +function wfDashboard() { + const c = []; + ['สินค้าทั้งหมด', 'รับเข้า (เดือนนี้)', 'จ่ายออก (เดือนนี้)', 'สินค้าใกล้หมด'].forEach((l, i) => c.push(tile(232 + i * 237, 116, 222, l))); + c.push(rect(232, 218, 610, 300, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(250, 240, 'กราฟความเคลื่อนไหวสินค้า 12 เดือน', { size: 13.5, anchor: 'start', weight: 700 })); + for (let i = 0; i < 12; i += 1) { const h1 = 40 + ((i * 53) % 150), h2 = 20 + ((i * 31) % 110); c.push(rect(262 + i * 48, 490 - h1, 16, h1, { fill: '#9fd3ea', stroke: 'none', rx: 2 }), rect(280 + i * 48, 490 - h2, 16, h2, { fill: '#c9c9c9', stroke: 'none', rx: 2 })); } + c.push(rect(860, 218, 318, 300, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(876, 240, 'กิจกรรมล่าสุด', { size: 13.5, anchor: 'start', weight: 700 })); + for (let i = 0; i < 6; i += 1) c.push(``, rect(906, 272 + i * 38, 170, 10, { fill: WF_DARK, stroke: 'none', rx: 3 }), rect(1110, 272 + i * 38, 50, 10, { fill: '#c9c9c9', stroke: 'none', rx: 3 })); + c.push(rect(232, 535, 946, 200, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(250, 557, 'สินค้าใกล้หมด / สินค้าเคลื่อนไหวมากที่สุด', { size: 13.5, anchor: 'start', weight: 700 })); + c.push(grid(250, 575, [['สินค้า', 330], ['คลัง', 230], ['คงเหลือ', 170, 'r'], ['จุดสั่งซื้อ', 180, 'r']], 4)); + return shell('แดชบอร์ด', 'แดชบอร์ด', c.join('')); +} +function wfList() { + const c = []; + c.push(btn(1040, 112, 138, '+ สร้างใหม่', true)); + ['ทั้งหมด', 'รอกำหนดคลัง', 'ร่าง', 'ยืนยันแล้ว', 'ยกเลิก'].forEach((l, i) => c.push(tile(232 + i * 190, 158, 176, l))); + c.push(rect(232, 258, 946, 56, { fill: WF_FILL, stroke: '#c8c8c8', rx: 6 })); + c.push(rect(246, 270, 300, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(260, 286, 'ค้นหาเลขที่เอกสาร / ผู้ติดต่อ', { size: 12, anchor: 'start', fill: '#aaa' })); + c.push(rect(560, 270, 170, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(572, 286, 'สถานะ ▾', { size: 12.5, anchor: 'start' })); + c.push(rect(744, 270, 250, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(756, 286, 'ช่วงวันที่ DD/MM/YYYY – DD/MM/YYYY', { size: 12, anchor: 'start', fill: '#aaa' })); + c.push(btn(1010, 270, 80, 'ค้นหา'), btn(1098, 270, 70, 'ล้าง')); + c.push(grid(232, 330, [['เลขที่', 150], ['วันที่', 120], ['ผู้ติดต่อ', 250], ['ยอดรวม', 140, 'r'], ['สถานะ', 140], ['การทำงาน', 146]], 9)); + c.push(text(232, 695, 'แสดง 1–10 จาก 120 รายการ', { size: 12.5, anchor: 'start', fill: '#555' })); + ['‹', '1', '2', '3', '›'].forEach((p, i) => c.push(rect(990 + i * 38, 680, 32, 30, { fill: p === '1' ? BLUE : '#fff', stroke: '#b5b5b5', rx: 4 }), text(1006 + i * 38, 695, p, { size: 13.2, fill: p === '1' ? '#fff' : INK }))); + return shell('ใบสั่งขาย (หน้ารายการ)', 'ขาย', c.join('')); +} +function wfDocument() { + const c = []; + c.push(rect(232, 112, 946, 150, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(250, 132, 'ข้อมูลเอกสาร', { size: 13.5, anchor: 'start', weight: 700 })); + c.push(field(250, 152, 280, 'ผู้ติดต่อ *', 'ค้นหาผู้ติดต่อ…'), field(550, 152, 180, 'วันที่เอกสาร *', 'DD/MM/YYYY'), field(750, 152, 200, 'แผนก *', 'เลือกแผนก ▾'), field(970, 152, 190, 'สถานะ', 'ร่าง')); + c.push(field(250, 208, 910, 'หมายเหตุ', '')); + c.push(rect(232, 278, 946, 300, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(250, 298, 'รายการสินค้า', { size: 13.5, anchor: 'start', weight: 700 }), btn(1060, 284, 104, '+ เพิ่มรายการ')); + c.push(grid(250, 322, [['SKU', 110], ['สินค้า', 240], ['คลัง', 130], ['จำนวน', 90, 'r'], ['ราคา/หน่วย', 110, 'r'], ['ภาษี %', 70, 'r'], ['รวม', 110, 'r'], ['', 40]], 5)); + c.push(rect(232, 594, 946, 150, { fill: '#fff', stroke: '#b5b5b5', rx: 6 })); + ['ยอดรวมก่อนภาษี', 'ส่วนลด', 'ภาษีมูลค่าเพิ่ม', 'ค่าขนส่ง'].forEach((l, i) => c.push(text(900, 612 + i * 26, l, { size: 12.5, anchor: 'end', fill: '#555' }), rect(920, 603 + i * 26, 240, 18, { fill: WF_FILL, stroke: '#c8c8c8', rx: 3 }))); + c.push(text(250, 616, 'ยอดสุทธิ', { size: 14, anchor: 'start', weight: 700 }), rect(250, 632, 200, 34, { fill: WF_DARK, stroke: 'none', rx: 4 })); + c.push(btn(250, 690, 110, 'บันทึกร่าง', true), btn(372, 690, 110, 'ยืนยัน'), btn(494, 690, 90, 'พิมพ์'), btn(596, 690, 90, 'ยกเลิก')); + return shell('ใบสั่งขาย (หน้าบันทึก/แก้ไข)', 'ขาย', c.join('')); +} +function wfStockIn() { + const c = []; + c.push(rect(232, 112, 600, 620, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(250, 134, 'บันทึกรับสินค้าเข้า', { size: 13.5, anchor: 'start', weight: 700 })); + c.push(field(250, 156, 270, 'คลังสินค้า *', 'เลือกคลัง ▾'), field(540, 156, 270, 'วันที่รับ *', 'DD/MM/YYYY')); + c.push(field(250, 216, 460, 'สินค้า (พิมพ์หรือสแกนบาร์โค้ด) *', 'SKU / ชื่อสินค้า'), btn(720, 226, 90, 'สแกน')); + c.push(field(250, 276, 170, 'จำนวน *', '0.0000'), field(440, 276, 170, 'Lot Number', ''), field(630, 276, 180, 'วันหมดอายุ', 'DD/MM/YYYY')); + c.push(field(250, 336, 560, 'Serial Number', 'คั่นด้วยเครื่องหมายจุลภาค')); + c.push(text(250, 400, 'ตำแหน่งจัดเก็บ *', { size: 12.5, anchor: 'start', fill: '#444' })); + c.push(rect(250, 410, 180, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(262, 426, 'Zone ▾', { size: 12.5, anchor: 'start' }), rect(440, 410, 180, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(452, 426, 'Aisle ▾', { size: 12.5, anchor: 'start' }), rect(630, 410, 180, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(642, 426, 'Bin ▾', { size: 12.5, anchor: 'start' })); + c.push(field(250, 462, 560, 'เอกสารอ้างอิง', 'เลขที่ PO / ใบส่งของ')); + c.push(rect(250, 528, 560, 80, { fill: WF_FILL, stroke: '#b5b5b5', rx: 6, dash: '6 4' }), text(530, 568, ['แนบไฟล์ (ลากวางหรือคลิกเพื่อเลือก)', 'ไฟล์ที่อนุญาต: PDF, JPG, PNG'], { size: 12.5, fill: '#777' })); + c.push(btn(250, 640, 120, 'บันทึกร่าง', true), btn(382, 640, 120, 'อนุมัติรับเข้า'), btn(514, 640, 90, 'ยกเลิก')); + c.push(rect(850, 112, 328, 620, { fill: '#fff', stroke: '#b5b5b5', rx: 6 }), text(866, 134, 'ข้อมูลช่วยตัดสินใจ', { size: 13.5, anchor: 'start', weight: 700 })); + c.push(tile(866, 156, 296, 'ยอดคงเหลือในคลังนี้'), tile(866, 252, 296, 'ช่องจัดเก็บที่ว่าง')); + c.push(text(866, 370, 'ประวัติความเคลื่อนไหวล่าสุด', { size: 13.2, anchor: 'start', weight: 700 }), grid(866, 386, [['วันที่', 110], ['ประเภท', 90], ['จำนวน', 96, 'r']], 6)); + return shell('รับสินค้าเข้า (Stock-in)', 'คลังสินค้า', c.join('')); +} +function wfReport() { + const c = []; + c.push(rect(232, 112, 946, 96, { fill: WF_FILL, stroke: '#c8c8c8', rx: 6 }), text(250, 132, 'ตัวกรองรายงาน', { size: 13.5, anchor: 'start', weight: 700 })); + c.push(rect(250, 148, 200, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(262, 164, 'คลังสินค้า ▾', { size: 12.5, anchor: 'start' })); + c.push(rect(462, 148, 200, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(474, 164, 'หมวดสินค้า ▾', { size: 12.5, anchor: 'start' })); + c.push(rect(674, 148, 250, 32, { fill: '#fff', stroke: '#b5b5b5', rx: 4 }), text(686, 164, 'ช่วงวันที่', { size: 12.5, anchor: 'start', fill: '#aaa' })); + c.push(btn(936, 148, 70, 'แสดง', true), btn(1014, 148, 70, 'พิมพ์'), btn(1092, 148, 76, 'ส่งออก')); + ['ยอดยกมา', 'รับเข้า', 'จ่ายออก', 'คงเหลือ'].forEach((l, i) => c.push(tile(232 + i * 237, 224, 222, l))); + c.push(grid(232, 324, [['SKU', 130], ['สินค้า', 260], ['คลัง', 160], ['ยกมา', 100, 'r'], ['รับเข้า', 100, 'r'], ['จ่ายออก', 100, 'r'], ['คงเหลือ', 96, 'r']], 10)); + c.push(text(232, 715, 'รายงานแสดงเฉพาะบริษัทและคลังที่ผู้ใช้ได้รับสิทธิ์', { size: 12.5, anchor: 'start', fill: '#555' })); + return shell('รายงานความเคลื่อนไหวสินค้า', 'รายงาน', c.join('')); +} + +/** [file, caption, svg] — in the order they appear in the Software Design document. */ +export const FIGURES = { + architecture: ['hld-architecture', 'รูปที่ 1 High Level Architecture Diagram — โครงสร้างระบบแบ่งตามชั้นการทำงาน', architecture], + useCase: ['hld-use-case', 'รูปที่ 2 Use Case Diagram — ผู้ใช้งานและกลุ่มการใช้งานหลัก', useCase], + component: ['hld-component', 'รูปที่ 3 Component Diagram — โมดูลของระบบและความสัมพันธ์', components], + deployment: ['hld-deployment', 'รูปที่ 4 Deployment Diagram — การติดตั้งบนสภาพแวดล้อมใช้งานจริง', deployment], + wfLogin: ['wf-login', 'รูปที่ 5 Wireframe หน้าจอเข้าสู่ระบบ', wfLogin], + wfDashboard: ['wf-dashboard', 'รูปที่ 6 Wireframe หน้าจอแดชบอร์ด', wfDashboard], + wfList: ['wf-list', 'รูปที่ 7 Wireframe หน้ารายการเอกสาร (ตัวอย่างใบสั่งขาย) — ใช้รูปแบบเดียวกันทุกเอกสาร', wfList], + wfDocument: ['wf-document', 'รูปที่ 8 Wireframe หน้าบันทึกเอกสาร (ตัวอย่างใบสั่งขาย) — ใช้กับเอกสารขาย จัดซื้อ และการเงิน', wfDocument], + wfStockIn: ['wf-stock-in', 'รูปที่ 9 Wireframe หน้าจอรับสินค้าเข้า', wfStockIn], + wfReport: ['wf-report', 'รูปที่ 10 Wireframe หน้าจอรายงาน', wfReport], +}; +/** Markdown image line for a figure; the path is relative to the document's folder. */ +export const figure = (key) => `![${FIGURES[key][1]}](figures/${FIGURES[key][0]}.png)`; diff --git a/scripts/sdlc-seed/figures/hld-architecture.png b/scripts/sdlc-seed/figures/hld-architecture.png new file mode 100644 index 0000000..b094330 Binary files /dev/null and b/scripts/sdlc-seed/figures/hld-architecture.png differ diff --git a/scripts/sdlc-seed/figures/hld-component.png b/scripts/sdlc-seed/figures/hld-component.png new file mode 100644 index 0000000..ae5e5ae Binary files /dev/null and b/scripts/sdlc-seed/figures/hld-component.png differ diff --git a/scripts/sdlc-seed/figures/hld-deployment.png b/scripts/sdlc-seed/figures/hld-deployment.png new file mode 100644 index 0000000..36f0950 Binary files /dev/null and b/scripts/sdlc-seed/figures/hld-deployment.png differ diff --git a/scripts/sdlc-seed/figures/hld-use-case.png b/scripts/sdlc-seed/figures/hld-use-case.png new file mode 100644 index 0000000..e69a9b6 Binary files /dev/null and b/scripts/sdlc-seed/figures/hld-use-case.png differ diff --git a/scripts/sdlc-seed/figures/wf-dashboard.png b/scripts/sdlc-seed/figures/wf-dashboard.png new file mode 100644 index 0000000..b559fe6 Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-dashboard.png differ diff --git a/scripts/sdlc-seed/figures/wf-document.png b/scripts/sdlc-seed/figures/wf-document.png new file mode 100644 index 0000000..09cfabc Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-document.png differ diff --git a/scripts/sdlc-seed/figures/wf-list.png b/scripts/sdlc-seed/figures/wf-list.png new file mode 100644 index 0000000..7d5c178 Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-list.png differ diff --git a/scripts/sdlc-seed/figures/wf-login.png b/scripts/sdlc-seed/figures/wf-login.png new file mode 100644 index 0000000..c96c314 Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-login.png differ diff --git a/scripts/sdlc-seed/figures/wf-report.png b/scripts/sdlc-seed/figures/wf-report.png new file mode 100644 index 0000000..104362b Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-report.png differ diff --git a/scripts/sdlc-seed/figures/wf-stock-in.png b/scripts/sdlc-seed/figures/wf-stock-in.png new file mode 100644 index 0000000..40540bd Binary files /dev/null and b/scripts/sdlc-seed/figures/wf-stock-in.png differ diff --git a/scripts/sdlc-seed/history.mjs b/scripts/sdlc-seed/history.mjs index 588d4dc..dfa65e5 100644 --- a/scripts/sdlc-seed/history.mjs +++ b/scripts/sdlc-seed/history.mjs @@ -24,7 +24,7 @@ export const TASKS = [ ['4.1', 'Project Control', 'Progress & Meeting Records', 'ติดตามความก้าวหน้า ประเด็นปัญหา มติ และการแก้ไขตลอดโครงการ', ['ApS', 'YaB'], '2026-01-05', '2026-08-24', 'Progress Status, Meeting Record', 'Completed', 'บันทึกรายงวดตลอดโครงการ'], ['4.2', 'Project Control', 'Configuration & Repository Control', 'ควบคุม Source Code, Baseline, เวอร์ชันเอกสาร และการสำรองข้อมูล', ['ThS', 'YaB'], '2026-02-19', '2026-08-24', 'Software Configuration', 'Completed', 'Git origin + backup remote'], ['4.3', 'Verification', 'Verify Work Products', 'ตรวจสอบความต้องการ ออกแบบ ส่วนประกอบ และการสอบกลับ', ['PaNg', 'NoC'], '2026-05-30', '2026-08-17', 'Verification Results', 'Completed', 'ตรวจสอบ 4 รอบ รอบสุดท้าย 17 ส.ค. 69'], - ['4.4', 'Validation', 'System Test & UAT', 'ทดสอบระบบตาม Test Case และทดสอบการยอมรับโดยผู้ใช้', ['PaNg', 'SeV'], '2026-08-10', '2026-08-14', 'Test Report, Validation Results', 'Completed', 'ทดสอบ 45 Test Case และ 12 สถานการณ์ UAT'], + ['4.4', 'Validation', 'System Test & UAT', 'ทดสอบระบบตาม Test Case และทดสอบการยอมรับโดยผู้ใช้', ['PaNg', 'SeV'], '2026-08-10', '2026-08-14', 'Test Report, Validation Results', 'Completed', `ทดสอบ 45 Test Case และ UAT ครบ 14 หมวดความต้องการ (${CRS.length} รายการ)`], ['4.5', 'Documentation', 'Operational Documentation', 'จัดทำคู่มือผู้ใช้ คู่มือผู้ดูแลระบบ และคู่มือบำรุงรักษา', ['ThS', 'YaB'], '2026-06-01', '2026-08-17', 'User / Operation / Maintenance docs', 'Completed', 'จัดทำครบ 3 ฉบับ'], ['4.6', 'Stabilization', 'Post-baseline Corrections', 'แก้ไขปัญหาการเข้าสู่ระบบและค่าตั้งค่าหลัง Baseline', ['ThS'], '2026-08-03', '2026-08-03', 'Correction Register', 'Completed', 'Git b2c4374'], ['4.7', 'Stabilization', 'Demonstration Data & Delivery Package', 'เตรียมข้อมูลสาธิต ปรับแบรนด์ และชุดติดตั้ง Docker Compose', ['ThS'], '2026-08-14', '2026-08-17', 'Demo data, Docker stack', 'Completed', 'Git dd48a8b–6c39700'], @@ -66,56 +66,67 @@ export const CORRECTIONS = [ ['ISS-028', '2026-07-28', '2026-08-03', 'สูง', 'การเข้าสู่ระบบและค่าตั้งค่าสภาพแวดล้อมผิดพลาดหลัง Baseline', 'ค่าตั้งค่าของสภาพแวดล้อมใหม่ไม่ตรงกับที่ระบบคาดหวัง', 'แก้ไขการเข้าสู่ระบบและค่าตั้งค่าสภาพแวดล้อม', 'ThS', 'b2c4374', 'TC-UN12.004'], ]; -/** Change Reports: one document each. */ -export const CHANGES = [ - { - id: 'CH-001', date: '2026-05-21', file: 'Rack to Bin Rename', - titleTh: 'เปลี่ยนคำเรียกตำแหน่งจัดเก็บจาก Rack เป็น Bin', - requester: P.NoC, unit: 'ฝ่ายวิเคราะห์ระบบ / ตัวแทนผู้ใช้งานคลังสินค้า', - type: 'Scope', typeChecked: 'Quality', priority: 'Medium', - description: 'เปลี่ยนคำเรียกตำแหน่งจัดเก็บสินค้าจาก "Rack" เป็น "Bin" ทั้งระบบ ครอบคลุมป้ายกำกับหน้าจอ, custom.js, เครื่องมือบาร์โค้ด (BarcodeManager.php, location_barcode_label.php, retrieve_rack.php) และคลาสจัดการคลังสินค้า สต๊อก ใบสั่งขาย รายงาน ใบรับคืน ใบคืนผู้ขาย สินค้า และการตั้งค่าบริษัท', - justification: 'ให้คำที่ใช้ในระบบตรงกับคำที่พนักงานคลังสินค้าใช้จริงในการปฏิบัติงาน ลดความสับสนระหว่างการใช้งานและการอบรม', - impact: [ - ['ผลกระทบต่อ Scope', 'แก้ไข 14 ไฟล์ ประมาณ 1,000 บรรทัด ครอบคลุมคลาสจัดการ 8 คลาสและเครื่องมือบาร์โค้ด ไม่มีการเพิ่มฟังก์ชันใหม่'], - ['ผลกระทบต่อ Schedule', 'ดำเนินการภายในช่วงพัฒนาปัจจุบัน ไม่กระทบกำหนดส่งมอบ'], - ['ผลกระทบต่อ Budget/Cost', 'ไม่มีค่าใช้จ่ายเพิ่ม ใช้ทรัพยากรทีมพัฒนาเดิม'], - ['ผลกระทบต่อ Resource', 'ผู้พัฒนา 1 คน'], - ['ผลกระทบต่อ Quality/Deliverables', 'เป็นการเปลี่ยนคำเรียกเท่านั้น ไม่เปลี่ยนพฤติกรรมของระบบ ข้อบกพร่องที่เกิดจากการเปลี่ยนไม่ครบให้บันทึกใน Correction Register (ISS-023)'], - ], - commit: '8f57ab5', result: 'ดำเนินการแล้วเสร็จ และตรวจสอบผลด้วย TC-UN03.001 ผ่านเมื่อ 10–14 ส.ค. 69', - }, - { - id: 'CH-002', date: '2026-08-08', file: 'Demo Data Population', - titleTh: 'เพิ่มชุดข้อมูลสาธิตสำหรับการตรวจรับและสาธิตระบบ', - requester: P.ApS, unit: 'ฝ่ายบริหารโครงการ / เตรียมการส่งมอบ', - type: 'Scope', typeChecked: 'Quality', priority: 'Medium', - description: 'เพิ่มสคริปต์สร้างข้อมูลสาธิต 3 ไฟล์ (demo_seed.php, demo_seed_more_orders.php, demo_seed_transactions.php) สำหรับใบสั่งขาย รูปแบบคำสั่งซื้อเพิ่มเติม และประวัติรายการเคลื่อนไหว พร้อมตั้งค่าไดเรกทอรี Log ของบริการ Node.js ที่ใช้ระหว่างสร้างข้อมูล', - justification: 'ระบบที่ติดตั้งใหม่ไม่มีประวัติรายการ ทำให้ตรวจรับรายงานและขั้นตอนการทำงานไม่ได้ จึงต้องมีข้อมูลตัวอย่างที่ใกล้เคียงการใช้งานจริงสำหรับการตรวจรับและการสาธิต', - impact: [ - ['ผลกระทบต่อ Scope', 'แก้ไข 9 ไฟล์ เพิ่มประมาณ 2,900 บรรทัด เป็นสคริปต์สร้างข้อมูลใหม่ ไม่แก้ตรรกะหลักของระบบ'], - ['ผลกระทบต่อ Schedule', 'ดำเนินการภายในช่วงเตรียมส่งมอบตามแผน'], - ['ผลกระทบต่อ Budget/Cost', 'ไม่มีค่าใช้จ่ายเพิ่ม'], - ['ผลกระทบต่อ Resource', 'ผู้พัฒนา 1 คน'], - ['ผลกระทบต่อ Quality/Deliverables', 'เป็นการเพิ่มข้อมูลสาธิตเท่านั้น ข้อมูลสาธิตต้องแยกจากข้อมูลใช้งานจริงตาม CR07:004'], - ], - commit: 'dd48a8b', result: 'ดำเนินการแล้วเสร็จเมื่อ 14 ส.ค. 69 และใช้เป็นข้อมูลตั้งต้นของการทดสอบและ UAT', - }, - { - id: 'CH-003', date: '2026-08-10', file: 'Delivery Preparation Bundle', - titleTh: 'ปรับอัตลักษณ์องค์กรและเพิ่มชุดติดตั้ง Docker Compose', - requester: P.SeV, unit: 'ผู้บริหาร / ฝ่ายพัฒนา', - type: 'Scope', typeChecked: 'Quality', priority: 'Medium', - description: 'รวมการเปลี่ยนแปลงเพื่อเตรียมส่งมอบ 2 รายการ: (1) เปลี่ยนชุดอัตลักษณ์องค์กร ได้แก่ โลโก้ (logo.png, logo.svg), Favicon และภาพหัวเอกสาร พร้อมปรับไฟล์ UI ที่อ้างอิง และ (2) เพิ่มชุดติดตั้ง Docker Compose สำหรับใช้งานจริง ประกอบด้วย Compose file, Dockerfile, แม่แบบค่าตั้งค่า, Entrypoint, SQL เริ่มต้น, .env.example และสคริปต์สร้าง .env แบบโต้ตอบ', - justification: 'ให้ชุดส่งมอบใช้อัตลักษณ์องค์กรของลูกค้าอย่างถูกต้อง และมีเส้นทางการติดตั้งที่ทำซ้ำได้ โดยไม่นำค่าความลับเข้า Source Control หรือฝังไว้ใน Image', - impact: [ - ['ผลกระทบต่อ Scope', 'ปรับแบรนด์ 23 ไฟล์ (ภาพและไฟล์ PHP/CSS 11 ไฟล์) และเพิ่มไฟล์ติดตั้ง 10 ไฟล์'], - ['ผลกระทบต่อ Schedule', 'ดำเนินการภายในช่วงเตรียมส่งมอบ 15–17 ส.ค. 69'], - ['ผลกระทบต่อ Budget/Cost', 'ไม่มีค่าใช้จ่ายเพิ่ม'], - ['ผลกระทบต่อ Resource', 'ผู้พัฒนา 1 คน'], - ['ผลกระทบต่อ Quality/Deliverables', 'ภาพหัวเอกสารถูกใช้ในเอกสารส่งมอบ ชุด Docker Compose สร้างค่าความลับจาก .env ขณะเริ่ม Container ตาม CR10:003'], - ], - commit: '63cea23, 136084f, 6c39700', result: 'ดำเนินการแล้วเสร็จเมื่อ 17 ส.ค. 69 และตรวจสอบผลด้วย TC-UN13.002 และ TC-UN13.003', - }, +/** + * Change control. A change request is raised only for something the delivery cannot do without: + * it adds, removes or alters a deliverable, and so moves Man-day, schedule or cost. + * Adjustments that fail that test are handled as decisions or tasks and listed here as reviewed. + */ +export const CHANGE_CRITERIA = [ + ['เป็นสิ่งจำเป็นต่อการส่งมอบ', 'หากไม่ดำเนินการ จะส่งมอบสิ่งส่งมอบ (Work Product) หรือความต้องการที่ตกลงไว้ไม่ได้'], + ['เปลี่ยนแปลงขอบเขตหรือสิ่งส่งมอบ', 'เพิ่ม ลด หรือแก้ไขความต้องการ (CR) หรือสิ่งส่งมอบที่ตั้ง Baseline แล้ว เช่น เพิ่มโมดูล หรือรองรับ 2 ภาษา'], + ['กระทบทรัพยากรของโครงการ', 'กระทบ Man-day กำหนดส่งมอบ หรือค่าใช้จ่าย จึงต้องประเมินผลกระทบและขออนุมัติก่อนดำเนินการ'], +]; +/** Adjustments reviewed against CHANGE_CRITERIA: [date, topic, requesterId, assessment, handledAs, reference]. */ +export const CHANGE_REVIEW = [ + ['2026-05-23', 'ปรับคำเรียกตำแหน่งจัดเก็บจาก Rack เป็น Bin ทั้งระบบ', 'NoC', + 'เป็นการปรับคำเรียกบนหน้าจอให้ตรงกับการปฏิบัติงานจริง ไม่เพิ่มหรือลดฟังก์ชัน ไม่กระทบ Man-day และส่งมอบได้แม้ไม่ปรับ', + 'มติที่ประชุม ดำเนินการภายใน Task 3.9', 'Meeting Record 23 พ.ค. 69, Correction Register ISS-023'], + ['2026-08-03', 'เตรียมข้อมูลสาธิตสำหรับการตรวจรับและการสาธิตระบบ', 'ApS', + 'เป็นข้อมูลตั้งต้นสำหรับตรวจรับ ไม่ใช่สิ่งส่งมอบ และต้องแยกจากข้อมูลใช้งานจริงตาม CR07:004', + 'งานเตรียมการส่งมอบ Task 4.7', 'Meeting Record 3 ส.ค. 69, 14 ส.ค. 69'], + ['2026-08-14', 'ปรับอัตลักษณ์องค์กรและจัดทำชุดติดตั้ง Docker Compose', 'SeV', + 'ชุดติดตั้ง Docker Compose อยู่ในความต้องการ CR10:002 ตั้งแต่ Baseline และการปรับอัตลักษณ์องค์กรไม่เปลี่ยนแปลงฟังก์ชันหรือสิ่งส่งมอบ', + 'งานเตรียมการส่งมอบ Task 4.7', 'Meeting Record 14 ส.ค. 69, 17 ส.ค. 69'], +]; + +/** + * Verification rounds, planned in the Software Project Plan and recorded in Verification Results. + * The 232-day project is reviewed about every two months, with a final round before delivery. + */ +export const VERIFICATION_ROUNDS = [ + { v: 'V0.1', date: '2026-03-17', no: 1, time: '09:00 – 12:00 น.', hours: 3, topic: 'ตรวจสอบเอกสารวางแผนโครงการและความต้องการ', wps: ['WP 1.0', 'WP 2.0'] }, + { v: 'V0.2', date: '2026-05-29', no: 2, time: '09:00 – 12:00 น.', hours: 3, topic: 'ตรวจสอบเอกสารความต้องการซอฟต์แวร์และการออกแบบ', wps: ['WP 3.0', 'WP 4.0', 'WP 5.0'] }, + { v: 'V0.3', date: '2026-07-31', no: 3, time: '09:00 – 12:00 น.', hours: 3, topic: 'ตรวจสอบชุดทดสอบและการสอบกลับ', wps: ['WP 6.0'] }, + { v: 'V1.0', date: '2026-08-17', no: 4, time: '09:00 – 16:00 น.', hours: 6, 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'] }, +]; +/** Rules every verification round follows (plan section and each Verification Results record). */ +export const VERIFICATION_RULES = [ + 'เจ้าหน้าที่ควบคุมเอกสารต้องตรวจสอบแต่ละรายการอย่างละเอียด และต้องมีหลักฐานเพียงพอที่จะสรุปผลว่าผ่าน', + 'ผู้ปฏิบัติงานที่เกี่ยวข้องควรร่วมรับฟังผลการตรวจสอบ เพื่อให้แก้ไขได้ทันทีเมื่อพบประเด็น', + 'การตรวจสอบแต่ละครั้งไม่ควรถูกขัดจังหวะ ซึ่งจะทำให้การตรวจสอบเลื่อนออกไป', + 'ห้ามให้ผู้อื่นตรวจสอบแทนผู้ที่ได้รับมอบหมาย', +]; + +/** + * Lessons drawn from the Correction Register at project close: what the team changes next time. + * [theme, issue ids, what happened, preventive action for the next project] + */ +export const LESSONS = [ + ['ความปลอดภัยและการควบคุมสิทธิ์', ['ISS-001', 'ISS-003', 'ISS-004', 'ISS-006', 'ISS-009', 'ISS-011', 'ISS-015', 'ISS-016', 'ISS-017', 'ISS-018', 'ISS-024', 'ISS-026'], + 'ข้อบกพร่องกลุ่มใหญ่ที่สุดเกิดจากการเพิ่ม Role Guard การตรวจสิทธิ์ และการจำกัด Session ทีละส่วนระหว่างพัฒนา', + 'กำหนด Secure Coding Checklist และรูปแบบการตรวจสิทธิ์กลางตั้งแต่ช่วงออกแบบ และทบทวนโค้ดด้านความปลอดภัยทุกโมดูลก่อนรวมเข้า Baseline'], + ['ขั้นตอน Onboarding และการลงทะเบียน', ['ISS-007', 'ISS-008', 'ISS-013'], + 'เส้นทางการรับคำเชิญมีหลายเงื่อนไขที่ไม่ได้ระบุครบในการออกแบบ', + 'เขียน Test Case ครบทุกเส้นทางของขั้นตอนหลายสถานะก่อนพัฒนา และทดสอบซ้ำทุกครั้งที่แก้ไข'], + ['ความสอดคล้องระหว่างข้อกำหนดกับการพัฒนา', ['ISS-019', 'ISS-020', 'ISS-022'], + 'ข้อกำหนดและเอกสารถูกปรับระหว่างพัฒนา ทำให้เกิดช่องว่างกับโค้ด', + 'ปรับข้อกำหนดและ Traceability Record ในรอบเดียวกับการแก้โค้ด และตรวจความสอดคล้องในทุกรอบ Verification'], + ['ความถูกต้องของข้อมูลสต๊อกและบัญชี', ['ISS-002', 'ISS-012'], + 'การแปลงชนิดข้อมูลและการตรวจสอบความสัมพันธ์ของข้อมูลไม่ครอบคลุม', + 'ตรวจสอบข้อมูลนำเข้าและความสัมพันธ์ฝั่งเซิร์ฟเวอร์ทุกคำสั่งที่เปลี่ยนสต๊อกหรือ GL และเพิ่มชุดทดสอบวงจรเอกสาร'], + ['มาตรฐานโค้ดและการตั้งค่าสภาพแวดล้อม', ['ISS-005', 'ISS-010', 'ISS-014', 'ISS-021', 'ISS-023', 'ISS-025', 'ISS-027', 'ISS-028'], + 'พัฒนาหลายโมดูลคู่ขนานโดยไม่มีมาตรฐานการตั้งชื่อ เส้นทางไฟล์ และค่าตั้งค่ากลาง', + 'กำหนด Coding Standard และแม่แบบค่าตั้งค่าตั้งแต่ต้นโครงการ และทดสอบการติดตั้งบนสภาพแวดล้อมใหม่ทุกครั้งก่อนตั้ง Baseline'], ]; /** @@ -133,10 +144,10 @@ export const PERIODS = [ ['2026-05-08', '2026-04-30', '2026-05-08', 8, [['3.4', 'In Progress', 80, 'พัฒนาการเข้าสู่ระบบและสิทธิ์ตามบทบาทเกือบครบ เหลือขั้นตอนกู้คืนรหัสผ่าน'], ['3.5', 'Completed', 100, 'พัฒนาใบสั่งขาย ใบรับคืน ใบแจ้งหนี้ คลังหลายชั้น และบาร์โค้ดครบตามแผน'], ['3.9', 'In Progress', 25, 'เริ่มทบทวน Role Guard และการรวมศูนย์การตรวจสิทธิ์']], ['ISS-003', 'ISS-004', 'ISS-005'], [], { date: '2026-05-13', topic: 'ติดตามการเตรียมใช้งานจริง สคริปต์ติดตั้ง และการเริ่มโมดูลบัญชี' }], ['2026-05-13', '2026-05-11', '2026-05-13', 9, [['3.4', 'Completed', 100, 'พัฒนาการเข้าสู่ระบบ Onboarding และกู้คืนรหัสผ่านครบถ้วน'], ['3.6', 'Completed', 100, 'จัดทำ Base URL อัตโนมัติ สคริปต์ติดตั้งฐานข้อมูล และข้อมูลทดสอบ'], ['3.7', 'In Progress', 20, 'เริ่มพัฒนาโมดูลบัญชีและผังบัญชี']], ['ISS-006', 'ISS-007', 'ISS-008', 'ISS-009'], [], { date: '2026-05-23', topic: 'ติดตามการพัฒนาบัญชี การเงิน และการควบคุมสิทธิ์ผู้ใช้' }], ['2026-05-23', '2026-05-20', '2026-05-23', 10, [['3.7', 'Completed', 100, 'พัฒนาผังบัญชี GL สมุดรายวัน รายงานบัญชี ใบวางบิลและใบเสร็จครบตามแผน'], ['3.8', 'In Progress', 45, 'อยู่ระหว่างพัฒนา Socket.IO และตารางสรุปยอด'], ['3.9', 'In Progress', 60, 'เพิ่มการเชิญผู้ใช้ การควบคุมสิทธิ์แอปพลิเคชัน และโควตารายการ']], ['ISS-010', 'ISS-011', 'ISS-012', 'ISS-013', 'ISS-014', 'ISS-015'], [], { date: '2026-05-29', topic: 'สรุปผลการพัฒนาและตั้ง Baseline การพัฒนา' }], - ['2026-05-29', '2026-05-24', '2026-05-29', 11, [['3.8', 'Completed', 100, 'พัฒนาบริการแจ้งเตือน Real-time ตารางสรุปยอด และงานตามกำหนดเวลาครบถ้วน'], ['3.9', 'Completed', 100, 'ทบทวนความปลอดภัย ขอบเขตบริษัท วงจรเอกสาร และปิดข้อบกพร่องที่พบ'], ['3.10', 'Completed', 100, 'ลดความซ้ำซ้อนของคลาสและตั้ง Baseline การพัฒนาเมื่อ 29 พ.ค. 69']], ['ISS-016', 'ISS-017', 'ISS-018', 'ISS-019', 'ISS-020', 'ISS-021', 'ISS-022', 'ISS-023', 'ISS-024', 'ISS-025', 'ISS-026', 'ISS-027'], ['CH-001'], { date: '2026-08-03', topic: 'ติดตามการตรวจสอบเอกสาร การจัดทำคู่มือ และการแก้ไขหลัง Baseline' }], + ['2026-05-29', '2026-05-24', '2026-05-29', 11, [['3.8', 'Completed', 100, 'พัฒนาบริการแจ้งเตือน Real-time ตารางสรุปยอด และงานตามกำหนดเวลาครบถ้วน'], ['3.9', 'Completed', 100, 'ทบทวนความปลอดภัย ขอบเขตบริษัท วงจรเอกสาร และปิดข้อบกพร่องที่พบ'], ['3.10', 'Completed', 100, 'ลดความซ้ำซ้อนของคลาสและตั้ง Baseline การพัฒนาเมื่อ 29 พ.ค. 69']], ['ISS-016', 'ISS-017', 'ISS-018', 'ISS-019', 'ISS-020', 'ISS-021', 'ISS-022', 'ISS-023', 'ISS-024', 'ISS-025', 'ISS-026', 'ISS-027'], [], { date: '2026-08-03', topic: 'ติดตามการตรวจสอบเอกสาร การจัดทำคู่มือ และการแก้ไขหลัง Baseline' }], ['2026-08-03', '2026-06-01', '2026-08-03', 12, [['4.3', 'In Progress', 70, 'ตรวจสอบเอกสารความต้องการ ออกแบบ และการสอบกลับ รอบที่ 1–3'], ['4.5', 'In Progress', 80, 'จัดทำคู่มือผู้ใช้ คู่มือผู้ดูแลระบบ และคู่มือบำรุงรักษา'], ['4.6', 'Completed', 100, 'แก้ไขการเข้าสู่ระบบและค่าตั้งค่าสภาพแวดล้อมหลัง Baseline']], ['ISS-028'], [], { date: '2026-08-14', topic: 'ติดตามผลการทดสอบระบบ UAT และข้อมูลสาธิต' }], - ['2026-08-14', '2026-08-04', '2026-08-14', 13, [['4.4', 'Completed', 100, 'ทดสอบระบบ 45 Test Case และ UAT 12 สถานการณ์ ผ่านทั้งหมดระหว่าง 10–14 ส.ค. 69'], ['4.7', 'In Progress', 60, 'จัดทำข้อมูลสาธิตเสร็จ อยู่ระหว่างปรับแบรนด์และชุดติดตั้ง Docker Compose'], ['5.1', 'In Progress', 70, 'ตรวจสอบความครบถ้วนของ Work Products']], [], ['CH-002'], { date: '2026-08-17', topic: 'สรุปผลการตรวจสอบรอบสุดท้าย และตรวจรับส่งมอบระบบ' }], - ['2026-08-17', '2026-08-15', '2026-08-17', 14, [['4.3', 'Completed', 100, 'ตรวจสอบ Work Products รอบที่ 4 ครบทุกรายการ ผลผ่านทั้งหมด'], ['4.5', 'Completed', 100, 'คู่มือผู้ใช้ คู่มือผู้ดูแลระบบ และคู่มือบำรุงรักษาเสร็จสมบูรณ์'], ['4.7', 'Completed', 100, 'ปรับแบรนด์และชุดติดตั้ง Docker Compose เสร็จ Baseline 6c39700'], ['5.1', 'Completed', 100, 'จัดทำ List of Evidence ครบทุก Work Product'], ['5.3', 'In Progress', 80, 'ลูกค้าตรวจรับระบบเมื่อ 17 ส.ค. 69 เหลือการอบรมและปิดโครงการ']], [], ['CH-003'], { date: '2026-08-24', topic: 'สรุปผลการอบรม การปิดงานควบคุมปฏิบัติการ และปิดโครงการ' }], + ['2026-08-14', '2026-08-04', '2026-08-14', 13, [['4.4', 'Completed', 100, `ทดสอบระบบ 45 Test Case และ UAT ครบ 14 หมวดความต้องการ (${CRS.length} รายการ) ผ่านทั้งหมดระหว่าง 10–14 ส.ค. 69`], ['4.7', 'In Progress', 60, 'จัดทำข้อมูลสาธิตเสร็จ อยู่ระหว่างปรับแบรนด์และชุดติดตั้ง Docker Compose'], ['5.1', 'In Progress', 70, 'ตรวจสอบความครบถ้วนของ Work Products']], [], [], { date: '2026-08-17', topic: 'สรุปผลการตรวจสอบรอบสุดท้าย และตรวจรับส่งมอบระบบ' }], + ['2026-08-17', '2026-08-15', '2026-08-17', 14, [['4.3', 'Completed', 100, 'ตรวจสอบ Work Products รอบที่ 4 ครบทุกรายการ ผลผ่านทั้งหมด'], ['4.5', 'Completed', 100, 'คู่มือผู้ใช้ คู่มือผู้ดูแลระบบ และคู่มือบำรุงรักษาเสร็จสมบูรณ์'], ['4.7', 'Completed', 100, 'ปรับแบรนด์และชุดติดตั้ง Docker Compose เสร็จ Baseline 6c39700'], ['5.1', 'Completed', 100, 'จัดทำ List of Evidence ครบทุก Work Product'], ['5.3', 'In Progress', 80, 'ลูกค้าตรวจรับระบบเมื่อ 17 ส.ค. 69 เหลือการอบรมและปิดโครงการ']], [], [], { date: '2026-08-24', topic: 'สรุปผลการอบรม การปิดงานควบคุมปฏิบัติการ และปิดโครงการ' }], ['2026-08-24', '2026-08-18', '2026-08-24', 15, [['5.2', 'Completed', 100, 'อบรมผู้ใช้งาน 6 คน เมื่อ 22 ส.ค. 69 ผ่านการทดลองใช้งานครบทุกขั้นตอน'], ['5.3', 'Completed', 100, 'ปิดงานควบคุมปฏิบัติการ 23 ส.ค. 69 และปิดโครงการอย่างเป็นทางการ 24 ส.ค. 69'], ['4.1', 'Completed', 100, 'บันทึกความก้าวหน้าและรายงานการประชุมครบตลอดโครงการ'], ['4.2', 'Completed', 100, 'ควบคุมเวอร์ชันและสำรองข้อมูลครบ พร้อม Tag sdlc-v1.0-final']], [], [], null], ]; @@ -201,11 +212,11 @@ export const MEETINGS = [ }, { date: '2026-05-23', phase: 'Project Execution', taskId: '3.7', taskName: 'Accounting & Finance Workflows', time: '09:00 – 11:00 น.', - attachment: 'Progress Status Record 23 พ.ค. 69, Change Report CH-001', + attachment: 'Progress Status Record 23 พ.ค. 69', progress: [['Phase 3: Project Execution', 'กำลังดำเนินการ', 85, 'บัญชีและการเงินเสร็จ เหลือบริการแจ้งเตือนและการทบทวนความปลอดภัย'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 72, 'เตรียมเข้าสู่ Baseline การพัฒนา']], - agenda: [['ผลการพัฒนาบัญชีและการเงิน', 'ตรวจสอบความครบถ้วนตาม CR01:015–CR01:017'], ['พิจารณาคำขอเปลี่ยนแปลง CH-001 (Rack เป็น Bin)', 'ประเมินผลกระทบและอนุมัติ'], ['แผนงานก่อนตั้ง Baseline การพัฒนา', 'ยืนยันงานที่ต้องเสร็จภายใน 29 พ.ค. 69']], - discussion: [['บัญชีและการเงิน', 'พัฒนาผังบัญชี GL สมุดรายวัน รายงานบัญชี ใบวางบิลและใบเสร็จครบตามความต้องการ', ['ThS', 'NoC'], 'เสร็จสิ้น'], ['คำขอเปลี่ยนแปลง CH-001', 'เปลี่ยนคำเรียกตำแหน่งจัดเก็บจาก Rack เป็น Bin ให้ตรงกับคำที่พนักงานคลังใช้จริง ประเมินผลกระทบระดับ Medium ไม่กระทบกำหนดส่งมอบ', ['SeV', 'ApS', 'NoC'], 'อนุมัติ'], ['ความปลอดภัยและโควตารายการ', 'เพิ่มการควบคุมสิทธิ์แอปพลิเคชันและโควตารายการต่อบริษัท', ['ThS'], 'ดำเนินการ']], - actions: [['ดำเนินการเปลี่ยนคำเรียกตามคำขอ CH-001', ['ThS'], '2026-05-27', 'Scheduled'], ['ทบทวนความปลอดภัยและวงจรเอกสารก่อนตั้ง Baseline (Task 3.9)', ['ThS', 'PaNg'], '2026-05-28', 'Scheduled'], ['บันทึกการแก้ไข ISS-010 ถึง ISS-015 ใน Correction Register', ['YaB'], '2026-05-25', 'Scheduled']], + agenda: [['ผลการพัฒนาบัญชีและการเงิน', 'ตรวจสอบความครบถ้วนตาม CR01:015–CR01:017'], ['คำเรียกตำแหน่งจัดเก็บ (Rack / Bin)', 'กำหนดคำเรียกที่ใช้ในหน้าจอให้ตรงกับการปฏิบัติงานจริง'], ['แผนงานก่อนตั้ง Baseline การพัฒนา', 'ยืนยันงานที่ต้องเสร็จภายใน 29 พ.ค. 69']], + discussion: [['บัญชีและการเงิน', 'พัฒนาผังบัญชี GL สมุดรายวัน รายงานบัญชี ใบวางบิลและใบเสร็จครบตามความต้องการ', ['ThS', 'NoC'], 'เสร็จสิ้น'], ['คำเรียกตำแหน่งจัดเก็บ', 'ที่ประชุมมีมติให้ใช้คำว่า Bin แทน Rack ทั้งระบบให้ตรงกับคำที่พนักงานคลังใช้จริง เป็นการปรับคำเรียกบนหน้าจอ ไม่เพิ่มหรือลดฟังก์ชันและไม่กระทบ Man-day จึงไม่ถือเป็นคำขอเปลี่ยนแปลง', ['SeV', 'ApS', 'NoC'], 'มติที่ประชุม'], ['ความปลอดภัยและโควตารายการ', 'เพิ่มการควบคุมสิทธิ์แอปพลิเคชันและโควตารายการต่อบริษัท', ['ThS'], 'ดำเนินการ']], + actions: [['ปรับคำเรียก Rack เป็น Bin ตามมติที่ประชุม', ['ThS'], '2026-05-27', 'Scheduled'], ['ทบทวนความปลอดภัยและวงจรเอกสารก่อนตั้ง Baseline (Task 3.9)', ['ThS', 'PaNg'], '2026-05-28', 'Scheduled'], ['บันทึกการแก้ไข ISS-010 ถึง ISS-015 ใน Correction Register', ['YaB'], '2026-05-25', 'Scheduled']], next: { date: '2026-05-29', topic: 'สรุปผลการพัฒนาและตั้ง Baseline การพัฒนา' }, }, { @@ -228,19 +239,19 @@ export const MEETINGS = [ }, { date: '2026-08-14', phase: 'Validation', taskId: '4.4', taskName: 'System Test & UAT', time: '09:00 – 11:00 น.', - attachment: 'Test Report, Validation Results, Change Report CH-002', - progress: [['Phase 4: Verification & Validation', 'เสร็จสมบูรณ์', 100, 'ทดสอบ 45 Test Case และ UAT 12 สถานการณ์ ผ่านทั้งหมด'], ['Phase 5: Project Close', 'กำลังดำเนินการ', 60, 'อยู่ระหว่างตรวจสอบ Work Products และเตรียมชุดส่งมอบ'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 92, 'เตรียมตรวจรับและปิดโครงการ']], - agenda: [['สรุปผลการทดสอบระบบ 45 Test Case', 'ยืนยันผลการทดสอบและข้อบกพร่องคงค้าง'], ['สรุปผลการทดสอบการยอมรับ (UAT) 12 สถานการณ์', 'ยืนยันความพร้อมใช้งานจริง'], ['พิจารณาคำขอเปลี่ยนแปลง CH-002 (ข้อมูลสาธิต)', 'ประเมินผลกระทบและอนุมัติ'], ['แผนงานปิดโครงการ', 'ยืนยันงานที่เหลือถึง 24 ส.ค. 69']], - discussion: [['ผลการทดสอบระบบ', 'ทดสอบ 45 Test Case บน Internal Testing Server ผ่านทั้งหมด ไม่พบข้อบกพร่องคงค้าง', ['PaNg'], 'ผ่าน'], ['ผลการทดสอบการยอมรับ', 'ตัวแทนลูกค้าทดสอบ 12 สถานการณ์บนสภาพแวดล้อมใช้งานจริง ผ่านทั้งหมด', ['SeV'], 'ผ่าน'], ['คำขอเปลี่ยนแปลง CH-002', 'เพิ่มชุดข้อมูลสาธิตเพื่อใช้ตรวจรับรายงานและขั้นตอนการทำงาน ประเมินผลกระทบระดับ Medium', ['ApS', 'SeV'], 'อนุมัติ'], ['งานที่เหลือ', 'ตรวจสอบ Work Products รอบสุดท้าย เตรียมชุดติดตั้ง ตรวจรับ อบรม และปิดโครงการ', ['ApS', 'YaB'], 'ดำเนินการ']], - actions: [['ตรวจสอบ Work Products รอบที่ 4 และจัดทำ List of Evidence', ['YaB', 'ApS'], '2026-08-17', 'Scheduled'], ['จัดทำชุดติดตั้ง Docker Compose และปรับแบรนด์ (CH-003)', ['ThS'], '2026-08-17', 'Scheduled'], ['นัดตรวจรับส่งมอบระบบกับ Project Sponsor', ['ApS'], '2026-08-17', 'Scheduled']], + attachment: 'Test Report, Validation Results', + progress: [['Phase 4: Verification & Validation', 'เสร็จสมบูรณ์', 100, `ทดสอบ 45 Test Case และ UAT ครบ 14 หมวดความต้องการ (${CRS.length} รายการ) ผ่านทั้งหมด`], ['Phase 5: Project Close', 'กำลังดำเนินการ', 60, 'อยู่ระหว่างตรวจสอบ Work Products และเตรียมชุดส่งมอบ'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 92, 'เตรียมตรวจรับและปิดโครงการ']], + agenda: [['สรุปผลการทดสอบระบบ 45 Test Case', 'ยืนยันผลการทดสอบและข้อบกพร่องคงค้าง'], ['สรุปผลการทดสอบการยอมรับ (UAT) ตาม Customer Requirements CR01–CR14', 'ยืนยันความพร้อมใช้งานจริง'], ['ข้อมูลสาธิตสำหรับการตรวจรับ (Task 4.7)', 'ยืนยันความพร้อมของข้อมูลตั้งต้น'], ['แผนงานปิดโครงการ', 'ยืนยันงานที่เหลือถึง 24 ส.ค. 69']], + discussion: [['ผลการทดสอบระบบ', 'ทดสอบ 45 Test Case บน Internal Testing Server ผ่านทั้งหมด ไม่พบข้อบกพร่องคงค้าง', ['PaNg'], 'ผ่าน'], ['ผลการทดสอบการยอมรับ', `ตัวแทนลูกค้าทดสอบการยอมรับครบ 14 หมวดความต้องการ (${CRS.length} รายการ) บนสภาพแวดล้อมใช้งานจริง ผ่านทั้งหมด`, ['SeV'], 'ผ่าน'], ['ข้อมูลสาธิต', 'จัดเตรียมข้อมูลสาธิตสำหรับการตรวจรับรายงานและขั้นตอนการทำงานเสร็จแล้ว เป็นงานเตรียมการส่งมอบตาม Task 4.7 ไม่เปลี่ยนแปลงขอบเขตหรือสิ่งส่งมอบ', ['ApS', 'SeV'], 'เสร็จสิ้น'], ['งานที่เหลือ', 'ตรวจสอบ Work Products รอบสุดท้าย เตรียมชุดติดตั้ง ตรวจรับ อบรม และปิดโครงการ', ['ApS', 'YaB'], 'ดำเนินการ']], + actions: [['ตรวจสอบ Work Products รอบที่ 4 และจัดทำ List of Evidence', ['YaB', 'ApS'], '2026-08-17', 'Scheduled'], ['จัดทำชุดติดตั้ง Docker Compose (CR10:002) และปรับแบรนด์ (Task 4.7)', ['ThS'], '2026-08-17', 'Scheduled'], ['นัดตรวจรับส่งมอบระบบกับ Project Sponsor', ['ApS'], '2026-08-17', 'Scheduled']], next: { date: '2026-08-17', topic: 'สรุปผลการตรวจสอบรอบสุดท้ายและตรวจรับส่งมอบระบบ' }, }, { date: '2026-08-17', phase: 'Project Close', taskId: '5.3', taskName: 'Acceptance & Project Closure', time: '09:00 – 11:00 น.', - attachment: 'Acceptance Report, List of Evidence, Verification Results, Change Report CH-003', + attachment: 'Acceptance Report, List of Evidence, Verification Results', progress: [['Phase 3: Project Execution', 'เสร็จสมบูรณ์', 100, 'พัฒนาระบบครบตามขอบเขต Baseline 6c39700'], ['Phase 4: Verification & Validation', 'เสร็จสมบูรณ์', 100, 'ตรวจสอบ ทดสอบ และ UAT ผ่านครบทุกรายการ'], ['Phase 5: Project Close', 'กำลังดำเนินการ', 80, 'ตรวจรับระบบแล้ว เหลือการอบรมและปิดงานควบคุมปฏิบัติการ'], ['รวมความคืบหน้าทั้งโครงการ', 'ตามแผน', 96, 'ตรวจรับระบบเรียบร้อย']], - agenda: [['นำเสนอผลการดำเนินโครงการและสิ่งส่งมอบ', 'สรุปผลงานทั้งหมดเทียบกับแผนและผลลัพธ์จริง'], ['ตรวจสอบความครบถ้วนของเอกสารและหลักฐาน', 'ยืนยันเอกสารครบตามมาตรฐาน ISO/IEC 29110'], ['พิจารณาคำขอเปลี่ยนแปลง CH-003', 'ประเมินผลกระทบและอนุมัติ'], ['พิจารณาตรวจรับส่งมอบระบบ', 'ลงมติผลการตรวจรับ']], - discussion: [['ผลการดำเนินโครงการ', 'พัฒนาระบบครบตามขอบเขต 11 ระบบงาน ทดสอบและ UAT ผ่านทั้งหมด ไม่มีข้อบกพร่องระดับวิกฤตคงค้าง', ['ApS', 'SeV'], 'ผ่านการรับรอง'], ['ความครบถ้วนของเอกสาร', 'ตรวจสอบ Work Products รอบที่ 4 ครบทุกรายการ ผลผ่านทั้งหมด และจัดทำ List of Evidence เรียบร้อย', ['YaB', 'PaNg'], 'สมบูรณ์'], ['คำขอเปลี่ยนแปลง CH-003', 'ปรับอัตลักษณ์องค์กรและเพิ่มชุดติดตั้ง Docker Compose ประเมินผลกระทบระดับ Medium', ['SeV', 'ApS'], 'อนุมัติ'], ['ผลการตรวจรับ', 'Project Sponsor ตรวจรับสิ่งส่งมอบทั้งหมด ผลการตรวจรับ Accepted', ['SeV'], 'ตรวจรับแล้ว']], + agenda: [['นำเสนอผลการดำเนินโครงการและสิ่งส่งมอบ', 'สรุปผลงานทั้งหมดเทียบกับแผนและผลลัพธ์จริง'], ['ตรวจสอบความครบถ้วนของเอกสารและหลักฐาน', 'ยืนยันเอกสารครบตามมาตรฐาน ISO/IEC 29110'], ['ชุดติดตั้งและอัตลักษณ์องค์กร (Task 4.7)', 'ยืนยันความพร้อมของชุดส่งมอบ'], ['พิจารณาตรวจรับส่งมอบระบบ', 'ลงมติผลการตรวจรับ']], + discussion: [['ผลการดำเนินโครงการ', 'พัฒนาระบบครบตามขอบเขต 11 ระบบงาน ทดสอบและ UAT ผ่านทั้งหมด ไม่มีข้อบกพร่องระดับวิกฤตคงค้าง', ['ApS', 'SeV'], 'ผ่านการรับรอง'], ['ความครบถ้วนของเอกสาร', 'ตรวจสอบ Work Products รอบที่ 4 ครบทุกรายการ ผลผ่านทั้งหมด และจัดทำ List of Evidence เรียบร้อย', ['YaB', 'PaNg'], 'สมบูรณ์'], ['ชุดติดตั้งและอัตลักษณ์องค์กร', 'จัดทำชุดติดตั้ง Docker Compose ตามความต้องการ CR10:002 และปรับอัตลักษณ์องค์กรในหน้าจอและเอกสารเสร็จแล้ว เป็นงานเตรียมการส่งมอบตาม Task 4.7 ไม่เปลี่ยนแปลงขอบเขตหรือสิ่งส่งมอบ', ['SeV', 'ApS'], 'เสร็จสิ้น'], ['ผลการตรวจรับ', 'Project Sponsor ตรวจรับสิ่งส่งมอบทั้งหมด ผลการตรวจรับ Accepted', ['SeV'], 'ตรวจรับแล้ว']], actions: [['จัดอบรมผู้ใช้งานก่อนเปิดใช้งานจริง (Task 5.2)', ['ThS', 'PaNg'], '2026-08-22', 'Scheduled'], ['ปิดงานควบคุมการสำรองข้อมูลและการเฝ้าระวังระบบ', ['ThS'], '2026-08-23', 'Scheduled'], ['ปิดโครงการและส่งมอบเอกสารเข้าระบบควบคุมเอกสาร', ['ApS', 'YaB'], '2026-08-24', 'Scheduled']], next: { date: '2026-08-24', topic: 'สรุปผลการอบรม การปิดงานควบคุมปฏิบัติการ และปิดโครงการอย่างเป็นทางการ' }, }, @@ -254,3 +265,10 @@ export const MEETINGS = [ next: null, }, ]; + +// Sanity: every correction is drawn into exactly one lesson. +{ + const drawn = LESSONS.flatMap(([, issueIds]) => issueIds); + const missing = CORRECTIONS.map(([id]) => id).filter((id) => !drawn.includes(id)); + if (missing.length || drawn.length !== new Set(drawn).size) throw new Error(`Lessons must cover each correction once; missing: ${missing.join(', ')}`); +} diff --git a/scripts/sdlc-seed/project.mjs b/scripts/sdlc-seed/project.mjs index 97550d4..877ee20 100644 --- a/scripts/sdlc-seed/project.mjs +++ b/scripts/sdlc-seed/project.mjs @@ -38,7 +38,7 @@ export const WPS = [ ['WP 2.0', `เอกสาร ${CODE} Customer Requirements`, 'ส่งเอกสารจำนวน 1 ชุด'], ['WP 3.0', `เอกสาร ${CODE} Software Requirements Specification`, 'ส่งเอกสารจำนวน 1 ชุด'], ['WP 4.0', `เอกสาร ${CODE} Software Design`, 'ส่งเอกสารจำนวน 1 ชุด'], - ['WP 5.0', `เอกสาร ${CODE} Change Report`, 'ส่งเอกสารจำนวน 3 ฉบับ (CH-001–CH-003)'], + ['WP 5.0', `เอกสาร ${CODE} Change Report`, 'ส่งเอกสารจำนวน 1 ชุด (ทะเบียนการควบคุมการเปลี่ยนแปลง)'], ['WP 6.0', `เอกสาร ${CODE} Test Case and Test Procedures`, 'ส่งเอกสารจำนวน 1 ชุด'], ['WP 7.0', `เอกสาร ${CODE} Validation Results`, 'ส่งเอกสารจำนวน 1 ชุด'], ['WP 8.0', `เอกสาร ${CODE} Software User Document`, 'ส่งเอกสารจำนวน 1 ชุด'], @@ -62,118 +62,115 @@ export const SCOPE = [ ['ระบบติดตั้งและตั้งค่า', ['ติดตั้งแบบ Manual ผ่าน setup.php', 'ติดตั้งแบบ Container ผ่าน Docker Compose (php-apache, mariadb, node/pm2)', 'สร้างค่าตั้งค่าและความลับของระบบจาก .env โดยไม่เก็บใน Source Control']], ]; -/** - * Customer Requirements (CR01–CR14). Each: [id, text, remark]. - * Remark keeps the original FR-/NFR- identifier that appeared in earlier drafts so cross-references stay valid. - */ +/** Customer Requirements (CR01–CR14). Each: [id, text]. */ export const CR_GROUPS = [ ['CR01', 'Feature & Functional Characteristics', [ - ['CR01:001', 'ระบบต้องรองรับการลงทะเบียนเจ้าของบริษัทและการเชิญผู้ใช้งานเข้าร่วมบริษัท (Onboarding)', 'FR-001'], - ['CR01:002', 'ระบบต้องยืนยันตัวตนผู้ใช้และบังคับสิทธิ์ตามบทบาท Owner, Admin, Staff และ Viewer', 'FR-002'], - ['CR01:003', 'ระบบต้องรองรับการกู้คืนรหัสผ่าน การควบคุม Session และการยืนยัน OTP ตามที่กำหนด', 'FR-003'], - ['CR01:004', 'ระบบต้องให้ผู้ดูแลจัดการข้อมูลบริษัท, SMTP, การตั้งค่าระบบ, ผู้ใช้งาน และสิทธิ์การเข้าถึงแอปพลิเคชัน', 'FR-004'], - ['CR01:005', 'ระบบต้องจัดการข้อมูลคลังสินค้า, พื้นที่/ช่องจัดเก็บ, หมวดสินค้า, สินค้า, ประเภทผู้ติดต่อ และผู้ติดต่อ', 'FR-005'], - ['CR01:006', 'ระบบต้องรองรับโครงสร้างตำแหน่งจัดเก็บทั้งแบบคลังเดียวและแบบหลายชั้น (คลัง/พื้นที่/ช่อง)', 'FR-006'], - ['CR01:007', 'ระบบต้องบันทึกการรับสินค้าเข้า (Stock-in) ระบุสินค้า จำนวน ตำแหน่ง เอกสารอ้างอิง และข้อมูลติดตาม', 'FR-007'], - ['CR01:008', 'ระบบต้องบันทึกการจ่ายสินค้าออก (Stock-out) โดยตรวจสอบสิทธิ์และยอดคงเหลือก่อนจ่าย', 'FR-008'], - ['CR01:009', 'ระบบต้องโอนย้ายสินค้าระหว่างตำแหน่งจัดเก็บที่ได้รับอนุญาตโดยยอดต้นทาง/ปลายทางสมดุลกัน', 'FR-009'], - ['CR01:010', 'ระบบต้องติดตาม Lot, Serial Number และวันหมดอายุของสินค้าที่เกี่ยวข้อง', 'FR-010'], - ['CR01:011', 'ระบบต้องแสดงภาพรวมสต๊อก, ประวัติความเคลื่อนไหว, ความจุ/การใช้พื้นที่, สินค้าใกล้หมด, สินค้าหมดอายุ และข้อมูล Lot', 'FR-011'], - ['CR01:012', 'ระบบต้องพิมพ์บาร์โค้ดสินค้า (SKU) และตำแหน่งจัดเก็บ และรองรับการสแกนในหน้าจอที่กำหนด', 'FR-012'], - ['CR01:013', 'ระบบต้องสร้างและจัดการใบเสนอราคา, ใบสั่งขาย, ใบแจ้งหนี้, ใบรับคืน และใบลดหนี้', 'FR-013'], - ['CR01:014', 'ระบบต้องสร้างและจัดการใบขอซื้อ, ใบสั่งซื้อ, ใบแจ้งหนี้ซื้อ และใบคืนสินค้าผู้ขาย', 'FR-014'], - ['CR01:015', 'ระบบต้องสร้างและจัดการใบวางบิลรับ, ใบเสร็จรับเงิน, ใบวางบิลจ่าย และใบสำคัญจ่าย', 'FR-015'], - ['CR01:016', 'ระบบต้องจัดการผังบัญชี, แผนก, สูตรบัญชี, สมุดรายวัน และบัญชีแยกประเภท', 'FR-016'], - ['CR01:017', 'ระบบต้องจัดทำรายงานงบทดลอง, งบกำไรขาดทุน, งบดุล, ภาษีมูลค่าเพิ่ม, สมุดรายวัน และความเคลื่อนไหว GL', 'FR-017'], - ['CR01:018', 'ระบบต้องออกเลขที่เอกสารอัตโนมัติและควบคุมสถานะ/วงจรชีวิตของเอกสาร', 'FR-018'], - ['CR01:019', 'ระบบต้องรองรับการแนบไฟล์ที่อนุญาตกับรายการที่กำหนด', 'FR-019'], - ['CR01:020', 'ระบบต้องให้ผู้ใช้กรอง ดู พิมพ์ และส่งออกรายงานปฏิบัติการและรายงานผู้บริหาร', 'FR-020'], - ['CR01:021', 'ระบบต้องแจ้งเตือนผู้ใช้ที่เกี่ยวข้องเมื่อสถานะเอกสารเปลี่ยนหรือมีเหตุการณ์ปฏิบัติการ', 'FR-021'], - ['CR01:022', 'ระบบต้องสรุปยอดสต๊อก/GL และแจ้งเตือนสินค้าใกล้หมดและใบแจ้งหนี้ค้างชำระตามกำหนดเวลา', 'FR-022'], - ['CR01:023', 'ระบบต้องเก็บผู้สร้าง ผู้แก้ไข สถานะ และประวัติรายการเพื่อการตรวจสอบ', 'FR-023'], - ['CR01:024', 'ระบบต้องจำกัดข้อมูลบริษัทและคลังสินค้าให้เฉพาะผู้ใช้ที่ได้รับอนุญาตในบริบทปัจจุบัน', 'FR-024'], + ['CR01:001', 'ระบบต้องรองรับการลงทะเบียนเจ้าของบริษัทและการเชิญผู้ใช้งานเข้าร่วมบริษัท (Onboarding)'], + ['CR01:002', 'ระบบต้องยืนยันตัวตนผู้ใช้และบังคับสิทธิ์ตามบทบาท Owner, Admin, Staff และ Viewer'], + ['CR01:003', 'ระบบต้องรองรับการกู้คืนรหัสผ่าน การควบคุม Session และการยืนยัน OTP ตามที่กำหนด'], + ['CR01:004', 'ระบบต้องให้ผู้ดูแลจัดการข้อมูลบริษัท, SMTP, การตั้งค่าระบบ, ผู้ใช้งาน และสิทธิ์การเข้าถึงแอปพลิเคชัน'], + ['CR01:005', 'ระบบต้องจัดการข้อมูลคลังสินค้า, พื้นที่/ช่องจัดเก็บ, หมวดสินค้า, สินค้า, ประเภทผู้ติดต่อ และผู้ติดต่อ'], + ['CR01:006', 'ระบบต้องรองรับโครงสร้างตำแหน่งจัดเก็บทั้งแบบคลังเดียวและแบบหลายชั้น (คลัง/พื้นที่/ช่อง)'], + ['CR01:007', 'ระบบต้องบันทึกการรับสินค้าเข้า (Stock-in) ระบุสินค้า จำนวน ตำแหน่ง เอกสารอ้างอิง และข้อมูลติดตาม'], + ['CR01:008', 'ระบบต้องบันทึกการจ่ายสินค้าออก (Stock-out) โดยตรวจสอบสิทธิ์และยอดคงเหลือก่อนจ่าย'], + ['CR01:009', 'ระบบต้องโอนย้ายสินค้าระหว่างตำแหน่งจัดเก็บที่ได้รับอนุญาตโดยยอดต้นทาง/ปลายทางสมดุลกัน'], + ['CR01:010', 'ระบบต้องติดตาม Lot, Serial Number และวันหมดอายุของสินค้าที่เกี่ยวข้อง'], + ['CR01:011', 'ระบบต้องแสดงภาพรวมสต๊อก, ประวัติความเคลื่อนไหว, ความจุ/การใช้พื้นที่, สินค้าใกล้หมด, สินค้าหมดอายุ และข้อมูล Lot'], + ['CR01:012', 'ระบบต้องพิมพ์บาร์โค้ดสินค้า (SKU) และตำแหน่งจัดเก็บ และรองรับการสแกนในหน้าจอที่กำหนด'], + ['CR01:013', 'ระบบต้องสร้างและจัดการใบเสนอราคา, ใบสั่งขาย, ใบแจ้งหนี้, ใบรับคืน และใบลดหนี้'], + ['CR01:014', 'ระบบต้องสร้างและจัดการใบขอซื้อ, ใบสั่งซื้อ, ใบแจ้งหนี้ซื้อ และใบคืนสินค้าผู้ขาย'], + ['CR01:015', 'ระบบต้องสร้างและจัดการใบวางบิลรับ, ใบเสร็จรับเงิน, ใบวางบิลจ่าย และใบสำคัญจ่าย'], + ['CR01:016', 'ระบบต้องจัดการผังบัญชี, แผนก, สูตรบัญชี, สมุดรายวัน และบัญชีแยกประเภท'], + ['CR01:017', 'ระบบต้องจัดทำรายงานงบทดลอง, งบกำไรขาดทุน, งบดุล, ภาษีมูลค่าเพิ่ม, สมุดรายวัน และความเคลื่อนไหว GL'], + ['CR01:018', 'ระบบต้องออกเลขที่เอกสารอัตโนมัติและควบคุมสถานะ/วงจรชีวิตของเอกสาร'], + ['CR01:019', 'ระบบต้องรองรับการแนบไฟล์ที่อนุญาตกับรายการที่กำหนด'], + ['CR01:020', 'ระบบต้องให้ผู้ใช้กรอง ดู พิมพ์ และส่งออกรายงานปฏิบัติการและรายงานผู้บริหาร'], + ['CR01:021', 'ระบบต้องแจ้งเตือนผู้ใช้ที่เกี่ยวข้องเมื่อสถานะเอกสารเปลี่ยนหรือมีเหตุการณ์ปฏิบัติการ'], + ['CR01:022', 'ระบบต้องสรุปยอดสต๊อก/GL และแจ้งเตือนสินค้าใกล้หมดและใบแจ้งหนี้ค้างชำระตามกำหนดเวลา'], + ['CR01:023', 'ระบบต้องเก็บผู้สร้าง ผู้แก้ไข สถานะ และประวัติรายการเพื่อการตรวจสอบ'], + ['CR01:024', 'ระบบต้องจำกัดข้อมูลบริษัทและคลังสินค้าให้เฉพาะผู้ใช้ที่ได้รับอนุญาตในบริบทปัจจุบัน'], ]], ['CR02', 'Performance Considerations', [ - ['CR02:001', 'ระบบต้องตอบสนองงานประจำวัน (เปิดหน้าจอ, ค้นหา, สร้างเอกสาร) ภายในเวลาที่ใช้งานได้จริงบนสภาพแวดล้อมที่ตกลง', 'NFR-006'], - ['CR02:002', 'ระบบต้องมีตารางสรุปยอด (Aggregate) เพื่อให้แดชบอร์ดและรายงานแสดงผลได้โดยไม่ต้องคำนวณใหม่ทุกครั้ง', 'NFR-006'], - ['CR02:003', 'ระบบต้องรองรับปริมาณข้อมูลและผู้ใช้พร้อมกันในระดับที่ตกลงสำหรับสภาพแวดล้อมใช้งานจริง', 'NFR-006'], + ['CR02:001', 'ระบบต้องตอบสนองงานประจำวัน (เปิดหน้าจอ, ค้นหา, สร้างเอกสาร) ภายในเวลาที่ใช้งานได้จริงบนสภาพแวดล้อมที่ตกลง'], + ['CR02:002', 'ระบบต้องมีตารางสรุปยอด (Aggregate) เพื่อให้แดชบอร์ดและรายงานแสดงผลได้โดยไม่ต้องคำนวณใหม่ทุกครั้ง'], + ['CR02:003', 'ระบบต้องรองรับปริมาณข้อมูลและผู้ใช้พร้อมกันในระดับที่ตกลงสำหรับสภาพแวดล้อมใช้งานจริง'], ]], ['CR03', 'Interface Considerations', [ - ['CR03:001', 'ระบบต้องเชื่อมต่อฐานข้อมูล MySQL/MariaDB 2 ฐาน (wms สำหรับผู้ใช้/บริษัท และ wms2 สำหรับคลัง/บัญชี)', 'Operational context'], - ['CR03:002', 'ระบบต้องใช้งานผ่าน Web Browser มาตรฐาน (Chrome, Edge, Firefox) ได้', 'NFR-008'], - ['CR03:003', 'ระบบต้องส่งเหตุการณ์ไปยังบริการ Node.js ผ่าน Endpoint ภายในที่ป้องกันด้วย Secret', 'NFR-002'], - ['CR03:004', 'Browser ต้องเชื่อมต่อ Socket.IO Endpoint สาธารณะเพื่อรับการแจ้งเตือนแบบ Real-time', 'FR-021'], - ['CR03:005', 'ระบบต้องส่งอีเมล Onboarding, กู้คืนรหัสผ่าน และแจ้งเตือนผ่าน SMTP ที่ตั้งค่าต่อบริษัท', 'FR-004'], + ['CR03:001', 'ระบบต้องเชื่อมต่อฐานข้อมูล MySQL/MariaDB 2 ฐาน (wms สำหรับผู้ใช้/บริษัท และ wms2 สำหรับคลัง/บัญชี)'], + ['CR03:002', 'ระบบต้องใช้งานผ่าน Web Browser มาตรฐาน (Chrome, Edge, Firefox) ได้'], + ['CR03:003', 'ระบบต้องส่งเหตุการณ์ไปยังบริการ Node.js ผ่าน Endpoint ภายในที่ป้องกันด้วย Secret'], + ['CR03:004', 'Browser ต้องเชื่อมต่อ Socket.IO Endpoint สาธารณะเพื่อรับการแจ้งเตือนแบบ Real-time'], + ['CR03:005', 'ระบบต้องส่งอีเมล Onboarding, กู้คืนรหัสผ่าน และแจ้งเตือนผ่าน SMTP ที่ตั้งค่าต่อบริษัท'], ]], ['CR04', 'Required System Characteristics', [ - ['CR04:001', 'ระบบต้องพัฒนาบนสถาปัตยกรรม Web-based Application', 'Operational context'], - ['CR04:002', 'ระบบต้องเก็บข้อมูลแบบ Relational Database และรักษา Referential Integrity', 'Data requirements'], - ['CR04:003', 'ระบบต้องรองรับการเข้าสู่ระบบด้วย Username/Password และกำหนดบทบาทผู้ใช้', 'FR-002'], - ['CR04:004', 'ระบบต้องทำงานบน PHP 8 ขึ้นไป, MySQL/MariaDB และ Node.js', 'NFR-008'], + ['CR04:001', 'ระบบต้องพัฒนาบนสถาปัตยกรรม Web-based Application'], + ['CR04:002', 'ระบบต้องเก็บข้อมูลแบบ Relational Database และรักษา Referential Integrity'], + ['CR04:003', 'ระบบต้องรองรับการเข้าสู่ระบบด้วย Username/Password และกำหนดบทบาทผู้ใช้'], + ['CR04:004', 'ระบบต้องทำงานบน PHP 8 ขึ้นไป, MySQL/MariaDB และ Node.js'], ]], ['CR05', 'Human Engineering Considerations', [ - ['CR05:001', 'UI ต้องเป็น Responsive ใช้งานได้ทั้งบน Desktop และอุปกรณ์หน้าคลังสินค้า (Tablet/Mobile)', 'NFR-005'], - ['CR05:002', 'เมนูและปุ่มคำสั่งต้องแสดงตามบทบาทและสิทธิ์การเข้าถึงของผู้ใช้', 'Interface requirements'], - ['CR05:003', 'ระบบต้องแสดงผลการตรวจสอบข้อมูล สถานะ ความสำเร็จ และข้อผิดพลาดอย่างชัดเจน', 'Interface requirements'], - ['CR05:004', 'ระบบต้องมีขั้นตอนยืนยันก่อนลบ ยกเลิก หรือทำรายการที่ย้อนกลับไม่ได้', 'Usability practice'], - ['CR05:005', 'ระบบต้องพิมพ์เอกสารธุรกิจและฉลากบาร์โค้ดในรูปแบบที่ใช้งานได้', 'Interface requirements'], + ['CR05:001', 'UI ต้องเป็น Responsive ใช้งานได้ทั้งบน Desktop และอุปกรณ์หน้าคลังสินค้า (Tablet/Mobile)'], + ['CR05:002', 'เมนูและปุ่มคำสั่งต้องแสดงตามบทบาทและสิทธิ์การเข้าถึงของผู้ใช้'], + ['CR05:003', 'ระบบต้องแสดงผลการตรวจสอบข้อมูล สถานะ ความสำเร็จ และข้อผิดพลาดอย่างชัดเจน'], + ['CR05:004', 'ระบบต้องมีขั้นตอนยืนยันก่อนลบ ยกเลิก หรือทำรายการที่ย้อนกลับไม่ได้'], + ['CR05:005', 'ระบบต้องพิมพ์เอกสารธุรกิจและฉลากบาร์โค้ดในรูปแบบที่ใช้งานได้'], ]], ['CR06', 'Security Considerations', [ - ['CR06:001', 'การเชื่อมต่อในสภาพแวดล้อมใช้งานจริงต้องเข้ารหัสด้วย HTTPS/TLS', 'NFR-001'], - ['CR06:002', 'ค่าตั้งค่าและความลับของระบบต้องไม่ถูกเก็บใน Source Control และไม่เข้าถึงได้จากเว็บสาธารณะ', 'NFR-001'], - ['CR06:003', 'การทำงานฝั่งเซิร์ฟเวอร์ต้องตรวจสอบข้อมูลนำเข้า ยืนยันตัวตน ตรวจสิทธิ์ และจำกัดขอบเขตบริษัท/คลัง', 'NFR-002'], - ['CR06:004', 'ระบบต้องจำกัดสิทธิ์การเข้าถึงตามบทบาท (Role-based Access Control) ทั้งใน UI และฝั่งเซิร์ฟเวอร์', 'FR-002'], - ['CR06:005', 'ระบบต้องป้องกัน SQL Injection และ Cross-Site Scripting', 'NFR-002'], - ['CR06:006', 'ระบบต้องบล็อกการเข้าสู่ระบบซ้ำซ้อน (Concurrent Login) ของบัญชีเดียวกัน', 'FR-003'], + ['CR06:001', 'การเชื่อมต่อในสภาพแวดล้อมใช้งานจริงต้องเข้ารหัสด้วย HTTPS/TLS'], + ['CR06:002', 'ค่าตั้งค่าและความลับของระบบต้องไม่ถูกเก็บใน Source Control และไม่เข้าถึงได้จากเว็บสาธารณะ'], + ['CR06:003', 'การทำงานฝั่งเซิร์ฟเวอร์ต้องตรวจสอบข้อมูลนำเข้า ยืนยันตัวตน ตรวจสิทธิ์ และจำกัดขอบเขตบริษัท/คลัง'], + ['CR06:004', 'ระบบต้องจำกัดสิทธิ์การเข้าถึงตามบทบาท (Role-based Access Control) ทั้งใน UI และฝั่งเซิร์ฟเวอร์'], + ['CR06:005', 'ระบบต้องป้องกัน SQL Injection และ Cross-Site Scripting'], + ['CR06:006', 'ระบบต้องบล็อกการเข้าสู่ระบบซ้ำซ้อน (Concurrent Login) ของบัญชีเดียวกัน'], ]], ['CR07', 'Environmental Considerations', [ - ['CR07:001', 'ระบบต้องทำงานบน Linux Server ในรูปแบบติดตั้งเอง (LAMP) หรือ Docker Compose', 'NFR-004'], - ['CR07:002', 'ระบบต้องใช้เขตเวลา Asia/Bangkok อย่างสม่ำเสมอทั้งแอปพลิเคชันและงานตามกำหนดเวลา', 'NFR-010'], - ['CR07:003', 'ระบบต้องใช้งานได้บนอุปกรณ์ Desktop และอุปกรณ์พกพาผ่าน Web Browser', 'NFR-005'], - ['CR07:004', 'ระบบต้องแยกข้อมูลสาธิต/ทดสอบออกจากข้อมูลใช้งานจริงได้', 'Data requirements'], + ['CR07:001', 'ระบบต้องทำงานบน Linux Server ในรูปแบบติดตั้งเอง (LAMP) หรือ Docker Compose'], + ['CR07:002', 'ระบบต้องใช้เขตเวลา Asia/Bangkok อย่างสม่ำเสมอทั้งแอปพลิเคชันและงานตามกำหนดเวลา'], + ['CR07:003', 'ระบบต้องใช้งานได้บนอุปกรณ์ Desktop และอุปกรณ์พกพาผ่าน Web Browser'], + ['CR07:004', 'ระบบต้องแยกข้อมูลสาธิต/ทดสอบออกจากข้อมูลใช้งานจริงได้'], ]], ['CR08', 'Operational Considerations', [ - ['CR08:001', 'ระบบต้องมีการสำรองฐานข้อมูลอัตโนมัติรายวัน', 'NFR-004'], - ['CR08:002', 'ระบบต้องกู้คืนข้อมูลจากชุดสำรองได้ตามขั้นตอนที่จัดทำเป็นเอกสาร', 'NFR-004'], - ['CR08:003', 'ระบบต้องมีการเฝ้าระวังสถานะบริการ Web, Database และ Node.js พร้อมแจ้งเตือนเมื่อขัดข้อง', 'NFR-004'], - ['CR08:004', 'ระบบต้องรองรับหลายบริษัท (Multi-company) และหลายคลังสินค้าภายใต้การแยกข้อมูล', 'FR-024'], - ['CR08:005', 'งานตามกำหนดเวลาต้องทำงานสำเร็จโดยไม่สร้างผลลัพธ์ซ้ำหรือเกินสิทธิ์', 'FR-022'], + ['CR08:001', 'ระบบต้องมีการสำรองฐานข้อมูลอัตโนมัติรายวัน'], + ['CR08:002', 'ระบบต้องกู้คืนข้อมูลจากชุดสำรองได้ตามขั้นตอนที่จัดทำเป็นเอกสาร'], + ['CR08:003', 'ระบบต้องมีการเฝ้าระวังสถานะบริการ Web, Database และ Node.js พร้อมแจ้งเตือนเมื่อขัดข้อง'], + ['CR08:004', 'ระบบต้องรองรับหลายบริษัท (Multi-company) และหลายคลังสินค้าภายใต้การแยกข้อมูล'], + ['CR08:005', 'งานตามกำหนดเวลาต้องทำงานสำเร็จโดยไม่สร้างผลลัพธ์ซ้ำหรือเกินสิทธิ์'], ]], ['CR09', 'Maintenance Considerations', [ - ['CR09:001', 'ซอฟต์แวร์ต้องมีโครงสร้างแบบโมดูล (Manager Classes / API) เพื่อให้แก้ไขได้โดยไม่กระทบส่วนอื่น', 'NFR-007'], - ['CR09:002', 'ระบบต้องมีแม่แบบค่าตั้งค่า (Configuration Template) และควบคุมเวอร์ชันด้วย Git', 'NFR-007'], - ['CR09:003', 'ระบบต้องมีเอกสารคู่มือการบำรุงรักษาและประวัติข้อบกพร่องที่แก้ไขแล้ว', 'NFR-004'], - ['CR09:004', 'การเปลี่ยนแปลงโครงสร้างฐานข้อมูลต้องสะท้อนใน setup.php และตาราง schema_migrations', 'NFR-007'], + ['CR09:001', 'ซอฟต์แวร์ต้องมีโครงสร้างแบบโมดูล (Manager Classes / API) เพื่อให้แก้ไขได้โดยไม่กระทบส่วนอื่น'], + ['CR09:002', 'ระบบต้องมีแม่แบบค่าตั้งค่า (Configuration Template) และควบคุมเวอร์ชันด้วย Git'], + ['CR09:003', 'ระบบต้องมีเอกสารคู่มือการบำรุงรักษาและประวัติข้อบกพร่องที่แก้ไขแล้ว'], + ['CR09:004', 'การเปลี่ยนแปลงโครงสร้างฐานข้อมูลต้องสะท้อนใน setup.php และตาราง schema_migrations'], ]], ['CR10', 'Installation Considerations', [ - ['CR10:001', 'ระบบต้องติดตั้งฐานข้อมูลได้ในขั้นตอนเดียวผ่าน setup.php', 'NFR-004'], - ['CR10:002', 'ระบบต้องติดตั้งแบบ Container ได้ด้วยคำสั่ง docker compose up -d --build', 'NFR-004'], - ['CR10:003', 'ระบบต้องมีสคริปต์สร้างไฟล์ .env และค่าความลับอัตโนมัติ (docker/init-env.sh)', 'NFR-001'], - ['CR10:004', 'ระบบต้องมีเอกสารขั้นตอนการติดตั้งและตั้งค่า', 'NFR-004'], + ['CR10:001', 'ระบบต้องติดตั้งฐานข้อมูลได้ในขั้นตอนเดียวผ่าน setup.php'], + ['CR10:002', 'ระบบต้องติดตั้งแบบ Container ได้ด้วยคำสั่ง docker compose up -d --build'], + ['CR10:003', 'ระบบต้องมีสคริปต์สร้างไฟล์ .env และค่าความลับอัตโนมัติ (docker/init-env.sh)'], + ['CR10:004', 'ระบบต้องมีเอกสารขั้นตอนการติดตั้งและตั้งค่า'], ]], ['CR11', 'Support Considerations', [ - ['CR11:001', 'ต้องมีคู่มือผู้ใช้งาน (Software User Document)', 'Documentation'], - ['CR11:002', 'ต้องมีคู่มือปฏิบัติงานสำหรับผู้ดูแลระบบ (Product Operation Guide)', 'Documentation'], - ['CR11:003', 'ต้องมีการอบรมผู้ใช้งานก่อนเปิดใช้งานจริง', 'Training'], - ['CR11:004', 'ต้องมีช่องทางสนับสนุนและระดับการให้บริการ (SLA) หลังส่งมอบ', 'Maintenance'], + ['CR11:001', 'ต้องมีคู่มือผู้ใช้งาน (Software User Document)'], + ['CR11:002', 'ต้องมีคู่มือปฏิบัติงานสำหรับผู้ดูแลระบบ (Product Operation Guide)'], + ['CR11:003', 'ต้องมีการอบรมผู้ใช้งานก่อนเปิดใช้งานจริง'], + ['CR11:004', 'ต้องมีช่องทางสนับสนุนและระดับการให้บริการ (SLA) หลังส่งมอบ'], ]], ['CR12', 'Design Constraints', [ - ['CR12:001', 'ระบบต้องพัฒนาด้วย PHP, MariaDB และ Node.js ตามที่องค์กรอนุมัติ', 'NFR-008'], - ['CR12:002', 'ระบบต้องควบคุม Source Code ด้วย Git โดยมี main เป็น Baseline หลัก', 'Configuration'], - ['CR12:003', 'รหัสผ่านผู้ใช้ต้องเข้ารหัสด้วย bcrypt และไม่เก็บหรือบันทึกเป็นข้อความธรรมดา', 'NFR-002'], - ['CR12:004', 'โครงการต้องจัดทำ Work Products ตามมาตรฐาน ISO/IEC 29110 Basic Profile', 'NFR-009'], + ['CR12:001', 'ระบบต้องพัฒนาด้วย PHP, MariaDB และ Node.js ตามที่องค์กรอนุมัติ'], + ['CR12:002', 'ระบบต้องควบคุม Source Code ด้วย Git โดยมี main เป็น Baseline หลัก'], + ['CR12:003', 'รหัสผ่านผู้ใช้ต้องเข้ารหัสด้วย bcrypt และไม่เก็บหรือบันทึกเป็นข้อความธรรมดา'], + ['CR12:004', 'โครงการต้องจัดทำ Work Products ตามมาตรฐาน ISO/IEC 29110 Basic Profile'], ]], ['CR13', 'Safety and Reliability Considerations', [ - ['CR13:001', 'การเปลี่ยนแปลงฐานข้อมูลที่เกี่ยวข้องกัน (เอกสาร + สต๊อก + GL) ต้องเป็น Transaction เดียวกัน', 'NFR-003'], - ['CR13:002', 'ระบบต้องป้องกันยอดสต๊อกติดลบและความเคลื่อนไหวซ้ำซ้อน', 'NFR-003'], - ['CR13:003', 'ระบบต้องรองรับการสำรองและกู้คืน (Backup & Recovery) ทั้ง Source Code และฐานข้อมูล', 'NFR-004'], - ['CR13:004', 'ระบบต้องจัดการข้อผิดพลาดโดยแสดงข้อความที่เข้าใจได้แทน Fatal Error', 'NFR-006'], + ['CR13:001', 'การเปลี่ยนแปลงฐานข้อมูลที่เกี่ยวข้องกัน (เอกสาร + สต๊อก + GL) ต้องเป็น Transaction เดียวกัน'], + ['CR13:002', 'ระบบต้องป้องกันยอดสต๊อกติดลบและความเคลื่อนไหวซ้ำซ้อน'], + ['CR13:003', 'ระบบต้องรองรับการสำรองและกู้คืน (Backup & Recovery) ทั้ง Source Code และฐานข้อมูล'], + ['CR13:004', 'ระบบต้องจัดการข้อผิดพลาดโดยแสดงข้อความที่เข้าใจได้แทน Fatal Error'], ]], ['CR14', 'Quality Expectations', [ - ['CR14:001', 'ระบบต้องผ่านการทดสอบตาม Test Case ที่กำหนดก่อนส่งมอบ', 'Acceptance'], - ['CR14:002', 'ทุกความต้องการต้องสอบกลับได้ถึงการออกแบบ ส่วนประกอบ และหลักฐานการทดสอบ', 'NFR-009'], - ['CR14:003', 'ระบบต้องผ่านการทดสอบการยอมรับ (UAT) โดยตัวแทนลูกค้าบนสภาพแวดล้อมใช้งานจริง', 'Acceptance'], - ['CR14:004', 'ต้องไม่มีข้อบกพร่องระดับวิกฤตค้างอยู่ในด้านความปลอดภัย การแยกข้อมูล และความถูกต้องของสต๊อก/บัญชี', 'Acceptance'], + ['CR14:001', 'ระบบต้องผ่านการทดสอบตาม Test Case ที่กำหนดก่อนส่งมอบ'], + ['CR14:002', 'ทุกความต้องการต้องสอบกลับได้ถึงการออกแบบ ส่วนประกอบ และหลักฐานการทดสอบ'], + ['CR14:003', 'ระบบต้องผ่านการทดสอบการยอมรับ (UAT) โดยตัวแทนลูกค้าบนสภาพแวดล้อมใช้งานจริง'], + ['CR14:004', 'ต้องไม่มีข้อบกพร่องระดับวิกฤตค้างอยู่ในด้านความปลอดภัย การแยกข้อมูล และความถูกต้องของสต๊อก/บัญชี'], ]], ]; export const CRS = CR_GROUPS.flatMap(([, , rows]) => rows); diff --git a/sdlc-delivery.zip b/sdlc-delivery.zip index 6120050..7b50338 100644 Binary files a/sdlc-delivery.zip and b/sdlc-delivery.zip differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.docx index 5a6f378..f301957 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.pdf index 0caf83e..120ec8c 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/1.Statement of Work/200-WMS-26-001-00 Statement of Work 25690105 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.docx index f4ec909..4157919 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.pdf index 4752718..f0736af 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/10.Project Repository (Backup)/200-WMS-26-001-00 Project Repository Backup 25690824 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.docx index 13c6260..45c521a 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.pdf index d9a377e..63da3c1 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/1-Work Schedule/200-WMS-26-001-00 Work Schedule 25690213 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.docx index eb1eff8..054dfe4 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.pdf index bc02436..342f307 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/2-Software Project Plan/200-WMS-26-001-00 Software Project Plan 25690213 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.docx b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.docx index 243abb0..088416b 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.pdf index a7b54e3..9081373 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/2.Project Plan/3-Customer Requirement/200-WMS-26-001-00 Customer Requirements 25690206 V1.0 NoC.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.docx index e456bc7..db54917 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.pdf index 5f70a96..905e6f9 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690109 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.docx index e694e97..140227e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.pdf index bcadfd2..b9d388f 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690123 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.docx index f4855a1..5d2ef62 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.pdf index ac57abd..2d22052 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690206 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.docx index 1ddd33f..0ecfce6 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.pdf index 9125c19..f1353d9 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690218 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.docx index a883392..5e3b5ab 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.pdf index 59907fe..93899af 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690225 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.docx index 9fd7746..5f93a30 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.pdf index 8e48e63..136a747 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690317 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.docx index 570d6c3..9ef7bb5 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.pdf index db03dc2..7bf0f4a 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690429 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.docx index ddfd156..3456b91 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.pdf index 81ce208..261b6df 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690508 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.docx index e8addc5..b34e313 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.pdf index 1a5e96c..f387d1e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690513 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.docx index 6de7906..b478a2d 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.pdf index 6282593..7db7881 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690523 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.docx index c1fd4a9..c64d312 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.pdf index d3329f1..deefc5e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690529 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.docx index c7306a3..093370e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.pdf index 741b0c3..52d5054 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690803 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.docx index 1940110..0e91cca 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.pdf index 838ff39..eb2a6e0 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690814 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.docx index ad79dc7..4ac6be6 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.pdf index b6ce640..6623a8f 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690817 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.docx index aaadcc2..27f5b2c 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.pdf index abb50b1..6c7c109 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/3.Progress Status Record/200-WMS-26-001-00 Progress Status Record 25690824 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.docx index f6fcd5c..31c6de8 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.pdf index 6f3ec2b..6a3c7ad 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/4.Correction Register/200-WMS-26-001-00 Correction Register 25690817 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.docx index 0ae6932..394c04c 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.pdf index 64b4fa2..9dcaa22 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/5.Acceptance Report/200-WMS-26-001-00 Acceptance Report 25690817 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.docx b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.docx deleted file mode 100644 index 5ee1254..0000000 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.docx and /dev/null differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.pdf deleted file mode 100644 index f8e1607..0000000 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690521 V1.0 NoC.pdf and /dev/null differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.docx b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.docx deleted file mode 100644 index 33b1f59..0000000 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.docx and /dev/null differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.pdf deleted file mode 100644 index 2e01bb3..0000000 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690810 V1.0 SeV.pdf and /dev/null differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.docx similarity index 92% rename from sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.docx rename to sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.docx index 0e63ee8..b73aa2e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.pdf similarity index 80% rename from sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.pdf rename to sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.pdf index b75a2f9..827deb5 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690808 V1.0 ApS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/6.Change Report/200-WMS-26-001-00 Change Report 25690817 V1.0 ApS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.docx index 2b6d685..08a31b8 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.pdf index 8d9949b..191a37d 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690105 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.docx index 33c4f69..306031e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.pdf index 0b930f0..18c155e 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690123 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.docx index f1c0028..143546d 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.pdf index 19eb56f..59b53cc 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690218 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.docx index 2fb3636..a2c4c3b 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.pdf index 79f9710..eef1a80 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690317 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.docx index b550b1a..dbfcebd 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.pdf index e9583c0..18294b3 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690429 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.docx index 6c16699..38b5697 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.pdf index d3ea2f1..8f6f969 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690513 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.docx index 986db84..70153ad 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.pdf index f70fd9a..cb64cbc 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690523 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.docx index 2bb16f2..ff63308 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.pdf index 8d3eab4..d99a63d 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690529 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.docx index 2f209e8..be8ac8d 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.pdf index d1188db..b800a87 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690803 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.docx index 97e99fd..d85baa4 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.pdf index 106b4d4..2f08cad 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690814 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.docx index fa67e72..eebfaaf 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.pdf index 65a6d58..00b3a96 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690817 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.docx b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.docx index e0f3280..3bb5c61 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.pdf index 4a33ee6..31e39cd 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/7.Meeting Record/200-WMS-26-001-00 Minutes Of Meeting 25690824 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.docx index 80a6f19..367cb83 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.pdf index cb7e80c..a8a53a6 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/8.Software Configuration/200-WMS-26-001-00 Software Configuration 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.docx b/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.docx index fb1c175..80f8cde 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.docx and b/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.pdf b/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.pdf index 4999d23..3cb4fe7 100644 Binary files a/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.pdf and b/sdlc-delivery/1-PM Process (10 Work Product)/9.Project Repository/200-WMS-26-001-00 Project Repository 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.docx b/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.docx index 2949bd6..ad99e9b 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.pdf index 098ebf8..af4d683 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/11.Software Requirements specification (SRS)/200-WMS-26-001-00 Software Requirements 25690225 V1.0 NoC.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.docx b/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.docx index c72daad..5de2f4c 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.pdf index 623ca06..71cd60c 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/12.Software design/200-WMS-26-001-00 Software Design 25690306 V1.0 NoC.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.docx b/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.docx index 63f4010..b1efd33 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.pdf index 7be1686..5604f4b 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/13.Traceability record/200-WMS-26-001-00 Traceability Record 25690306 V1.0 NoC.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.docx b/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.docx index e895f3b..f21b1b3 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.pdf index b623327..6e6bb45 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/14.Software Components/200-WMS-26-001-00 Software Components 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.docx index 2d32428..6987aa2 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.pdf index b53a810..7ceea6c 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/15.Test Cases and Test Procedures/200-WMS-26-001-00 Test Case and Test Procedures 25690731 V1.0 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.docx index 39730d2..4e7d305 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.pdf index fb85247..48c2a67 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/16.Test Report/200-WMS-26-001-00 Test Report 25690814 V1.0 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.docx b/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.docx index 20b2f0b..6a6aa4b 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.pdf index 5d14f8f..09d61ab 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/17.Software/200-WMS-26-001-00 Software 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.docx b/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.docx index da3b08c..47f1603 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.pdf index bfdc5e5..3500955 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/18.Software User Documentation/200-WMS-26-001-00 Software User Document 25690814 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.docx b/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.docx index 3384a07..50a7d64 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.pdf index c51da79..9be5715 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/19.Product Operation Guide/200-WMS-26-001-00 Product Operation Guide 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.docx b/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.docx index 08d6bd6..684261d 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.pdf index 085ab20..2bc520d 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/20.Maintenance Documentation/200-WMS-26-001-00 Maintenance Document 25690817 V1.0 ThS.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.docx index 1412c87..fb73646 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.pdf index 8a87188..5601556 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690317 V0.1 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.docx index 2e5909c..9e0a735 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.pdf index 55f868c..8752168 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690529 V0.2 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.docx index 4189cc6..d222599 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.pdf index 810364d..07f5648 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690731 V0.3 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.docx index e84fdcd..1a46d3b 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.pdf index c851c71..2f41adb 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/21.Verification Result/200-WMS-26-001-00 Verification Results 25690817 V1.0 PaNg.pdf differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.docx b/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.docx index 0c995f3..74d3f7b 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.docx and b/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.docx differ diff --git a/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.pdf b/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.pdf index c9d9567..a615d58 100644 Binary files a/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.pdf and b/sdlc-delivery/2-SI Process (12 Work Product)/22.Validation Result/200-WMS-26-001-00 Validation Results 25690814 V1.0 PaNg.pdf differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.docx b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.docx index 64c3e3a..6502bb5 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.docx and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.docx differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.pdf b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.pdf index 68eaf5f..a0590da 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.pdf and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 List of Evidence 25690824 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.docx b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.docx index a801e4a..a3e5eed 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.docx and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.docx differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.pdf b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.pdf index 2635917..de875e2 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.pdf and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Project Charter Report 25690123 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.docx b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.docx index aed4894..1cc48e0 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.docx and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.docx differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.pdf b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.pdf index b65eb86..fb38eb3 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.pdf and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Stakeholder Register 25690116 V1.0 YaB.pdf differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.docx b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.docx index cdb6b1b..5b3b8be 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.docx and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.docx differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.pdf b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.pdf index 236b756..2118c0c 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.pdf and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 TRACEABILITY-RECORD 25690817 V1.0 NoC.pdf differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.docx b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.docx index 22748d9..c10b111 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.docx and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.docx differ diff --git a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.pdf b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.pdf index 848306c..1e1b431 100644 Binary files a/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.pdf and b/sdlc-delivery/3-Other Document/200-WMS-26-001-00 Training Report 25690822 V1.0 YaB.pdf differ