You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2955 lines
95 KiB
2955 lines
95 KiB
const userController = require("./controllers/userController");
|
|
const { User,Counter, generateBookingId,resetCounter,generateCustomerId,ProfilePicture} = require('./models/User')
|
|
|
|
//const tanksController = require("./controllers/tanksController");
|
|
const tankersController = require("./controllers/tankersController.js");
|
|
const createConnectionController = require("./controllers/createConnectionController");
|
|
const storeController = require("./controllers/storeController.js")
|
|
const boom = require("boom");
|
|
const bcrypt = require('bcrypt');
|
|
const { ProfilePictureStore,generateinstallationId,Store, Survey, PlumbingWorkPictures, ElectrictyWorkPictures, MaterialRecievedPictures, Support, ManualTestVideo, ProfilePictureInstallTeamMember} = require("./models/store");
|
|
const cors = require('fastify-cors');
|
|
|
|
|
|
//const cors = require("cors");
|
|
const swagger = require("./config/swagger");
|
|
const rawBody = require('raw-body')
|
|
const uuidv4 = require("uuid").v4;
|
|
const fastify = require("fastify")({
|
|
logger: true,
|
|
//disableRequestLogging: true,
|
|
genReqId(req) {
|
|
// you get access to the req here if you need it - must be a synchronous function
|
|
return uuidv4();
|
|
},
|
|
});
|
|
|
|
// const Fastify = require("fastify");
|
|
|
|
fastify.register(cors, {
|
|
origin: 'http://armintaaqua.com:3000', // Allow only your frontend URL
|
|
methods: ['GET', 'POST', 'PUT', 'DELETE'], // Allowed HTTP methods
|
|
allowedContentTypes: ['application/json', 'multipart/form-data'],
|
|
});
|
|
|
|
|
|
// const Fastify = require("fastify");
|
|
// const server = Fastify({
|
|
// logger: true,
|
|
// // ajv: { plugins: [ajvPlugin] },
|
|
// genReqId(req) {
|
|
// // you get access to the req here if you need it - must be a synchronous function
|
|
// return uuidv4();
|
|
// },
|
|
// });
|
|
|
|
// fastify.register(View).ready((err) => {
|
|
// if (err) console.error(err);
|
|
|
|
// console.log(fastify.config.PORT); // or fastify[options.confKey]
|
|
// // output: { PORT: 3000 }
|
|
// engine: {
|
|
// ejs: require('ejs'),
|
|
// },
|
|
// root: join(__dirname, 'views/html'),
|
|
// });
|
|
|
|
|
|
const now = () => Date.now();
|
|
|
|
const fastifyEnv = require("fastify-env");
|
|
|
|
const schema = {
|
|
type: "object",
|
|
required: ["PORT"],
|
|
properties: {
|
|
PORT: {
|
|
type: "string",
|
|
default: 3000,
|
|
},
|
|
APIVERSION: {
|
|
type: "string",
|
|
default: "1.0.0",
|
|
},
|
|
},
|
|
};
|
|
|
|
const options = {
|
|
confKey: "config", // optional, default: 'config'
|
|
schema: schema,
|
|
// data: data // optional, default: process.env
|
|
};
|
|
fastify.register(fastifyEnv, options).ready((err) => {
|
|
if (err) console.error(err);
|
|
|
|
console.log(fastify.config.PORT); // or fastify[options.confKey]
|
|
// output: { PORT: 3000 }
|
|
fastify.decorate("conf", {
|
|
port: fastify.config.PORT,
|
|
APIVERSION: fastify.config.APIVERSION,
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const apiversion = "1.0.0";
|
|
const path = require("path");
|
|
|
|
// Using static content for swagger documentation. Generated swagger UI is not user friendly.
|
|
|
|
fastify.register(require("fastify-static"), {
|
|
root: path.join(__dirname, "api-docs"),
|
|
prefix: "/api-docs", // optional: default '/'
|
|
});
|
|
|
|
|
|
|
|
fastify.register(require("fastify-swagger"), swagger.options);
|
|
|
|
const customJwtAuth = require("./customAuthJwt");
|
|
fastify.register(customJwtAuth);
|
|
//login route - accept user credentials and send a token with role . "user" role is required to use the app.
|
|
|
|
// support login using application/x-www-form-urlencoded so users can login via a web form in addition to api
|
|
|
|
// fastify.register(require("fastify-formbody"));
|
|
// fastify.register(require('fastify-multipart'))
|
|
// fastify.register(require("fastify-cors"), {
|
|
// // put your options here
|
|
// origin: [
|
|
// new RegExp("http://localhost"),
|
|
// new RegExp("http://simply-backoffice.true2air.com"),
|
|
// new RegExp("http://localhost:3000"),
|
|
// ],
|
|
// credentials: true,
|
|
// optionsSuccessStatus: 200,
|
|
// });
|
|
|
|
fastify.register((fastify, opts, done) => {
|
|
fastify.addContentTypeParser(
|
|
"application/json",
|
|
{ parseAs: "buffer" },
|
|
function (_req, body, done) {
|
|
try {
|
|
done(null, body)
|
|
} catch (error) {
|
|
error.statusCode = 400
|
|
done(error, undefined)
|
|
}
|
|
}
|
|
)
|
|
|
|
done(null)
|
|
})
|
|
|
|
|
|
|
|
|
|
fastify.register(require('point-of-view'), {
|
|
engine: {
|
|
nunjucks: require('nunjucks')
|
|
},
|
|
root: path.join(__dirname, "views"),
|
|
includeViewExtension: true,
|
|
|
|
});
|
|
|
|
// * This is for login user as a simply user *
|
|
|
|
fastify.post("/api/login", {
|
|
schema: {
|
|
description: "This is for Login User",
|
|
tags: ["Login"],
|
|
summary: "This is for User Login",
|
|
body: {
|
|
type: "object",
|
|
required: ["phone", "password"],
|
|
properties: {
|
|
phone: { type: "string" },
|
|
password: { type: "string" },
|
|
fcmIds: { type: "array", items: { type: "string" }, default: [] },
|
|
deviceId: { type: "string" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
const { phone, password, fcmIds, deviceId } = req.body;
|
|
console.log(password, phone);
|
|
|
|
const loginObject = await userController.loginUser(req, fcmIds, deviceId);
|
|
console.log("loginObject",loginObject)
|
|
if (!loginObject.same) {
|
|
return reply.send({
|
|
simplydata: {
|
|
error: true,
|
|
code: 400,
|
|
message: "Invalid UserId or Password supplied",
|
|
},
|
|
});
|
|
}
|
|
|
|
const user = loginObject.user;
|
|
const phoneVerified = user.phoneVerified;
|
|
const oneTimePasswordSetFlag = user.oneTimePasswordSetFlag;
|
|
|
|
if (fcmIds.length > 0) {
|
|
await User.updateOne(
|
|
{ customerId: user.customerId },
|
|
{ $addToSet: { fcmIds: { $each: fcmIds } } }
|
|
);
|
|
}
|
|
|
|
if (!phoneVerified) {
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
phoneVerified: false,
|
|
phone: loginObject.isStaff ? loginObject.staffMember.phone : user.phone,
|
|
oneTimePasswordSetFlag,
|
|
message: "Please Verify your phone number",
|
|
},
|
|
});
|
|
}
|
|
|
|
// if (oneTimePasswordSetFlag) {
|
|
// return reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// phoneVerified,
|
|
// phone: loginObject.isStaff ? loginObject.staffMember.phone : user.phone,
|
|
// oneTimePasswordSetFlag: true,
|
|
// message: "Password must be reset",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
const tokenPayload = {
|
|
username: loginObject.isStaff ? loginObject.staffMember.name : user.username,
|
|
userId: user._id,
|
|
roles: user.profile.role,
|
|
};
|
|
|
|
const token = fastify.jwt.sign(tokenPayload, { expiresIn: "30d" });
|
|
|
|
const profilePicture = await ProfilePicture.findOne({ customerId: user.customerId });
|
|
const responsePayload = {
|
|
simplydata: {
|
|
error: false,
|
|
apiversion: fastify.config.APIVERSION,
|
|
access_token: token,
|
|
buildingName: user.buildingName,
|
|
email: user.emails,
|
|
phone: loginObject.isStaff ? loginObject.staffMember.phone : user.phone,
|
|
customerId: user.customerId,
|
|
username: loginObject.isStaff ? loginObject.staffMember.name : user.username,
|
|
address1: user.profile.address1,
|
|
address2: user.profile.address2,
|
|
phoneVerified: user.phoneVerified,
|
|
oneTimePasswordSetFlag: user.oneTimePasswordSetFlag,
|
|
latitude: user.latitude,
|
|
longitude: user.longitude,
|
|
type: user.profile.role,
|
|
loginType: loginObject.isStaff ? "staff" : "user",
|
|
},
|
|
};
|
|
|
|
if (loginObject.isStaff) {
|
|
let allMotorAccess = loginObject.staffMember.all_motor_access;
|
|
|
|
// Normalize the value if it matches the given variations
|
|
if (["view", "view only", "View", "View Only"].includes(allMotorAccess)) {
|
|
allMotorAccess = "view";
|
|
}
|
|
|
|
responsePayload.simplydata.all_motor_access = allMotorAccess;
|
|
}
|
|
|
|
if (profilePicture) {
|
|
responsePayload.simplydata.picture = profilePicture.picture;
|
|
}
|
|
|
|
reply.send(responsePayload);
|
|
},
|
|
});
|
|
|
|
|
|
// fastify.post("/api/login", {
|
|
// schema: {
|
|
// description: "This is for Login User",
|
|
// tags: ["Login"],
|
|
// summary: "This is for User Login",
|
|
// body: {
|
|
// type: "object",
|
|
// required: ["phone", "password"],
|
|
// properties: {
|
|
// phone: { type: "string", description: "Registered phone number" },
|
|
// password: { type: "string", description: "Password for authentication" },
|
|
// fcmIds: { type: "array", items: { type: "string" }, default: [] },
|
|
// deviceId: { type: "string" }
|
|
// }
|
|
// }
|
|
// },
|
|
// async handler(req, reply) {
|
|
// try {
|
|
// const { phone, password, fcmIds = [], deviceId } = req.body;
|
|
|
|
// // Find user by phone
|
|
// const user = await User.findOne({ phone });
|
|
// console.log("user",user)
|
|
// if (!user) {
|
|
// return reply.code(400).send({ simplydata: { error: true, message: "User not found" } });
|
|
// }
|
|
|
|
// // Verify password (bcrypt)
|
|
// const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
// if (!isMatch) {
|
|
// return reply.code(400).send({ simplydata: { error: true, message: "Invalid credentials" } });
|
|
// }
|
|
|
|
// // Update FCM Ids if present
|
|
// if (fcmIds.length > 0) {
|
|
// await User.updateOne(
|
|
// { customerId: user.customerId },
|
|
// { $addToSet: { fcmIds: { $each: fcmIds } } }
|
|
// );
|
|
// }
|
|
|
|
// // Phone Verification
|
|
// if (!user.phoneVerified) {
|
|
// return reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// phoneVerified: false,
|
|
// phone: user.phone,
|
|
// oneTimePasswordSetFlag: user.oneTimePasswordSetFlag,
|
|
// message: "Please Verify your phone number"
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
// // Password reset flag
|
|
// if (user.oneTimePasswordSetFlag) {
|
|
// return reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// phoneVerified: user.phoneVerified,
|
|
// phone: user.phone,
|
|
// oneTimePasswordSetFlag: true,
|
|
// message: "Password must be reset"
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
// // JWT Token Payload
|
|
// const tokenPayload = {
|
|
// username: user.username,
|
|
// userId: user._id,
|
|
// roles: user.profile.role
|
|
// };
|
|
|
|
// // JWT Token Generation (matches /api/storelogin style)
|
|
// const token = fastify.jwt.sign(tokenPayload, /* no direct secret here, assumes plugin config */{ expiresIn: "30d" });
|
|
|
|
// // Profile Picture
|
|
// const profilePicture = await ProfilePicture.findOne({ customerId: user.customerId });
|
|
|
|
// // Response Construction
|
|
// const responsePayload = {
|
|
// simplydata: {
|
|
// error: false,
|
|
// message: "Login successful",
|
|
// apiversion: fastify.config ? fastify.config.APIVERSION : undefined,
|
|
// access_token: token,
|
|
// buildingName: user.buildingName,
|
|
// email: user.emails,
|
|
// phone: user.phone,
|
|
// customerId: user.customerId,
|
|
// username: user.username,
|
|
// address1: user.profile.address1,
|
|
// address2: user.profile.address2,
|
|
// phoneVerified: user.phoneVerified,
|
|
// oneTimePasswordSetFlag: user.oneTimePasswordSetFlag,
|
|
// latitude: user.latitude,
|
|
// longitude: user.longitude,
|
|
// type: user.profile.role,
|
|
// loginType: "user"
|
|
// }
|
|
// };
|
|
|
|
// if (profilePicture) {
|
|
// responsePayload.simplydata.picture = profilePicture.picture;
|
|
// }
|
|
|
|
// return reply.send(responsePayload);
|
|
|
|
// } catch (error) {
|
|
// console.error("Login Error:", error);
|
|
// return reply.code(500).send({ simplydata: { error: true, message: "Internal server error" } });
|
|
// }
|
|
// }
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
fastify.post("/api/installotplogin", {
|
|
schema: {
|
|
description: "This is for Login Otp Installation",
|
|
tags: ["Install"],
|
|
summary: "This is for Login Otp Installation",
|
|
body: {
|
|
type: "object",
|
|
required: ["phone", "phoneVerificationCode"],
|
|
properties: {
|
|
phoneVerificationCode: { type: "string" },
|
|
phone: { type: "string" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const phone = req.body.phone;
|
|
const phoneVerificationCode = req.body.phoneVerificationCode;
|
|
|
|
const installationExists = await Install.findOne({
|
|
phone: phone,
|
|
phoneVerificationCode: phoneVerificationCode,
|
|
});
|
|
|
|
if (installationExists) {
|
|
const filter = {
|
|
phone: phone,
|
|
phoneVerificationCode: phoneVerificationCode,
|
|
};
|
|
const update = { phoneVerified: true };
|
|
await Install.findOneAndUpdate(filter, update);
|
|
|
|
const loginObject = await userController.loginUserWithOTP(req);
|
|
|
|
if (loginObject.same) {
|
|
if (loginObject.user) {
|
|
const { user } = loginObject;
|
|
const phoneVerified = user.phoneVerified;
|
|
const oneTimePasswordSetFlag = user.oneTimePasswordSetFlag;
|
|
|
|
if (!phoneVerified) {
|
|
reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
phoneVerified: false,
|
|
phone: user.phone,
|
|
oneTimePasswordSetFlag: oneTimePasswordSetFlag,
|
|
message: "Please Verify your phone number",
|
|
},
|
|
});
|
|
} else if (oneTimePasswordSetFlag) {
|
|
reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
phoneVerified: phoneVerified,
|
|
phone: user.phone,
|
|
oneTimePasswordSetFlag: true,
|
|
message: "Password must be reset",
|
|
},
|
|
});
|
|
} else {
|
|
const token = fastify.jwt.sign(
|
|
{
|
|
firstName: user.firstName,
|
|
},
|
|
{ expiresIn: "30d" }
|
|
);
|
|
|
|
const profilePicture = await ProfilePictureInstall.findOne({
|
|
customerId: user._id,
|
|
});
|
|
console.log(user)
|
|
const responsePayload = {
|
|
simplydata: {
|
|
error: false,
|
|
apiversion: fastify.config.APIVERSION,
|
|
access_token: token,
|
|
email: user.emails,
|
|
installationId: user.installationId,
|
|
phone: user.phone,
|
|
//name: user.name,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
phoneVerified: user.phoneVerified,
|
|
oneTimePasswordSetFlag: user.oneTimePasswordSetFlag,
|
|
type: user.profile.role,
|
|
fcmIds: user.fcmIds,
|
|
team: user.team,
|
|
city: user.city,
|
|
manager: user.manager,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
address: user.address,
|
|
alternativeNumber: user.alternativeNumber,
|
|
},
|
|
};
|
|
|
|
if (profilePicture) {
|
|
responsePayload.simplydata.picture = profilePicture.picture;
|
|
}
|
|
|
|
reply.send(responsePayload);
|
|
}
|
|
} else {
|
|
reply.send({
|
|
simplydata: {
|
|
error: true,
|
|
code: 400,
|
|
message: "Invalid Details",
|
|
},
|
|
});
|
|
}
|
|
} else {
|
|
reply.send({
|
|
simplydata: {
|
|
error: true,
|
|
code: 400,
|
|
message: "Invalid phone or phoneVerificationCode supplied",
|
|
},
|
|
});
|
|
}
|
|
} else {
|
|
reply.send({
|
|
armintatankdata: {
|
|
error: true,
|
|
code: 10005,
|
|
message: "10005 - Verification code entered cannot be validated.",
|
|
},
|
|
});
|
|
}
|
|
} catch (err) {
|
|
throw boom.boomify(err);
|
|
}
|
|
},
|
|
});
|
|
|
|
|
|
// fastify.post("/api/storelogin", {
|
|
// schema: {
|
|
// description: "This is for Store Login",
|
|
// tags: ["Store-Data"],
|
|
// summary: "This is for Store Login",
|
|
// body: {
|
|
// type: "object",
|
|
// required: ["phone", "password"],
|
|
// properties: {
|
|
// phone: { type: "string" },
|
|
// password: { type: "string" },
|
|
// },
|
|
// },
|
|
// },
|
|
// async handler(request, reply) {
|
|
// try {
|
|
// let store = await Store.findOne({ phone: request.body.phone });
|
|
// if (!store) {
|
|
// return reply.code(400).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// code: 400,
|
|
// message: "Invalid Phone or Password",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// const isMatch = await bcrypt.compare(request.body.password, store.services.password.bcrypt);
|
|
// if (!isMatch) {
|
|
// return reply.code(400).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// code: 400,
|
|
// message: "Invalid Phone or Password",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
|
|
|
|
// const token = fastify.jwt.sign(
|
|
// {
|
|
// storename: store.storename,
|
|
// storeId: store._id,
|
|
// roles: store.profile.role,
|
|
// },
|
|
// { expiresIn: "30d" }
|
|
// );
|
|
|
|
|
|
// var profilePicture = await ProfilePictureStore.findOne({ storeId: store.storeId });
|
|
|
|
// if (!profilePicture) {
|
|
// reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// apiversion: fastify.config.APIVERSION,
|
|
// access_token: token,
|
|
// email: store.emails,
|
|
// phone: store.phone,
|
|
// storeId: store.storeId,
|
|
// storename: store.storename,
|
|
// office_address: store.profile.office_address,
|
|
// phoneVerified: store.phoneVerified,
|
|
// oneTimePasswordSetFlag: store.oneTimePasswordSetFlag,
|
|
// latitude: store.latitude,
|
|
// longitude: store.longitude,
|
|
// description: store.description,
|
|
// type: store.profile.role,
|
|
// typeasobj: JSON.stringify(Object.assign({}, store.profile.role)),
|
|
// },
|
|
// });
|
|
// } else {
|
|
// reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// apiversion: fastify.config.APIVERSION,
|
|
// access_token: token,
|
|
// picture: profilePicture.picture,
|
|
// email: store.emails,
|
|
// phone: store.phone,
|
|
// storeId: store.storeId,
|
|
// storename: store.storename,
|
|
// office_address: store.profile.office_address,
|
|
// phoneVerified: store.phoneVerified,
|
|
// oneTimePasswordSetFlag: store.oneTimePasswordSetFlag,
|
|
// latitude: store.latitude,
|
|
// longitude: store.longitude,
|
|
// description: store.description,
|
|
// type: store.profile.role,
|
|
// typeasobj: JSON.stringify(Object.assign({}, store.profile.role)),
|
|
// },
|
|
// });
|
|
// }
|
|
// } catch (err) {
|
|
// throw boom.boomify(err);
|
|
// }
|
|
// },
|
|
// });
|
|
|
|
fastify.get("/api/reset_token/:customerId", {
|
|
|
|
schema: {
|
|
description: "This is for Reset Token",
|
|
tags: ["Login"],
|
|
summary: "This is for Reset Token",
|
|
params: {
|
|
type: "object",
|
|
properties: {
|
|
customerId: {
|
|
type: "string",
|
|
description: "customerId",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
async handler(req, reply) {
|
|
try {
|
|
const customerId = req.params.customerId
|
|
const get_user = await userController.getSingleUser(req);
|
|
const token = fastify.jwt.sign(
|
|
{
|
|
customerId: get_user.customerId,
|
|
userId: get_user._id,
|
|
roles: get_user.profile.role,
|
|
},
|
|
{ expiresIn: "30d" }
|
|
);
|
|
|
|
reply.send({ access_token: token, customerId: get_user.customerId });
|
|
} catch (err) {
|
|
console.log(err);
|
|
error = {
|
|
simplydata: {
|
|
error: true,
|
|
code: 400,
|
|
message: "Reset Token failed",
|
|
},
|
|
};
|
|
reply.status(401).send(error);
|
|
}
|
|
},
|
|
});
|
|
|
|
|
|
|
|
fastify.get('/testtemp', (req, reply) => {
|
|
reply.view('layouts/main', {});
|
|
});
|
|
|
|
// const multipart = require('fastify-multipart');
|
|
|
|
// fastify.register(multipart);
|
|
//fastify-auth plugin is required so we can define routes in seperate files and verify jwt supplied in preHandlers for each request.
|
|
//const multer = require("fastify-multer");
|
|
fastify.register(require("fastify-auth"));
|
|
const dbConnection = require("./config/config");
|
|
fastify.register(dbConnection);
|
|
//fastify.register(multer.contentParser);
|
|
const { Schema } = require("mongoose");
|
|
// fastify.register(dbConnection);
|
|
|
|
fastify.register(require("./routes/usersRoute"));
|
|
|
|
fastify.register(require("./routes/tanksRoute"));
|
|
fastify.register(require("./routes/createConnectionsRoute"));
|
|
fastify.register(require("./routes/tankersRoute.js"));
|
|
fastify.register(require("./routes/supplierRoute"));
|
|
fastify.register(require("./routes/supplierOrdersRoutes"));
|
|
fastify.register(require("./routes/friendRequestRoute"));
|
|
fastify.register(require("./routes/adminRoute"));
|
|
fastify.register(require("./routes/storeRoute"));
|
|
fastify.register(require("./routes/departmentRoute.js"));
|
|
fastify.register(require("./routes/installationRoute.js"));
|
|
|
|
|
|
|
|
// Testing route allows for retrieving a user by phone so one can see what is the phone verification code sent for a given user's phone
|
|
// Also allows deletion of a user with a given phone number
|
|
fastify.register(require("./routes/forTestingRoute"));
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const {Storage} = require('@google-cloud/storage');
|
|
const { Supplier, profilePictureSupplier } = require("./models/supplier");
|
|
//const multer = require('fastify-multer');
|
|
//const fastifyMulter = require('fastify-multer');
|
|
//const upload = fastifyMulter.single('file');
|
|
//fastify.register(fastifyMulter.contentParser);
|
|
const multer = require('multer');
|
|
//const upload = multer({ dest: 'uploads/' });
|
|
const { ProfilePictureInstall, Install } = require("./models/store.js");
|
|
const { TeamMemberProfilePicture, CompanyProfilePicture, Deparments, IndianLocations } = require("./models/Department.js");
|
|
fastify.register(require('fastify-formbody'));
|
|
// fastify.register(multer.contentParser);
|
|
// const multipart = require('fastify-multipart');
|
|
|
|
fastify.addContentTypeParser('multipart/form-data', (request, payload, done) => {
|
|
done(null, payload);
|
|
});
|
|
//const multipart = require('@fastify/multipart');
|
|
|
|
// fastify.register(multipart, {
|
|
// limits: {
|
|
// fileSize: 10 * 1024 * 1024, // 10 MB
|
|
// },
|
|
// attachFieldsToBody: true,
|
|
// });
|
|
// fastify.register(multipart);
|
|
// const fastifyMultipart = require('@fastify/multipart');
|
|
|
|
// fastify.register(fastifyMultipart, {
|
|
// limits: {
|
|
// fieldNameSize: 100,
|
|
// fieldSize: 1000000,
|
|
// fields: 10,
|
|
// fileSize: 1000000,
|
|
// files: 10,
|
|
// headerPairs: 2000
|
|
// }
|
|
// });
|
|
|
|
const formbody = require('@fastify/formbody');
|
|
|
|
fastify.register(formbody);
|
|
|
|
|
|
// const multipart = require("@fastify/multipart");
|
|
|
|
// // register multipart
|
|
// fastify.register(require("@fastify/multipart"), {
|
|
// limits: {
|
|
// fileSize: 10 * 1024 * 1024, // 10 MB
|
|
// },
|
|
// attachFieldsToBody: true,
|
|
// });
|
|
const gc = new Storage({
|
|
keyFilename : path.join(__dirname, "../src/arminta-tank-keyFile.json"),
|
|
projectId : 'arminta-tank'
|
|
})
|
|
|
|
const storage = new Storage({
|
|
keyFilename : path.join(__dirname, "../src/arminta-tank-keyFile.json"),
|
|
projectId : 'arminta-tank'
|
|
});
|
|
// console.log(storage)
|
|
// const cloudinary = require('cloudinary').v2;
|
|
// const FormData = require('form-data');
|
|
// const mv = require('mv');
|
|
|
|
// cloudinary.config({
|
|
// cloud_name: 'dalqpseol',
|
|
// api_key: '121595628244491',
|
|
// api_secret: 'jnuny_0fMYovQS0eyvIVXQTl4RY'
|
|
// });
|
|
|
|
// Register fastify-file-upload plugin
|
|
//fastify.register(require('fastify-multipart'));
|
|
|
|
// fastify.register(require("@fastify/multipart"), {
|
|
// attachFieldsToBody: true,
|
|
// });
|
|
|
|
// fastify.post('/upload', async (request, reply) => {
|
|
// try {
|
|
// const data = await request.file();
|
|
|
|
// // Generate a unique file name
|
|
// const fileName = `${data.filename}`;
|
|
|
|
// const filePath = `${fileName}`;
|
|
|
|
// // Move the file to a temporary location
|
|
// const writeStream = fs.createWriteStream(filePath);
|
|
// data.file.pipe(writeStream);
|
|
|
|
// writeStream.on('close', () => {
|
|
// // Upload the image to Cloudinary
|
|
// cloudinary.uploader.upload(filePath, (error, result) => {
|
|
// if (error) {
|
|
// reply.code(500).send({ error: 'Failed to upload file to Cloudinary' });
|
|
// } else {
|
|
// // Get the public URL of the uploaded image
|
|
// const publicUrl = result.secure_url;
|
|
|
|
// // Remove the temporary file
|
|
// fs.unlinkSync(filePath);
|
|
|
|
// // Return the public URL
|
|
// reply.send({ url: publicUrl });
|
|
// }
|
|
// });
|
|
// });
|
|
|
|
// writeStream.on('error', (err) => {
|
|
// reply.code(500).send({ error: 'Failed to move file' });
|
|
// });
|
|
// } catch (err) {
|
|
// reply.code(500).send({ error: 'An error occurred' });
|
|
// }
|
|
// });
|
|
|
|
|
|
// fastify.post('/upload/:supplierId', async (request, reply) => {
|
|
// try {
|
|
// const supplierId = request.params.supplierId;
|
|
// const data = await request.file();
|
|
|
|
// // Generate a unique file name
|
|
// const fileName = `${data.filename}`;
|
|
|
|
// const filePath = `${fileName}`;
|
|
|
|
// // Move the file to a temporary location
|
|
// const writeStream = fs.createWriteStream(filePath);
|
|
// data.file.pipe(writeStream);
|
|
|
|
// writeStream.on('close', () => {
|
|
// // Upload the image to Cloudinary
|
|
// cloudinary.uploader.upload(filePath, (error, result) => {
|
|
// if (error) {
|
|
// reply.code(500).send({ error: 'Failed to upload file to Cloudinary' });
|
|
// } else {
|
|
// // Get the public URL of the uploaded image
|
|
// const publicUrl = result.secure_url;
|
|
|
|
// // Remove the temporary file
|
|
// fs.unlinkSync(filePath);
|
|
|
|
// // Store the URL in the database
|
|
// // Assuming you have a database connection and a ProfilePictureSupplier model
|
|
// profilePictureSupplier.findOneAndUpdate(
|
|
// { supplierId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true },
|
|
// (error, picture) => {
|
|
// if (error) {
|
|
// reply.code(500).send({ error: 'Failed to update database' });
|
|
// } else {
|
|
// // Return the public URL
|
|
// reply.send({ picture: publicUrl });
|
|
// }
|
|
// }
|
|
// );
|
|
// }
|
|
// });
|
|
// });
|
|
|
|
// writeStream.on('error', (err) => {
|
|
// reply.code(500).send({ error: 'Failed to move file' });
|
|
// });
|
|
// } catch (err) {
|
|
// reply.code(500).send({ error: 'An error occurred' });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post('/api/uploads_team_profile/:customerId', async (request, reply) => {
|
|
// try {
|
|
// const customerId = request.params.customerId;
|
|
// const data = await request.file();
|
|
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${data.filename}`;
|
|
|
|
// const file = storage.bucket(bucketName).file(filePath);
|
|
// const writeStream = file.createWriteStream();
|
|
|
|
// data.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on('finish', resolve);
|
|
// writeStream.on('error', reject);
|
|
// });
|
|
|
|
// // Make file public
|
|
// await file.makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // Update DB with async/await
|
|
// const picture = await TeamMemberProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ picture: publicUrl });
|
|
// } catch (err) {
|
|
// console.error(err);
|
|
// reply.code(500).send({ error: 'An error occurred', details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post('/api/uploads_team_profile/:customerId', async (request, reply) => {
|
|
// try {
|
|
// const { customerId } = request.params;
|
|
|
|
// // get uploaded file
|
|
// //const data = await request.file();
|
|
// const data = request.body.file;
|
|
// if (!data) {
|
|
// return reply.code(400).send({ error: 'No file uploaded' });
|
|
// }
|
|
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${data.filename}`;
|
|
|
|
// const file = storage.bucket(bucketName).file(filePath);
|
|
// const writeStream = file.createWriteStream();
|
|
|
|
// data.file.pipe(writeStream);
|
|
// console.log("Logs",request.headers['content-type']);
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on('finish', resolve);
|
|
// writeStream.on('error', reject);
|
|
// });
|
|
|
|
// // make file public
|
|
// await file.makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // save in DB
|
|
// const picture = await TeamMemberProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({ picture: publicUrl });
|
|
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: 'Upload failed', details: err.message });
|
|
// }
|
|
// });
|
|
const fastifyMulter = require('fastify-multer');
|
|
const mime = require("mime-types");
|
|
// const upload = fastifyMulter({
|
|
// dest: 'uploads/',
|
|
// limits: {
|
|
// fieldNameSize: 100,
|
|
// fieldSize: 1000000,
|
|
// fields: 10,
|
|
// fileSize: 1000000000000000,
|
|
// files: 10,
|
|
// headerPairs: 2000
|
|
// }
|
|
// });
|
|
|
|
// fastify.register(upload.contentParser);
|
|
|
|
// fastify.post('/api/uploads_team_profile/:customerId', {
|
|
// preHandler: upload.single('file')
|
|
// }, async (request, reply) => {
|
|
// try {
|
|
// const { customerId } = request.params;
|
|
// const file = await request.file; // Uncomment this line
|
|
// const formData = new FormData();
|
|
// formData.append('file', file);
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${file.originalname}`;
|
|
|
|
// const fileBuffer = await fs.promises.readFile(file.path);
|
|
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// // make file public
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // save in DB
|
|
// const picture = await TeamMemberProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({ picture: publicUrl });
|
|
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: 'Upload failed', details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post('/api/uploads_admin_profile/:customerId', {
|
|
// preHandler: upload.single('file')
|
|
// }, async (request, reply) => {
|
|
// try {
|
|
// const { customerId } = request.params;
|
|
// const file = await request.file; // Uncomment this line
|
|
// const formData = new FormData();
|
|
// formData.append('file', file);
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${file.originalname}`;
|
|
|
|
// const fileBuffer = await fs.promises.readFile(file.path);
|
|
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// // make file public
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // save in DB
|
|
// const picture = await AdminProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({ picture: publicUrl });
|
|
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: 'Upload failed', details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post("/api/uploads_installation_profile/:installationId", {
|
|
// preHandler: upload.single("file"), // your multer/fastify-multipart preHandler
|
|
// }, async (request, reply) => {
|
|
// try {
|
|
// const { installationId } = request.params;
|
|
// const file = request.file; // in fastify-multer this is set by preHandler
|
|
|
|
// if (!file) {
|
|
// return reply.code(400).send({ error: "No file uploaded (expected field name 'file')." });
|
|
// }
|
|
|
|
// // basic file validation
|
|
// const allowed = ["image/jpeg", "image/jpg", "image/png"];
|
|
// if (!allowed.includes(file.mimetype)) {
|
|
// return reply.code(400).send({ error: "Only JPEG/PNG images are allowed." });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const ext = mime.extension(file.mimetype) || (file.originalname.split(".").pop() || "png");
|
|
// const safeBase = path.parse(file.originalname).name.replace(/[^\w.-]/g, "_");
|
|
// const filePath = `arminta_team_profiles/${safeBase}-${Date.now()}.${ext}`;
|
|
|
|
// // read temp file to buffer
|
|
// const fileBuffer = await fs.promises.readFile(file.path);
|
|
|
|
// // upload to GCS
|
|
// const bucket = storage.bucket(bucketName);
|
|
// const gcsFile = bucket.file(filePath);
|
|
// await gcsFile.save(fileBuffer, {
|
|
// resumable: false,
|
|
// contentType: file.mimetype,
|
|
// public: true,
|
|
// metadata: { cacheControl: "public, max-age=31536000" },
|
|
// });
|
|
// await gcsFile.makePublic();
|
|
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // 1) Upsert installation profile picture collection
|
|
// await ProfilePictureInstall.findOneAndUpdate(
|
|
// { installationId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// // 2) Update department doc where departmentId === installationId
|
|
// const deptUpdate = await Deparments.findOneAndUpdate(
|
|
// { departmentId: installationId },
|
|
// { picture: publicUrl },
|
|
// { new: true }
|
|
// );
|
|
|
|
// // 3) (Optional) also save on the installation doc itself if you keep picture there
|
|
// // await Installations.findOneAndUpdate(
|
|
// // { installationId },
|
|
// // { picture: publicUrl },
|
|
// // { new: true }
|
|
// // );
|
|
|
|
// return reply.send({
|
|
// installationId,
|
|
// picture: publicUrl,
|
|
// departmentUpdated: Boolean(deptUpdate),
|
|
// message: deptUpdate
|
|
// ? "Upload successful. Department picture updated."
|
|
// : "Upload successful. No department matched this installationId.",
|
|
// });
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: "Upload failed", details: err.message });
|
|
// } finally {
|
|
// // best effort: clean up temp file if your preHandler writes to disk
|
|
// try { if (request.file?.path) await fs.promises.unlink(request.file.path); } catch {}
|
|
// }
|
|
// });
|
|
|
|
// fastify.post('/api/uploads_installation_profile/:installationId', {
|
|
// preHandler: upload.single('file')
|
|
// }, async (request, reply) => {
|
|
// try {
|
|
// const { installationId } = request.params;
|
|
// const file = await request.file; // Uncomment this line
|
|
// const formData = new FormData();
|
|
// formData.append('file', file);
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${file.originalname}`;
|
|
|
|
// const fileBuffer = await fs.promises.readFile(file.path);
|
|
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// // make file public
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // save in DB
|
|
// const picture = await ProfilePictureInstall.findOneAndUpdate(
|
|
// { installationId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({ picture: publicUrl });
|
|
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: 'Upload failed', details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post('/api/uploads_team_profile/:customerId', async (request, reply) => {
|
|
// try {
|
|
// const { customerId } = request.params;
|
|
|
|
// // get uploaded file
|
|
// const file = await request.multipart();
|
|
// if (!file) {
|
|
// return reply.code(400).send({ error: 'No file uploaded' });
|
|
// }
|
|
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_team_profiles/${file.filename}`;
|
|
|
|
// const fileBuffer = await fs.promises.readFile(file.filepath);
|
|
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// // make file public
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // save in DB
|
|
// const picture = await TeamMemberProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({ picture: publicUrl });
|
|
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: 'Upload failed', details: err.message });
|
|
// }
|
|
// });
|
|
// fastify.post('/api/uploads_company_profile/:customerId', async (request, reply) => {
|
|
// try {
|
|
// const customerId = request.params.customerId;
|
|
// const data = await request.file();
|
|
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_company_profiles/${data.filename}`;
|
|
|
|
// const file = storage.bucket(bucketName).file(filePath);
|
|
// const writeStream = file.createWriteStream();
|
|
|
|
// data.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on('finish', resolve);
|
|
// writeStream.on('error', reject);
|
|
// });
|
|
|
|
// // Make file public
|
|
// await file.makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // Update DB with async/await
|
|
// const picture = await CompanyProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ picture: publicUrl });
|
|
// } catch (err) {
|
|
// console.error(err);
|
|
// reply.code(500).send({ error: 'An error occurred', details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post("/api/uploads_installation_TeamMember_profile/:installationId/:teamMemberId", {
|
|
// preHandler: upload.single("file"),
|
|
// }, async (request, reply) => {
|
|
// try {
|
|
// const { installationId ,teamMemberId} = request.params;
|
|
// //const teamMemberId = request.body?.teamMemberId; // OPTIONAL
|
|
// const file = request.file;
|
|
|
|
// if (!file) {
|
|
// return reply.code(400).send({ error: "No file uploaded (field name 'file')." });
|
|
// }
|
|
|
|
// // Validate image type
|
|
// const allowed = ["image/jpeg", "image/jpg", "image/png"];
|
|
// if (!allowed.includes(file.mimetype)) {
|
|
// return reply.code(400).send({ error: "Only JPEG/PNG images are allowed." });
|
|
// }
|
|
|
|
// // Build GCS path
|
|
// const ext = (mime.extension(file.mimetype) || path.extname(file.originalname).slice(1) || "png").toLowerCase();
|
|
// const safeBase = path.parse(file.originalname).name.replace(/[^\w.-]/g, "_");
|
|
// const filePath = `arminta_team_profiles/${safeBase}-${Date.now()}.${ext}`;
|
|
// const bucketName = "arminta_profile_pictures";
|
|
|
|
// // Upload
|
|
// const buffer = await fs.promises.readFile(file.path);
|
|
// const bucket = storage.bucket(bucketName);
|
|
// const gcsFile = bucket.file(filePath);
|
|
// await gcsFile.save(buffer, {
|
|
// resumable: false,
|
|
// public: true,
|
|
// contentType: file.mimetype,
|
|
// metadata: { cacheControl: "public, max-age=31536000" },
|
|
// });
|
|
// await gcsFile.makePublic();
|
|
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// // Always upsert the installation-level picture doc
|
|
// await ProfilePictureInstallTeamMember.findOneAndUpdate(
|
|
// { installationId, teamMemberId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
|
|
// // Update department picture where departmentId === installationId
|
|
// const deptUpdate = await Deparments.findOneAndUpdate(
|
|
// { departmentId: installationId },
|
|
// { picture: publicUrl },
|
|
// { new: true }
|
|
// );
|
|
|
|
// let teamMemberUpdated = false;
|
|
// if (teamMemberId) {
|
|
// // 1) Upsert team-member picture collection
|
|
// await ProfilePictureInstallTeamMember.findOneAndUpdate(
|
|
// { teamMemberId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// // 2) Update nested item inside Installations.team_member.team_member[]
|
|
// // Using arrayFilters to match the correct team member element
|
|
// const res = await Install.updateOne(
|
|
// { installationId },
|
|
// {
|
|
// $set: {
|
|
// "team_member.team_member.$[tm].picture": publicUrl
|
|
// }
|
|
// },
|
|
// {
|
|
// arrayFilters: [{ "tm.teamMemberId": teamMemberId }]
|
|
// }
|
|
// );
|
|
// teamMemberUpdated = res.modifiedCount > 0;
|
|
// }
|
|
|
|
// return reply.send({
|
|
// installationId,
|
|
// teamMemberId: teamMemberId || null,
|
|
// picture: publicUrl,
|
|
// departmentUpdated: Boolean(deptUpdate),
|
|
// teamMemberUpdated,
|
|
// message: teamMemberId
|
|
// ? (teamMemberUpdated
|
|
// ? "Upload successful. Installation + team member picture updated."
|
|
// : "Upload successful. Team member not found under this installation.")
|
|
// : "Upload successful. Installation picture updated.",
|
|
// });
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply.code(500).send({ error: "Upload failed", details: err.message });
|
|
// } finally {
|
|
// try { if (request.file?.path) await fs.promises.unlink(request.file.path); } catch {}
|
|
// }
|
|
// });
|
|
|
|
fastify.post('/api/uploads/:supplierId', async (request, reply) => {
|
|
try {
|
|
const supplierId = request.params.supplierId;
|
|
const data = await request.file();
|
|
|
|
// Generate a unique file name
|
|
const fileName = `${data.filename}`;
|
|
|
|
// Define the destination bucket and file path
|
|
const bucketName = 'arminta_profile_pictures';
|
|
const filePath = `${fileName}`;
|
|
|
|
// Create a write stream to the destination file in the bucket
|
|
const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// Pipe the file data to the write stream
|
|
data.file.pipe(writeStream);
|
|
|
|
writeStream.on('finish', async () => {
|
|
try {
|
|
// Make the uploaded file publicly accessible
|
|
await storage.bucket(bucketName).file(filePath).makePublic();
|
|
|
|
const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
profilePictureSupplier.findOneAndUpdate(
|
|
{ supplierId },
|
|
{ picture: publicUrl },
|
|
{ new: true, upsert: true },
|
|
(error, picture) => {
|
|
if (error) {
|
|
reply.code(500).send({ error: 'Failed to update database' });
|
|
} else {
|
|
// Return the public URL
|
|
reply.send({ picture: publicUrl });
|
|
}
|
|
}
|
|
);
|
|
} catch (error) {
|
|
reply.code(500).send({ error: 'Failed to make file public' });
|
|
}
|
|
});
|
|
|
|
writeStream.on('error', (err) => {
|
|
reply.code(500).send({ error: 'Failed to move file' });
|
|
});
|
|
} catch (err) {
|
|
reply.code(500).send({ error: 'An error occurred' });
|
|
}
|
|
});
|
|
|
|
|
|
|
|
// fastify.post('/api/uploads-user/:customerId', async (request, reply) => {
|
|
// try {
|
|
// const customerId = request.params.customerId;
|
|
// const data = await request.file();
|
|
|
|
// // Generate a unique file name
|
|
|
|
// const fileName = `${data.filename}`;
|
|
|
|
|
|
// // Define the destination bucket and file path
|
|
// const bucketName = 'arminta_profile_pictures';
|
|
// const filePath = `arminta_user_profiles/${fileName}`;
|
|
|
|
// // Create a write stream to the destination file in the bucket
|
|
// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// // Pipe the file data to the write stream
|
|
// data.file.pipe(writeStream);
|
|
|
|
// writeStream.on('finish', async () => {
|
|
// try {
|
|
// // Make the uploaded file publicly accessible
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
// ProfilePicture.findOneAndUpdate(
|
|
// { customerId },
|
|
// { picture: publicUrl },
|
|
// { new: true, upsert: true },
|
|
// (error, picture) => {
|
|
// if (error) {
|
|
// reply.code(500).send({ error: 'Failed to update database' });
|
|
// } else {
|
|
// // Return the public URL
|
|
// reply.send({ picture: publicUrl });
|
|
// }
|
|
// }
|
|
// );
|
|
// } catch (error) {
|
|
// reply.code(500).send({ error: 'Failed to make file public' });
|
|
// }
|
|
// });
|
|
|
|
|
|
// writeStream.on('error', (err) => {
|
|
// reply.code(500).send({ error: 'Failed to move file' });
|
|
// });
|
|
// } catch (err) {
|
|
// reply.code(500).send({ error: 'An error occurred' });
|
|
// }
|
|
// });
|
|
|
|
|
|
// fastify.post("/api/uploads-electricty-work/:customerId/:installationId", async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = await request.files(); // Await files properly
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for await (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`;
|
|
// const filePath = `electricty_work_picture/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading file: ${file.filename} → ${filePath}`);
|
|
|
|
// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// file.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on("finish", async () => {
|
|
// try {
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`File uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (error) {
|
|
// console.error("Failed to make file public:", error);
|
|
// reject(error);
|
|
// }
|
|
// });
|
|
|
|
// writeStream.on("error", (err) => {
|
|
// console.error("Failed to upload file:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
// }
|
|
|
|
// // Update MongoDB: Convert URLs to { url: "..." } objects
|
|
// const updatedRecord = await ElectrictyWorkPictures.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ success: true, pictures: publicUrls, details: updatedRecord });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// reply.code(500).send({ error: "An error occurred", details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post(
|
|
// "/api/uploads-electricty-work/:customerId/:installationId",
|
|
// { preHandler: upload.any() }, // allow multiple files
|
|
// async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = request.files;
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random()
|
|
// .toString(36)
|
|
// .substring(7)}-${file.originalname}`;
|
|
// const filePath = `electricty_work_picture/${uniqueFileName}`;
|
|
|
|
// // ✅ Handle buffer vs path depending on multer storage
|
|
// const fileBuffer = file.buffer
|
|
// ? file.buffer // memoryStorage
|
|
// : await fs.promises.readFile(file.path); // diskStorage
|
|
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
|
|
// console.log(`✅ Uploaded: ${publicUrl}`);
|
|
// }
|
|
|
|
// // Update MongoDB
|
|
// const updatedRecord = await ElectrictyWorkPictures.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({
|
|
// success: true,
|
|
// pictures: publicUrls,
|
|
// details: updatedRecord,
|
|
// });
|
|
// } catch (err) {
|
|
// console.error("❌ Upload Error:", err);
|
|
// return reply.code(500).send({ error: "Upload failed", details: err.message });
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// fastify.post("/api/uploads-manualTestVideo-work/:customerId/:installationId", async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = await request.files(); // Await files properly
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for await (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`;
|
|
// const filePath = `electricty_work_picture/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading file: ${file.filename} → ${filePath}`);
|
|
|
|
// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// file.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on("finish", async () => {
|
|
// try {
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`File uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (error) {
|
|
// console.error("Failed to make file public:", error);
|
|
// reject(error);
|
|
// }
|
|
// });
|
|
|
|
// writeStream.on("error", (err) => {
|
|
// console.error("Failed to upload file:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
// }
|
|
|
|
// // Update MongoDB: Convert URLs to { url: "..." } objects
|
|
// const updatedRecord = await ManualTestVideo.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ success: true, pictures: publicUrls, details: updatedRecord });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// reply.code(500).send({ error: "An error occurred", details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post(
|
|
// "/api/uploads-manualTestVideo-work/:customerId/:installationId",
|
|
// { preHandler: upload.any() },
|
|
// async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = request.files;
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random()
|
|
// .toString(36)
|
|
// .substring(7)}-${file.originalname}`;
|
|
// const filePath = `manual_test_video/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading video: ${file.originalname} → ${filePath}`);
|
|
|
|
// const gcsFile = storage.bucket(bucketName).file(filePath);
|
|
|
|
// // Use a proper write stream with full metadata
|
|
// const stream = gcsFile.createWriteStream({
|
|
// metadata: {
|
|
// contentType: file.mimetype || "video/mp4", // fallback to mp4
|
|
// contentDisposition: "inline", // ensures browser plays instead of downloads
|
|
// },
|
|
// resumable: false,
|
|
// });
|
|
|
|
// stream.write(file.buffer);
|
|
// stream.end();
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// stream.on("finish", async () => {
|
|
// try {
|
|
// await gcsFile.makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`✅ Uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (err) {
|
|
// reject(err);
|
|
// }
|
|
// });
|
|
// stream.on("error", (err) => {
|
|
// console.error("Upload Error:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
// }
|
|
|
|
// const updatedRecord = await ManualTestVideo.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { videoUrl: { $each: publicUrls.map((url) => ({ url })) } } }, // use videoUrl field
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({
|
|
// success: true,
|
|
// videos: publicUrls,
|
|
// details: updatedRecord,
|
|
// });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// return reply.code(500).send({ error: "Upload failed", details: err.message });
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
|
|
// fastify.post(
|
|
// "/api/uploads-manualTestVideo-work/:customerId/:installationId",
|
|
// { preHandler: upload.any() }, // Multer saves files to "uploads/"
|
|
// async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = request.files; // Multer saves file info here
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random()
|
|
// .toString(36)
|
|
// .substring(7)}-${file.originalname}`;
|
|
// const filePath = `manual_test_video/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading video: ${file.path} → ${filePath}`);
|
|
|
|
// const gcsFile = storage.bucket(bucketName).file(filePath);
|
|
// const stream = gcsFile.createWriteStream({
|
|
// metadata: {
|
|
// contentType: file.mimetype || "video/mp4",
|
|
// contentDisposition: "inline",
|
|
// },
|
|
// resumable: false,
|
|
// });
|
|
|
|
// // Pipe from disk to GCS
|
|
// fs.createReadStream(file.path).pipe(stream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// stream.on("finish", async () => {
|
|
// try {
|
|
// await gcsFile.makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`✅ Uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (err) {
|
|
// reject(err);
|
|
// }
|
|
// });
|
|
// stream.on("error", (err) => {
|
|
// console.error("Upload Error:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
|
|
// // optional: cleanup temp file
|
|
// fs.unlink(file.path, (err) => {
|
|
// if (err) console.error("Temp file cleanup failed:", err);
|
|
// });
|
|
// }
|
|
|
|
// // Update MongoDB
|
|
// const updatedRecord = await ManualTestVideo.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } },
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({
|
|
// success: true,
|
|
// videos: publicUrls,
|
|
// details: updatedRecord,
|
|
// });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// return reply
|
|
// .code(500)
|
|
// .send({ error: "Upload failed", details: err.message });
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// fastify.post("/api/uploads-plumbing-work/:customerId/:installationId", async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = await request.files(); // Await files properly
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for await (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`;
|
|
// const filePath = `plumbing_work_picture/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading file: ${file.filename} → ${filePath}`);
|
|
|
|
// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// file.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on("finish", async () => {
|
|
// try {
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`File uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (error) {
|
|
// console.error("Failed to make file public:", error);
|
|
// reject(error);
|
|
// }
|
|
// });
|
|
|
|
// writeStream.on("error", (err) => {
|
|
// console.error("Failed to upload file:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
// }
|
|
|
|
// // Update MongoDB: Convert URLs to { url: "..." } objects
|
|
// const updatedRecord = await PlumbingWorkPictures.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ success: true, pictures: publicUrls, details: updatedRecord });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// reply.code(500).send({ error: "An error occurred", details: err.message });
|
|
// }
|
|
// });
|
|
|
|
// fastify.post("/api/uploads-material-recieved/:customerId/:installationId", async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = await request.files(); // Await files properly
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for await (const file of files) {
|
|
// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`;
|
|
// const filePath = `plumbing_work_picture/${uniqueFileName}`;
|
|
|
|
// console.log(`Uploading file: ${file.filename} → ${filePath}`);
|
|
|
|
// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
// file.file.pipe(writeStream);
|
|
|
|
// await new Promise((resolve, reject) => {
|
|
// writeStream.on("finish", async () => {
|
|
// try {
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// console.log(`File uploaded: ${publicUrl}`);
|
|
// resolve();
|
|
// } catch (error) {
|
|
// console.error("Failed to make file public:", error);
|
|
// reject(error);
|
|
// }
|
|
// });
|
|
|
|
// writeStream.on("error", (err) => {
|
|
// console.error("Failed to upload file:", err);
|
|
// reject(err);
|
|
// });
|
|
// });
|
|
// }
|
|
|
|
// // Update MongoDB: Convert URLs to { url: "..." } objects
|
|
// const updatedRecord = await MaterialRecievedPictures.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// reply.send({ success: true, pictures: publicUrls, details: updatedRecord });
|
|
// } catch (err) {
|
|
// console.error("Upload Error:", err);
|
|
// reply.code(500).send({ error: "An error occurred", details: err.message });
|
|
// }
|
|
// });
|
|
|
|
|
|
// fastify.post("/api/installLogin", {
|
|
// schema: {
|
|
// description: "This is for Login Install",
|
|
// tags: ["Installation"],
|
|
// summary: "This is for Login Install",
|
|
// body: {
|
|
// type: "object",
|
|
// required: ["type", "phone", "password"],
|
|
// properties: {
|
|
// type: { type: "string", description: "User role type (e.g., 'admin', 'manager')" },
|
|
// phone: { type: "string", description: "Registered phone number" },
|
|
// password: { type: "string", description: "Password for authentication" },
|
|
// },
|
|
// },
|
|
// },
|
|
// async handler(req, reply) {
|
|
// try {
|
|
// const { type, phone, password } = req.body;
|
|
|
|
// // Check if user exists in the Department Schema
|
|
// const user = await Deparments.findOne({ phone });
|
|
|
|
// if (!user) {
|
|
// return reply.code(400).send({ message: "User not found" });
|
|
// }
|
|
|
|
// // Verify Password
|
|
// const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
|
|
// if (!isMatch) {
|
|
// return reply.code(400).send({ message: "Invalid credentials" });
|
|
// }
|
|
|
|
// // Check if department details already exist in installation schema
|
|
// let installation = await Install.findOne({ phone });
|
|
|
|
// if (!installation) {
|
|
// // Create a new entry in installation schema with departmentId as installationId
|
|
// installation = new Install({
|
|
// phone: user.phone,
|
|
// installationId: user.departmentId, // Store departmentId in installationId
|
|
// firstName: user.firstName,
|
|
// lastName: user.lastName,
|
|
// email: user.email,
|
|
// alternativeNumber: user.alternativeContactNumber,
|
|
// departmentName: user.departmentName,
|
|
// designation: user.desginationName,
|
|
// reportingManager: user.reportingManager,
|
|
// city: user.city,
|
|
// zone: user.zone,
|
|
// address1: user.address1,
|
|
// address2: user.address2,
|
|
// profile: {
|
|
// state: user.state,
|
|
// country: user.country,
|
|
// role: type, // Store type in profile.role
|
|
// },
|
|
// });
|
|
|
|
// await installation.save();
|
|
// }
|
|
|
|
// // Ensure `type` is stored in `profile.role`
|
|
// if (!installation.profile?.role) {
|
|
// installation.profile.role = type;
|
|
// await installation.save(); // Save the updated type
|
|
// }
|
|
|
|
// // Fetch profile picture if available
|
|
// const profilePicture = await ProfilePictureInstall.findOne({ customerId: installation._id });
|
|
|
|
// // Generate JWT Token
|
|
// const token = fastify.jwt.sign(
|
|
// { userId: user._id, phone: user.phone, role: installation.profile?.role },
|
|
// "your_secret_key",
|
|
// { expiresIn: "7d" }
|
|
// );
|
|
|
|
// // Construct response payload
|
|
// const responsePayload = {
|
|
// simplydata: {
|
|
// error: false,
|
|
// apiversion: fastify.config.APIVERSION,
|
|
// access_token: token,
|
|
// email: installation.emails || [],
|
|
// installationId: installation.installationId,
|
|
// phone: installation.phone,
|
|
// address1: installation.address1,
|
|
// address2: installation.address2,
|
|
// phoneVerified: installation.phoneVerified,
|
|
// oneTimePasswordSetFlag: installation.oneTimePasswordSetFlag,
|
|
// type: installation.profile?.role || "user", // Default to "user" if not available
|
|
// fcmIds: installation.fcmId || null,
|
|
// team: installation.team,
|
|
// city: installation.city,
|
|
// manager: installation.manager,
|
|
// firstName: installation.firstName,
|
|
// lastName: installation.lastName,
|
|
// address: installation.address || "",
|
|
// alternativeNumber: installation.alternativeNumber || null,
|
|
// profilePicture: profilePicture ? profilePicture.pictureUrl : null, // Include profile picture URL if available
|
|
// },
|
|
// };
|
|
|
|
// return reply.send(responsePayload);
|
|
// } catch (error) {
|
|
// console.error("Login Error:", error);
|
|
// return reply.code(500).send({ message: "Internal server error" });
|
|
// }
|
|
// },
|
|
// });
|
|
|
|
// fastify.post(
|
|
// "/api/uploads-material-recieved/:customerId/:installationId",
|
|
// { preHandler: upload.any() }, // use 'files' field for multiple uploads
|
|
// async (request, reply) => {
|
|
// try {
|
|
// const { customerId, installationId } = request.params;
|
|
// const files = request.files; // multer-style files array
|
|
|
|
// if (!files || files.length === 0) {
|
|
// return reply.code(400).send({ error: "No files uploaded" });
|
|
// }
|
|
|
|
// const bucketName = "arminta_profile_pictures";
|
|
// const publicUrls = [];
|
|
|
|
// for (const file of files) {
|
|
// // Generate unique file name
|
|
// const uniqueFileName = `${Date.now()}-${Math.random()
|
|
// .toString(36)
|
|
// .substring(7)}-${file.originalname}`;
|
|
// const filePath = `plumbing_work_picture/${uniqueFileName}`;
|
|
|
|
// // Read file buffer
|
|
// const fileBuffer = await fs.promises.readFile(file.path);
|
|
|
|
// // Upload to GCS
|
|
// await storage.bucket(bucketName).file(filePath).save(fileBuffer);
|
|
|
|
// // Make file public
|
|
// await storage.bucket(bucketName).file(filePath).makePublic();
|
|
|
|
// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
// publicUrls.push(publicUrl);
|
|
// }
|
|
|
|
// // Save/Update in DB
|
|
// const updatedRecord = await MaterialRecievedPictures.findOneAndUpdate(
|
|
// { customerId, installationId },
|
|
// { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } }, // Append images
|
|
// { new: true, upsert: true }
|
|
// );
|
|
|
|
// return reply.send({
|
|
// success: true,
|
|
// pictures: publicUrls,
|
|
// details: updatedRecord,
|
|
// });
|
|
// } catch (err) {
|
|
// request.log.error(err);
|
|
// return reply
|
|
// .code(500)
|
|
// .send({ error: "Upload failed", details: err.message });
|
|
// }
|
|
// }
|
|
// );
|
|
fastify.post("/api/installLogin", {
|
|
schema: {
|
|
description: "Login as Installation Manager",
|
|
tags: ["Installation"],
|
|
summary: "Installation Manager login",
|
|
body: {
|
|
type: "object",
|
|
required: ["type", "phone", "password"],
|
|
properties: {
|
|
type: { type: "string", enum: ["Installation_Manager"], description: "Login type" },
|
|
phone: { type: "string", description: "Registered phone number" },
|
|
password: { type: "string", description: "Password" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const { type, phone, password } = req.body;
|
|
|
|
// Find department record
|
|
const user = await Deparments.findOne({ phone }).lean();
|
|
if (!user) {
|
|
return reply.code(400).send({ message: "User not found" });
|
|
}
|
|
|
|
// Validate password
|
|
const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
if (!isMatch) {
|
|
return reply.code(401).send({ message: "Invalid credentials" });
|
|
}
|
|
|
|
// Find or create installation document
|
|
let installation = await Install.findOne({ phone });
|
|
if (!installation) {
|
|
installation = new Install({
|
|
phone,
|
|
installationId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
picture: user.picture,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
role: type, // store login type
|
|
},
|
|
});
|
|
await installation.save();
|
|
} else if (!installation.profile?.role) {
|
|
installation.profile.role = type;
|
|
await installation.save();
|
|
}
|
|
|
|
// Generate JWT
|
|
const token = fastify.jwt.sign(
|
|
{ userId: user._id, phone, role: type },
|
|
"your_secret_key", // replace with config
|
|
{ expiresIn: "7d" }
|
|
);
|
|
|
|
return reply.send({
|
|
success: true,
|
|
message: "Login successful",
|
|
simplydata: {
|
|
error: false,
|
|
access_token: token,
|
|
installationId: installation.installationId,
|
|
phone: installation.phone,
|
|
firstName: installation.firstName,
|
|
lastName: installation.lastName,
|
|
city: installation.city,
|
|
email: installation.emails?.map(e => e.email) || [],
|
|
type: installation.profile?.role || type,
|
|
team: installation.team,
|
|
manager: installation.manager,
|
|
fcmId: installation.fcmId,
|
|
alternativeNumber: installation.alternativeNumber,
|
|
phoneVerified: installation.phoneVerified,
|
|
picture: installation.picture
|
|
},
|
|
});
|
|
} catch (err) {
|
|
console.error("installLogin error:", err);
|
|
reply.code(500).send({ message: "Internal server error" });
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// fastify.post("/api/teamMemberLogin", {
|
|
// schema: {
|
|
// description: "Login API for team members",
|
|
// tags: ["Installation"],
|
|
// summary: "Login as a Team Member",
|
|
// body: {
|
|
// type: "object",
|
|
// required: ["type", "phone", "password"],
|
|
// properties: {
|
|
// type: { type: "string", description: "Role type of the user (e.g., 'team_member')" },
|
|
// phone: { type: "string", description: "Registered phone number of the team member" },
|
|
// password: { type: "string", description: "Password for authentication" },
|
|
// },
|
|
// },
|
|
// },
|
|
// async handler(request, reply) {
|
|
// try {
|
|
// const { type, phone, password } = request.body;
|
|
|
|
// // ✅ Step 1: Find the team member in `Deparments`
|
|
// const department = await Deparments.findOne({
|
|
// "team_member.team_member.phone": phone
|
|
// });
|
|
|
|
// if (!department) {
|
|
// return reply.status(401).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// message: "Invalid phone number",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// // ✅ Step 2: Find the specific team member
|
|
// const teamMember = department.team_member.team_member.find(
|
|
// (member) => member.phone === phone
|
|
// );
|
|
|
|
// if (!teamMember) {
|
|
// return reply.status(401).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// message: "Invalid phone number",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// // ✅ Step 3: Verify password
|
|
// const isPasswordValid = await bcrypt.compare(password, teamMember.password);
|
|
|
|
// if (!isPasswordValid) {
|
|
// return reply.status(401).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// message: "Invalid phone number or password",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// console.log("Team Member First Name:", teamMember.firstName); // ✅ Debugging
|
|
|
|
// // ✅ Step 4: Check if this team member already exists in `Install`
|
|
// let installation = await Install.findOne({
|
|
// installationId: department.departmentId
|
|
// });
|
|
|
|
// if (!installation) {
|
|
// return reply.status(404).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// message: "Installation not found",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// // Check if team member already exists in Install schema
|
|
// const existingTeamMember = installation.team_member.team_member.find(
|
|
// (member) => member.phone === phone
|
|
// );
|
|
|
|
// if (!existingTeamMember) {
|
|
// // ✅ Step 5: Add team member details to `Install` schema
|
|
// installation.team_member.team_member.push({
|
|
// teamMemberId: teamMember.teamMemberId,
|
|
// firstName: teamMember.firstName,
|
|
// phone: teamMember.phone,
|
|
// email: teamMember.email,
|
|
// alternativePhone: teamMember.alternativePhone,
|
|
// installationTeamMemId: installation.installationId,
|
|
// password: teamMember.password, // Store hashed password
|
|
// status: teamMember.status || "active",
|
|
// type: type, // Store login type
|
|
// });
|
|
|
|
// await installation.save();
|
|
// }
|
|
|
|
// // ✅ Step 6: Generate JWT token
|
|
// const token = fastify.jwt.sign(
|
|
// { phone: teamMember.phone, role: type, installationId: installation.installationId },
|
|
// "JWT_SECRET",
|
|
// { expiresIn: "1h" }
|
|
// );
|
|
|
|
// return reply.send({
|
|
// simplydata: {
|
|
// error: false,
|
|
// message: "Login successful",
|
|
// access_token: token,
|
|
// phone: teamMember.phone,
|
|
// firstName: teamMember.firstName || null, // ✅ Now included
|
|
// teamMemberId: teamMember.teamMemberId,
|
|
// alternativePhone: teamMember.alternativePhone || null,
|
|
// email: teamMember.email || null,
|
|
// status: teamMember.status || "active",
|
|
// type: teamMember.type,
|
|
// installationId: installation.installationId
|
|
// },
|
|
// });
|
|
|
|
// } catch (err) {
|
|
// console.error("Error logging in:", err);
|
|
// reply.status(500).send({
|
|
// simplydata: {
|
|
// error: true,
|
|
// message: "Internal server error",
|
|
// },
|
|
// });
|
|
// }
|
|
// },
|
|
// });
|
|
|
|
|
|
fastify.post("/api/teamMemberLogin", {
|
|
schema: {
|
|
description: "Login as Installation Team Member",
|
|
tags: ["Installation"],
|
|
summary: "Team member login",
|
|
body: {
|
|
type: "object",
|
|
required: ["type", "phone", "password"],
|
|
properties: {
|
|
type: { type: "string", enum: ["Installation_TeamMember"], description: "Login type" },
|
|
phone: { type: "string", description: "Team member phone" },
|
|
password: { type: "string", description: "Password" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const { type, phone, password } = req.body;
|
|
|
|
// Find department with this team member phone
|
|
const department = await Deparments.findOne({ "team_member.team_member.phone": phone }).lean();
|
|
if (!department) {
|
|
return reply.code(401).send({ message: "Invalid phone number" });
|
|
}
|
|
|
|
// Find the actual team member
|
|
const teamMember = department.team_member.team_member.find(m => m.phone === phone);
|
|
if (!teamMember) {
|
|
return reply.code(401).send({ message: "Invalid phone number" });
|
|
}
|
|
|
|
// Validate password
|
|
const isMatch = await bcrypt.compare(password, teamMember.password);
|
|
if (!isMatch) {
|
|
return reply.code(401).send({ message: "Invalid credentials" });
|
|
}
|
|
|
|
// Find install document
|
|
const installation = await Install.findOne({ installationId: department.departmentId });
|
|
if (!installation) {
|
|
return reply.code(404).send({ message: "Installation not found" });
|
|
}
|
|
|
|
// Add team member to install if missing
|
|
const alreadyExists = installation.team_member?.team_member?.some(m => m.phone === phone);
|
|
if (!alreadyExists) {
|
|
installation.team_member.team_member.push({
|
|
teamMemberId: teamMember.teamMemberId,
|
|
firstName: teamMember.firstName,
|
|
phone: teamMember.phone,
|
|
installationTeamMemId: installation.installationId,
|
|
password: teamMember.password,
|
|
status: teamMember.status || "active",
|
|
email: teamMember.email,
|
|
alternativePhone: teamMember.alternativePhone,
|
|
type
|
|
});
|
|
await installation.save();
|
|
}
|
|
|
|
// Generate JWT
|
|
const token = fastify.jwt.sign(
|
|
{ phone, role: type, installationId: installation.installationId },
|
|
"your_secret_key", // replace with config
|
|
{ expiresIn: "1h" }
|
|
);
|
|
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
access_token: token,
|
|
phone: teamMember.phone,
|
|
firstName: teamMember.firstName,
|
|
teamMemberId: teamMember.teamMemberId,
|
|
alternativePhone: teamMember.alternativePhone,
|
|
email: teamMember.email,
|
|
status: teamMember.status || "active",
|
|
type: type,
|
|
installationId: installation.installationId
|
|
}
|
|
});
|
|
} catch (err) {
|
|
console.error("teamMemberLogin error:", err);
|
|
reply.code(500).send({ message: "Internal server error" });
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
fastify.post("/api/surveyLogin", {
|
|
schema: {
|
|
description: "This is for Login Survey",
|
|
tags: ["Survey"],
|
|
summary: "This is for Login Survey",
|
|
body: {
|
|
type: "object",
|
|
required: [ "phone", "password"],
|
|
properties: {
|
|
phone: { type: "string", description: "Registered phone number" },
|
|
password: { type: "string", description: "Password for authentication" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const { phone, password } = req.body;
|
|
|
|
// Check if user exists in the Department Schema
|
|
const user = await Deparments.findOne({ phone });
|
|
console.log("user", user)
|
|
|
|
if (!user) {
|
|
return reply.code(400).send({ message: "User not found" });
|
|
}
|
|
|
|
// Verify Password
|
|
const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
|
|
if (!isMatch) {
|
|
return reply.code(400).send({ message: "Invalid credentials" });
|
|
}
|
|
|
|
let survey = await Survey.findOne({ phone });
|
|
|
|
if (!survey) {
|
|
survey = new Survey({
|
|
phone: user.phone,
|
|
surveyId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
//role: type, // Store type in profile.role
|
|
},
|
|
});
|
|
|
|
await survey.save();
|
|
}
|
|
|
|
const token = fastify.jwt.sign(
|
|
{ phone: user.phone },
|
|
"Scret",
|
|
{ expiresIn: "1h" }
|
|
);
|
|
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
message: "Login successful",
|
|
access_token: token,
|
|
phone: user.phone,
|
|
surveyId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
//role: type, // Store type in profile.role
|
|
},
|
|
},
|
|
});
|
|
// return reply.send(survey);
|
|
} catch (error) {
|
|
console.error("Login Error:", error);
|
|
return reply.code(500).send({ message: "Internal server error" });
|
|
}
|
|
},
|
|
});
|
|
|
|
const moment = require("moment-timezone");
|
|
const { AdminProfilePicture } = require("./models/admin.js");
|
|
|
|
fastify.post("/api/supportLogin", {
|
|
schema: {
|
|
description: "This is for Login Support",
|
|
tags: ["Support"],
|
|
summary: "This is for Login Support",
|
|
body: {
|
|
type: "object",
|
|
required: ["phone", "password", "type"],
|
|
properties: {
|
|
phone: { type: "string" },
|
|
password: { type: "string" },
|
|
type: { type: "string" },
|
|
},
|
|
},
|
|
},
|
|
handler: async (req, reply) => {
|
|
try {
|
|
const { phone, password, type } = req.body;
|
|
const user = await Deparments.findOne({ phone });
|
|
if (!user) return reply.code(400).send({ message: "User not found" });
|
|
|
|
const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
if (!isMatch) return reply.code(400).send({ message: "Invalid credentials" });
|
|
|
|
// Format login times
|
|
const now = moment().tz("Asia/Kolkata");
|
|
const dateOfLogin = now.format("DD-MM-YYYY");
|
|
const timeOfLogin = now.format("HH:mm:ss");
|
|
|
|
let support = await Support.findOne({ phone });
|
|
|
|
if (!support) {
|
|
support = new Support({
|
|
phone: user.phone,
|
|
supportId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
},
|
|
dateOfLogin,
|
|
timeOfLogin,
|
|
});
|
|
await support.save();
|
|
} else {
|
|
// Update login time only if access token is being issued (new login)
|
|
await Support.updateOne(
|
|
{ phone },
|
|
{ $set: { dateOfLogin, timeOfLogin } }
|
|
);
|
|
}
|
|
|
|
const token = fastify.jwt.sign(
|
|
{
|
|
userId: user._id,
|
|
phone: user.phone,
|
|
role: type,
|
|
},
|
|
"Scret",
|
|
{ expiresIn: "1h" }
|
|
);
|
|
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
apiversion: "1.0.0",
|
|
access_token: token,
|
|
email: user.email || [],
|
|
supportId: user.departmentId || "",
|
|
phone: user.phone,
|
|
address1: user.address1 || "",
|
|
address2: user.address2 || "",
|
|
phoneVerified: false,
|
|
oneTimePasswordSetFlag: false,
|
|
type: type,
|
|
fcmIds: null,
|
|
team: null,
|
|
city: user.city || "",
|
|
manager: user.reportingManager || null,
|
|
firstName: user.firstName || "",
|
|
lastName: user.lastName || "",
|
|
address: "",
|
|
alternativeNumber: user.alternativeContactNumber || "",
|
|
profilePicture: null,
|
|
dateOfLogin,
|
|
timeOfLogin,
|
|
currentTime: now.format("HH:mm:ss")
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error("Login Error:", error);
|
|
return reply.code(500).send({ message: "Internal server error" });
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
fastify.post("/api/supportTeamMemberLogin", {
|
|
schema: {
|
|
description: "Login Support TeamMember",
|
|
tags: ["Support"],
|
|
summary: "Login for Support TeamMember",
|
|
body: {
|
|
type: "object",
|
|
required: ["type", "phone", "password"],
|
|
properties: {
|
|
type: {
|
|
type: "string",
|
|
description: "Role type of the user (e.g., 'Support_TeamMember')"
|
|
},
|
|
phone: {
|
|
type: "string",
|
|
description: "Registered phone number of the team member"
|
|
},
|
|
password: {
|
|
type: "string",
|
|
description: "Password for authentication"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const { type, phone, password } = req.body;
|
|
|
|
if (type !== "Support_TeamMember") {
|
|
return reply.code(400).send({ error: "Invalid user type" });
|
|
}
|
|
|
|
const support = await Support.findOne({
|
|
"team_member.team_member.phone": phone
|
|
});
|
|
|
|
if (!support) {
|
|
return reply.code(404).send({ error: 'Team member not found' });
|
|
}
|
|
|
|
const teamMember = support.team_member.team_member.find(
|
|
member => member.phone === phone
|
|
);
|
|
|
|
if (!teamMember) {
|
|
return reply.code(404).send({ error: 'Team member not found' });
|
|
}
|
|
|
|
if (!teamMember.password) {
|
|
return reply.code(401).send({ error: 'Password not set' });
|
|
}
|
|
|
|
const isPasswordValid = await bcrypt.compare(password, teamMember.password);
|
|
if (!isPasswordValid) {
|
|
return reply.code(401).send({ error: 'Invalid credentials' });
|
|
}
|
|
|
|
const token = fastify.jwt.sign(
|
|
{
|
|
support_teamMemberId: teamMember.support_teamMemberId,
|
|
name: teamMember.name,
|
|
phone: teamMember.phone,
|
|
type: type
|
|
},
|
|
"JWT_SECRET",
|
|
{ expiresIn: '7d' }
|
|
);
|
|
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
apiversion: "1.0.0",
|
|
access_token: token,
|
|
email: [],
|
|
support_teamMemberId: teamMember.support_teamMemberId || "",
|
|
phone: teamMember.phone,
|
|
address1: teamMember.address1 || "",
|
|
address2: teamMember.address2 || "",
|
|
phoneVerified: false,
|
|
oneTimePasswordSetFlag: false,
|
|
type: type,
|
|
fcmIds: null,
|
|
team: null,
|
|
city: teamMember.city || "",
|
|
manager: null,
|
|
firstName: teamMember.name?.split(" ")[0] || "",
|
|
lastName: teamMember.name?.split(" ")[1] || "",
|
|
address: "",
|
|
alternativeNumber: teamMember.alternativeNumber || "",
|
|
profilePicture: null
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Error during team member login:", error);
|
|
return reply.code(500).send({ error: "Internal server error" });
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
fastify.post("/api/storelogin", {
|
|
schema: {
|
|
description: "This is for Store Login",
|
|
tags: ["Store-Data"],
|
|
summary: "This is for Store Login",
|
|
body: {
|
|
type: "object",
|
|
required: [ "phone", "password"],
|
|
properties: {
|
|
phone: { type: "string", description: "Registered phone number" },
|
|
password: { type: "string", description: "Password for authentication" },
|
|
},
|
|
},
|
|
},
|
|
async handler(req, reply) {
|
|
try {
|
|
const { phone, password } = req.body;
|
|
|
|
// Check if user exists in the Department Schema
|
|
const user = await Deparments.findOne({ phone });
|
|
console.log("user", user)
|
|
|
|
if (!user) {
|
|
return reply.code(400).send({ message: "User not found" });
|
|
}
|
|
|
|
// Verify Password
|
|
const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
|
|
|
|
if (!isMatch) {
|
|
return reply.code(400).send({ message: "Invalid credentials" });
|
|
}
|
|
|
|
let store = await Store.findOne({ phone });
|
|
|
|
if (!store) {
|
|
store = new Store({
|
|
phone: user.phone,
|
|
storeId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
//role: type, // Store type in profile.role
|
|
},
|
|
});
|
|
|
|
await store.save();
|
|
}
|
|
|
|
const token = fastify.jwt.sign(
|
|
{ phone: user.phone },
|
|
"Scret",
|
|
{ expiresIn: "1h" }
|
|
);
|
|
|
|
return reply.send({
|
|
simplydata: {
|
|
error: false,
|
|
message: "Login successful",
|
|
access_token: token,
|
|
phone: user.phone,
|
|
storeId: user.departmentId,
|
|
firstName: user.firstName,
|
|
lastName: user.lastName,
|
|
email: user.email,
|
|
alternativeNumber: user.alternativeContactNumber,
|
|
departmentName: user.departmentName,
|
|
designation: user.desginationName,
|
|
reportingManager: user.reportingManager,
|
|
city: user.city,
|
|
zone: user.zone,
|
|
address1: user.address1,
|
|
address2: user.address2,
|
|
profile: {
|
|
state: user.state,
|
|
country: user.country,
|
|
//role: type, // Store type in profile.role
|
|
},
|
|
},
|
|
});
|
|
// return reply.send(survey);
|
|
} catch (error) {
|
|
console.error("Login Error:", error);
|
|
return reply.code(500).send({ message: "Internal server error" });
|
|
}
|
|
},
|
|
});
|
|
|
|
fastify.post("/add-states", async (request, reply) => {
|
|
try {
|
|
const statesData = [
|
|
{
|
|
state: "Andhra Pradesh",
|
|
majorCities: [
|
|
"Adoni", "Amaravati", "Anantapur", "Chandragiri", "Chittoor",
|
|
"Guntur", "Kadapa", "Kakinada", "Kurnool", "Machilipatnam",
|
|
"Rajahmundry", "Tirupati", "Vijayawada", "Visakhapatnam", "Vizianagaram"
|
|
],
|
|
},
|
|
{
|
|
state: "Arunachal Pradesh",
|
|
majorCities: ["Itanagar", "Naharlagun", "Tawang", "Pasighat", "Ziro"],
|
|
},
|
|
{
|
|
state: "Assam",
|
|
majorCities: ["Guwahati", "Dibrugarh", "Silchar", "Jorhat", "Tezpur"],
|
|
},
|
|
{
|
|
state: "Bihar",
|
|
majorCities: ["Patna", "Gaya", "Bhagalpur", "Muzaffarpur", "Purnia"],
|
|
},
|
|
{
|
|
state: "Chhattisgarh",
|
|
majorCities: ["Raipur", "Bhilai", "Bilaspur", "Durg", "Korba"],
|
|
},
|
|
{
|
|
state: "Goa",
|
|
majorCities: ["Panaji", "Margao", "Vasco da Gama", "Mapusa"],
|
|
},
|
|
{
|
|
state: "Gujarat",
|
|
majorCities: ["Ahmedabad", "Surat", "Vadodara", "Rajkot", "Bhavnagar"],
|
|
},
|
|
{
|
|
state: "Haryana",
|
|
majorCities: ["Chandigarh", "Faridabad", "Gurugram", "Hisar", "Panipat"],
|
|
},
|
|
{
|
|
state: "Himachal Pradesh",
|
|
majorCities: ["Shimla", "Manali", "Dharamshala", "Mandi", "Solan"],
|
|
},
|
|
{
|
|
state: "Jharkhand",
|
|
majorCities: ["Ranchi", "Jamshedpur", "Dhanbad", "Bokaro", "Hazaribagh"],
|
|
},
|
|
{
|
|
state: "Karnataka",
|
|
majorCities: ["Bengaluru", "Mysuru", "Hubballi", "Mangaluru", "Belagavi"],
|
|
},
|
|
{
|
|
state: "Kerala",
|
|
majorCities: ["Thiruvananthapuram", "Kochi", "Kozhikode", "Thrissur", "Alappuzha"],
|
|
},
|
|
{
|
|
state: "Madhya Pradesh",
|
|
majorCities: ["Bhopal", "Indore", "Gwalior", "Jabalpur", "Ujjain"],
|
|
},
|
|
{
|
|
state: "Maharashtra",
|
|
majorCities: ["Mumbai", "Pune", "Nagpur", "Nashik", "Aurangabad"],
|
|
},
|
|
{
|
|
state: "Manipur",
|
|
majorCities: ["Imphal", "Bishnupur", "Thoubal", "Churachandpur"],
|
|
},
|
|
{
|
|
state: "Meghalaya",
|
|
majorCities: ["Shillong", "Tura", "Jowai", "Nongstoin"],
|
|
},
|
|
{
|
|
state: "Mizoram",
|
|
majorCities: ["Aizawl", "Lunglei", "Champhai", "Serchhip"],
|
|
},
|
|
{
|
|
state: "Nagaland",
|
|
majorCities: ["Kohima", "Dimapur", "Mokokchung", "Tuensang"],
|
|
},
|
|
{
|
|
state: "Odisha",
|
|
majorCities: ["Bhubaneswar", "Cuttack", "Rourkela", "Berhampur", "Sambalpur"],
|
|
},
|
|
{
|
|
state: "Punjab",
|
|
majorCities: ["Chandigarh", "Ludhiana", "Amritsar", "Jalandhar", "Patiala"],
|
|
},
|
|
{
|
|
state: "Rajasthan",
|
|
majorCities: ["Jaipur", "Jodhpur", "Udaipur", "Kota", "Ajmer"],
|
|
},
|
|
{
|
|
state: "Sikkim",
|
|
majorCities: ["Gangtok", "Namchi", "Mangan", "Gyalshing"],
|
|
},
|
|
{
|
|
state: "Tamil Nadu",
|
|
majorCities: ["Chennai", "Coimbatore", "Madurai", "Tiruchirappalli", "Salem"],
|
|
},
|
|
{
|
|
state: "Telangana",
|
|
majorCities: ["Hyderabad", "Warangal", "Nizamabad", "Karimnagar", "Khammam"],
|
|
},
|
|
{
|
|
state: "Tripura",
|
|
majorCities: ["Agartala", "Udaipur", "Dharmanagar", "Kailashahar"],
|
|
},
|
|
{
|
|
state: "Uttar Pradesh",
|
|
majorCities: ["Lucknow", "Kanpur", "Varanasi", "Agra", "Meerut"],
|
|
},
|
|
{
|
|
state: "Uttarakhand",
|
|
majorCities: ["Dehradun", "Haridwar", "Nainital", "Rishikesh"],
|
|
},
|
|
{
|
|
state: "West Bengal",
|
|
majorCities: ["Kolkata", "Howrah", "Durgapur", "Siliguri", "Asansol"],
|
|
},
|
|
{
|
|
state: "Andaman and Nicobar Islands",
|
|
majorCities: ["Port Blair"],
|
|
},
|
|
{
|
|
state: "Chandigarh",
|
|
majorCities: ["Chandigarh"],
|
|
},
|
|
{
|
|
state: "Dadra and Nagar Haveli and Daman and Diu",
|
|
majorCities: ["Daman", "Diu", "Silvassa"],
|
|
},
|
|
{
|
|
state: "Lakshadweep",
|
|
majorCities: ["Kavaratti"],
|
|
},
|
|
{
|
|
state: "Delhi",
|
|
majorCities: ["New Delhi"],
|
|
},
|
|
{
|
|
state: "Puducherry",
|
|
majorCities: ["Puducherry", "Karaikal", "Mahe", "Yanam"],
|
|
},
|
|
];
|
|
|
|
await IndianLocations.deleteMany();
|
|
await IndianLocations.insertMany(statesData);
|
|
|
|
reply.send({ message: "✅ All states added successfully!" });
|
|
} catch (error) {
|
|
reply.status(500).send({ error: "❌ Error inserting states: " + error });
|
|
}
|
|
});
|
|
|
|
// Run the server!
|
|
// const start = async () => {
|
|
|
|
// try {
|
|
|
|
|
|
// await fastify.listen(3000, "0.0.0.0");
|
|
// fastify.log.info(`listening on ${fastify.server.address().port}`);
|
|
// fastify.log.info(`server listening on ${fastify.config}`);
|
|
// } catch (err) {
|
|
// fastify.log.error(err);
|
|
// process.exit(1);
|
|
// }
|
|
// };
|
|
const start = async () => {
|
|
try {
|
|
await fastify.listen({ port: 3000, host: "0.0.0.0" }); // ✅ correct usage in Fastify v4
|
|
fastify.log.info(`Server listening on ${fastify.server.address().port}`);
|
|
} catch (err) {
|
|
fastify.log.error(err);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
start(); |