--- version: 1.1 --- # Pre-interview question We have created this exercise to gain insights into your development skills. ## What to do? There are two parts to the questions: The first part is about your coding skill. The second part is about your knowledge. ## Coding Choose either one language to finish - [Routing - Javascript](https://hackmd.io/@Aigniter/Sk42DKyxY) - [Routing - Typescript](https://hackmd.io/@Aigniter/Bk9FY7Glc) ## Short questions The questions below may contain 1 or more syntax error(s), logical error(s) or security issue(s). Please point them out as many as you can. 1. ```javascript= // Purpose: given a list of users and return a list of VIP member users const NODE_ENV = process.env.NODE_ENV || "development"; const knexFile = require("../knexfile")[NODE_ENV] const knex = require('knex')(knexFile); .... async function filterAccount(userIdList) { await userIdList.filter(async (userId) => { const user = await knex('users').first('*').where({id: userId}); return user.isVIP === true; }); return userIdList; } ``` 2. ```javascript= const NODE_ENV = process.env.NODE_ENV || "development"; const knexFile = require("../knexfile")[NODE_ENV] const knex = require('knex')(knexFile); .... // Purpose: Randomly select N birthday month users and get them a reward coupon async function birthdayCustomerReward(knex, rewardCouponID, limit) { const month = new Date().getMonth() + 1; //random select limit customers const birthdayCustomer = (await knex.raw( "SELECT id FROM user WHERE birth_month = ? ORDER BY RAND() LIMIT ?", [month, limit] ))[0]; // The return object is an array which includes the data and some metadata, we just need the data part so we just take the first part of the array. for (let i = 0; i <= birthdayCustomer.length; i++) { await assignCoupon(rewardCouponID, birthdayCustomer[i].id) } } ``` 3. ```javascript= const NODE_ENV = process.env.NODE_ENV || "development"; const knexFile = require("../knexfile")[NODE_ENV] const knex = require('knex')(knexFile); ... //https://www.npmjs.com/package/knex // const Exception = require('./Exception.js'); const passwordUtils = require('./passwordUtils'); // a utils for password handling // Purpose: Delete user async function deleteUser(id, password) { try { // It checks user password is correct. // The return object is an array which includes the data and some metadata, we just need the data part so we just take the first part of the array. const passwordInfo = ( await knex.raw("SELECT password FROM user where `id` = '" + id + "'") )[0]; // console.log(passwordInfo); if (passwordInfo.length) { const passwordHash = passwordInfo[0].password; const passwordCheck = await passwordUtils.verify(passwordHash, password); if (!passwordCheck) { throw new Error("Incorrect password"); } } // It checks the user has any existing uncompleted orders. // The return object is an array which includes the data and some metadata, we just need the data part so we just take the first part of the array. const existingProcessingOrder = ( await knex.raw( "SELECT COUNT(*) AS count FROM order_history where `user_id` = '" + id + "' AND `status` = 'processing'" ) )[0]; // console.log(existingProcessingOrder); if ( existingProcessingOrder[0].count > 0 ) { throw new Error(`The user ${id} exists uncompleted orders`); } else { await knex("users").where({ id: id }).del(); } } catch (err) { console.log(err); throw new Error("Internal server error"); } } ``` - Answer all 3 questions in `<your_name>_short_questions.txt`. ## Submission - Zip `<your_name>_p1.js` or `<your_name>_p1.ts` and `<your_name>_short_questions.txt` to `<your_name>_answer.zip`, e.g. `Siu_Ming_Chan_answer.zip` - Reply this email before the deadline and attach the `<your_name>_answer.zip` ## Problems? Feel free to contact us if something is not clear or you encounter any difficulties.