diff --git a/server/controllers/adminController.js b/server/controllers/adminController.js
index d4a20ae..02f1fd5 100644
--- a/server/controllers/adminController.js
+++ b/server/controllers/adminController.js
@@ -27,15 +27,17 @@ exports.publishResult = async (data, authorization) => {
const [admin] = await db.query('SELECT id FROM admins WHERE session_token = ?', [token]);
if (!admin) throw { status: 401, message: 'Unauthorized' };
- const { team, date, result } = data;
+ const { team, date, result, announcement_time } = data; // renamed draw_time
// validate if the team exists
const teams = await db.query('SELECT id FROM teams WHERE name = ?', [team.toUpperCase()]);
if (!teams.length) throw { status: 400, message: 'Team does not exist. Create team first.' };
// publish result using team id
await db.query(`
- INSERT INTO results (team_id, result_date, result)
- VALUES (?, ?, ?)
- ON DUPLICATE KEY UPDATE result = VALUES(result)
- `, [teams[0].id, date, result]);
+ INSERT INTO results (team_id, result_date, result, announcement_time)
+ VALUES (?, ?, ?, COALESCE(?, '00:00:00'))
+ ON DUPLICATE KEY UPDATE
+ result = VALUES(result),
+ announcement_time = VALUES(announcement_time)
+ `, [teams[0].id, date, result, announcement_time]);
};
diff --git a/server/controllers/resultController.js b/server/controllers/resultController.js
index 24a44a4..f989bc8 100644
--- a/server/controllers/resultController.js
+++ b/server/controllers/resultController.js
@@ -7,7 +7,7 @@ exports.getMonthlyResults = async (req, res) => {
return res.status(400).json({ error: 'Team and month are required.' });
}
const results = await db.query(`
- SELECT r.result, r.result_date
+ SELECT r.result, r.result_date, r.announcement_time
FROM results r
JOIN teams t ON r.team_id = t.id
WHERE t.name = ? AND DATE_FORMAT(r.result_date, '%Y-%m') = ?
@@ -28,7 +28,7 @@ exports.getDailyResults = async (req, res) => {
return res.status(400).json({ error: 'Date query parameter is required.' });
}
const results = await db.query(`
- SELECT t.name as team, r.result, r.result_date
+ SELECT t.name as team, r.result, r.result_date, r.announcement_time
FROM results r
JOIN teams t ON r.team_id = t.id
WHERE r.result_date = ?
diff --git a/server/controllers/teamController.js b/server/controllers/teamController.js
index 1d16f50..0e02b52 100644
--- a/server/controllers/teamController.js
+++ b/server/controllers/teamController.js
@@ -12,15 +12,15 @@ exports.getAllTeams = async (req, res) => {
exports.createTeam = async (req, res) => {
try {
- const { name, announcement_time } = req.body;
+ const { name } = req.body;
- if (!name || !announcement_time) {
- return res.status(400).json({ error: 'Name and announcement time are required' });
+ if (!name) {
+ return res.status(400).json({ error: 'Name is required' });
}
await db.query(
- 'INSERT INTO teams (name, announcement_time) VALUES (?, ?)',
- [name.toUpperCase(), announcement_time]
+ 'INSERT INTO teams (name) VALUES (?)',
+ [name.toUpperCase()]
);
res.status(201).json({ success: true, message: 'Team created successfully' });
@@ -33,26 +33,14 @@ exports.createTeam = async (req, res) => {
exports.updateTeam = async (req, res) => {
try {
const { id } = req.params;
- const { name, announcement_time } = req.body;
+ const { name } = req.body;
- if (!name && !announcement_time) {
- return res.status(400).json({ error: 'At least one field (name or announcement time) is required' });
+ if (!name) {
+ return res.status(400).json({ error: 'At least name is required' });
}
- const fields = [];
- const values = [];
-
- if (name) {
- fields.push('name = ?');
- values.push(name.toUpperCase());
- }
-
- if (announcement_time) {
- fields.push('announcement_time = ?');
- values.push(announcement_time);
- }
-
- values.push(id);
+ const fields = ['name = ?'];
+ const values = [name.toUpperCase(), id];
await db.query(`UPDATE teams SET ${fields.join(', ')} WHERE id = ?`, values);
diff --git a/server/middlewares/validation.js b/server/middlewares/validation.js
index e4b38a5..417a66f 100644
--- a/server/middlewares/validation.js
+++ b/server/middlewares/validation.js
@@ -2,8 +2,7 @@ const Joi = require('joi');
exports.validateTeam = (req, res, next) => {
const schema = Joi.object({
- name: Joi.string().max(100).required(),
- announcement_time: Joi.string().pattern(/^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/).required()
+ name: Joi.string().max(100).required()
});
const { error } = schema.validate(req.body);
diff --git a/server/postman_collection.json b/server/postman_collection.json
index ed78bf8..d0d70f6 100644
--- a/server/postman_collection.json
+++ b/server/postman_collection.json
@@ -44,7 +44,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n \"team\": \"BIKANER SUPER\",\n \"date\": \"2025-03-12\",\n \"result\": \"45\"\n}"
+ "raw": "{\n \"team\": \"BIKANER SUPER\",\n \"date\": \"2025-03-12\",\n \"result\": \"45\",\n \"announcement_time\": \"02:30:00\"\n}"
},
"url": {
"raw": "http://localhost:3000/admin/results",
@@ -85,7 +85,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n \"name\": \"NEW TEAM\",\n \"announcement_time\": \"02:30:00\"\n}"
+ "raw": "{\n \"name\": \"NEW TEAM\"\n}"
},
"url": {
"raw": "http://localhost:3000/api/teams",
@@ -112,7 +112,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n \"name\": \"UPDATED TEAM\",\n \"announcement_time\": \"03:00:00\"\n}"
+ "raw": "{\n \"name\": \"UPDATED TEAM\"\n}"
},
"url": {
"raw": "http://localhost:3000/api/teams/1",
@@ -182,7 +182,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n \"name\": \"\",\n \"announcement_time\": \"02:30:00\"\n}"
+ "raw": "{\n \"name\": \"\"\n}"
},
"url": {
"raw": "http://localhost:3000/api/teams",
diff --git a/server/readme.md b/server/readme.md
index 0c08a76..bc341c8 100644
--- a/server/readme.md
+++ b/server/readme.md
@@ -109,12 +109,10 @@ The server will listen on the port specified in your `.env` file (default is 300
Retrieve all teams (public).
- **POST /api/teams**
- Create a new team (admin only, requires Bearer token).
- _Request Body Example:_
+ Create a new team (admin only).
```json
{
- "name": "NEW TEAM",
- "announcement_time": "02:30:00"
+ "name": "NEW TEAM"
}
```
@@ -128,8 +126,7 @@ The server will listen on the port specified in your `.env` file (default is 300
A sample endpoint (POST /api/teams) will sanitize HTML input. For example, sending:
```json
{
- "name": "",
- "announcement_time": "02:30:00"
+ "name": ""
}
```
will have the `<` and `>` characters escaped to protect against XSS.
diff --git a/server/routes/public.js b/server/routes/public.js
index 244c433..68e25c6 100644
--- a/server/routes/public.js
+++ b/server/routes/public.js
@@ -14,7 +14,7 @@ router.get('/results', async (req, res) => {
}
const [result] = await db.query(`
- SELECT r.result, r.result_date, t.name AS team
+ SELECT r.result, r.result_date, r.announcement_time, t.name AS team
FROM results r
JOIN teams t ON r.team_id = t.id
WHERE t.name = ? AND r.result_date = ?
@@ -39,7 +39,7 @@ router.get('/today', async (req, res) => {
}
const results = await db.query(`
- SELECT t.name AS team, r.result, r.result_date
+ SELECT t.name AS team, r.result, r.result_date, r.announcement_time
FROM results r
JOIN teams t ON r.team_id = t.id
WHERE r.result_date = ?
diff --git a/server/schema.sql b/server/schema.sql
index a768c6c..8ba1b64 100644
--- a/server/schema.sql
+++ b/server/schema.sql
@@ -4,7 +4,6 @@ USE kingdb_prod;
CREATE TABLE teams (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
- announcement_time TIME NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
@@ -12,6 +11,7 @@ CREATE TABLE results (
id INT AUTO_INCREMENT PRIMARY KEY,
team_id INT NOT NULL,
result_date DATE NOT NULL,
+ announcement_time TIME NOT NULL,
result VARCHAR(10) NOT NULL,
FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,
UNIQUE KEY uniq_team_date (team_id, result_date)
diff --git a/server/scripts/test-api.js b/server/scripts/test-api.js
index 157a76f..c12ed7f 100644
--- a/server/scripts/test-api.js
+++ b/server/scripts/test-api.js
@@ -17,8 +17,7 @@ const BASE_URL = 'http://localhost:3000';
const createTeamResponse = await axios.post(
`${BASE_URL}/api/teams`,
{
- name: 'NEW TEAM',
- announcement_time: '02:30:00'
+ name: 'NEW TEAM'
},
{
headers: { Authorization: `Bearer ${sessionToken}` }
@@ -35,8 +34,7 @@ const BASE_URL = 'http://localhost:3000';
const updateTeamResponse = await axios.put(
`${BASE_URL}/api/teams/1`,
{
- name: 'UPDATED TEAM',
- announcement_time: '03:00:00'
+ name: 'UPDATED TEAM'
},
{
headers: { Authorization: `Bearer ${sessionToken}` }
diff --git a/server/server.js b/server/server.js
index b444a6a..bb97ca9 100644
--- a/server/server.js
+++ b/server/server.js
@@ -10,7 +10,7 @@ const teamRoutes = require('./routes/team');
const app = express();
-app.use(cors({ origin: ['http://localhost:3000', 'https://your-production-domain.com'] }));
+app.use(cors({ origin: ['http://localhost:3000', '*', 'https://your-production-domain.com'] }));
app.use(express.json({ limit: '10kb' }));
app.use(security.anonymizeIP);
app.use(security.sanitizeInput);