#!/usr/bin/env node
/**
* WorkflowMCP Sample Data Generator
* Adds sample data for testing and demonstration purposes
*/
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
import { randomUUID } from 'crypto';
const DB_PATH = './data/workflow.db';
/**
* Generate sample data for WorkflowMCP
*/
async function addSampleData() {
console.log('π― WorkflowMCP Sample Data Generator');
console.log('=====================================\n');
try {
// Connect to database
const db = await open({
filename: DB_PATH,
driver: sqlite3.Database
});
console.log('β
Connected to database');
// Check if data already exists
const existingPRDs = await db.get('SELECT COUNT(*) as count FROM prds');
const existingTasks = await db.get('SELECT COUNT(*) as count FROM tasks');
const existingDocs = await db.get('SELECT COUNT(*) as count FROM documents');
if (existingPRDs.count > 0 || existingTasks.count > 0 || existingDocs.count > 0) {
console.log('β οΈ Sample data already exists:');
console.log(` π PRDs: ${existingPRDs.count}, Tasks: ${existingTasks.count}, Documents: ${existingDocs.count}`);
console.log(' Skipping data generation to avoid duplicates.\n');
console.log('π‘ To reset and add fresh sample data:');
console.log(' 1. Delete data/workflow.db');
console.log(' 2. Run: node init-database.js');
console.log(' 3. Run: node add-sample-data.js');
await db.close();
return;
}
console.log('π Adding sample data...\n');
// Sample PRDs
const samplePRDs = [
{
id: randomUUID(),
title: 'μν¬νλ‘μ° MCP νλ«νΌ κ°λ°',
description: 'AI κΈ°λ° νλ‘μ νΈ κ΄λ¦¬ λ° νμ
νλ«νΌ ꡬμΆμ μν μ’
ν© μꡬμ¬ν λ¬Έμ',
requirements: JSON.stringify([
'μ¬μ©μ μΈμ¦ λ° κΆν κ΄λ¦¬ μμ€ν
',
'PRD, μμ
, κ³ν κ΄λ¦¬ κΈ°λ₯',
'μ€μκ° νμ
λ° μλ¦Ό μμ€ν
',
'λμ보λ λ° λΆμ κΈ°λ₯',
'ν
μ€νΈ κ΄λ¦¬ μμ€ν
'
]),
priority: 'High',
status: 'approved',
tags: JSON.stringify(['platform', 'mcp', 'ai', 'collaboration'])
},
{
id: randomUUID(),
title: 'ν
μ€νΈ μλν μμ€ν
',
description: 'ν΅ν© ν
μ€νΈ μλν λ° CI/CD νμ΄νλΌμΈ ꡬμΆ',
requirements: JSON.stringify([
'λ¨μ ν
μ€νΈ μλν',
'ν΅ν© ν
μ€νΈ νκ²½ ꡬμΆ',
'CI/CD νμ΄νλΌμΈ μ€μ ',
'ν
μ€νΈ 리ν¬νΈ μμ±'
]),
priority: 'High',
status: 'review',
tags: JSON.stringify(['testing', 'automation', 'cicd'])
},
{
id: randomUUID(),
title: 'μ¬μ©μ κ²½ν κ°μ ',
description: 'λμ보λ UI/UX κ°μ λ° μ κ·Όμ± ν₯μ',
requirements: JSON.stringify([
'λ°μν λμμΈ μ μ©',
'μ κ·Όμ± κ°μ΄λλΌμΈ μ€μ',
'μ¬μ©μ νΌλλ°± μμ€ν
',
'μ±λ₯ μ΅μ ν'
]),
priority: 'Medium',
status: 'draft',
tags: JSON.stringify(['ui', 'ux', 'accessibility', 'performance'])
}
];
console.log('π Creating sample PRDs...');
for (const prd of samplePRDs) {
await db.run(`
INSERT INTO prds (id, title, description, requirements, priority, status, tags, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, [prd.id, prd.title, prd.description, prd.requirements, prd.priority, prd.status, prd.tags]);
}
console.log(` β
${samplePRDs.length} PRDs created`);
// Sample Tasks
const sampleTasks = [
{
id: randomUUID(),
title: 'λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ μ€κ³',
description: 'SQLite λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§ μ€κ³ λ° μ΅μ ν',
status: 'done',
priority: 'High',
assignee: 'dev-team',
estimated_hours: 16,
actual_hours: 18,
tags: JSON.stringify(['database', 'schema', 'sqlite'])
},
{
id: randomUUID(),
title: 'MCP μλ² κ΅¬ν',
description: 'Model Context Protocol μλ² κ΅¬ν λ° 35κ° λꡬ κ°λ°',
status: 'done',
priority: 'High',
assignee: 'backend-team',
estimated_hours: 40,
actual_hours: 45,
tags: JSON.stringify(['mcp', 'server', 'tools'])
},
{
id: randomUUID(),
title: 'μΉ λμ보λ κ°λ°',
description: 'SvelteKit κΈ°λ° λ°μν μΉ λμ보λ ꡬν',
status: 'in_progress',
priority: 'High',
assignee: 'frontend-team',
estimated_hours: 32,
actual_hours: 28,
tags: JSON.stringify(['frontend', 'sveltekit', 'dashboard'])
},
{
id: randomUUID(),
title: 'ν
μ€νΈ μΌμ΄μ€ μμ±',
description: 'ν΅μ¬ κΈ°λ₯μ λν ν
μ€νΈ μΌμ΄μ€ μμ± λ° μ€ν',
status: 'pending',
priority: 'Medium',
assignee: 'qa-team',
estimated_hours: 24,
tags: JSON.stringify(['testing', 'qa', 'validation'])
},
{
id: randomUUID(),
title: 'λ¬Έμν μμ
',
description: 'μ¬μ©μ κ°μ΄λ λ° API λ¬Έμ μμ±',
status: 'pending',
priority: 'Medium',
assignee: 'tech-writer',
estimated_hours: 20,
tags: JSON.stringify(['documentation', 'guide', 'api'])
}
];
console.log('π Creating sample tasks...');
for (const task of sampleTasks) {
await db.run(`
INSERT INTO tasks (id, title, description, status, priority, assignee, estimated_hours, actual_hours, tags, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, [task.id, task.title, task.description, task.status, task.priority, task.assignee, task.estimated_hours, task.actual_hours || null, task.tags]);
}
console.log(` β
${sampleTasks.length} tasks created`);
// Sample Documents
const sampleDocuments = [
{
title: 'νλ‘μ νΈ μꡬμ¬ν λΆμ λ³΄κ³ μ',
content: `# νλ‘μ νΈ μꡬμ¬ν λΆμ λ³΄κ³ μ
## κ°μ
WorkflowMCP νλ‘μ νΈμ ν΅μ¬ μꡬμ¬νμ λΆμν κ²°κ³Όλ₯Ό μ 리ν©λλ€.
## μ£Όμ λ°κ²¬μ¬ν
1. **AI ν΅ν©μ μ€μμ±**: Claude Codeμμ μνν ν΅ν©μ΄ ν΅μ¬ μ±κ³΅ μμ
2. **νμ₯μ± μꡬ**: λλμ νλ‘μ νΈ λ°μ΄ν°λ₯Ό ν¨μ¨μ μΌλ‘ μ²λ¦¬ν΄μΌ ν¨
3. **μ¬μ©μ± μ°μ **: κ°λ°μ μ€μ¬μ μ§κ΄μ μΈ μΈν°νμ΄μ€ νμ
## κΆμ₯μ¬ν
- MCP νλ‘ν μ½ νμ€ μ€μ
- SQLiteλ₯Ό ν΅ν κ²½λνλ λ°μ΄ν° κ΄λ¦¬
- λ°μν μΉ λμ보λ ꡬν`,
doc_type: 'analysis',
category: 'requirements',
summary: 'WorkflowMCP νλ‘μ νΈμ μꡬμ¬ν λΆμ λ° κΆμ₯μ¬ν',
tags: JSON.stringify(['requirements', 'analysis', 'project'])
},
{
title: 'λ°μ΄ν°λ² μ΄μ€ μ€κ³ λ¬Έμ',
content: `# λ°μ΄ν°λ² μ΄μ€ μ€κ³ λ¬Έμ
## μ€ν€λ§ λ²μ
- νμ¬ λ²μ : 3.0.0
- μ΅μ’
μ
λ°μ΄νΈ: ${new Date().toISOString().split('T')[0]}
## ν΅μ¬ ν
μ΄λΈ
1. **prds**: μ ν μꡬμ¬ν λ¬Έμ
2. **tasks**: μμ
κ΄λ¦¬
3. **plans**: νλ‘μ νΈ κ³ν
4. **documents**: λ¬Έμ κ΄λ¦¬
5. **test_cases**: ν
μ€νΈ μΌμ΄μ€ κ΄λ¦¬
## κ΄κ³ν μ€κ³
- μΈλν€ μ μ½μ‘°κ±΄μ ν΅ν λ°μ΄ν° λ¬΄κ²°μ± λ³΄μ₯
- νΈλ¦¬κ±°λ₯Ό ν΅ν μλ μ
λ°μ΄νΈ λ‘μ§
- μΈλ±μ€ μ΅μ νλ‘ μ±λ₯ ν₯μ
## μ±λ₯ κ³ λ €μ¬ν
- FTS5λ₯Ό ν΅ν μ λ¬Έ κ²μ μ§μ
- λ·°λ₯Ό ν΅ν 볡μ‘ν 쿼리 μ΅μ ν
- μ μ ν μΈλ±μ± μ λ΅`,
doc_type: 'specification',
category: 'database',
summary: 'WorkflowMCP SQLite λ°μ΄ν°λ² μ΄μ€ μ€κ³ μμΈ λ¬Έμ',
tags: JSON.stringify(['database', 'schema', 'design', 'sqlite'])
},
{
title: 'MCP λꡬ ν
μ€νΈ κ²°κ³Ό',
content: `# MCP λꡬ ν
μ€νΈ κ²°κ³Ό
## ν
μ€νΈ κ°μ
- ν
μ€νΈ μΌμ: ${new Date().toLocaleDateString('ko-KR')}
- ν
μ€νΈ λꡬ: 35κ° MCP λꡬ
- ν
μ€νΈ νκ²½: Claude Code CLI
## ν
μ€νΈ κ²°κ³Ό μμ½
- β
μ±κ³΅: 33/35 λꡬ (94.3%)
- β οΈ κ²½κ³ : 2/35 λꡬ (5.7%)
- β μ€ν¨: 0/35 λꡬ (0%)
## μ£Όμ μ±κ³Ό
1. **CRUD μμ
**: λͺ¨λ μμ±, μ½κΈ°, μμ , μμ μμ
μ μ μλ
2. **κ²μ κΈ°λ₯**: μ λ¬Έ κ²μ λ° νν°λ§ κΈ°λ₯ μλ²½ μλ
3. **κ΄κ³ν μμ
**: μν°ν° κ° μ°κ²° μμ
μ±κ³΅μ μν
## κ°μ κΆμ₯μ¬ν
- μλ¬ νΈλ€λ§ κ°ν
- μ±λ₯ λͺ¨λν°λ§ μΆκ°
- λ‘κΉ
μμ€ν
κ°μ `,
doc_type: 'test_results',
category: 'testing',
summary: 'MCP μλ² λꡬλ€μ λν μ’
ν© ν
μ€νΈ κ²°κ³Ό λ° μ±λ₯ λΆμ',
tags: JSON.stringify(['mcp', 'testing', 'results', 'tools'])
},
{
title: 'λμ보λ UI κ°λ° κ°μ΄λ',
content: `# λμ보λ UI κ°λ° κ°μ΄λ
## λμμΈ μμΉ
1. **μΌκ΄μ±**: λͺ¨λ νμ΄μ§μμ ν΅μΌλ UI ν¨ν΄ μ¬μ©
2. **μ κ·Όμ±**: WCAG 2.1 AA μμ€ μ€μ
3. **λ°μμ±**: λͺ¨λ°μΌλΆν° λ°μ€ν¬νκΉμ§ μλ²½ μ§μ
## μ»΄ν¬λνΈ κ΅¬μ‘°
- **μΉ΄λ κΈ°λ° λ μ΄μμ**: μ 보λ₯Ό λͺ
ννκ² κ΅¬λΆ
- **νν° μμ€ν
**: μ§κ΄μ μΈ λ°μ΄ν° νν°λ§
- **λ€λΉκ²μ΄μ
**: μΌκ΄λ CRUD ν¨ν΄
## κΈ°μ μ€ν
- **νλ‘ νΈμλ**: SvelteKit + Tailwind CSS
- **μν κ΄λ¦¬**: Svelte stores
- **λΌμ°ν
**: SvelteKit νμΌ κΈ°λ° λΌμ°ν
## μ±λ₯ μ΅μ ν
- μ½λ λΆν λ° μ§μ° λ‘λ©
- μ΄λ―Έμ§ μ΅μ ν
- μΊμ± μ λ΅`,
doc_type: 'specification',
category: 'frontend',
summary: 'μΉ λμ보λ UI κ°λ°μ μν μ’
ν© κ°μ΄λ λ¬Έμ',
tags: JSON.stringify(['ui', 'frontend', 'guide', 'sveltekit'])
}
];
console.log('π Creating sample documents...');
for (const doc of sampleDocuments) {
await db.run(`
INSERT INTO documents (title, content, doc_type, category, summary, tags, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, [doc.title, doc.content, doc.doc_type, doc.category, doc.summary, doc.tags]);
}
console.log(` β
${sampleDocuments.length} documents created`);
// Sample Test Cases
const sampleTestCases = [
{
id: randomUUID(),
title: 'PRD μμ± κΈ°λ₯ ν
μ€νΈ',
description: 'PRD μμ± API λ° UI κΈ°λ₯μ μ μ μλ νμΈ',
type: 'integration',
status: 'active',
priority: 'High',
preconditions: 'λμ보λμ λ‘κ·ΈμΈλ μν',
test_steps: JSON.stringify([
'PRD κ΄λ¦¬ νμ΄μ§ μ μ',
'μ PRD μΆκ° λ²νΌ ν΄λ¦',
'νμ νλ μ
λ ₯ (μ λͺ©, μ€λͺ
)',
'μ μ₯ λ²νΌ ν΄λ¦',
'μμ±λ PRD νμΈ'
]),
expected_result: 'PRDκ° μ±κ³΅μ μΌλ‘ μμ±λκ³ λͺ©λ‘μ νμλ¨',
tags: JSON.stringify(['prd', 'crud', 'integration'])
},
{
id: randomUUID(),
title: 'κ²μ κΈ°λ₯ μ±λ₯ ν
μ€νΈ',
description: 'λλ λ°μ΄ν° νκ²½μμ κ²μ μ±λ₯ νμΈ',
type: 'system',
status: 'active',
priority: 'Medium',
preconditions: '1000κ° μ΄μμ λ¬Έμκ° λ°μ΄ν°λ² μ΄μ€μ μ‘΄μ¬',
test_steps: JSON.stringify([
'λ¬Έμ κ²μ νμ΄μ§ μ μ',
'ν€μλ "ν
μ€νΈ" μ
λ ₯',
'κ²μ μ€ν',
'μλ΅ μκ° μΈ‘μ ',
'κ²°κ³Ό μ νμ± νμΈ'
]),
expected_result: '2μ΄ μ΄λ΄μ μ νν κ²μ κ²°κ³Ό λ°ν',
tags: JSON.stringify(['search', 'performance', 'fts'])
}
];
console.log('π§ͺ Creating sample test cases...');
for (const testCase of sampleTestCases) {
await db.run(`
INSERT INTO test_cases (id, title, description, type, status, priority, preconditions, test_steps, expected_result, tags, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
`, [testCase.id, testCase.title, testCase.description, testCase.type, testCase.status, testCase.priority, testCase.preconditions, testCase.test_steps, testCase.expected_result, testCase.tags]);
}
console.log(` β
${sampleTestCases.length} test cases created`);
// Final verification
console.log('\nπ Verifying sample data...');
const finalCounts = await Promise.all([
db.get('SELECT COUNT(*) as count FROM prds'),
db.get('SELECT COUNT(*) as count FROM tasks'),
db.get('SELECT COUNT(*) as count FROM documents'),
db.get('SELECT COUNT(*) as count FROM test_cases')
]);
console.log(' π Final counts:');
console.log(` PRDs: ${finalCounts[0].count}`);
console.log(` Tasks: ${finalCounts[1].count}`);
console.log(` Documents: ${finalCounts[2].count}`);
console.log(` Test Cases: ${finalCounts[3].count}`);
await db.close();
console.log('\nπ SAMPLE DATA CREATION COMPLETE!');
console.log('=====================================');
console.log('π‘ You can now:');
console.log(' 1. Start the MCP server: npm start');
console.log(' 2. Start the dashboard: cd dashboard && npm run dev');
console.log(' 3. View sample data at: http://localhost:3301');
console.log(' 4. Test MCP tools with Claude Code');
} catch (error) {
console.error('\nβ SAMPLE DATA CREATION FAILED');
console.error('===============================');
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
// Only run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
addSampleData();
}
export default addSampleData;