# ๐Ÿ’ป Developer โ€” ์„ค๊ณ„๋œ ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ, ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ ๊ฒฐ๊ณผ ๊ธฐ๋ก์„ ์œ„ํ•œ API ์—ฐ๋™ ๊ตฌ์กฐ ๋˜๋Š” ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์ถ•์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๊ธฐ์ˆ ์  ํ”„๋ ˆ์ž„์›Œํฌ(Mock-up)๋ฅผ ์„ค๊ณ„ํ•˜์„ธ์š”. ๐Ÿ’ป Developer: ์ž‘์—… ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ## ๐Ÿ› ๏ธ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์ถ• Mock-up (TypeScript/Node.js) ์„ค๊ณ„๋œ AO/TTV ํ…Œ์ŠคํŠธ ๊ฐ€์„ค์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด, Bundle ๊ฒฐ๊ณผ์™€ ํ‘œ์ค€(Baseline) ๊ฒฐ๊ณผ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ณ  ์ •๋Ÿ‰์  ์ง€ํ‘œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ตœ์†Œํ•œ์˜ API ์—ฐ๋™ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ์ด Mock-up์€ ์‹ค์ œ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉ๋˜์–ด AO/TTV ์ง€ํ‘œ๋ฅผ ์ธก์ •ํ•˜๋Š” ๊ธฐ๋ฐ˜ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ### 1. ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ (Type Definitions) ๋จผ์ €, ์ธก์ •ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ์™€ ๊ฒฐ๊ณผ๋ฅผ ๋ช…ํ™•ํžˆ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ```typescript // src/types.ts (๊ฐ€์ •) /** * Bundle ๊ฒฐ๊ณผ์˜ ๊ตฌ์กฐ ์ •์˜ */ export interface BundleResult { taskId: string; stepsTaken: number; // AO ์ธก์ • ์ง€ํ‘œ: ์ˆ˜ํ–‰๋œ ๋‹จ๊ณ„ ์ˆ˜ accuracyScore: number; // AO ์ธก์ • ์ง€ํ‘œ: ๊ฒฐ๊ณผ ์ •ํ™•๋„ ์ ์ˆ˜ (0.0 ~ 1.0) timeTakenMs: number; // TTV ์ธก์ • ์ง€ํ‘œ: ์†Œ์š” ์‹œ๊ฐ„ (๋ฐ€๋ฆฌ์ดˆ) timestamp: Date; } /** * Standard/Competitor ๊ฒฐ๊ณผ์˜ ๊ตฌ์กฐ ์ •์˜ (Baseline) */ export interface StandardResult { taskId: string; stepsTaken: number; // Baseline ๋‹จ๊ณ„ ์ˆ˜ accuracyScore: number; // Baseline ์ •ํ™•๋„ ์ ์ˆ˜ (0.0 ~ 1.0) timeTakenMs: number; // Baseline ์†Œ์š” ์‹œ๊ฐ„ (๋ฐ€๋ฆฌ์ดˆ) timestamp: Date; } /** * ์ตœ์ข… ๋น„๊ต ๊ฒฐ๊ณผ ๊ตฌ์กฐ ์ •์˜ */ export interface ComparisonReport { bundle: BundleResult; standard: StandardResult; efficiencyRatio: number; // bundle.stepsTaken / standard.stepsTaken (AO ๋น„๊ต์šฉ) accuracyDelta: number; // bundle.accuracyScore - standard.accuracyScore (์ •ํ™•๋„ ์ฐจ์ด) timeRatio: number; // bundle.timeTakenMs / standard.timeTakenMs (TTV ๋น„๊ต์šฉ) reportTimestamp: Date; } ``` ### 2. Mock API Service ๊ตฌํ˜„ (Simulation Layer) ์‹ค์ œ ์™ธ๋ถ€ API ํ˜ธ์ถœ ๋Œ€์‹ , ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋งž์ถฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์œ„์ ์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ```typescript // src/TestService.ts import { BundleResult, StandardResult, ComparisonReport } from './types'; /** * ๊ฐ€์ƒ์˜ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ๊ธฐ (์‹ค์ œ๋กœ๋Š” API ํ˜ธ์ถœ๋กœ ๋Œ€์ฒด๋จ) */ class TestDataSimulator { private static generateRandomData(baseSteps: number, baseAccuracy: number, baseTime: number): Omit { // ๋…ธ์ด์ฆˆ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ˜„์‹ค์ ์ธ ๋ณ€๋™์„ฑ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. const noise = (Math.random() - 0.5) * 0.2; // +/- 10% ๋ณ€๋™ return { stepsTaken: Math.round(baseSteps * (1 + noise)), accuracyScore: Math.min(1.0, Math.max(0.1, baseAccuracy + (Math.random() - 0.5) * 0.1)), // ์ •ํ™•๋„ ๋ฒ”์œ„ ์œ ์ง€ timeTakenMs: Math.round(baseTime * (1 + noise)), }; } /** * Bundle ๊ฒฐ๊ณผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (๋†’์€ ํšจ์œจ์„ฑ ๊ฐ€์ •) */ public static generateBundleData(id: string): BundleResult { // Bundle์€ ํ‘œ์ค€๋ณด๋‹ค ํšจ์œจ์ ์ด๋ผ๊ณ  ๊ฐ€์ • (Steps 30% ๊ฐ์†Œ ๋ชฉํ‘œ) const baseSteps = 100; // ํ‘œ์ค€ ๋Œ€๋น„ ๋†’๊ฒŒ ์„ค์ •ํ•˜์—ฌ ๋น„๊ต ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•จ const baseAccuracy = 0.95; // ๋†’์€ ์ •ํ™•๋„ ๊ฐ€์ • const baseTime = 5000; // 5์ดˆ ์ด๋‚ด ์™„๋ฃŒ ๊ฐ€์ • return { taskId: id, stepsTaken: Math.round(baseSteps * 0.7), // ํšจ์œจ์„ฑ ์ž…์ฆ ๋ชฉํ‘œ (์˜ˆ: 70) accuracyScore: baseAccuracy + Math.random() * 0.1, // ์•ฝ๊ฐ„์˜ ๋ณ€๋™์„ฑ ํ—ˆ์šฉ timeTakenMs: baseTime * 0.5, // ๋น ๋ฅธ TTV ์ž…์ฆ ๋ชฉํ‘œ (์˜ˆ: 2.5์ดˆ) timestamp: new Date(), }; } /** * Standard/Competitor ๊ฒฐ๊ณผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (Baseline) */ public static generateStandardData(id: string): StandardResult { // ํ‘œ์ค€์€ ๋น„๊ต ๊ธฐ์ค€์ด ๋˜๋ฏ€๋กœ ์•ฝ๊ฐ„ ๋” ๋น„ํšจ์œจ์ ์ด๊ฑฐ๋‚˜ ๋А๋ฆฌ๊ฒŒ ์„ค์ • return { taskId: id, stepsTaken: 100, // ๊ธฐ์ค€ ๋‹จ๊ณ„ ์ˆ˜ accuracyScore: 0.85 + Math.random() * 0.1, // ๊ธฐ์ค€ ์ •ํ™•๋„ timeTakenMs: 8000, // ๋น„๊ต ๊ธฐ์ค€ ์‹œ๊ฐ„ timestamp: new Date(), }; } /** * ๋น„๊ต ๋ฆฌํฌํŠธ ์ƒ์„ฑ ํ•จ์ˆ˜ (ํ•ต์‹ฌ ๋กœ์ง) */ public static generateComparisonReport(bundleData: BundleResult, standardData: StandardResult): ComparisonReport { const efficiencyRatio = bundleData.stepsTaken / standardData.stepsTaken; const accuracyDelta = bundleData.accuracyScore - standardData.accuracyScore; const timeRatio = bundleData.timeTakenMs / standardData.timeTakenMs; return { bundle: bundleData, standard: standardData, efficiencyRatio: parseFloat(efficiencyRatio.toFixed(3)), accuracyDelta: parseFloat(accuracyDelta.toFixed(3)), timeRatio: parseFloat(timeRatio.toFixed(3)), reportTimestamp: new Date(), }; } } export const TestService = { generateComparisonReport: (bundleId: string, standardId: string): ComparisonReport => { const bundleData = TestDataSimulator.generateBundleData(bundleId); const standardData = TestDataSimulator.generateStandardData(standardId); return TestDataSimulator.generateComparisonReport(bundleData, standardData); } }; ``` ### 3. ์‚ฌ์šฉ ์˜ˆ์‹œ (Usage Example) ์ด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•˜๊ณ , ๊ฐ€์„ค ๊ฒ€์ฆ์— ํ•„์š”ํ•œ ํ•ต์‹ฌ ์ง€ํ‘œ๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. ```typescript // src/main.ts (์‹คํ–‰ ์˜ˆ์‹œ) import { TestService } from './TestService'; import { ComparisonReport } from './types'; console.log("--- ๐Ÿงช AO/TTV ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ์‹คํ–‰ ---"); // 1. ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ const bundleReport: ComparisonReport = TestService.generateComparisonReport("BUNDLE_V1", "STANDARD_V1"); console.log("\nโœ… Bundle ์„ฑ๋Šฅ ๋ณด๊ณ ์„œ:"); console.log(` Bundle Steps: ${bundleReport.bundle.stepsTaken} (๋ชฉํ‘œ ๋Œ€๋น„ ํšจ์œจ์„ฑ ์ธก์ •)`); console.log(` Bundle Accuracy: ${bundleReport.bundle.accuracyScore}`); console.log(` Bundle Time (ms): ${bundleReport.bundle.timeTakenMs}`); console.log("\n๐Ÿ†š Standard (Baseline) ์„ฑ๋Šฅ ๋ณด๊ณ ์„œ:"); console.log(` Standard Steps: ${bundleReport.standard.stepsTaken}`); console.log(` Standard Accuracy: ${bundleReport.standard.accuracyScore}`); console.log(` Standard Time (ms): ${bundleReport.standard.timeTakenMs}`); console.log("\n๐Ÿ“Š ์ตœ์ข… ๋น„๊ต ๋ถ„์„:"); console.log("============================="); console.log(`๐Ÿš€ ํšจ์œจ์„ฑ ๋น„์œจ (Steps Ratio): ${bundleReport.efficiencyRatio}x`); console.log(`โœจ ์ •ํ™•๋„ ์ฐจ์ด (Accuracy Delta): ${bundleReport.accuracyDelta}`); console.log(`โฑ๏ธ ์‹œ๊ฐ„ ๋น„์œจ (TTV Ratio): ${bundleReport.timeRatio}x`); // --- ์‚ฌ์šฉ๋ฒ• ๊ฐ€์ด๋“œ --- console.log("\n\n๐Ÿ‘‰ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•:"); console.log("1. TestService.generateComparisonReport(\"Bundle_ID\", \"Standard_ID\")๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๊ต ๋ฆฌํฌํŠธ๋ฅผ ์ฆ‰์‹œ ์–ป์Šต๋‹ˆ๋‹ค."); console.log("2. ์ด ๋ฆฌํฌํŠธ์˜ `efficiencyRatio`์™€ `timeRatio`๋ฅผ ํ†ตํ•ด ๊ฐ€์„ค Set A์˜ ์Šน๋ฆฌ ๊ธฐ์ค€์„ ์ถฉ์กฑํ–ˆ๋Š”์ง€ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค."); ``` ### ๐Ÿ“ ๋‹ค์Œ ๋‹จ๊ณ„: ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์— ์‹ค์ œ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ํ†ตํ•ฉ ๋ฐ ์ž๋™ํ™” ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ