박권수

feat. new DataTable :Bottle -> TakeMedicineHistory / BottleMedicine, API Change, Test

module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
}
};
{
"extends": "eslint:recommended",
"rules": {
// "semi": ["warn", "never"],
"quotes": ["warn", "single"],
"no-console": ["off"],
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
"no-constant-condition" : ["off"]
},
"parserOptions": {
"ecmaVersion": 9
},
"env": {
"es6": true,
"node": true,
"browser": true,
"amd": true
},
"globals": {
"$": true,
"require": true,
"process": true
},
"root": true
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ const updateMedicineInfo = require('./src/lib/UpdatingMedicineInfo');
const MqttServer = require('./src/util/MqttServer');
require('dotenv').config();
// eslint-disable-next-line no-undef
const { SERVER_PORT, MONGO_URL } = process.env;
const app = new Koa();
......@@ -21,7 +22,7 @@ Mongoose.connect(MONGO_URL, {
useCreateIndex : true
}).then(() => {
console.log('\x1b[1;32mMongo DB is connected : ', MONGO_URL, '\x1b[0m');
updateMedicineInfo.updateMedicineInfo();
// updateMedicineInfo.updateMedicineInfo();
}).catch(e => {
console.log(e);
})
......
This diff could not be displayed because it is too large.
......@@ -19,5 +19,8 @@
"dependencies": {
"moment": "^2.29.1",
"mqtt": "^4.2.6"
},
"devDependencies": {
"eslint": "^7.32.0"
}
}
......
......@@ -20,7 +20,10 @@ exports.register = async(ctx) => {
userId : Joi.string().email().max(50).required(),
password : Joi.string().required(),
passwordCheck : Joi.string().required(),
})
userNm : Joi.string().required(),
userAge : Joi.number().required(),
contact : Joi.string().required(),
});
const result = schema.validate(ctx.request.body);
if(result.error || password !== passwordCheck) {
......@@ -41,7 +44,6 @@ exports.register = async(ctx) => {
});
await user.setPassword(password);
await user.save();
const profile = new Profile({
userId,
......@@ -50,6 +52,7 @@ exports.register = async(ctx) => {
contact,
});
await user.save();
await profile.save();
ctx.status = 201;
......@@ -68,6 +71,7 @@ exports.doctorRegister = async ctx => {
userId : Joi.string().email().max(50).required(),
password : Joi.string().required(),
passwordCheck : Joi.string().required(),
info : Joi.object().required(),
})
const result = schema.validate(ctx.request.body);
......@@ -90,7 +94,6 @@ exports.doctorRegister = async ctx => {
});
await doctor.setPassword(password);
doctor.save();
const doctorInfo = new DoctorInfo({
doctorId : userId,
......@@ -98,6 +101,8 @@ exports.doctorRegister = async ctx => {
useYn : 'W',
});
doctor.save();
doctorInfo.save();
ctx.status = 201;
......
/* eslint-disable no-undef */
//어플에서 약병 등록 및, 약병에 관한 정보 조회 = 여기서 mqtt통신으로 broker에 데이터를 요청한다.
const Bottle = require('../../models/bottle');
const Hub = require('../../models/hub');
const Medicine = require('../../models/medicine');
const User = require('../../models/user');
const History = require('../../models/history');
const PatientInfo = require('../../models/patientInfo');
const TakeMedicineHist = require('../../models/takeMedicineHistory');
const BottleMedicine = require('../../models/bottleMedicine');
const Feedback = require('../../models/feedback');
const Mqtt = require('../../lib/MqttModule');
const jwt = require('jsonwebtoken');
......@@ -16,7 +20,7 @@ exports.bottleConnect = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -70,7 +74,7 @@ exports.bottleDisconnect = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -102,7 +106,7 @@ exports.bottleDisconnect = async(ctx) => {
};
//약병 정보를 조회 -> 약병에 현재 데이터를 요청한다. message : req
//약병 정보를 조회 -> 약병의 기록을 가져온다. message : req
exports.getBottleInfo = async(ctx) => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
......@@ -111,7 +115,7 @@ exports.getBottleInfo = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -126,41 +130,101 @@ exports.getBottleInfo = async(ctx) => {
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.getHub_UserId() !== userId || user.userTypeCd !== 'DOCTOR') {
if(hub.userId !== userId) {
ctx.status = 403;
return;
}
if(user.userTypeCd === 'NORMAL') {
const hosting = hub.getHubHost();
//서버에서 bottle로 데이터를 요청한다.
const client = await Mqtt.mqttOn(hosting);
const topic = 'bottle/' + bottleId + '/stb';
const message = 'req';
await Mqtt.mqttPublishMessage(client, { topic, message });
const bottle = await Bottle.findByBottleId(bottleId);
const hosting = hub.getHubHost();
//서버에서 bottle로 데이터를 요청한다.
const client = await Mqtt.mqttOn(hosting);
const topic = 'bottle/' + bottleId + '/stb';
const message = 'req';
await Mqtt.mqttPublishMessage(client, { topic, message });
const bottleMedicine = await BottleMedicine.find({ bottleId })
.sort({ regDtm : 'desc' })
.limit(1);
if(bottleMedicine.length) {
const takeMedicineHist = await TakeMedicineHist
.find({ bmId : bottleMedicine[0]._id })
.sort({ takeDate : 'desc' })
.populate('bmId');
ctx.status = 200;
ctx.body = bottle;
ctx.body = takeMedicineHist;
} else {
ctx.status = 404;
ctx.body = {
error : '정보가 등록되지 않은 약병'
}
}
}
//약병에 대한 피드백의 정보를 가져옴
exports.getBottleFeedback = async ctx => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
ctx.status = 401;
return;
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자'
}
return;
} else if (user.userTypeCd === 'DOCTOR') {
let result = {
bottle,
history : [],
};
}
result.historyList = History.findByBottleId(bottle.bottleId);
const { bottleId } = ctx.params;
ctx.status = 200;
ctx.body = result;
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병'
}
return;
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.userId !== userId) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음'
}
return;
}
}
//약병의 ID를 찾아서 약의 정보를 등록 : Post
const bottleMedicine = await BottleMedicine.find({ bottleId })
.sort({ regDtm : 'desc' })
.limit(1);
if(bottleMedicine.length) {
const feedbackList = await Feedback.find({ bmId : bottleMedicine[0]._id })
.sort({ fdbDtm : 'desc' })
.populate('bmId');
ctx.status = 200;
ctx.body = feedbackList;
} else {
ctx.status = 404;
ctx.body = {
error : '정보가 등록되지 않은 약병',
};
}
};
//약병의 ID를 찾아서 약의 정보와 처방의를 등록 : Post
exports.setMedicine = async(ctx) => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
......@@ -169,42 +233,103 @@ exports.setMedicine = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { bottleId } = ctx.params;
const { medicineId, dosage } = ctx.request.body;
const { medicineId, dosage, doctorId } = ctx.request.body;
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '약병 찾을 수 없음.',
}
return;
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.getHub_UserId() !== userId) {
ctx.status = 403;
ctx.body = {
error : '해당 허브 권한 없음',
}
return;
}
const medicine = await Medicine.findByMedicineId(medicineId);
if(!medicine) {
ctx.status = 404;
ctx.body = {
error : '해당 약 존재하지 않음',
}
return;
}
await Bottle.findOneAndUpdate({
bottleId
}, {
if(doctorId !== undefined && doctorId !== null && doctorId !== '') {
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
if(!patientInfo) {
ctx.status = 403;
ctx.body = {
error : '담당의가 아님',
};
return;
}
}
const bottleMedicine = new BottleMedicine({
bottleId,
medicineId,
dosage : parseInt(dosage)
});
doctorId,
dosage,
});
bottleMedicine.save();
ctx.status = 200;
}
};
// //비어있는 약병에 의사를 등록한다.
// exports.registerDoctorToBottle = async ctx => {
// const token = ctx.req.headers.authorization;
// if(!token || !token.length) {
// ctx.status = 401;
// return;
// }
// const { userId } = jwt.verify(token, process.env.JWT_SECRET);
// const user = await User.findByUserId(userId);
// if(!user || !user.userTypeCd || user.useYn !== 'Y') {
// ctx.status = 403;
// return;
// }
// const { bottleId } = ctx.params;
// const { doctorId } = ctx.request.body;
// const bottle = await Bottle.findByBottleId(bottleId);
// if(!bottle) {
// ctx.status = 404;
// return;
// }
// if(bottle.getDoctorId()) {
// ctx.status = 403;
// return;
// }
// const patinetInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
// if(!patinetInfo) {
// ctx.status = 404;
// return;
// }
// bottle.setDoctorId(doctorId);
// bottle.save();
// ctx.status = 200;
// };
//로그인한 유저의 약병 리스트 가져오기
exports.getBottleList = async(ctx) => {
......@@ -215,7 +340,7 @@ exports.getBottleList = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -243,4 +368,4 @@ exports.getBottleList = async(ctx) => {
ctx.status = 200;
ctx.body = bottleList;
}
\ No newline at end of file
};
\ No newline at end of file
......
......@@ -28,6 +28,14 @@ bottle.delete('/:bottleId', bottleCtrl.bottleDisconnect);
bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
/**
* 약병에 대한 피드백 확인
* request parameter : bottleId
* url : http://localhost:4000/api/bottle/feedback/:bottleId
* return : feedback List
*/
bottle.get('/feedback/:bottleId', bottleCtrl.getBottleFeedback);
/**
* 약병에 약 등록 = 약 검색 후 약 ID(medicineId)와 복용 정보 보고 사용자가 약 복용량(dosage) 입력
* request parameter : medicineId, dosage
* url : http://localhost:4000/api/bottle/:bottleId
......@@ -36,6 +44,14 @@ bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
bottle.patch('/:bottleId', bottleCtrl.setMedicine);
/**
* 비어있는 약병에 전담의 등록
* request parameter : bottleId, doctorId
* url : http://localhost:4000/api/bottle/doctor/:bottleId
* return null;
*/
// bottle.patch('/doctor/:bottleId', bottleCtrl.registerDoctorToBottle);
/**
* 현재 로그인한 유저의 허브 중, 해당 허브에 등록된 약병 리스트를 가져옴
* request parameter : x
* url : http://localhost:4000/api/bottle/hub/:hubId
......
......@@ -3,7 +3,8 @@ const User = require('../../models/user');
const Profile = require('../../models/profile');
const Bottle = require('../../models/bottle');
const Medicine = require('../../models/medicine');
const History = require('../../models/history');
const BottleMedicine = require('../../models/bottleMedicine');
const TakeMedicineHist = require('../../models/takeMedicineHistory');
const Feedback = require('../../models/feedback');
const Hub = require('../../models/hub');
const PatientInfo = require('../../models/patientInfo');
......@@ -21,19 +22,21 @@ exports.getPatientList = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const managePatientIdList = await PatientInfo.findAllByDoctorId(userId);
const managePatientIdList = await PatientInfo.findAllByDoctorIdAndUseYn(userId, 'Y');
const result = managePatientIdList.map(async patientId => {
const patient = await User.findByUserId(patientId);
return patient;
});
const result = [];
await Promise.all(managePatientIdList.map(async patient => {
const patientProfile = await Profile.findByUserId(patient.patientId);
result.push(patientProfile);
}));
ctx.status = 200;
ctx.body = result;
......@@ -52,21 +55,22 @@ exports.getPatientDetail = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { patientId } = ctx.params;
const { patientId } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!isDoctorsPatient) {
ctx.status = 403;
return;
......@@ -78,12 +82,12 @@ exports.getPatientDetail = async ctx => {
const reqUserHubList = await Hub.findAllByUserId(patientId);
const reqUserBottleList = [];
await Promise.all(reqUserHubList.map(async hub => {
const bottleList = await Bottle.findAllByHubId(hub.hubId);
const bottleList = await Bottle.findAllByHubId(hub.hubId, userId);
reqUserBottleList.push(...bottleList);
}));
const result = {
...profile,
profile,
info : isDoctorsPatient.getInfo(),
bottleList : reqUserBottleList,
};
......@@ -105,10 +109,14 @@ exports.getBottleDetail = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자',
}
return;
}
......@@ -116,29 +124,29 @@ exports.getBottleDetail = async ctx => {
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병',
}
return;
}
if(bottle.getDoctorId() !== userId) {
const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId });
if(!bottleMedicine) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음',
}
return;
}
//약병에 들어있는 약 정보와 복용 내역을 가져온다.
const bottleInfo = {
temperature : bottle.temperature,
humidity : bottle.humidity,
dosage : bottle.dosage,
balance : bottle.balance,
};
const medicine = await Medicine.findByMedicineId(bottle.getMedicineId());
const takeHistory = await History.findByBottleIdAndMedicineId(bottleId, bottle.getMedicineId());
const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
const takeMedicineHist = await TakeMedicineHist.find({
bmId : bottleMedicine._id,
}).sort({ takeDate : 'desc' });
const result = {
bottleInfo,
medicine,
takeHistory,
takeMedicineHist,
};
ctx.status = 200;
......@@ -158,21 +166,22 @@ exports.writeReqPatientReport = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { reqUserId, info } = ctx.request.body;
const patient = await User.findByUserId(reqUserId);
const { patientId, info } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(reqUserId, userId);
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!patientInfo) {
ctx.status = 404;
return;
......@@ -197,10 +206,14 @@ exports.writeReqBottleFeedback = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자',
}
return;
}
......@@ -208,17 +221,27 @@ exports.writeReqBottleFeedback = async ctx => {
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병'
}
return;
}
if(bottle.getDoctorId() !== userId) {
const bottleMedicine = await BottleMedicine.find({ bottleId, doctorId : userId })
.sort({ regDtm : 'desc' })
.limit(1);
if(!bottleMedicine.length) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음'
}
return;
}
const newFeedback = new Feedback({
fdbDtm : new Date(),
fdbType,
bottleId,
bmId : bottleMedicine[0]._id,
doctorId : userId,
feedback,
});
......@@ -240,27 +263,35 @@ exports.registerNewPatient = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR') {
ctx.status = 403;
return;
}
const { reqUserId } = ctx.request.body;
const patient = await User.findByUserId(reqUserId);
const { patientId } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const isExistPatientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
if(isExistPatientInfo) {
ctx.status = 403;
return;
}
const patientInfo = new PatientInfo({
patientId : reqUserId,
patientId,
doctorId : userId,
info : '',
useYn : 'W',
});
patientInfo.updateInfo('환자 등록');
patientInfo.updateInfo('환자 등록 요청');
patientInfo.save();
ctx.status = 200;
......@@ -279,8 +310,9 @@ exports.removeReqPatient = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR') {
ctx.status = 403;
return;
......@@ -293,16 +325,14 @@ exports.removeReqPatient = async ctx => {
return;
}
const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!patientInfo) {
ctx.status = 404;
return;
}
await PatientInfo.deleteOne({
patientId,
doctorId : userId,
});
await patientInfo.setUseYn('N')
patientInfo.save();
ctx.status = 200;
......
......@@ -17,7 +17,7 @@ doctor.get('/patient', doctorCtrl.getPatientList);
* url : http://localhost:4000/doctor/patient/:patientId
* return : patient Detail
*/
doctor.get('/patient/:patientId', doctorCtrl.getPatientDetail);
doctor.get('/patient/detail', doctorCtrl.getPatientDetail);
/**
* 현재 로그인한 유저(의사)의 관리 약병 상세 정보를 가져옴
......@@ -37,7 +37,7 @@ doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail);
doctor.patch('/patient', doctorCtrl.writeReqPatientReport);
/**
* 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 기록함
* 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 등록함.
* request parameter : bottleId, fdbType, feedback
* url : http://localhost:4000/doctor/bottle
* return : null
......
......@@ -12,8 +12,9 @@ exports.hubConnect = async (ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -53,8 +54,9 @@ exports.getHubList = async(ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -77,8 +79,9 @@ exports.hubDisconnect = async(ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......
const Router = require('koa-router')
const auth = require('./auth')
const user = require('./user')
const bottle = require('./bottle')
const hub = require('./hub')
const medicine = require('./medicine')
const Router = require('koa-router');
const auth = require('./auth');
const user = require('./user');
const bottle = require('./bottle');
const hub = require('./hub');
const medicine = require('./medicine');
const doctor = require('./doctor');
const manage = require('./manage');
const api = new Router();
api.use('/auth', auth.routes())
api.use('/user', user.routes())
api.use('/bottle', bottle.routes())
api.use('/hub', hub.routes())
api.use('/medicine', medicine.routes())
api.use('/auth', auth.routes());
api.use('/user', user.routes());
api.use('/bottle', bottle.routes());
api.use('/hub', hub.routes());
api.use('/medicine', medicine.routes());
api.use('/doctor', doctor.routes());
api.use('/manage', manage.routes());
module.exports = api;
\ No newline at end of file
......
const Router = require('koa-router');
const manage = new Router();
module.exports = manage;
\ No newline at end of file
......@@ -8,23 +8,9 @@ exports.medicineSearch = async(ctx) => {
return;
}
const { name, company, target } = ctx.request.body;
const { keyword } = ctx.request.body;
let result = [];
if (name && name !== '' && name !== undefined)
result = await medicineSearch_ByName(name);
else if (company && company !== '' && company !== undefined)
result = await medicineSearch_ByCompany(company);
else if (target && target !== '' && target !== undefined)
result = await medicineSearch_ByTarget(target);
if(!result.length) {
ctx.status = 404;
return;
}
const result = await Medicine.findByKeyword(keyword);
ctx.status = 200;
ctx.body = result;
......@@ -47,22 +33,4 @@ exports.medicineGet = async(ctx) => {
ctx.status = 200;
ctx.body = medicine;
}
//이름으로 약 검색
const medicineSearch_ByName = async(name) => {
const result = await Medicine.findByName(name);
return result;
}
//제조사명으로 약 검색
const medicineSearch_ByCompany = async(company) => {
const result = await Medicine.findByCompany(company);
return result;
}
//타겟 병명으로 약 검색
const medicineSearch_ByTarget = async(target) => {
const result = await Medicine.findByTarget(target);
return result;
}
\ No newline at end of file
......
......@@ -11,4 +11,22 @@ const user = new Router();
*/
user.get('/', userCtrl.getMyDetail);
/**
* 유저를 등록하려는 의사의 요청을 전부 보여준다
* request parameter : token,
* url : http://localhost:4000/api/user/doctorrequest
* return : List
*/
user.get('/doctorrequest', userCtrl.viewAllDoctorRegister);
/**
* 유저를 등록하려는 의사의 요청을 수락한다.
* request parameter : token, doctorId,
* url : http://localhost:4000/api/user/doctorrequest/:doctorId
* return : null
*/
user.post('/doctorrequest/accept', userCtrl.acceptDoctorRegister);
module.exports = user;
......
//유저에 관련된 Api
const User = require('../../models/user');
const Profile = require('../../models/profile');
const PatientInfo = require('../../models/patientInfo');
const jwt = require('jsonwebtoken');
/**
* 내 정보를 확인한다.
* @param {*} ctx
* http methods : get
*/
exports.getMyDetail = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
......@@ -12,7 +18,7 @@ exports.getMyDetail = async ctx => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findById(userId)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -25,7 +31,71 @@ exports.getMyDetail = async ctx => {
}
//toDo
/**
* 내 정보를 업데이트한다.
* @param {*} ctx
* http methods : post
*/
exports.updateMyInfo = async ctx => {
}
};
/**
* 의사가 요청한 환자 등록을 확인한다.
* @param {*} ctx
* http methods : get
*/
exports.viewAllDoctorRegister = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
ctx.status = 401
return
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const patientInfoList = await PatientInfo.findAllByPatientIdAndUseYn(userId, 'W');
ctx.status = 200;
ctx.body = patientInfoList;
};
/**
* 의사가 요청한 환자 등록을 수락한다/
* @param {*} ctx
* http methods : post
*/
exports.acceptDoctorRegister = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
ctx.status = 401
return
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { doctorId } = ctx.request.body;
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'W');
if(!patientInfo) {
ctx.status = 404;
return;
}
patientInfo.updateInfo('환자 등록 요청 수락');
patientInfo.setUseYn('Y');
patientInfo.save();
ctx.status = 200;
};
......
const Bottle = require('../models/bottle');
const History = require('../models/history');
const BottleMedicine = require('../models/bottleMedicine');
const TakeMedicineHist = require('../models/takeMedicineHistory');
//message subscribe 후 message를 가공한 이후 해당 데이터를 보낼 topic과 message를 리턴하는 함수
exports.dataPublish = async (topic, message) => {
//client가 subscribe를 하면 메시지를 보낸 약병의 topic과 message를 가공 및 보낸 약병의 bottleId를 가져옴
const data = await factoring(topic, message);
const { bottleId } = data;
//가공된 데이터를 bottleId의 약병에 업데이트
await bottleInfoUpdate(data);
//가공된 데이터를 메시지로 만들어 topic과 message 리턴
const result = await transPublishingTopicAndMessage(bottleId);
const result = await transPublishingTopicAndMessage(data.bottleId);
return result;
......@@ -26,13 +25,11 @@ const factoring = async (topic, message) => {
if(isOpen === '0')
balance = await balanceFactoring(balance);
else balance = '-1';
const openDate = new Date();
return {
bottleId,
isOpen,
openDate,
openDate : new Date(),
temperature,
humidity,
balance
......@@ -66,39 +63,32 @@ const bottleInfoUpdate = async(data) => {
humidity = parseFloat(humidity);
balance = parseInt(balance);
const bottle = await Bottle.findByBottleId(bottleId);
const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
if(bottle) {
if(bottleMedicine) {
if(isOpen) {
const history = new History({
takeDate : new Date(openDate),
bottleId,
medicineId : bottle.getMedicineId(),
const takeMedicineHist = new TakeMedicineHist({
takeDate : openDate,
bmId : bottleMedicine._id,
temperature,
humidity,
balance,
});
history.save();
}
if(balance !== -1) {
await Bottle.findOneAndUpdate({
bottleId
}, { balance })
takeMedicineHist.save();
}
bottle.updateTemperature(temperature);
bottle.updateHumidity(humidity);
bottle.save();
}
}
//해당 MQTT Broker(client)에 bottleId의 정보에 관한 topic과 message를 리턴한다.
const transPublishingTopicAndMessage = async(bottleId) => {
const topic = 'bottle/' + bottleId + '/stb';
const bottle = await Bottle.findByBottleId(bottleId);
const recentOpen = bottle.getRecentOpenDate();
const dosage = bottle.getDosage();
const message = 'res/' + await transDate(recentOpen) + '/' + dosage;
const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
const takeMedicineHist = await TakeMedicineHist.find({
bmId : bottleMedicine._id
}).sort((a, b) => a.takeDate < b.takeDate)[0];
const message = 'res/' + await transDate(takeMedicineHist.takeDate) + '/' + bottleMedicine.dosage;
return {
topic,
......
const mqtt = require('mqtt')
const clientList = []
exports.mqttOn = async (hosting, func) => {
exports.mqttOn = async (hosting, foo) => {
const filterIndex = clientList.findIndex(client => {
return (client.options.clientId === hosting.clientId
&& client.options.host === hosting.host
......@@ -17,7 +17,7 @@ exports.mqttOn = async (hosting, func) => {
})
client.on('message', async (topic, message) => {
const result = await func(topic, message.toString())
const result = await foo(topic, message.toString())
console.log('\x1b[1;32msubscribe : topic', topic, 'message : ', message.toString(), '\x1b[0m')
this.mqttPublishMessage(client, result)
})
......
......@@ -15,7 +15,7 @@ const jwtMiddleware = async (ctx, next) => {
};
const now = Math.floor(Date.now() / 1000);
if (decoded.exp - now < 60 * 60 * 24 * 7) {
const user = await User.findById(decoded._id);
const user = await User.findByUserId(decoded._id);
const token = user.generateToken();
ctx.cookies.set('access_token', token, {
......
......@@ -4,13 +4,7 @@ const Schema = mongoose.Schema;
const BottleSchema = new Schema ({
bottleId : { type : Number, required : true, unique : true },
temperature : { type : Number, default : 0 },
humidity : { type : Number, default : 0 },
balance : { type : Number, default : 0 },
medicineId : { type : Number, },
dosage : { type : Number, default : 0 },
hubId : { type : Number, required : true, },
doctorId : { type : String, default : null, },
hubId : { type : Number, required : true, ref : 'Hub', },
});
BottleSchema.statics.findByBottleId = function(bottleId) {
......@@ -21,56 +15,13 @@ BottleSchema.statics.findAllByHubId = function(hubId) {
return this.find({ hubId });
};
BottleSchema.statics.findAllByDoctorId = function(doctorId) {
return this.find({ doctorId });
}
BottleSchema.methods.getBottleId = function() {
return this.bottleId;
};
BottleSchema.methods.getTemperature = function() {
return this.temperature;
};
BottleSchema.methods.getHumidity = function() {
return this.humidity;
};
BottleSchema.methods.getBalance = function() {
return this.balance;
};
BottleSchema.methods.getDosage = function() {
return this.dosage;
};
BottleSchema.methods.getMedicineId = function() {
return this.medicineId;
};
BottleSchema.methods.getHubId = function() {
return this.hubId;
};
BottleSchema.methods.getDoctorId = function() {
return this.doctorId;
};
BottleSchema.methods.setMedicineId = function(medicineId) {
this.medicineId = medicineId;
};
BottleSchema.methods.setDosage = function(dosage) {
this.dosage = dosage;
};
BottleSchema.methods.updateTemperature = function (temperature) {
this.temperature = temperature;
};
BottleSchema.methods.updateHumidity = function (humidity) {
this.humidity = humidity;
};
module.exports = mongoose.model('Bottle', BottleSchema);
\ No newline at end of file
......
......@@ -2,31 +2,33 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const TakeMedicineHistorySchema = new Schema ({
takeDate : {
type : Date,
const BottleMedicineSchema = new Schema({
bottleId : {
type : Number,
ref : 'Bottle',
required : true,
default : Date.now,
},
medicineId : {
type : Number,
ref : 'Medicine',
required : true,
},
doctorId : {
type : String,
ref : 'User',
required : true,
},
bottleId : {
dosage : {
type : Number,
ref : 'Bottle',
required : true,
default : 0,
},
regDtm : {
type : Date,
required : true,
default : Date.now,
}
});
TakeMedicineHistorySchema.statics.findByBottleId = async function(bottleId) {
return this.find({ bottleId });
};
TakeMedicineHistorySchema.statics.findByBottleIdAndMedicineId = async function(bottleId, medicineId) {
return this.find({ bottleId, medicineId });
};
module.export = mongoose.model("TakeMedicineHist", TakeMedicineHistorySchema);
\ No newline at end of file
module.exports = mongoose.model('BottleMedicine', BottleMedicineSchema);
\ No newline at end of file
......
......@@ -7,7 +7,7 @@ const DoctorInfoSchema = new Schema({
info : {
doctorLicense : { type : String, required : true, },
hospitalNm : { type : String, default : null, },
hosptialAddr : { type : String, default : null, },
hospitalAddr : { type : String, default : null, },
contact : { type : String, required : true, },
},
useYn : { type : String, default : 'W', required : true, },
......
......@@ -5,8 +5,12 @@ const Schema = mongoose.Schema;
const FeedbackSchema = new Schema({
fdbDtm : { type : Date, default : Date.now, required : true, },
fdbType : { type : String, required : true, },
bottleId : { type : Number, required : true, },
doctorId : { type : String, required : true, },
bmId : {
type : Schema.Types.ObjectId,
required : true,
ref : 'BottleMedicine',
},
doctorId : { type : String, required : true, ref : 'User', },
feedback : { type : String, required : true, },
});
......
......@@ -12,31 +12,14 @@ const MedicineSchema = new Schema ({
antiEffect : { type : String, required : true }
})
MedicineSchema.statics.findByName = async function(name) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.name.includes(name)
});
return result;
};
MedicineSchema.statics.findByCompany = async function(company) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.company.includes(company)
});
return result;
};
MedicineSchema.statics.findByTarget = async function(target) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.target.includes(target)
});
return result;
MedicineSchema.statics.findByKeyword = function(keyword) {
return this.find({
$or : [
{ name : { $regex : keyword }},
{ company : { $regex : keyword }},
{ target : { $regex : keyword }},
]
})
};
MedicineSchema.statics.findByMedicineId = function(medicineId) {
......
......@@ -4,27 +4,36 @@ const moment = require('moment');
const Schema = mongoose.Schema;
const PatientInfoSchema = new Schema({
patientId : { type : String, required : true, },
doctorId : { type : String, required : true, },
patientId : { type : String, required : true, ref : 'User', },
doctorId : { type : String, required : true, ref : 'User', },
info : { type : String, required : true, },
useYn : { type : String, required : true, default : 'W', },
});
PatientInfoSchema.statics.findAllByPatientId = function(patientId) {
return this.find({ patientId });
PatientInfoSchema.statics.findAllByPatientIdAndUseYn = function(patientId, useYn) {
return this.find({ patientId, useYn });
};
PatientInfoSchema.statics.findAllByDoctorId = function(doctorId) {
return this.find({ doctorId });
PatientInfoSchema.statics.findAllByDoctorIdAndUseYn = function(doctorId, useYn) {
return this.find({ doctorId, useYn });
};
PatientInfoSchema.statics.findByPatientIdAndDoctorId = function(patientId, doctorId) {
return this.findOne({ patientId, doctorId });
};
PatientInfoSchema.statics.findByPatientIdAndDoctorIdAndUseYn = function(patientId, doctorId, useYn) {
return this.findOne({ patientId, doctorId, useYn });
};
PatientInfoSchema.methods.getInfo = function() {
return this.info;
};
PatientInfoSchema.methods.setUseYn = function(useYn) {
this.useYn = useYn;
};
PatientInfoSchema.methods.updateInfo = function(info) {
const date = moment(new Date()).format('YYYY-MM-DD hh:mm');
if(this.info.length)
......
......@@ -3,7 +3,7 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProfileSchema = new Schema({
userId : { type : String, required : true, },
userId : { type : String, required : true, ref : 'User', },
userNm : { type : String, required : true, },
userAge : { type : Number, required : true, },
contact : { type : String, required : true, },
......
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const TakeMedicineHistorySchema = new Schema ({
takeDate : {
type : Date,
required : true,
default : Date.now,
},
bmId : {
type : Schema.Types.ObjectId,
ref : 'BottleMedicine',
required : true,
},
temperature : { type : Number, default : 0 },
humidity : { type : Number, default : 0 },
balance : { type : Number, default : 0 },
});
module.exports = mongoose.model('TakeMedicineHist', TakeMedicineHistorySchema);
\ No newline at end of file
......@@ -5,7 +5,7 @@ const jwt = require('jsonwebtoken');
const Schema = mongoose.Schema;
const UserSchema = new Schema ({
userId : { type: String, required : true, unique : true, lowercase : true },
userId : { type: String, required : true, unique : true, lowercase : true, },
hashedPassword : { type : String, required : true },
userTypeCd : { type : String, required : true, default : 'NORMAL' },
useYn : { type : String, default : 'W', required : true, },
......@@ -39,6 +39,7 @@ UserSchema.methods.generateToken = function() {
_id : this._id,
userId : this.userId
},
// eslint-disable-next-line no-undef
process.env.JWT_SECRET,
{ expiresIn : '30d' }
);
......
This diff is collapsed. Click to expand it.