add brain
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
{
|
||||
"scan_metadata": {
|
||||
"directory": "/project/src",
|
||||
"scan_date": "2024-01-15T09:00:00",
|
||||
"scanner_version": "1.0.0"
|
||||
},
|
||||
"summary": {
|
||||
"total_files_scanned": 25,
|
||||
"total_lines_scanned": 12543,
|
||||
"total_debt_items": 28,
|
||||
"health_score": 68.5,
|
||||
"debt_density": 1.12
|
||||
},
|
||||
"debt_items": [
|
||||
{
|
||||
"id": "DEBT-0001",
|
||||
"type": "large_function",
|
||||
"description": "create_user function in user_service.py is 89 lines long",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0002",
|
||||
"type": "duplicate_code",
|
||||
"description": "Password validation logic duplicated in 3 locations",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0003",
|
||||
"type": "security_risk",
|
||||
"description": "Hardcoded API key in payment_processor.py",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "critical",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0004",
|
||||
"type": "high_complexity",
|
||||
"description": "process_payment function has cyclomatic complexity of 24",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0005",
|
||||
"type": "missing_docstring",
|
||||
"description": "PaymentProcessor class missing docstring",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0006",
|
||||
"type": "todo_comment",
|
||||
"description": "TODO: Move this to configuration file",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0007",
|
||||
"type": "empty_catch_blocks",
|
||||
"description": "Empty catch block in update_user method",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0008",
|
||||
"type": "magic_numbers",
|
||||
"description": "Magic number 1800 used for lock timeout",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0009",
|
||||
"type": "deep_nesting",
|
||||
"description": "Deep nesting detected: 6 levels in preferences handling",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0010",
|
||||
"type": "long_line",
|
||||
"description": "Line too long: 156 characters",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0011",
|
||||
"type": "commented_code",
|
||||
"description": "Dead code left in comments",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0012",
|
||||
"type": "global_variables",
|
||||
"description": "Global variable userCache should be encapsulated",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0013",
|
||||
"type": "synchronous_ajax",
|
||||
"description": "Synchronous AJAX call blocks UI thread",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0014",
|
||||
"type": "hardcoded_values",
|
||||
"description": "Tax rates hardcoded in payment processing logic",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0015",
|
||||
"type": "no_error_handling",
|
||||
"description": "API calls without proper error handling",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0016",
|
||||
"type": "inefficient_algorithm",
|
||||
"description": "O(n) user search could be optimized with indexing",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0017",
|
||||
"type": "memory_leak_risk",
|
||||
"description": "Event listeners attached without cleanup",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0018",
|
||||
"type": "sql_injection_risk",
|
||||
"description": "Potential SQL injection in user query",
|
||||
"file_path": "src/database.py",
|
||||
"severity": "critical",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0019",
|
||||
"type": "outdated_dependency",
|
||||
"description": "jQuery version 2.1.4 has known security vulnerabilities",
|
||||
"file_path": "package.json",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0020",
|
||||
"type": "test_debt",
|
||||
"description": "No unit tests for critical payment processing logic",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0021",
|
||||
"type": "large_class",
|
||||
"description": "UserService class has 15 methods",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0022",
|
||||
"type": "unused_imports",
|
||||
"description": "Unused import: sys",
|
||||
"file_path": "src/utils.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0023",
|
||||
"type": "missing_type_hints",
|
||||
"description": "Function get_user_score missing type hints",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0024",
|
||||
"type": "circular_dependency",
|
||||
"description": "Circular import between user_service and auth_service",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0025",
|
||||
"type": "inconsistent_naming",
|
||||
"description": "Variable name userID should be user_id",
|
||||
"file_path": "src/auth.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0026",
|
||||
"type": "broad_exception",
|
||||
"description": "Catching generic Exception instead of specific types",
|
||||
"file_path": "src/database.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0027",
|
||||
"type": "deprecated_api",
|
||||
"description": "Using deprecated datetime.utcnow() method",
|
||||
"file_path": "src/utils.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0028",
|
||||
"type": "logging_issue",
|
||||
"description": "Using print() instead of proper logging",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"scan_metadata": {
|
||||
"directory": "/project/src",
|
||||
"scan_date": "2024-02-01T14:30:00",
|
||||
"scanner_version": "1.0.0"
|
||||
},
|
||||
"summary": {
|
||||
"total_files_scanned": 27,
|
||||
"total_lines_scanned": 13421,
|
||||
"total_debt_items": 22,
|
||||
"health_score": 74.2,
|
||||
"debt_density": 0.81
|
||||
},
|
||||
"debt_items": [
|
||||
{
|
||||
"id": "DEBT-0001",
|
||||
"type": "large_function",
|
||||
"description": "create_user function in user_service.py is 89 lines long",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0002",
|
||||
"type": "duplicate_code",
|
||||
"description": "Password validation logic duplicated in 3 locations",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0004",
|
||||
"type": "high_complexity",
|
||||
"description": "process_payment function has cyclomatic complexity of 24",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0005",
|
||||
"type": "missing_docstring",
|
||||
"description": "PaymentProcessor class missing docstring",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0007",
|
||||
"type": "empty_catch_blocks",
|
||||
"description": "Empty catch block in update_user method",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0009",
|
||||
"type": "deep_nesting",
|
||||
"description": "Deep nesting detected: 6 levels in preferences handling",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0010",
|
||||
"type": "long_line",
|
||||
"description": "Line too long: 156 characters",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0011",
|
||||
"type": "commented_code",
|
||||
"description": "Dead code left in comments",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0012",
|
||||
"type": "global_variables",
|
||||
"description": "Global variable userCache should be encapsulated",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0013",
|
||||
"type": "synchronous_ajax",
|
||||
"description": "Synchronous AJAX call blocks UI thread",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0014",
|
||||
"type": "hardcoded_values",
|
||||
"description": "Tax rates hardcoded in payment processing logic",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0015",
|
||||
"type": "no_error_handling",
|
||||
"description": "API calls without proper error handling",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0016",
|
||||
"type": "inefficient_algorithm",
|
||||
"description": "O(n) user search could be optimized with indexing",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0017",
|
||||
"type": "memory_leak_risk",
|
||||
"description": "Event listeners attached without cleanup",
|
||||
"file_path": "src/frontend.js",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0021",
|
||||
"type": "large_class",
|
||||
"description": "UserService class has 15 methods",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0024",
|
||||
"type": "circular_dependency",
|
||||
"description": "Circular import between user_service and auth_service",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0026",
|
||||
"type": "broad_exception",
|
||||
"description": "Catching generic Exception instead of specific types",
|
||||
"file_path": "src/database.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-01-15T09:00:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0029",
|
||||
"type": "missing_validation",
|
||||
"description": "New API endpoint missing input validation",
|
||||
"file_path": "src/api.py",
|
||||
"severity": "high",
|
||||
"detected_date": "2024-02-01T14:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0030",
|
||||
"type": "performance_issue",
|
||||
"description": "N+1 query detected in user listing",
|
||||
"file_path": "src/user_service.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-02-01T14:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0031",
|
||||
"type": "css_debt",
|
||||
"description": "Inline styles should be moved to CSS files",
|
||||
"file_path": "templates/user_profile.html",
|
||||
"severity": "low",
|
||||
"detected_date": "2024-02-01T14:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0032",
|
||||
"type": "accessibility_issue",
|
||||
"description": "Missing alt text for images",
|
||||
"file_path": "templates/dashboard.html",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-02-01T14:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0033",
|
||||
"type": "configuration_debt",
|
||||
"description": "Environment-specific config hardcoded in application",
|
||||
"file_path": "src/config.py",
|
||||
"severity": "medium",
|
||||
"detected_date": "2024-02-01T14:30:00",
|
||||
"status": "identified"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
// Frontend JavaScript with various technical debt examples
|
||||
|
||||
// TODO: Move configuration to separate file
|
||||
const API_BASE_URL = "https://api.example.com";
|
||||
const API_KEY = "abc123def456"; // FIXME: Should be in environment
|
||||
|
||||
// Global variables - should be encapsulated
|
||||
var userCache = {};
|
||||
var authToken = null;
|
||||
var currentUser = null;
|
||||
|
||||
// HACK: Polyfill for older browsers - should use proper build system
|
||||
if (!String.prototype.includes) {
|
||||
String.prototype.includes = function(search) {
|
||||
return this.indexOf(search) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
class UserInterface {
|
||||
constructor() {
|
||||
this.components = {};
|
||||
this.eventHandlers = [];
|
||||
|
||||
// Long parameter list in constructor
|
||||
this.init(document, window, localStorage, sessionStorage, navigator, history, location);
|
||||
}
|
||||
|
||||
// Function with too many parameters
|
||||
init(doc, win, localStorage, sessionStorage, nav, hist, loc) {
|
||||
this.document = doc;
|
||||
this.window = win;
|
||||
this.localStorage = localStorage;
|
||||
this.sessionStorage = sessionStorage;
|
||||
this.navigator = nav;
|
||||
this.history = hist;
|
||||
this.location = loc;
|
||||
|
||||
// Deep nesting example
|
||||
if (this.localStorage) {
|
||||
if (this.localStorage.getItem('user')) {
|
||||
if (JSON.parse(this.localStorage.getItem('user'))) {
|
||||
if (JSON.parse(this.localStorage.getItem('user')).preferences) {
|
||||
if (JSON.parse(this.localStorage.getItem('user')).preferences.theme) {
|
||||
if (JSON.parse(this.localStorage.getItem('user')).preferences.theme === 'dark') {
|
||||
document.body.classList.add('dark-theme');
|
||||
} else if (JSON.parse(this.localStorage.getItem('user')).preferences.theme === 'light') {
|
||||
document.body.classList.add('light-theme');
|
||||
} else {
|
||||
document.body.classList.add('default-theme');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Large function that does too many things
|
||||
renderUserDashboard(userId, includeStats, includeRecent, includeNotifications, includeSettings, includeHelp) {
|
||||
let user = this.getUser(userId);
|
||||
|
||||
if (!user) {
|
||||
console.log("User not found"); // Should use proper logging
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<div class="dashboard">';
|
||||
|
||||
// Inline HTML generation - should use templates
|
||||
html += '<header class="dashboard-header">';
|
||||
html += '<h1>Welcome, ' + user.name + '</h1>';
|
||||
html += '<div class="user-avatar">';
|
||||
html += '<img src="' + user.avatar + '" alt="Avatar" />';
|
||||
html += '</div>';
|
||||
html += '</header>';
|
||||
|
||||
// Repeated validation pattern
|
||||
if (includeStats && includeStats === true) {
|
||||
html += '<section class="stats">';
|
||||
html += '<h2>Your Statistics</h2>';
|
||||
|
||||
// Magic numbers everywhere
|
||||
if (user.loginCount > 100) {
|
||||
html += '<div class="stat-item">Frequent User (100+ logins)</div>';
|
||||
} else if (user.loginCount > 50) {
|
||||
html += '<div class="stat-item">Regular User (50+ logins)</div>';
|
||||
} else if (user.loginCount > 10) {
|
||||
html += '<div class="stat-item">Casual User (10+ logins)</div>';
|
||||
} else {
|
||||
html += '<div class="stat-item">New User</div>';
|
||||
}
|
||||
|
||||
html += '</section>';
|
||||
}
|
||||
|
||||
if (includeRecent && includeRecent === true) {
|
||||
html += '<section class="recent">';
|
||||
html += '<h2>Recent Activity</h2>';
|
||||
|
||||
// No error handling for API calls
|
||||
let recentActivity = this.fetchRecentActivity(userId);
|
||||
|
||||
if (recentActivity && recentActivity.length > 0) {
|
||||
html += '<ul class="activity-list">';
|
||||
for (let i = 0; i < recentActivity.length; i++) {
|
||||
let activity = recentActivity[i];
|
||||
html += '<li class="activity-item">';
|
||||
html += '<span class="activity-type">' + activity.type + '</span>';
|
||||
html += '<span class="activity-description">' + activity.description + '</span>';
|
||||
html += '<span class="activity-time">' + this.formatTime(activity.timestamp) + '</span>';
|
||||
html += '</li>';
|
||||
}
|
||||
html += '</ul>';
|
||||
} else {
|
||||
html += '<p>No recent activity</p>';
|
||||
}
|
||||
|
||||
html += '</section>';
|
||||
}
|
||||
|
||||
if (includeNotifications && includeNotifications === true) {
|
||||
html += '<section class="notifications">';
|
||||
html += '<h2>Notifications</h2>';
|
||||
|
||||
let notifications = this.getNotifications(userId);
|
||||
|
||||
// Duplicate HTML generation pattern
|
||||
if (notifications && notifications.length > 0) {
|
||||
html += '<ul class="notification-list">';
|
||||
for (let i = 0; i < notifications.length; i++) {
|
||||
let notification = notifications[i];
|
||||
html += '<li class="notification-item">';
|
||||
html += '<span class="notification-title">' + notification.title + '</span>';
|
||||
html += '<span class="notification-message">' + notification.message + '</span>';
|
||||
html += '<span class="notification-time">' + this.formatTime(notification.timestamp) + '</span>';
|
||||
html += '</li>';
|
||||
}
|
||||
html += '</ul>';
|
||||
} else {
|
||||
html += '<p>No notifications</p>';
|
||||
}
|
||||
|
||||
html += '</section>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
||||
// Direct DOM manipulation without cleanup
|
||||
document.getElementById('main-content').innerHTML = html;
|
||||
|
||||
// Event handler attachment without cleanup
|
||||
let buttons = document.querySelectorAll('.action-button');
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
buttons[i].addEventListener('click', function(event) {
|
||||
// Nested event handlers - memory leak risk
|
||||
let buttonType = event.target.getAttribute('data-type');
|
||||
if (buttonType === 'edit') {
|
||||
// Inline event handling - should be separate methods
|
||||
let modal = document.createElement('div');
|
||||
modal.className = 'modal';
|
||||
modal.innerHTML = '<div class="modal-content"><h3>Edit Profile</h3><button onclick="closeModal()">Close</button></div>';
|
||||
document.body.appendChild(modal);
|
||||
} else if (buttonType === 'delete') {
|
||||
if (confirm('Are you sure?')) { // Using confirm - poor UX
|
||||
// No error handling
|
||||
fetch(API_BASE_URL + '/users/' + userId, {
|
||||
method: 'DELETE',
|
||||
headers: {'Authorization': 'Bearer ' + authToken}
|
||||
});
|
||||
}
|
||||
} else if (buttonType === 'share') {
|
||||
// Hardcoded share logic
|
||||
if (navigator.share) {
|
||||
navigator.share({
|
||||
title: 'Check out my profile',
|
||||
url: window.location.href
|
||||
});
|
||||
} else {
|
||||
// Fallback for browsers without Web Share API
|
||||
let shareUrl = 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(window.location.href);
|
||||
window.open(shareUrl, '_blank');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate code - similar to above but for admin dashboard
|
||||
renderAdminDashboard(adminId) {
|
||||
let admin = this.getUser(adminId);
|
||||
|
||||
if (!admin) {
|
||||
console.log("Admin not found");
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<div class="admin-dashboard">';
|
||||
|
||||
html += '<header class="dashboard-header">';
|
||||
html += '<h1>Admin Panel - Welcome, ' + admin.name + '</h1>';
|
||||
html += '<div class="user-avatar">';
|
||||
html += '<img src="' + admin.avatar + '" alt="Avatar" />';
|
||||
html += '</div>';
|
||||
html += '</header>';
|
||||
|
||||
// Same pattern repeated
|
||||
html += '<section class="admin-stats">';
|
||||
html += '<h2>System Statistics</h2>';
|
||||
|
||||
let stats = this.getSystemStats();
|
||||
if (stats) {
|
||||
html += '<div class="stat-grid">';
|
||||
html += '<div class="stat-item">Total Users: ' + stats.totalUsers + '</div>';
|
||||
html += '<div class="stat-item">Active Users: ' + stats.activeUsers + '</div>';
|
||||
html += '<div class="stat-item">New Today: ' + stats.newToday + '</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</section>';
|
||||
html += '</div>';
|
||||
|
||||
document.getElementById('main-content').innerHTML = html;
|
||||
}
|
||||
|
||||
getUser(userId) {
|
||||
// Check cache first - but cache never expires
|
||||
if (userCache[userId]) {
|
||||
return userCache[userId];
|
||||
}
|
||||
|
||||
// Synchronous AJAX - blocks UI
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', API_BASE_URL + '/users/' + userId, false);
|
||||
xhr.setRequestHeader('Authorization', 'Bearer ' + authToken);
|
||||
xhr.send();
|
||||
|
||||
if (xhr.status === 200) {
|
||||
let user = JSON.parse(xhr.responseText);
|
||||
userCache[userId] = user;
|
||||
return user;
|
||||
} else {
|
||||
// Generic error handling
|
||||
console.error('Failed to fetch user');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
fetchRecentActivity(userId) {
|
||||
// Another synchronous call
|
||||
try {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', API_BASE_URL + '/users/' + userId + '/activity', false);
|
||||
xhr.setRequestHeader('Authorization', 'Bearer ' + authToken);
|
||||
xhr.send();
|
||||
|
||||
if (xhr.status === 200) {
|
||||
return JSON.parse(xhr.responseText);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallowing errors
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
getNotifications(userId) {
|
||||
// Yet another sync call - should be async
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', API_BASE_URL + '/users/' + userId + '/notifications', false);
|
||||
xhr.setRequestHeader('Authorization', 'Bearer ' + authToken);
|
||||
xhr.send();
|
||||
|
||||
if (xhr.status === 200) {
|
||||
return JSON.parse(xhr.responseText);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
formatTime(timestamp) {
|
||||
// Basic time formatting - should use proper library
|
||||
let date = new Date(timestamp);
|
||||
return date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear();
|
||||
}
|
||||
|
||||
// XXX: This method is never used
|
||||
formatCurrency(amount, currency) {
|
||||
if (currency === 'USD') {
|
||||
return '$' + amount.toFixed(2);
|
||||
} else if (currency === 'EUR') {
|
||||
return '€' + amount.toFixed(2);
|
||||
} else {
|
||||
return amount.toFixed(2) + ' ' + currency;
|
||||
}
|
||||
}
|
||||
|
||||
getSystemStats() {
|
||||
// Hardcoded test data - should come from API
|
||||
return {
|
||||
totalUsers: 12534,
|
||||
activeUsers: 8765,
|
||||
newToday: 23
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Global functions - should be methods or modules
|
||||
function closeModal() {
|
||||
// Assumes modal exists - no error checking
|
||||
document.querySelector('.modal').remove();
|
||||
}
|
||||
|
||||
function validateEmail(email) {
|
||||
// Regex without explanation - magic pattern
|
||||
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
||||
}
|
||||
|
||||
function validatePassword(password) {
|
||||
// Duplicate validation logic from backend
|
||||
if (password.length < 8) return false;
|
||||
if (!/[A-Z]/.test(password)) return false;
|
||||
if (!/[a-z]/.test(password)) return false;
|
||||
if (!/\d/.test(password)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// jQuery-style utility - reinventing the wheel
|
||||
function $(selector) {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
|
||||
function $all(selector) {
|
||||
return document.querySelectorAll(selector);
|
||||
}
|
||||
|
||||
// Global event handlers - should be encapsulated
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Inline anonymous function
|
||||
let ui = new UserInterface();
|
||||
|
||||
// Event delegation would be better
|
||||
document.body.addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('login-button')) {
|
||||
// Inline login logic
|
||||
let username = $('#username').value;
|
||||
let password = $('#password').value;
|
||||
|
||||
if (!username || !password) {
|
||||
alert('Please enter username and password'); // Poor UX
|
||||
return;
|
||||
}
|
||||
|
||||
// No CSRF protection
|
||||
fetch(API_BASE_URL + '/auth/login', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({username: username, password: password})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
authToken = data.token;
|
||||
currentUser = data.user;
|
||||
localStorage.setItem('authToken', authToken); // Storing sensitive data
|
||||
localStorage.setItem('currentUser', JSON.stringify(currentUser));
|
||||
window.location.reload(); // Poor navigation
|
||||
} else {
|
||||
alert('Login failed: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Login error:', error);
|
||||
alert('Login failed');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// // Old code left as comments - should be removed
|
||||
// function oldRenderFunction() {
|
||||
// var html = '<div>Old implementation</div>';
|
||||
// document.body.innerHTML = html;
|
||||
// }
|
||||
|
||||
// Commented out feature - should be removed or implemented
|
||||
// function darkModeToggle() {
|
||||
// if (document.body.classList.contains('dark-theme')) {
|
||||
// document.body.classList.remove('dark-theme');
|
||||
// document.body.classList.add('light-theme');
|
||||
// } else {
|
||||
// document.body.classList.remove('light-theme');
|
||||
// document.body.classList.add('dark-theme');
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,315 @@
|
||||
"""
|
||||
Payment processing module - contains various technical debt examples
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
from decimal import Decimal
|
||||
from typing import Dict, Any
|
||||
|
||||
|
||||
class PaymentProcessor:
|
||||
|
||||
def __init__(self):
|
||||
# TODO: These should come from environment or config
|
||||
self.stripe_key = "sk_test_1234567890"
|
||||
self.paypal_key = "paypal_secret_key_here"
|
||||
self.square_key = "square_api_key"
|
||||
|
||||
def process_payment(self, amount, currency, payment_method, customer_data, billing_address, shipping_address, items, discount_code, tax_rate, processing_fee, metadata):
|
||||
"""
|
||||
Process a payment - this function is too large and complex
|
||||
"""
|
||||
|
||||
# Input validation - should be extracted to separate function
|
||||
if not amount or amount <= 0:
|
||||
return {"success": False, "error": "Invalid amount"}
|
||||
|
||||
if not currency:
|
||||
return {"success": False, "error": "Currency required"}
|
||||
|
||||
if currency not in ["USD", "EUR", "GBP", "CAD", "AUD"]: # Hardcoded list
|
||||
return {"success": False, "error": "Unsupported currency"}
|
||||
|
||||
if not payment_method:
|
||||
return {"success": False, "error": "Payment method required"}
|
||||
|
||||
if not customer_data or "email" not in customer_data:
|
||||
return {"success": False, "error": "Customer email required"}
|
||||
|
||||
# Tax calculation - complex business logic that should be separate service
|
||||
tax_amount = 0
|
||||
if tax_rate:
|
||||
if currency == "USD":
|
||||
# US tax logic - hardcoded rules
|
||||
if billing_address and "state" in billing_address:
|
||||
state = billing_address["state"]
|
||||
if state == "CA":
|
||||
tax_amount = amount * 0.08 # California tax
|
||||
elif state == "NY":
|
||||
tax_amount = amount * 0.085 # New York tax
|
||||
elif state == "TX":
|
||||
tax_amount = amount * 0.0625 # Texas tax
|
||||
elif state == "FL":
|
||||
tax_amount = amount * 0.06 # Florida tax
|
||||
else:
|
||||
tax_amount = amount * 0.05 # Default tax
|
||||
elif currency == "EUR":
|
||||
# EU VAT logic - also hardcoded
|
||||
tax_amount = amount * 0.20 # 20% VAT
|
||||
elif currency == "GBP":
|
||||
tax_amount = amount * 0.20 # UK VAT
|
||||
|
||||
# Discount calculation - another complex block
|
||||
discount_amount = 0
|
||||
if discount_code:
|
||||
# FIXME: This should query a discount service
|
||||
if discount_code == "SAVE10":
|
||||
discount_amount = amount * 0.10
|
||||
elif discount_code == "SAVE20":
|
||||
discount_amount = amount * 0.20
|
||||
elif discount_code == "NEWUSER":
|
||||
discount_amount = min(50, amount * 0.25) # Max $50 discount
|
||||
elif discount_code == "LOYALTY":
|
||||
# Complex loyalty discount logic
|
||||
customer_tier = customer_data.get("tier", "bronze")
|
||||
if customer_tier == "gold":
|
||||
discount_amount = amount * 0.15
|
||||
elif customer_tier == "silver":
|
||||
discount_amount = amount * 0.10
|
||||
elif customer_tier == "bronze":
|
||||
discount_amount = amount * 0.05
|
||||
|
||||
# Calculate final amount
|
||||
final_amount = amount - discount_amount + tax_amount + processing_fee
|
||||
|
||||
# Payment method routing - should use strategy pattern
|
||||
if payment_method["type"] == "credit_card":
|
||||
# Credit card processing
|
||||
if payment_method["provider"] == "stripe":
|
||||
try:
|
||||
# Stripe API call - no retry logic
|
||||
response = requests.post(
|
||||
"https://api.stripe.com/v1/charges",
|
||||
headers={"Authorization": f"Bearer {self.stripe_key}"},
|
||||
data={
|
||||
"amount": int(final_amount * 100), # Convert to cents
|
||||
"currency": currency.lower(),
|
||||
"source": payment_method["token"],
|
||||
"description": f"Payment for {len(items)} items"
|
||||
}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
stripe_response = response.json()
|
||||
# Store transaction - should be in database
|
||||
transaction = {
|
||||
"id": stripe_response["id"],
|
||||
"amount": final_amount,
|
||||
"currency": currency,
|
||||
"status": "completed",
|
||||
"timestamp": time.time(),
|
||||
"provider": "stripe",
|
||||
"customer": customer_data["email"],
|
||||
"items": items,
|
||||
"tax_amount": tax_amount,
|
||||
"discount_amount": discount_amount
|
||||
}
|
||||
|
||||
# Send confirmation email - inline instead of separate service
|
||||
self.send_payment_confirmation_email(customer_data["email"], transaction)
|
||||
|
||||
return {"success": True, "transaction": transaction}
|
||||
else:
|
||||
return {"success": False, "error": "Stripe payment failed"}
|
||||
|
||||
except Exception as e:
|
||||
# Broad exception handling - should be more specific
|
||||
print(f"Stripe error: {e}") # Should use proper logging
|
||||
return {"success": False, "error": "Payment processing error"}
|
||||
|
||||
elif payment_method["provider"] == "square":
|
||||
# Square processing - duplicate code structure
|
||||
try:
|
||||
response = requests.post(
|
||||
"https://connect.squareup.com/v2/payments",
|
||||
headers={"Authorization": f"Bearer {self.square_key}"},
|
||||
json={
|
||||
"source_id": payment_method["token"],
|
||||
"amount_money": {
|
||||
"amount": int(final_amount * 100),
|
||||
"currency": currency
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
square_response = response.json()
|
||||
transaction = {
|
||||
"id": square_response["payment"]["id"],
|
||||
"amount": final_amount,
|
||||
"currency": currency,
|
||||
"status": "completed",
|
||||
"timestamp": time.time(),
|
||||
"provider": "square",
|
||||
"customer": customer_data["email"],
|
||||
"items": items,
|
||||
"tax_amount": tax_amount,
|
||||
"discount_amount": discount_amount
|
||||
}
|
||||
|
||||
self.send_payment_confirmation_email(customer_data["email"], transaction)
|
||||
|
||||
return {"success": True, "transaction": transaction}
|
||||
else:
|
||||
return {"success": False, "error": "Square payment failed"}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Square error: {e}")
|
||||
return {"success": False, "error": "Payment processing error"}
|
||||
|
||||
elif payment_method["type"] == "paypal":
|
||||
# PayPal processing - more duplicate code
|
||||
try:
|
||||
response = requests.post(
|
||||
"https://api.paypal.com/v2/checkout/orders",
|
||||
headers={"Authorization": f"Bearer {self.paypal_key}"},
|
||||
json={
|
||||
"intent": "CAPTURE",
|
||||
"purchase_units": [{
|
||||
"amount": {
|
||||
"currency_code": currency,
|
||||
"value": str(final_amount)
|
||||
}
|
||||
}]
|
||||
}
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
paypal_response = response.json()
|
||||
transaction = {
|
||||
"id": paypal_response["id"],
|
||||
"amount": final_amount,
|
||||
"currency": currency,
|
||||
"status": "completed",
|
||||
"timestamp": time.time(),
|
||||
"provider": "paypal",
|
||||
"customer": customer_data["email"],
|
||||
"items": items,
|
||||
"tax_amount": tax_amount,
|
||||
"discount_amount": discount_amount
|
||||
}
|
||||
|
||||
self.send_payment_confirmation_email(customer_data["email"], transaction)
|
||||
|
||||
return {"success": True, "transaction": transaction}
|
||||
else:
|
||||
return {"success": False, "error": "PayPal payment failed"}
|
||||
|
||||
except Exception as e:
|
||||
print(f"PayPal error: {e}")
|
||||
return {"success": False, "error": "Payment processing error"}
|
||||
|
||||
else:
|
||||
return {"success": False, "error": "Unsupported payment method"}
|
||||
|
||||
def send_payment_confirmation_email(self, email, transaction):
|
||||
# Email sending logic - should be separate service
|
||||
# HACK: Using print instead of actual email service
|
||||
print(f"Sending confirmation email to {email}")
|
||||
print(f"Transaction ID: {transaction['id']}")
|
||||
print(f"Amount: {transaction['currency']} {transaction['amount']}")
|
||||
|
||||
# TODO: Implement actual email sending
|
||||
pass
|
||||
|
||||
def refund_payment(self, transaction_id, amount=None):
|
||||
# Refund logic - incomplete implementation
|
||||
# TODO: Implement refund for different providers
|
||||
print(f"Refunding transaction {transaction_id}")
|
||||
if amount:
|
||||
print(f"Partial refund: {amount}")
|
||||
else:
|
||||
print("Full refund")
|
||||
|
||||
# XXX: This doesn't actually process the refund
|
||||
return {"success": True, "message": "Refund initiated"}
|
||||
|
||||
def get_transaction(self, transaction_id):
|
||||
# Should query database, but we don't have one
|
||||
# FIXME: Implement actual transaction lookup
|
||||
return {"id": transaction_id, "status": "unknown"}
|
||||
|
||||
def validate_credit_card(self, card_number, expiry_month, expiry_year, cvv):
|
||||
# Basic card validation - should use proper validation library
|
||||
if not card_number or len(card_number) < 13 or len(card_number) > 19:
|
||||
return False
|
||||
|
||||
# Luhn algorithm check - reimplemented poorly
|
||||
digits = [int(d) for d in card_number if d.isdigit()]
|
||||
checksum = 0
|
||||
for i, digit in enumerate(reversed(digits)):
|
||||
if i % 2 == 1:
|
||||
digit *= 2
|
||||
if digit > 9:
|
||||
digit -= 9
|
||||
checksum += digit
|
||||
|
||||
if checksum % 10 != 0:
|
||||
return False
|
||||
|
||||
# Expiry validation
|
||||
if expiry_month < 1 or expiry_month > 12:
|
||||
return False
|
||||
|
||||
current_year = int(time.strftime("%Y"))
|
||||
current_month = int(time.strftime("%m"))
|
||||
|
||||
if expiry_year < current_year:
|
||||
return False
|
||||
elif expiry_year == current_year and expiry_month < current_month:
|
||||
return False
|
||||
|
||||
# CVV validation
|
||||
if not cvv or len(cvv) < 3 or len(cvv) > 4:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# Module-level functions that should be in class or separate module
|
||||
def calculate_processing_fee(amount, provider):
|
||||
"""Calculate processing fee - hardcoded rates"""
|
||||
if provider == "stripe":
|
||||
return amount * 0.029 + 0.30 # Stripe rates
|
||||
elif provider == "paypal":
|
||||
return amount * 0.031 + 0.30 # PayPal rates
|
||||
elif provider == "square":
|
||||
return amount * 0.026 + 0.10 # Square rates
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def format_currency(amount, currency):
|
||||
"""Format currency - basic implementation"""
|
||||
# Should use proper internationalization
|
||||
if currency == "USD":
|
||||
return f"${amount:.2f}"
|
||||
elif currency == "EUR":
|
||||
return f"€{amount:.2f}"
|
||||
elif currency == "GBP":
|
||||
return f"£{amount:.2f}"
|
||||
else:
|
||||
return f"{currency} {amount:.2f}"
|
||||
|
||||
|
||||
# Global state - anti-pattern
|
||||
payment_processor_instance = None
|
||||
|
||||
|
||||
def get_payment_processor():
|
||||
global payment_processor_instance
|
||||
if payment_processor_instance is None:
|
||||
payment_processor_instance = PaymentProcessor()
|
||||
return payment_processor_instance
|
||||
@@ -0,0 +1,276 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
User service module with various tech debt examples
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import time
|
||||
import re
|
||||
from typing import Dict, List, Any, Optional
|
||||
|
||||
# TODO: Move this to configuration file
|
||||
DATABASE_URL = "postgresql://user:password123@localhost:5432/mydb"
|
||||
API_KEY = "sk-1234567890abcdef" # FIXME: This should be in environment variables
|
||||
|
||||
|
||||
class UserService:
|
||||
def __init__(self):
|
||||
self.users = {}
|
||||
self.cache = {}
|
||||
# HACK: Using dict for now, should be proper database connection
|
||||
self.db_connection = None
|
||||
|
||||
def create_user(self, name, email, password, age, phone, address, city, state, zip_code, country, preferences, notifications, billing_info):
|
||||
# Function with too many parameters - should use User dataclass
|
||||
if not name:
|
||||
return None
|
||||
if not email:
|
||||
return None
|
||||
if not password:
|
||||
return None
|
||||
if not age:
|
||||
return None
|
||||
if not phone:
|
||||
return None
|
||||
if not address:
|
||||
return None
|
||||
if not city:
|
||||
return None
|
||||
if not state:
|
||||
return None
|
||||
if not zip_code:
|
||||
return None
|
||||
if not country:
|
||||
return None
|
||||
|
||||
# Duplicate validation logic - should be extracted
|
||||
if age < 13:
|
||||
print("User must be at least 13 years old")
|
||||
return None
|
||||
if age > 150:
|
||||
print("Invalid age")
|
||||
return None
|
||||
|
||||
# More validation
|
||||
if not self.validate_email(email):
|
||||
print("Invalid email format")
|
||||
return None
|
||||
|
||||
# Password validation - duplicated elsewhere
|
||||
if len(password) < 8:
|
||||
print("Password too short")
|
||||
return None
|
||||
if not re.search(r"[A-Z]", password):
|
||||
print("Password must contain uppercase letter")
|
||||
return None
|
||||
if not re.search(r"[a-z]", password):
|
||||
print("Password must contain lowercase letter")
|
||||
return None
|
||||
if not re.search(r"\d", password):
|
||||
print("Password must contain digit")
|
||||
return None
|
||||
|
||||
# Deep nesting example
|
||||
if preferences:
|
||||
if 'notifications' in preferences:
|
||||
if preferences['notifications']:
|
||||
if 'email' in preferences['notifications']:
|
||||
if preferences['notifications']['email']:
|
||||
if 'frequency' in preferences['notifications']['email']:
|
||||
if preferences['notifications']['email']['frequency'] == 'daily':
|
||||
print("Daily email notifications enabled")
|
||||
elif preferences['notifications']['email']['frequency'] == 'weekly':
|
||||
print("Weekly email notifications enabled")
|
||||
else:
|
||||
print("Invalid notification frequency")
|
||||
|
||||
# TODO: Implement proper user ID generation
|
||||
user_id = str(hash(email)) # XXX: This is terrible for production
|
||||
|
||||
# Magic numbers everywhere
|
||||
password_hash = hashlib.sha256((password + "salt123").encode()).hexdigest()
|
||||
|
||||
user_data = {
|
||||
"id": user_id,
|
||||
"name": name,
|
||||
"email": email,
|
||||
"password_hash": password_hash,
|
||||
"age": age,
|
||||
"phone": phone,
|
||||
"address": address,
|
||||
"city": city,
|
||||
"state": state,
|
||||
"zip_code": zip_code,
|
||||
"country": country,
|
||||
"preferences": preferences,
|
||||
"notifications": notifications,
|
||||
"billing_info": billing_info,
|
||||
"created_at": time.time(),
|
||||
"updated_at": time.time(),
|
||||
"last_login": None,
|
||||
"login_count": 0,
|
||||
"is_active": True,
|
||||
"is_verified": False,
|
||||
"verification_token": None,
|
||||
"reset_token": None,
|
||||
"failed_login_attempts": 0,
|
||||
"locked_until": None,
|
||||
"subscription_level": "free",
|
||||
"credits": 100
|
||||
}
|
||||
|
||||
self.users[user_id] = user_data
|
||||
return user_id
|
||||
|
||||
def validate_email(self, email):
|
||||
# Duplicate validation logic - should be in utils
|
||||
if not email:
|
||||
return False
|
||||
if "@" not in email:
|
||||
return False
|
||||
if "." not in email:
|
||||
return False
|
||||
return True
|
||||
|
||||
def authenticate_user(self, email, password):
|
||||
# More duplicate validation
|
||||
if not email:
|
||||
return None
|
||||
if not password:
|
||||
return None
|
||||
|
||||
# Linear search through users - O(n) complexity
|
||||
for user_id, user_data in self.users.items():
|
||||
if user_data["email"] == email:
|
||||
# Same password hashing logic duplicated
|
||||
password_hash = hashlib.sha256((password + "salt123").encode()).hexdigest()
|
||||
if user_data["password_hash"] == password_hash:
|
||||
# Update login stats
|
||||
user_data["last_login"] = time.time()
|
||||
user_data["login_count"] += 1
|
||||
user_data["failed_login_attempts"] = 0
|
||||
return user_id
|
||||
else:
|
||||
# Failed login handling
|
||||
user_data["failed_login_attempts"] += 1
|
||||
if user_data["failed_login_attempts"] >= 5: # Magic number
|
||||
user_data["locked_until"] = time.time() + 1800 # 30 minutes
|
||||
return None
|
||||
return None
|
||||
|
||||
def get_user(self, user_id):
|
||||
# No error handling
|
||||
return self.users[user_id]
|
||||
|
||||
def update_user(self, user_id, updates):
|
||||
try:
|
||||
# Empty catch block - bad practice
|
||||
user = self.users[user_id]
|
||||
except:
|
||||
pass
|
||||
|
||||
# More validation duplication
|
||||
if "age" in updates:
|
||||
if updates["age"] < 13:
|
||||
print("User must be at least 13 years old")
|
||||
return False
|
||||
if updates["age"] > 150:
|
||||
print("Invalid age")
|
||||
return False
|
||||
|
||||
if "email" in updates:
|
||||
if not self.validate_email(updates["email"]):
|
||||
print("Invalid email format")
|
||||
return False
|
||||
|
||||
# Direct dictionary manipulation without validation
|
||||
for key, value in updates.items():
|
||||
user[key] = value
|
||||
|
||||
user["updated_at"] = time.time()
|
||||
return True
|
||||
|
||||
def delete_user(self, user_id):
|
||||
# print("Deleting user", user_id) # Commented out code
|
||||
# TODO: Implement soft delete instead
|
||||
del self.users[user_id]
|
||||
|
||||
def search_users(self, query):
|
||||
results = []
|
||||
# Inefficient search algorithm - O(n*m)
|
||||
for user_id, user_data in self.users.items():
|
||||
if query.lower() in user_data["name"].lower():
|
||||
results.append(user_data)
|
||||
elif query.lower() in user_data["email"].lower():
|
||||
results.append(user_data)
|
||||
elif query in user_data.get("phone", ""):
|
||||
results.append(user_data)
|
||||
return results
|
||||
|
||||
def export_users(self):
|
||||
# Security risk - no access control
|
||||
return json.dumps(self.users, indent=2)
|
||||
|
||||
def import_users(self, json_data):
|
||||
# No validation of imported data
|
||||
imported_users = json.loads(json_data)
|
||||
self.users.update(imported_users)
|
||||
|
||||
# def old_create_user(self, name, email):
|
||||
# # Old implementation kept as comment
|
||||
# return {"name": name, "email": email}
|
||||
|
||||
def calculate_user_score(self, user_id):
|
||||
user = self.users[user_id]
|
||||
score = 0
|
||||
|
||||
# Complex scoring logic with magic numbers
|
||||
if user["login_count"] > 10:
|
||||
score += 50
|
||||
elif user["login_count"] > 5:
|
||||
score += 30
|
||||
elif user["login_count"] > 1:
|
||||
score += 10
|
||||
|
||||
if user["subscription_level"] == "premium":
|
||||
score += 100
|
||||
elif user["subscription_level"] == "pro":
|
||||
score += 75
|
||||
elif user["subscription_level"] == "basic":
|
||||
score += 25
|
||||
|
||||
# Age-based scoring with arbitrary rules
|
||||
if user["age"] >= 18 and user["age"] <= 65:
|
||||
score += 20
|
||||
elif user["age"] > 65:
|
||||
score += 10
|
||||
|
||||
return score
|
||||
|
||||
|
||||
# Global variable - should be encapsulated
|
||||
user_service_instance = UserService()
|
||||
|
||||
|
||||
def get_user_service():
|
||||
return user_service_instance
|
||||
|
||||
|
||||
# Utility function that should be in separate module
|
||||
def hash_password(password, salt="salt123"):
|
||||
# Hardcoded salt - security issue
|
||||
return hashlib.sha256((password + salt).encode()).hexdigest()
|
||||
|
||||
|
||||
# Another utility function with duplicate logic
|
||||
def validate_password(password):
|
||||
if len(password) < 8:
|
||||
return False, "Password too short"
|
||||
if not re.search(r"[A-Z]", password):
|
||||
return False, "Password must contain uppercase letter"
|
||||
if not re.search(r"[a-z]", password):
|
||||
return False, "Password must contain lowercase letter"
|
||||
if not re.search(r"\d", password):
|
||||
return False, "Password must contain digit"
|
||||
return True, "Valid password"
|
||||
@@ -0,0 +1,285 @@
|
||||
[
|
||||
{
|
||||
"id": "DEBT-0001",
|
||||
"type": "large_function",
|
||||
"description": "create_user function in user_service.py is 89 lines long",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 13,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"function_name": "create_user",
|
||||
"length": 89,
|
||||
"recommended_max": 50
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0002",
|
||||
"type": "duplicate_code",
|
||||
"description": "Password validation logic duplicated in 3 locations",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 45,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"duplicate_count": 3,
|
||||
"other_files": ["src/auth.py", "src/frontend.js"]
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0003",
|
||||
"type": "security_risk",
|
||||
"description": "Hardcoded API key in payment_processor.py",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 10,
|
||||
"severity": "critical",
|
||||
"metadata": {
|
||||
"security_issue": "hardcoded_credentials",
|
||||
"exposure_risk": "high"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0004",
|
||||
"type": "high_complexity",
|
||||
"description": "process_payment function has cyclomatic complexity of 24",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 19,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"function_name": "process_payment",
|
||||
"complexity": 24,
|
||||
"recommended_max": 10
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0005",
|
||||
"type": "missing_docstring",
|
||||
"description": "PaymentProcessor class missing docstring",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 8,
|
||||
"severity": "low",
|
||||
"metadata": {
|
||||
"class_name": "PaymentProcessor"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0006",
|
||||
"type": "todo_comment",
|
||||
"description": "TODO: Move this to configuration file",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 8,
|
||||
"severity": "low",
|
||||
"metadata": {
|
||||
"comment": "TODO: Move this to configuration file"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0007",
|
||||
"type": "empty_catch_blocks",
|
||||
"description": "Empty catch block in update_user method",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 156,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"method_name": "update_user",
|
||||
"exception_type": "generic"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0008",
|
||||
"type": "magic_numbers",
|
||||
"description": "Magic number 1800 used for lock timeout",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 98,
|
||||
"severity": "low",
|
||||
"metadata": {
|
||||
"value": 1800,
|
||||
"context": "account_lockout_duration"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0009",
|
||||
"type": "deep_nesting",
|
||||
"description": "Deep nesting detected: 6 levels in preferences handling",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 32,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"nesting_level": 6,
|
||||
"recommended_max": 4
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0010",
|
||||
"type": "long_line",
|
||||
"description": "Line too long: 156 characters",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 127,
|
||||
"severity": "low",
|
||||
"metadata": {
|
||||
"length": 156,
|
||||
"recommended_max": 120
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0011",
|
||||
"type": "commented_code",
|
||||
"description": "Dead code left in comments",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 285,
|
||||
"severity": "low",
|
||||
"metadata": {
|
||||
"lines_of_commented_code": 8
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0012",
|
||||
"type": "global_variables",
|
||||
"description": "Global variable userCache should be encapsulated",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 7,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"variable_name": "userCache",
|
||||
"scope": "global"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0013",
|
||||
"type": "synchronous_ajax",
|
||||
"description": "Synchronous AJAX call blocks UI thread",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 189,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"method": "XMLHttpRequest",
|
||||
"async": false
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0014",
|
||||
"type": "hardcoded_values",
|
||||
"description": "Tax rates hardcoded in payment processing logic",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 45,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"values": ["0.08", "0.085", "0.0625", "0.06"],
|
||||
"context": "tax_calculation"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0015",
|
||||
"type": "no_error_handling",
|
||||
"description": "API calls without proper error handling",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 78,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"api_endpoint": "stripe",
|
||||
"error_scenarios": ["network_failure", "invalid_response"]
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0016",
|
||||
"type": "inefficient_algorithm",
|
||||
"description": "O(n) user search could be optimized with indexing",
|
||||
"file_path": "src/user_service.py",
|
||||
"line_number": 178,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"current_complexity": "O(n)",
|
||||
"recommended_complexity": "O(log n)",
|
||||
"method_name": "search_users"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0017",
|
||||
"type": "memory_leak_risk",
|
||||
"description": "Event listeners attached without cleanup",
|
||||
"file_path": "src/frontend.js",
|
||||
"line_number": 145,
|
||||
"severity": "medium",
|
||||
"metadata": {
|
||||
"event_type": "click",
|
||||
"cleanup_missing": true
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0018",
|
||||
"type": "sql_injection_risk",
|
||||
"description": "Potential SQL injection in user query",
|
||||
"file_path": "src/database.py",
|
||||
"line_number": 25,
|
||||
"severity": "critical",
|
||||
"metadata": {
|
||||
"query_type": "dynamic",
|
||||
"user_input": "unsanitized"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0019",
|
||||
"type": "outdated_dependency",
|
||||
"description": "jQuery version 2.1.4 has known security vulnerabilities",
|
||||
"file_path": "package.json",
|
||||
"line_number": 15,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"package": "jquery",
|
||||
"current_version": "2.1.4",
|
||||
"latest_version": "3.6.4",
|
||||
"vulnerabilities": ["CVE-2020-11022", "CVE-2020-11023"]
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
},
|
||||
{
|
||||
"id": "DEBT-0020",
|
||||
"type": "test_debt",
|
||||
"description": "No unit tests for critical payment processing logic",
|
||||
"file_path": "src/payment_processor.py",
|
||||
"line_number": 19,
|
||||
"severity": "high",
|
||||
"metadata": {
|
||||
"coverage": 0,
|
||||
"critical_paths": ["process_payment", "refund_payment"],
|
||||
"risk_level": "high"
|
||||
},
|
||||
"detected_date": "2024-02-10T10:30:00",
|
||||
"status": "identified"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user