generated from azures04/Base-REST-API
Add badges, checkins, and transport endpoints
Introduce gamification and check-in support plus expanded transport/admin APIs. Added DDL for checkins, badges and user_badges. New repositories: badgeRepository, userBadgeRepository, checkinRepository. New routes: admin badge management, admin transport (lines/platforms/stations), public transport endpoints, user checkins and stations endpoints, and user badges on /me. Services updated: adminService (badge CRUD & user assignment), userService (checkins, badge queries), authService (hasAdminRights). Minor package.json name update. These changes implement database, repo, service and route wiring for badges, user_badins and checkin features and additional transport admin routes.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function createBadge(name, description, icon, condition) {
|
||||
try {
|
||||
const sql = "INSERT INTO `badges` (name, description, icon, condition) VALUES (?, ?, ?, ?)"
|
||||
const rows = await pool.query(sql, [name, description, icon, condition])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findAllBadges() {
|
||||
try {
|
||||
const sql = "SELECT * FROM `badges` ORDER BY name"
|
||||
const rows = await pool.query(sql)
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findBadgeById(badgeId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM `badges` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [badgeId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateBadge(badgeId, updateData) {
|
||||
try {
|
||||
const fields = Object.keys(updateData)
|
||||
const values = Object.values(updateData)
|
||||
const setClause = fields.map(f => `${f} = ?`).join(", ")
|
||||
const sql = `UPDATE \`badges\` SET ${setClause} WHERE id = ?`
|
||||
const rows = await pool.query(sql, [...values, badgeId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteBadge(badgeId) {
|
||||
try {
|
||||
const sql = "DELETE FROM `badges` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [badgeId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createBadge,
|
||||
findAllBadges,
|
||||
findBadgeById,
|
||||
updateBadge,
|
||||
deleteBadge
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function createCheckin(userId, stationId, platformId, latitude, longitude, distance) {
|
||||
try {
|
||||
const sql = "INSERT INTO `checkins` (userId, stationId, platformId, latitude, longitude, distance) VALUES (?, ?, ?, ?, ?, ?)"
|
||||
const rows = await pool.query(sql, [userId, stationId, platformId, latitude, longitude, distance])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findCheckinById(checkinId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM `checkins` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [checkinId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findCheckinsByUserId(userId, limit = 50, offset = 0) {
|
||||
try {
|
||||
const sql = "SELECT * FROM `checkins` WHERE userId = ? ORDER BY checkinAt DESC LIMIT ? OFFSET ?"
|
||||
const rows = await pool.query(sql, [userId, limit, offset])
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findCheckinsByStation(stationId, limit = 50, offset = 0) {
|
||||
try {
|
||||
const sql = "SELECT * FROM `checkins` WHERE stationId = ? ORDER BY checkinAt DESC LIMIT ? OFFSET ?"
|
||||
const rows = await pool.query(sql, [stationId, limit, offset])
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function countCheckinsByUser(userId) {
|
||||
try {
|
||||
const sql = "SELECT COUNT(*) as count FROM `checkins` WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows[0].count
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function countCheckinsByUserAndStation(userId, stationId) {
|
||||
try {
|
||||
const sql = "SELECT COUNT(*) as count FROM `checkins` WHERE userId = ? AND stationId = ?"
|
||||
const rows = await pool.query(sql, [userId, stationId])
|
||||
return rows[0].count
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findUniqueStationsByUser(userId) {
|
||||
try {
|
||||
const sql = "SELECT DISTINCT stationId FROM `checkins` WHERE userId = ? ORDER BY checkinAt DESC"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteCheckin(checkinId) {
|
||||
try {
|
||||
const sql = "DELETE FROM `checkins` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [checkinId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createCheckin,
|
||||
findCheckinById,
|
||||
findCheckinsByUserId,
|
||||
findCheckinsByStation,
|
||||
countCheckinsByUser,
|
||||
countCheckinsByUserAndStation,
|
||||
findUniqueStationsByUser,
|
||||
deleteCheckin
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function assignBadgeToUser(userId, badgeId) {
|
||||
try {
|
||||
const sql = "INSERT INTO `user_badges` (userId, badgeId) VALUES (?, ?)"
|
||||
const rows = await pool.query(sql, [userId, badgeId])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findUserBadges(userId) {
|
||||
try {
|
||||
const sql = `SELECT ub.*, b.name, b.description, b.icon, b.condition
|
||||
FROM \`user_badges\` ub
|
||||
JOIN \`badges\` b ON ub.badgeId = b.id
|
||||
WHERE ub.userId = ?
|
||||
ORDER BY ub.unlockedAt DESC`
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function hasBadge(userId, badgeId) {
|
||||
try {
|
||||
const sql = "SELECT COUNT(*) as count FROM `user_badges` WHERE userId = ? AND badgeId = ?"
|
||||
const rows = await pool.query(sql, [userId, badgeId])
|
||||
return rows[0].count > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeBadgeFromUser(userId, badgeId) {
|
||||
try {
|
||||
const sql = "DELETE FROM `user_badges` WHERE userId = ? AND badgeId = ?"
|
||||
const rows = await pool.query(sql, [userId, badgeId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function countUserBadges(userId) {
|
||||
try {
|
||||
const sql = "SELECT COUNT(*) as count FROM `user_badges` WHERE userId = ?"
|
||||
const rows = await pool.query(sql, [userId])
|
||||
return rows[0].count
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
assignBadgeToUser,
|
||||
findUserBadges,
|
||||
hasBadge,
|
||||
removeBadgeFromUser,
|
||||
countUserBadges
|
||||
}
|
||||
Reference in New Issue
Block a user