forked from rohit/spurrin-backend
app versioning
This commit is contained in:
parent
0766e61de5
commit
b3a29c5ffa
@ -13,3 +13,15 @@ ADD COLUMN is_flagged BOOLEAN DEFAULT FALSE;
|
||||
ALTER TABLE interaction_logs
|
||||
ADD COLUMN report_text TEXT AFTER is_flagged;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS app_versions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
platform ENUM('android', 'ios') NOT NULL,
|
||||
latest_version VARCHAR(20) NOT NULL,
|
||||
stable_version VARCHAR(20) NOT NULL,
|
||||
under_maintenance BOOLEAN DEFAULT FALSE,
|
||||
last_updated DATE NOT NULL,
|
||||
app_url VARCHAR(500) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY unique_platform (platform)
|
||||
);
|
||||
@ -33,6 +33,7 @@ const appUserRoutes = require('./routes/appUsers');
|
||||
const excelDataRoutes = require('./routes/exceldata');
|
||||
const feedbackRoute = require('./routes/feedbacks');
|
||||
const analyticsRoute = require('./routes/analysis');
|
||||
const appVersionRoutes = require('./routes/appVersioning');
|
||||
|
||||
// Import services
|
||||
const { refreshExpiredTokens } = require('./services/cronJobs');
|
||||
@ -102,6 +103,7 @@ async function startServer() {
|
||||
app.use('/api/process_excel', excelDataRoutes);
|
||||
app.use('/api/feedbacks', feedbackRoute);
|
||||
app.use('/api/analytics', analyticsRoute);
|
||||
app.use('/api/app-versioning', appVersionRoutes);
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
|
||||
320
src/controllers/appVersionController.js
Normal file
320
src/controllers/appVersionController.js
Normal file
@ -0,0 +1,320 @@
|
||||
const db = require('../config/database');
|
||||
|
||||
// Get all app versions
|
||||
exports.getAllAppVersions = async (req, res) => {
|
||||
try {
|
||||
const query = 'SELECT * FROM app_versions ORDER BY platform';
|
||||
const rows = await db.query(query);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: rows
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching app versions:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Get app version by platform
|
||||
exports.getAppVersionByPlatform = async (req, res) => {
|
||||
try {
|
||||
const { platform } = req.params;
|
||||
|
||||
if (!['android', 'ios'].includes(platform)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Platform must be either "android" or "ios"'
|
||||
});
|
||||
}
|
||||
|
||||
const query = 'SELECT * FROM app_versions WHERE platform = ?';
|
||||
const rows = await db.query(query, [platform]);
|
||||
|
||||
if (rows.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: `No app version found for platform: ${platform}`
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: rows[0]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching app version:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Create new app version
|
||||
exports.createAppVersion = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
platform,
|
||||
latest_version,
|
||||
stable_version,
|
||||
under_maintenance = false,
|
||||
last_updated,
|
||||
app_url
|
||||
} = req.body;
|
||||
|
||||
// Validate required fields
|
||||
if (!platform || !latest_version || !stable_version || !last_updated || !app_url) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'All fields are required: platform, latest_version, stable_version, last_updated, app_url'
|
||||
});
|
||||
}
|
||||
|
||||
// Validate platform
|
||||
if (!['android', 'ios'].includes(platform)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Platform must be either "android" or "ios"'
|
||||
});
|
||||
}
|
||||
|
||||
// Check if platform already exists
|
||||
const existingQuery = 'SELECT id FROM app_versions WHERE platform = ?';
|
||||
const existingRows = await db.query(existingQuery, [platform]);
|
||||
|
||||
if (existingRows.length > 0) {
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
error: `App version for platform "${platform}" already exists. Use PUT to update.`
|
||||
});
|
||||
}
|
||||
|
||||
// Insert new app version
|
||||
const insertQuery = `
|
||||
INSERT INTO app_versions (platform, latest_version, stable_version, under_maintenance, last_updated, app_url)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
|
||||
const result = await db.query(insertQuery, [
|
||||
platform,
|
||||
latest_version,
|
||||
stable_version,
|
||||
under_maintenance,
|
||||
last_updated,
|
||||
app_url
|
||||
]);
|
||||
|
||||
// Fetch the created record
|
||||
const newVersion = await db.query('SELECT * FROM app_versions WHERE id = ?', [result.insertId]);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'App version created successfully',
|
||||
data: newVersion[0]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error creating app version:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Update app version by platform
|
||||
exports.updateAppVersion = async (req, res) => {
|
||||
try {
|
||||
const { platform } = req.params;
|
||||
const {
|
||||
latest_version,
|
||||
stable_version,
|
||||
under_maintenance,
|
||||
last_updated,
|
||||
app_url
|
||||
} = req.body;
|
||||
|
||||
// Validate platform
|
||||
if (!['android', 'ios'].includes(platform)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Platform must be either "android" or "ios"'
|
||||
});
|
||||
}
|
||||
|
||||
// Check if platform exists
|
||||
const existingQuery = 'SELECT id FROM app_versions WHERE platform = ?';
|
||||
const existingRows = await db.query(existingQuery, [platform]);
|
||||
|
||||
if (existingRows.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: `No app version found for platform: ${platform}`
|
||||
});
|
||||
}
|
||||
|
||||
// Build update query dynamically based on provided fields
|
||||
const updateFields = [];
|
||||
const updateValues = [];
|
||||
|
||||
if (latest_version !== undefined) {
|
||||
updateFields.push('latest_version = ?');
|
||||
updateValues.push(latest_version);
|
||||
}
|
||||
if (stable_version !== undefined) {
|
||||
updateFields.push('stable_version = ?');
|
||||
updateValues.push(stable_version);
|
||||
}
|
||||
if (under_maintenance !== undefined) {
|
||||
updateFields.push('under_maintenance = ?');
|
||||
updateValues.push(under_maintenance);
|
||||
}
|
||||
if (last_updated !== undefined) {
|
||||
updateFields.push('last_updated = ?');
|
||||
updateValues.push(last_updated);
|
||||
}
|
||||
if (app_url !== undefined) {
|
||||
updateFields.push('app_url = ?');
|
||||
updateValues.push(app_url);
|
||||
}
|
||||
|
||||
if (updateFields.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'At least one field must be provided for update'
|
||||
});
|
||||
}
|
||||
|
||||
updateValues.push(platform);
|
||||
|
||||
const updateQuery = `
|
||||
UPDATE app_versions
|
||||
SET ${updateFields.join(', ')}
|
||||
WHERE platform = ?
|
||||
`;
|
||||
|
||||
await db.query(updateQuery, updateValues);
|
||||
|
||||
// Fetch the updated record
|
||||
const updatedVersion = await db.query('SELECT * FROM app_versions WHERE platform = ?', [platform]);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'App version updated successfully',
|
||||
data: updatedVersion[0]
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error updating app version:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Delete app version by platform
|
||||
exports.deleteAppVersion = async (req, res) => {
|
||||
try {
|
||||
const { platform } = req.params;
|
||||
|
||||
// Validate platform
|
||||
if (!['android', 'ios'].includes(platform)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Platform must be either "android" or "ios"'
|
||||
});
|
||||
}
|
||||
|
||||
// Check if platform exists
|
||||
const existingQuery = 'SELECT id FROM app_versions WHERE platform = ?';
|
||||
const existingRows = await db.query(existingQuery, [platform]);
|
||||
|
||||
if (existingRows.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: `No app version found for platform: ${platform}`
|
||||
});
|
||||
}
|
||||
|
||||
// Delete the app version
|
||||
const deleteQuery = 'DELETE FROM app_versions WHERE platform = ?';
|
||||
await db.query(deleteQuery, [platform]);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: `App version for platform "${platform}" deleted successfully`
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error deleting app version:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Get app version status (for client apps to check updates)
|
||||
exports.getAppVersionStatus = async (req, res) => {
|
||||
try {
|
||||
const { platform, current_version } = req.query;
|
||||
|
||||
// Validate platform
|
||||
if (!platform || !['android', 'ios'].includes(platform)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Valid platform parameter is required (android or ios)'
|
||||
});
|
||||
}
|
||||
|
||||
// Get app version for the platform
|
||||
const query = 'SELECT * FROM app_versions WHERE platform = ?';
|
||||
const rows = await db.query(query, [platform]);
|
||||
|
||||
if (rows.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: `No app version found for platform: ${platform}`
|
||||
});
|
||||
}
|
||||
|
||||
const appVersion = rows[0];
|
||||
|
||||
// Determine if update is needed
|
||||
let update_required = false;
|
||||
let update_type = null;
|
||||
|
||||
if (current_version) {
|
||||
// Simple version comparison (you might want to use a proper semver library)
|
||||
if (current_version !== appVersion.latest_version) {
|
||||
update_required = true;
|
||||
update_type = 'latest';
|
||||
} else if (current_version !== appVersion.stable_version) {
|
||||
update_required = true;
|
||||
update_type = 'stable';
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: {
|
||||
platform: appVersion.platform,
|
||||
latest_version: appVersion.latest_version,
|
||||
stable_version: appVersion.stable_version,
|
||||
under_maintenance: appVersion.under_maintenance,
|
||||
last_updated: appVersion.last_updated,
|
||||
app_url: appVersion.app_url,
|
||||
update_required,
|
||||
update_type
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching app version status:', error.message);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
});
|
||||
}
|
||||
};
|
||||
28
src/migrations/20240610130000_create_app_versions.js
Normal file
28
src/migrations/20240610130000_create_app_versions.js
Normal file
@ -0,0 +1,28 @@
|
||||
const db = require('../../config/database');
|
||||
|
||||
module.exports = {
|
||||
async up() {
|
||||
// Create app_versions table
|
||||
await db.query(`
|
||||
CREATE TABLE IF NOT EXISTS app_versions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
platform ENUM('android', 'ios') NOT NULL,
|
||||
latest_version VARCHAR(20) NOT NULL,
|
||||
stable_version VARCHAR(20) NOT NULL,
|
||||
under_maintenance BOOLEAN DEFAULT FALSE,
|
||||
last_updated DATE NOT NULL,
|
||||
app_url VARCHAR(500) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY unique_platform (platform)
|
||||
)
|
||||
`);
|
||||
},
|
||||
|
||||
async down() {
|
||||
// Drop app_versions table
|
||||
await db.query(`
|
||||
DROP TABLE IF EXISTS app_versions
|
||||
`);
|
||||
}
|
||||
};
|
||||
41
src/routes/appVersioning.js
Normal file
41
src/routes/appVersioning.js
Normal file
@ -0,0 +1,41 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const appVersionController = require('../controllers/appVersionController');
|
||||
const authMiddleware = require('../middlewares/authMiddleware');
|
||||
const roleMiddleware = require('../middlewares/roleMiddleware');
|
||||
|
||||
// Public route - Get app version status (for client apps)
|
||||
router.get('/status', appVersionController.getAppVersionStatus);
|
||||
|
||||
// Protected routes - Require authentication and admin role
|
||||
// Get all app versions
|
||||
router.get('/',
|
||||
authMiddleware.authenticateToken,
|
||||
appVersionController.getAllAppVersions
|
||||
);
|
||||
|
||||
// Get app version by platform
|
||||
router.get('/:platform',
|
||||
authMiddleware.authenticateToken,
|
||||
appVersionController.getAppVersionByPlatform
|
||||
);
|
||||
|
||||
// Create new app version
|
||||
router.post('/create',
|
||||
authMiddleware.authenticateToken,
|
||||
appVersionController.createAppVersion
|
||||
);
|
||||
|
||||
// Update app version by platform
|
||||
router.put('/:platform',
|
||||
authMiddleware.authenticateToken,
|
||||
appVersionController.updateAppVersion
|
||||
);
|
||||
|
||||
// Delete app version by platform
|
||||
router.delete('/:platform',
|
||||
authMiddleware.authenticateToken,
|
||||
appVersionController.deleteAppVersion
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
Loading…
Reference in New Issue
Block a user