Initial commit: Due Diligence Tracker project
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
100
client/src/database/database.ts
Normal file
100
client/src/database/database.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import initSqlJs from 'sql.js';
|
||||
|
||||
let SQL: any = null;
|
||||
let db: any = null;
|
||||
|
||||
export interface Database {
|
||||
exec: (sql: string) => any[];
|
||||
run: (sql: string, params?: any[]) => void;
|
||||
prepare: (sql: string) => any;
|
||||
}
|
||||
|
||||
export const initDatabase = async (): Promise<Database> => {
|
||||
if (db) return db;
|
||||
|
||||
if (!SQL) {
|
||||
SQL = await initSqlJs({
|
||||
locateFile: (file: string) => `https://sql.js.org/dist/${file}`
|
||||
});
|
||||
}
|
||||
|
||||
db = new SQL.Database();
|
||||
|
||||
// Add run method for compatibility with seed data
|
||||
db.run = (sql: string, params?: any[]) => {
|
||||
if (params && params.length > 0) {
|
||||
const stmt = db.prepare(sql);
|
||||
stmt.run(params);
|
||||
stmt.free();
|
||||
} else {
|
||||
db.exec(sql);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize schema
|
||||
const schema = `
|
||||
CREATE TABLE IF NOT EXISTS dimensions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
icon TEXT,
|
||||
color TEXT,
|
||||
order_index INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS kpis (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
dimension_id INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
order_index INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (dimension_id) REFERENCES dimensions(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS checks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kpi_id INTEGER NOT NULL,
|
||||
question TEXT NOT NULL,
|
||||
check_type TEXT NOT NULL,
|
||||
current_value TEXT,
|
||||
expected_value TEXT,
|
||||
reference_url TEXT,
|
||||
reference_file_id INTEGER,
|
||||
comment TEXT,
|
||||
is_completed BOOLEAN DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (kpi_id) REFERENCES kpis(id),
|
||||
FOREIGN KEY (reference_file_id) REFERENCES files(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS files (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
original_name TEXT NOT NULL,
|
||||
stored_path TEXT NOT NULL,
|
||||
mime_type TEXT,
|
||||
size_bytes INTEGER,
|
||||
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS check_types (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
data_type TEXT NOT NULL,
|
||||
options_json TEXT,
|
||||
validation_json TEXT
|
||||
);
|
||||
`;
|
||||
|
||||
db.exec(schema);
|
||||
|
||||
return db;
|
||||
};
|
||||
|
||||
export const getDatabase = (): Database => {
|
||||
if (!db) {
|
||||
throw new Error('Database not initialized. Call initDatabase() first.');
|
||||
}
|
||||
return db;
|
||||
};
|
||||
164
client/src/database/seedData.ts
Normal file
164
client/src/database/seedData.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
import { Database } from './database';
|
||||
|
||||
export const seedDatabase = (db: Database) => {
|
||||
// Insert dimensions
|
||||
const dimensions = [
|
||||
{ name: 'Strategy', icon: 'Briefcase', color: '#4F46E5', order_index: 1 },
|
||||
{ name: 'Sales', icon: 'TrendingUp', color: '#10B981', order_index: 2 },
|
||||
{ name: 'Product', icon: 'Target', color: '#3B82F6', order_index: 3 },
|
||||
{ name: 'Organization', icon: 'Building', color: '#8B5CF6', order_index: 4 },
|
||||
{ name: 'Engineering', icon: 'Code', color: '#F59E0B', order_index: 5 },
|
||||
{ name: 'DevOps', icon: 'Shield', color: '#EF4444', order_index: 6 },
|
||||
{ name: 'Cyber', icon: 'Shield', color: '#6B7280', order_index: 7 },
|
||||
{ name: 'Finance', icon: 'DollarSign', color: '#059669', order_index: 8 },
|
||||
{ name: 'People', icon: 'Users', color: '#DC2626', order_index: 9 },
|
||||
{ name: 'Culture', icon: 'Heart', color: '#7C3AED', order_index: 10 }
|
||||
];
|
||||
|
||||
dimensions.forEach((dim, index) => {
|
||||
db.run(
|
||||
'INSERT INTO dimensions (name, icon, color, order_index) VALUES (?, ?, ?, ?)',
|
||||
[dim.name, dim.icon, dim.color, dim.order_index]
|
||||
);
|
||||
});
|
||||
|
||||
// Insert KPIs for Strategy
|
||||
const kpis = [
|
||||
// Strategy KPIs
|
||||
{ dimension_id: 1, name: 'Strategic Alignment', description: 'Vision and mission clarity', order_index: 1 },
|
||||
{ dimension_id: 1, name: 'Market Position', description: 'Competitive landscape analysis', order_index: 2 },
|
||||
{ dimension_id: 1, name: 'Business Model', description: 'Revenue and value proposition', order_index: 3 },
|
||||
{ dimension_id: 1, name: 'Strategic Planning', description: 'Long-term planning processes', order_index: 4 },
|
||||
{ dimension_id: 1, name: 'Innovation Strategy', description: 'R&D and innovation approach', order_index: 5 },
|
||||
{ dimension_id: 1, name: 'Risk Management', description: 'Strategic risk assessment', order_index: 6 },
|
||||
|
||||
// Sales KPIs
|
||||
{ dimension_id: 2, name: 'Sales Performance', description: 'Revenue and conversion metrics', order_index: 1 },
|
||||
{ dimension_id: 2, name: 'Customer Acquisition', description: 'Lead generation and conversion', order_index: 2 },
|
||||
{ dimension_id: 2, name: 'Sales Process', description: 'Sales methodology and tools', order_index: 3 },
|
||||
|
||||
// Product KPIs
|
||||
{ dimension_id: 3, name: 'Product Strategy', description: 'Product roadmap and vision', order_index: 1 },
|
||||
{ dimension_id: 3, name: 'Product Quality', description: 'Quality metrics and standards', order_index: 2 },
|
||||
{ dimension_id: 3, name: 'User Experience', description: 'Customer satisfaction and usability', order_index: 3 },
|
||||
{ dimension_id: 3, name: 'Product Innovation', description: 'Feature development and innovation', order_index: 4 },
|
||||
{ dimension_id: 3, name: 'Market Fit', description: 'Product-market fit analysis', order_index: 5 },
|
||||
|
||||
// Organization KPIs
|
||||
{ dimension_id: 4, name: 'Organizational Structure', description: 'Hierarchy and reporting lines', order_index: 1 },
|
||||
{ dimension_id: 4, name: 'Leadership', description: 'Management effectiveness', order_index: 2 },
|
||||
{ dimension_id: 4, name: 'Communication', description: 'Internal communication processes', order_index: 3 },
|
||||
{ dimension_id: 4, name: 'Decision Making', description: 'Decision processes and governance', order_index: 4 },
|
||||
{ dimension_id: 4, name: 'Change Management', description: 'Adaptability and change processes', order_index: 5 },
|
||||
|
||||
// Engineering KPIs
|
||||
{ dimension_id: 5, name: 'Development Practices', description: 'Coding standards and methodology', order_index: 1 },
|
||||
{ dimension_id: 5, name: 'Code Quality', description: 'Testing and code review processes', order_index: 2 },
|
||||
{ dimension_id: 5, name: 'Technical Architecture', description: 'System design and scalability', order_index: 3 },
|
||||
{ dimension_id: 5, name: 'Team Productivity', description: 'Velocity and delivery metrics', order_index: 4 },
|
||||
{ dimension_id: 5, name: 'Technical Debt', description: 'Code maintenance and refactoring', order_index: 5 },
|
||||
|
||||
// DevOps KPIs
|
||||
{ dimension_id: 6, name: 'Deployment Process', description: 'CI/CD and release management', order_index: 1 },
|
||||
{ dimension_id: 6, name: 'Infrastructure', description: 'System reliability and monitoring', order_index: 2 },
|
||||
{ dimension_id: 6, name: 'Automation', description: 'Process automation and tooling', order_index: 3 },
|
||||
|
||||
// Cyber KPIs
|
||||
{ dimension_id: 7, name: 'Security Policies', description: 'Security frameworks and policies', order_index: 1 },
|
||||
{ dimension_id: 7, name: 'Threat Management', description: 'Security monitoring and response', order_index: 2 },
|
||||
{ dimension_id: 7, name: 'Compliance', description: 'Regulatory compliance and auditing', order_index: 3 },
|
||||
{ dimension_id: 7, name: 'Data Protection', description: 'Data security and privacy', order_index: 4 },
|
||||
{ dimension_id: 7, name: 'Security Training', description: 'Employee security awareness', order_index: 5 },
|
||||
{ dimension_id: 7, name: 'Incident Response', description: 'Security incident handling', order_index: 6 },
|
||||
|
||||
// Finance KPIs
|
||||
{ dimension_id: 8, name: 'Financial Health', description: 'Revenue, profit, and cash flow', order_index: 1 },
|
||||
{ dimension_id: 8, name: 'Cost Management', description: 'Expense control and optimization', order_index: 2 },
|
||||
{ dimension_id: 8, name: 'Financial Planning', description: 'Budgeting and forecasting', order_index: 3 },
|
||||
{ dimension_id: 8, name: 'Investment Strategy', description: 'Capital allocation and ROI', order_index: 4 },
|
||||
{ dimension_id: 8, name: 'Financial Controls', description: 'Accounting and audit processes', order_index: 5 },
|
||||
{ dimension_id: 8, name: 'Risk Management', description: 'Financial risk assessment', order_index: 6 },
|
||||
{ dimension_id: 8, name: 'Funding Strategy', description: 'Capital raising and debt management', order_index: 7 },
|
||||
{ dimension_id: 8, name: 'Financial Reporting', description: 'Transparency and reporting standards', order_index: 8 },
|
||||
{ dimension_id: 8, name: 'Tax Strategy', description: 'Tax planning and compliance', order_index: 9 },
|
||||
{ dimension_id: 8, name: 'Treasury Management', description: 'Cash and liquidity management', order_index: 10 },
|
||||
{ dimension_id: 8, name: 'Investor Relations', description: 'Stakeholder communication', order_index: 11 },
|
||||
{ dimension_id: 8, name: 'Financial Technology', description: 'Fintech tools and systems', order_index: 12 },
|
||||
{ dimension_id: 8, name: 'Procurement', description: 'Vendor management and purchasing', order_index: 13 },
|
||||
|
||||
// People KPIs
|
||||
{ dimension_id: 9, name: 'Talent Acquisition', description: 'Recruitment and hiring processes', order_index: 1 },
|
||||
{ dimension_id: 9, name: 'Employee Development', description: 'Training and career progression', order_index: 2 },
|
||||
{ dimension_id: 9, name: 'Performance Management', description: 'Evaluation and feedback systems', order_index: 3 },
|
||||
{ dimension_id: 9, name: 'Compensation & Benefits', description: 'Salary and benefits structure', order_index: 4 },
|
||||
{ dimension_id: 9, name: 'Employee Engagement', description: 'Satisfaction and retention', order_index: 5 },
|
||||
|
||||
// Culture KPIs
|
||||
{ dimension_id: 10, name: 'Company Values', description: 'Core values and principles', order_index: 1 },
|
||||
{ dimension_id: 10, name: 'Work Environment', description: 'Workplace culture and atmosphere', order_index: 2 },
|
||||
{ dimension_id: 10, name: 'Diversity & Inclusion', description: 'D&I initiatives and metrics', order_index: 3 }
|
||||
];
|
||||
|
||||
kpis.forEach(kpi => {
|
||||
db.run(
|
||||
'INSERT INTO kpis (dimension_id, name, description, order_index) VALUES (?, ?, ?, ?)',
|
||||
[kpi.dimension_id, kpi.name, kpi.description, kpi.order_index]
|
||||
);
|
||||
});
|
||||
|
||||
// Insert check types
|
||||
const checkTypes = [
|
||||
{ name: 'text', data_type: 'text', options_json: null, validation_json: null },
|
||||
{
|
||||
name: 'dropdown',
|
||||
data_type: 'string',
|
||||
options_json: JSON.stringify(['Yes', 'Partially', 'No']),
|
||||
validation_json: JSON.stringify({ required: true })
|
||||
},
|
||||
{
|
||||
name: 'number',
|
||||
data_type: 'number',
|
||||
options_json: null,
|
||||
validation_json: JSON.stringify({ min: 0, max: Number.MAX_SAFE_INTEGER })
|
||||
},
|
||||
{
|
||||
name: 'percentage',
|
||||
data_type: 'number',
|
||||
options_json: null,
|
||||
validation_json: JSON.stringify({ min: 0, max: 100 })
|
||||
}
|
||||
];
|
||||
|
||||
checkTypes.forEach(type => {
|
||||
db.run(
|
||||
'INSERT INTO check_types (name, data_type, options_json, validation_json) VALUES (?, ?, ?, ?)',
|
||||
[type.name, type.data_type, type.options_json, type.validation_json]
|
||||
);
|
||||
});
|
||||
|
||||
// Insert sample checks for demonstration
|
||||
const sampleChecks = [
|
||||
// Strategy checks
|
||||
{ kpi_id: 1, question: 'Is the company vision clearly defined?', check_type: 'dropdown', current_value: null, expected_value: 'Yes', is_completed: true },
|
||||
{ kpi_id: 1, question: 'Are strategic goals documented and communicated?', check_type: 'dropdown', current_value: null, expected_value: 'Yes', is_completed: false },
|
||||
{ kpi_id: 1, question: 'Strategic alignment score (1-10)', check_type: 'number', expected_value: '8', current_value: '7', is_completed: false },
|
||||
|
||||
// Sales checks
|
||||
{ kpi_id: 7, question: 'Monthly revenue growth rate', check_type: 'percentage', expected_value: '15', current_value: '12', is_completed: false },
|
||||
{ kpi_id: 7, question: 'Sales conversion rate', check_type: 'percentage', expected_value: '25', current_value: '22', is_completed: false },
|
||||
|
||||
// Engineering checks
|
||||
{ kpi_id: 18, question: 'Development methodology', check_type: 'dropdown', expected_value: 'Agile', current_value: 'Agile', is_completed: true },
|
||||
{ kpi_id: 18, question: 'Average sprint velocity (story points)', check_type: 'number', expected_value: '40', current_value: '35', is_completed: false },
|
||||
{ kpi_id: 19, question: 'Code coverage percentage', check_type: 'percentage', expected_value: '80', current_value: '75', is_completed: false }
|
||||
];
|
||||
|
||||
sampleChecks.forEach(check => {
|
||||
db.run(
|
||||
'INSERT INTO checks (kpi_id, question, check_type, current_value, expected_value, is_completed) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
[check.kpi_id, check.question, check.check_type, check.current_value || null, check.expected_value || null, check.is_completed ? 1 : 0]
|
||||
);
|
||||
});
|
||||
|
||||
console.log('Database seeded successfully');
|
||||
};
|
||||
Reference in New Issue
Block a user