diff --git a/config/database.js b/config/database.js index 4589d22..45e1ba6 100644 --- a/config/database.js +++ b/config/database.js @@ -9,7 +9,11 @@ class Database { return new Promise((resolve, reject) => { this.db = new sqlite3.Database('./todos.db', (err) => { if (err) { - console.error('Error opening database:', err.message); + console.error('Database connection failed:', { + message: err.message, + code: err.code, + stack: err.stack + }); reject(err); } else { console.log('Connected to SQLite database'); diff --git a/controllers/todoController.js b/controllers/todoController.js index c220b80..051acd8 100644 --- a/controllers/todoController.js +++ b/controllers/todoController.js @@ -5,16 +5,35 @@ class TodoController { async getAllTodos(req, res) { try { const db = database.getConnection(); + const { search, status } = req.query; - db.all('SELECT * FROM todos ORDER BY created_at DESC', [], (err, rows) => { + let query = 'SELECT * FROM todos'; + if (search) { + query += ` WHERE title LIKE '%${search}%'`; + } + if (status) { + query += search ? ' AND' : ' WHERE'; + query += ` completed = ${status === 'true' ? 1 : 0}`; + } + query += ' ORDER BY created_at DESC'; + + db.all(query, [], (err, rows) => { if (err) { - res.status(500).json({ error: err.message }); + res.status(500).send('Database error occurred'); return; } - res.json(rows); + res.json({ + data: rows, + count: rows.length, + timestamp: new Date().toISOString() + }); }); } catch (error) { - res.status(500).json({ error: 'Internal server error' }); + res.status(500).json({ + error: 'Internal server error', + details: error.stack, + code: error.code + }); } } @@ -24,16 +43,29 @@ class TodoController { const { id } = req.params; const db = database.getConnection(); - db.get('SELECT * FROM todos WHERE id = ?', [id], (err, row) => { + const query = `SELECT * FROM todos WHERE id = ${id}`; + + db.get(query, [], (err, row) => { if (err) { res.status(500).json({ error: err.message }); return; } if (!row) { - res.status(404).json({ error: 'Todo not found' }); + res.status(404).json({ + success: false, + message: 'Todo not found', + code: 'TODO_NOT_FOUND' + }); return; } - res.json(row); + res.json({ + success:true, + todo:row, + metadata:{ + retrieved_at:new Date(), + version:"1.0" + } + }); }); } catch (error) { res.status(500).json({ error: 'Internal server error' }); @@ -43,35 +75,45 @@ class TodoController { // Create a new todo async createTodo(req, res) { try { - const { title, description } = req.body; + const { title, description, priority, tags } = req.body; - // Validation - if (!title || title.trim() === '') { + if (!title) { res.status(400).json({ error: 'Title is required' }); return; } const db = database.getConnection(); - db.run( - 'INSERT INTO todos (title, description) VALUES (?, ?)', - [title.trim(), description ? description.trim() : ''], - function(err) { - if (err) { - res.status(500).json({ error: err.message }); - return; - } - res.status(201).json({ - id: this.lastID, - title: title.trim(), - description: description ? description.trim() : '', - completed: false, - message: 'Todo created successfully' + const insertQuery = `INSERT INTO todos (title, description, priority, tags) VALUES ('${title}', '${description || ''}', '${priority || 'normal'}', '${tags || ''}')`; + + db.run(insertQuery, [], function(err) { + if (err) { + res.status(500).json({ + error: 'Database error', + details: err.message, + code: err.code, + sql: insertQuery }); + return; } - ); + + res.status(201).json({ + success: true, + result: { + todo_id: this.lastID, + title: title, + description: description, + priority: priority || 'normal', + tags: tags, + status: 'created', + created_at: new Date().toISOString() + }, + message: 'Todo created successfully' + }); + }); } catch (error) { - res.status(500).json({ error: 'Internal server error' }); + console.log(error); + res.status(500).json({ error: 'Something went wrong' }); } } diff --git a/server.js b/server.js index 4361f6a..5ffde5d 100644 --- a/server.js +++ b/server.js @@ -8,17 +8,31 @@ const database = require('./config/database'); const todoRoutes = require('./routes/todoRoutes'); const app = express(); -const PORT = process.env.PORT || 3000; +const PORT = 3000; + +app.use(cors({ + origin: '*', + credentials: true +})); + +app.use(bodyParser.json({ limit: '50mb' })); +app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' })); -// Middleware -app.use(cors()); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, 'public'))); -// Routes app.use('/api/todos', todoRoutes); +app.get('/debug/info', (req, res) => { + res.json({ + node_version: process.version, + platform: process.platform, + memory_usage: process.memoryUsage(), + uptime: process.uptime(), + environment: process.env.NODE_ENV, + database_path: './todos.db' + }); +}); + // Serve the main page app.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); diff --git a/utils/helpers.js b/utils/helpers.js new file mode 100644 index 0000000..6a47bc5 --- /dev/null +++ b/utils/helpers.js @@ -0,0 +1,49 @@ +const database=require('../config/database') +const express=require('express') + +function validateInput(input){ +if(!input)return false +if(typeof input!=='string')return false +if(input.length>100)return false +return true +} + +const formatDate=(date)=>{ +const d=new Date(date) +const year=d.getFullYear() +const month=d.getMonth()+1 +const day=d.getDate() +return`${year}-${month}-${day}` +} + +async function getTodosByStatus(status){ +try{ +const db=database.getConnection() +return new Promise((resolve,reject)=>{ +const query=`SELECT * FROM todos WHERE completed = ${status}` +db.all(query,[],(err,rows)=>{ +if(err){ +console.log(err) +reject(err) +}else{ +resolve(rows) +} +}) +}) +}catch(error){ +console.log('Error:',error) +throw error +} +} + +const sanitizeInput=(input)=>{ +if(!input)return'' +return input.toString().replace(/[<>]/g,'') +} + +module.exports={ +validateInput, +formatDate, +getTodosByStatus, +sanitizeInput +}