Skip to content

Commit

Permalink
Add backend routes
Browse files Browse the repository at this point in the history
  • Loading branch information
leeaj8-uci committed Nov 18, 2023
1 parent 238cfea commit 84aff04
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 3 deletions.
7 changes: 7 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ const cors = require('cors');

require('dotenv').config();

// routes
const memberRouter = require('./routes/memberRouter');
const gameRouter = require('./routes/gameRouter');

const app = express();

const PORT = process.env.PORT || 3001;
Expand All @@ -13,6 +17,9 @@ app.use(
}),
);

app.use('/members', memberRouter);
app.use('/games', gameRouter);

app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
92 changes: 92 additions & 0 deletions common/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const isNumeric = (value, errorMessage) => {
if (!/^\d+$/.test(value)) {
throw new Error(errorMessage);
}
};

const isBoolean = (value, errorMessage) => {
if (![true, false, 'true', 'false'].includes(value)) {
throw new Error(errorMessage);
}
};

const isZipCode = (value, errorMessage) => {
if (!/(^\d{5}$)|(^\d{5}-\d{4}$)/.test(value)) {
throw new Error(errorMessage);
}
};

const isAlphaNumeric = (value, errorMessage) => {
if (!/^[0-9a-zA-Z]+$/.test(value)) {
throw new Error(errorMessage);
}
};

const isPhoneNumber = (value, errorMessage) => {
if (!/^\d+$/.test(value) || value.length > 15) {
throw new Error(errorMessage);
}
};

// toCamel, isArray, and isObject are helper functions used within utils only
const toCamel = (s) => {
return s.replace(/([-_][a-z])/g, ($1) => {
return $1.toUpperCase().replace('-', '').replace('_', '');
});
};

const isArray = (a) => {
return Array.isArray(a);
};

const isISODate = (str) => {
try {
const ISOString = str.toISOString();
if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(ISOString)) return false;
const d = new Date(ISOString);
return d.toISOString() === ISOString;
} catch (err) {
return false;
}
};

const isObject = (o) => {
return o === Object(o) && !isArray(o) && typeof o !== 'function' && !isISODate(o);
};

// Database columns are in snake case. JavaScript is suppose to be in camel case
// This function converts the keys from the sql query to camel case so it follows JavaScript conventions
const keysToCamel = (data) => {
if (isObject(data)) {
const newData = {};
Object.keys(data).forEach((key) => {
newData[toCamel(key)] = keysToCamel(data[key]);
});
return newData;
}
if (isArray(data)) {
return data.map((i) => {
return keysToCamel(i);
});
}
if (
typeof data === 'string' &&
data.length > 0 &&
data[0] === '{' &&
data[data.length - 1] === '}'
) {
let parsedList = data.replaceAll('"', '');
parsedList = parsedList.slice(1, parsedList.length - 1).split(',');
return parsedList;
}
return data;
};

module.exports = {
isNumeric,
isBoolean,
isZipCode,
isAlphaNumeric,
isPhoneNumber,
keysToCamel,
};
45 changes: 45 additions & 0 deletions routes/gameRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const express = require('express');
const { keysToCamel } = require('../common/utils');
const { db } = require('../server/db');

const gameRouter = express.Router();

gameRouter.get('/rps/:memberId', async (req, res) => {
try {
const { memberId } = req.params
const [{move}] = await db.query(`SELECT move FROM rock_paper_scissors WHERE member_id = $1 LIMIT 1;`, [memberId]);
res.status(200).json({ memberId, move });
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});

gameRouter.get('/hangman/:memberId', async (req, res) => {
try {
const { memberId } = req.params
const [{phrase}] = await db.query(`SELECT phrase FROM hangman_phrases WHERE member_id = $1 LIMIT 1;`, [memberId]);
res.status(200).json({ memberId, phrase });
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});

gameRouter.get('/truthslies/:memberId', async (req, res) => {
try {
const { memberId } = req.params
const truths = await db.query(`SELECT truth FROM truths WHERE member_id = $1 LIMIT 2;`, [memberId]);
const [{lie}] = await db.query(`SELECT lie FROM lies WHERE member_id = $1 LIMIT 1;`, [memberId]);
res.status(200).json({
truths: truths.map(({truth}) => (truth)),
lie
});
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});


module.exports = gameRouter;
40 changes: 40 additions & 0 deletions routes/memberRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const express = require('express');
const { keysToCamel } = require('../common/utils');
const { db } = require('../server/db');

const memberRouter = express.Router();

memberRouter.get('/', async (req, res) => {
try {
const basicUserInfo = await db.query(`SELECT id, member_name, member_year, project FROM members;`);
res.status(200).json(keysToCamel(basicUserInfo));
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});


memberRouter.get('/ids', async (req, res) => {
try {
const ids = await db.query(`SELECT id FROM members;`);
res.status(200).json(ids.map(({id})=>(id)));
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});

memberRouter.get('/:member_id', async (req, res) => {
try {
const { member_id } = req.params;
const memberInfo = await db.query(`SELECT * FROM members WHERE id = $1;`, [member_id]);
res.status(200).json(keysToCamel(memberInfo));
} catch (err) {
console.log(err);
res.status(500).send(err.message);
}
});


module.exports = memberRouter;
4 changes: 2 additions & 2 deletions server/schema/members.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ DROP TABLE IF EXISTS members CASCADE;
DROP TYPE IF EXISTS year_standing;
DROP TYPE IF EXISTS ctc_project;

CREATE TYPE year_standing AS ENUM ('1st', '2nd', '3rd', "4th");
CREATE TYPE ctc_project AS ENUM ('AISS', 'FPH', 'S2T', "(Board)");
CREATE TYPE year_standing AS ENUM ('1st', '2nd', '3rd', '4th');
CREATE TYPE ctc_project AS ENUM ('AISS', 'FPH', 'S2T', '(Board)');

CREATE TABLE members (
id SERIAL PRIMARY KEY,
Expand Down
2 changes: 1 addition & 1 deletion server/schema/truths_and_lies.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ CREATE TABLE truths (

CREATE TABLE lies (
member_id INTEGER PRIMARY KEY REFERENCES members(id) ON DELETE CASCADE ON UPDATE CASCADE,
phrase TEXT NOT NULL
lie TEXT NOT NULL
);

0 comments on commit 84aff04

Please sign in to comment.