From eec6f8feed1f7d0cab1fd2be5887fef77af8a8d5 Mon Sep 17 00:00:00 2001 From: Nivetharamesh Date: Tue, 26 Aug 2025 15:30:50 +0530 Subject: [PATCH] Project create APi and collection create API completed --- .env | 4 +- src/api-server/app.ts | 18 ++ .../controller/collectionNodeController.ts | 51 +++ src/api-server/controller/controller.ts | 302 ------------------ .../controller/projectController.ts | 120 +++++++ src/api-server/main.ts | 11 +- src/api-server/routes/collectionRoutes.ts | 7 + src/api-server/routes/projectRoutes.ts | 8 + src/api-server/routes/routes.ts | 8 - src/shared/connection/connection.ts | 1 + src/shared/fsafdsa | 0 src/shared/model/collectionModel.ts | 11 +- src/shared/model/mvcModel.ts | 13 +- src/shared/model/projectmodel.ts | 5 + src/shared/services/collectionService.ts | 45 +++ src/shared/services/projectService.ts | 131 ++++++++ 16 files changed, 402 insertions(+), 333 deletions(-) create mode 100644 src/api-server/app.ts create mode 100644 src/api-server/controller/collectionNodeController.ts delete mode 100644 src/api-server/controller/controller.ts create mode 100644 src/api-server/controller/projectController.ts create mode 100644 src/api-server/routes/collectionRoutes.ts create mode 100644 src/api-server/routes/projectRoutes.ts delete mode 100644 src/api-server/routes/routes.ts delete mode 100644 src/shared/fsafdsa create mode 100644 src/shared/services/collectionService.ts create mode 100644 src/shared/services/projectService.ts diff --git a/.env b/.env index 9da78ba..ab4fe19 100644 --- a/.env +++ b/.env @@ -1,4 +1,6 @@ MONGO_URI=mongodb://192.168.0.110/ MONGO_USER=mydata MONGO_PASSWORD=mongodb@hexr2002 -MONGO_AUTH_DB=admin \ No newline at end of file +MONGO_AUTH_DB=admin + +API_PORT=9696 \ No newline at end of file diff --git a/src/api-server/app.ts b/src/api-server/app.ts new file mode 100644 index 0000000..758a034 --- /dev/null +++ b/src/api-server/app.ts @@ -0,0 +1,18 @@ +import express from "express"; +import cors from "cors"; +import dotenv from "dotenv"; +import projectRoutes from "./routes/projectRoutes"; +import collectionNodeRoutes from "./routes/collectionRoutes"; +dotenv.config({ quiet: true }); + +const app = express(); +app.use(cors()); +app.use(express.json({ limit: "50mb" })); +app.use( + express.urlencoded({ limit: "50mb", extended: true, parameterLimit: 50000 }) +); + +app.use("/api/v1", projectRoutes); +app.use("/api/v1", collectionNodeRoutes); + +export default app; diff --git a/src/api-server/controller/collectionNodeController.ts b/src/api-server/controller/collectionNodeController.ts new file mode 100644 index 0000000..347e1d3 --- /dev/null +++ b/src/api-server/controller/collectionNodeController.ts @@ -0,0 +1,51 @@ +import { Request, Response } from "express"; +import { collectionNodecreation } from "../../shared/services/collectionService"; + +export const collectionNodeCreationController = async ( + req: Request, + res: Response +): Promise => { + try { + const { organization, projectId, position } = req.body; + if (!organization || !projectId || !position) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + organization, + projectId, + position, + }; + const result = await collectionNodecreation(data); + + switch (result.status) { + case "project not found": + res.status(200).json({ + message: "project not found", + }); + break; + case "Collection node creation unsuccessfull": + res.status(200).json({ + message: "Collection node creation unsuccessfull", + }); + break; + case "Success": + res.status(200).json({ + message: "Node created successfully", + collectionNodeId: result.data, + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; diff --git a/src/api-server/controller/controller.ts b/src/api-server/controller/controller.ts deleted file mode 100644 index 8105ac4..0000000 --- a/src/api-server/controller/controller.ts +++ /dev/null @@ -1,302 +0,0 @@ -import fs from "node:fs"; -import { Request, Response } from "express"; -import path from "path"; -import MVCarcModel from "../../shared/model/mvcModel"; -import ProjectType from "../../shared/model/projectmodel"; -export const createcontroller = async ( - req: Request, - res: Response -): Promise => { - const { - pathName, - organization, - BaseName, - useableLanguage, - typeOfDB, - DBName, - userName, - architecture, - } = req.body; - - try { - const existing = await ProjectType(organization).findOne({ - createdBy: userName, - DBName: DBName, - typeOfDB: typeOfDB, - useableLanguage: useableLanguage, - architecture: architecture.toLowerCase(), - }); - if (existing) { - return res.status(403).json({ - message: "Project Already Exists", - }); - } else { - if (architecture.toLowerCase() === "mvc") { - const basePath = path.join(pathName, BaseName, "src"); - let folders: any[]; - const existingMvcForBase = await MVCarcModel(organization).findOne({ - BaseName: BaseName, - architecture: architecture.toLowerCase(), - }); - if (!existingMvcForBase) { - const getUniqueBasePath = ( - pathName: string, - BaseName: string - ): { finalBaseName: string; fullPath: string } => { - let counter = 0; - let newBaseName = BaseName; - let fullPath = path.join(pathName, newBaseName, "src"); - if (fs.existsSync(basePath)) { - counter++; - newBaseName = `${BaseName}-${counter}`; - fullPath = path.join(pathName, newBaseName, "src"); - } - - return { finalBaseName: newBaseName, fullPath }; - }; - const folderStructureFunction = async ( - folders: string[], - rootPath: string - ): Promise => { - const folderStatus: string[] = []; - for (const folder of folders) { - const fullPath = path.join(rootPath, folder); - if (!fs.existsSync(fullPath)) { - fs.mkdirSync(fullPath, { recursive: true }); - folderStatus.push(`Created: ${folder}`); - console.log("folder: ", folder); - BaseDataSave.folderNames.push(folder); - await BaseDataSave.save(); - } else { - folderStatus.push(`Already exists: ${folder}`); - } - } - return folderStatus; - }; - const mainFileCreate = async (rootPath: string): Promise => { - const mainfile = path.join(rootPath, "app.ts"); - try { - await fs.promises.access(rootPath); - } catch { - await fs.promises.mkdir(rootPath, { recursive: true }); - } - try { - await fs.promises.access(mainfile); - return res - .status(200) - .json({ message: "Model file already exists in this name" }); - } catch { - await fs.promises.writeFile(mainfile, ""); - } - }; - let folderStatus: string[] = []; - let basicName: string; - let rootPath: string; - if (fs.existsSync(basePath)) { - let { finalBaseName, fullPath } = getUniqueBasePath( - pathName, - BaseName - ); - basicName = finalBaseName; - rootPath = fullPath; - fs.mkdirSync(fullPath, { recursive: true }); - mainFileCreate(rootPath); - } else { - basicName = BaseName; - rootPath = basePath; - fs.mkdirSync(basePath, { recursive: true }); - mainFileCreate(rootPath); - } - let BaseDataSave = await ProjectType(organization).create({ - organization, - BaseName: basicName, - useableLanguage, - typeOfDB, - DBName, - createdBy: userName, - architecture: architecture.toLowerCase(), - }); - const MVCCreation = await MVCarcModel(organization).create({ - BaseName: basicName, - baseId: BaseDataSave._id, - createdBy: userName, - controllers: true, - routes: true, - models: true, - services: true, - middleware: true, - utils: true, - config: true, - }); - const mvcData = MVCCreation.toObject(); - - const excludedKeys = ["baseId", "_id", "__v"]; - const folders = Object.keys(mvcData).filter( - (key) => !excludedKeys.includes(key) && mvcData[key] === true - ); - - folderStatus = await folderStructureFunction(folders, rootPath); - return res.status(201).json({ - message: "Base structure created successfully", - folderStatus, - }); - } - } else { - console.log("New Architecture flow"); - } - } - } catch (error: unknown) { - res.send("error"); - } -}; - -// export const createcontroller = async ( -// req: Request, -// res: Response -// ): Promise => { -// const { -// pathName, -// organization, -// BaseName, -// useableLanguage, -// typeOfDB, -// DBName, -// userName, -// architecture, -// } = req.body; - -// try { -// const existing = await ProjectType(organization).findOne({ -// createdBy: userName, -// DBName: DBName, -// typeOfDB: typeOfDB, -// useableLanguage: useableLanguage, -// architecture: architecture.toLowerCase(), -// }); -// if (existing) { -// return res.status(403).json({ -// message: "Project Already Exists", -// }); -// } else { -// if (architecture.toLowerCase() === "mvc") { -// const basePath = path.join(pathName, BaseName, "src"); -// let folders: any[]; -// const existingMvcForBase = await MVCarcModel(organization).findOne({ -// BaseName: BaseName, -// architecture: architecture.toLowerCase(), -// }); -// if (!existingMvcForBase) { -// const getUniqueBasePath = ( -// pathName: string, -// BaseName: string -// ): { finalBaseName: string; fullPath: string } => { -// let counter = 0; -// let newBaseName = BaseName; -// let fullPath = path.join(pathName, newBaseName, "src"); -// if (fs.existsSync(basePath)) { -// counter++; -// newBaseName = `${BaseName}-${counter}`; -// fullPath = path.join(pathName, newBaseName, "src"); -// } - -// return { finalBaseName: newBaseName, fullPath }; -// }; -// const folderStructureFunction = async ( -// folders: string[], -// rootPath: string -// ): Promise => { -// const folderStatus: string[] = []; -// for (const folder of folders) { -// const fullPath = path.join(rootPath, folder); -// if (!fs.existsSync(fullPath)) { -// fs.mkdirSync(fullPath, { recursive: true }); -// folderStatus.push(`Created: ${folder}`); -// console.log("folder: ", folder); -// BaseDataSave.folderNames.push(folder); -// await BaseDataSave.save(); -// } else { -// folderStatus.push(`Already exists: ${folder}`); -// } -// } -// return folderStatus; -// }; -// const mainFileCreate = async (rootPath: string): Promise => { -// const mainfile = path.join(rootPath, "app.ts"); -// try { -// await fs.promises.access(rootPath); -// } catch { -// await fs.promises.mkdir(rootPath, { recursive: true }); -// } -// try { -// await fs.promises.access(mainfile); -// return res -// .status(200) -// .json({ message: "Model file already exists in this name" }); -// } catch { -// await fs.promises.writeFile(mainfile, ""); -// } -// }; -// let folderStatus: string[] = []; -// let basicName: string; -// let rootPath: string; -// if (fs.existsSync(basePath)) { -// let { finalBaseName, fullPath } = getUniqueBasePath( -// pathName, -// BaseName -// ); -// basicName = finalBaseName; -// rootPath = fullPath; -// fs.mkdirSync(fullPath, { recursive: true }); -// mainFileCreate(rootPath); -// } else { -// basicName = BaseName; -// rootPath = basePath; -// fs.mkdirSync(basePath, { recursive: true }); -// mainFileCreate(rootPath); -// } -// let BaseDataSave = await ProjectType(organization).create({ -// organization, -// BaseName: basicName, -// useableLanguage, -// typeOfDB, -// DBName, -// createdBy: userName, -// architecture: architecture.toLowerCase(), -// }); -// const MVCCreation = await MVCarcModel(organization).create({ -// BaseName: basicName, -// baseId: BaseDataSave._id, -// createdBy: userName, -// controllers: true, -// routes: true, -// models: true, -// services: true, -// middleware: true, -// utils: true, -// config: true, -// }); -// const mvcData = MVCCreation.toObject(); - -// const excludedKeys = [ -// "baseId", -// "_id", -// "__v", -// ]; -// const folders = Object.keys(mvcData).filter( -// (key) => !excludedKeys.includes(key) && mvcData[key] === true -// ); - -// folderStatus = await folderStructureFunction(folders, rootPath); -// return res.status(201).json({ -// message: "Base structure created successfully", -// folderStatus, -// }); -// } -// } else { -// console.log("New Architecture flow"); -// } -// } -// } catch (error: unknown) { -// res.send("error"); -// } -// }; diff --git a/src/api-server/controller/projectController.ts b/src/api-server/controller/projectController.ts new file mode 100644 index 0000000..bbaee31 --- /dev/null +++ b/src/api-server/controller/projectController.ts @@ -0,0 +1,120 @@ +import { Request, Response } from "express"; +import { + projectCreationService, + projectDatas, +} from "../../shared/services/projectService"; + +export const projectCreationController = async ( + req: Request, + res: Response +): Promise => { + try { + const { + organization, + useableLanguage, + projectName, + userName, + apiType, + architecture, + description, + } = req.body; + if ( + !organization || + !useableLanguage || + !projectName || + !userName || + !apiType || + !architecture + ) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const data = { + organization, + projectName, + useableLanguage, + description, + userName, + apiType, + architecture, + }; + const result = await projectCreationService(data); + + switch (result.status) { + case "Project Already Exists": + res.status(403).json({ + message: "Project Already Exists", + }); + break; + case "Already MVC architecture assigned to this projectId": + res.status(403).json({ + message: "Already MVC architecture assigned to this projectId", + }); + break; + case "Project creation unsuccessfull": + res.status(200).json({ + message: "Project creation unsuccessfull", + }); + break; + case "Success": + res.status(200).json({ + message: "Project created successfully", + projectId: result.data, + }); + break; + case "New architecture": + res.status(200).json({ + message: "New architecture", + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; + +export const getProjects = async ( + req: Request, + res: Response +): Promise => { + try { + const { organization } = req.body; + if (!organization) { + res.status(400).json({ + message: "All fields are required", + }); + return; + } + const result = await projectDatas(organization); + + switch (result.status) { + case "No project found": + res.status(200).json({}); + break; + case "Success": + res.status(200).json({ + message: "Project created successfully", + projectDatas: result.data, + }); + break; + default: + res.status(500).json({ + message: "Internal server error", + }); + break; + } + } catch (error) { + res.status(500).json({ + message: "Unknown error", + }); + } +}; diff --git a/src/api-server/main.ts b/src/api-server/main.ts index ae41058..ff0099c 100644 --- a/src/api-server/main.ts +++ b/src/api-server/main.ts @@ -1,12 +1,5 @@ -import express from "express"; -const app = express(); -import appRoutes from "../api-server/routes/routes"; -import bodyParser from "body-parser"; -import cors from "cors"; -app.use(bodyParser.json()); -app.use(cors()); -app.use(appRoutes); -const port = 9696; +import app from "./app"; +const port = process.env.API_PORT; app.listen(port, () => { console.log(`Port is running on the ${port}`); }); diff --git a/src/api-server/routes/collectionRoutes.ts b/src/api-server/routes/collectionRoutes.ts new file mode 100644 index 0000000..8fa06ab --- /dev/null +++ b/src/api-server/routes/collectionRoutes.ts @@ -0,0 +1,7 @@ +import express from "express"; +import { collectionNodeCreationController } from "../controller/collectionNodeController"; +collectionNodeCreationController; +const collectionNodeRoutes = express.Router(); + +collectionNodeRoutes.post("/NewNode", collectionNodeCreationController); +export default collectionNodeRoutes; diff --git a/src/api-server/routes/projectRoutes.ts b/src/api-server/routes/projectRoutes.ts new file mode 100644 index 0000000..1676c04 --- /dev/null +++ b/src/api-server/routes/projectRoutes.ts @@ -0,0 +1,8 @@ +import express from "express"; +import { projectCreationController } from "../controller/projectController"; + +const projectRoutes = express.Router(); + +projectRoutes.post("/Newproject", projectCreationController); +// appRoutes.post("/createfileModel", fileModelCreatecontroller); +export default projectRoutes; diff --git a/src/api-server/routes/routes.ts b/src/api-server/routes/routes.ts deleted file mode 100644 index 6681b73..0000000 --- a/src/api-server/routes/routes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import express from "express"; -import { createcontroller } from "../../api-server/controller/controller"; -import { fileModelCreatecontroller } from "../../api-server/controller/fileModelController"; -const appRoutes = express.Router(); - -appRoutes.post("/createfolder", createcontroller); -appRoutes.post("/createfileModel", fileModelCreatecontroller); -export default appRoutes \ No newline at end of file diff --git a/src/shared/connection/connection.ts b/src/shared/connection/connection.ts index 6a76248..ac2c857 100644 --- a/src/shared/connection/connection.ts +++ b/src/shared/connection/connection.ts @@ -13,6 +13,7 @@ const MainModel = ( collectionName: string ): Model => { const db1_url = `${process.env.MONGO_URI}${db}`; + console.log('process.env.MONGO_URI: ', process.env.MONGO_URI); const authOptions = { user: process.env.MONGO_USER, pass: process.env.MONGO_PASSWORD, diff --git a/src/shared/fsafdsa b/src/shared/fsafdsa deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/model/collectionModel.ts b/src/shared/model/collectionModel.ts index fd88dfc..d8c5a08 100644 --- a/src/shared/model/collectionModel.ts +++ b/src/shared/model/collectionModel.ts @@ -1,22 +1,23 @@ import { Schema, Document } from "mongoose"; import MainModel from "../connection/connection"; import { IProject } from "./projectmodel"; -interface IFileModel extends Document { +interface ICollectionNode extends Document { projectId: IProject["_id"]; collectionNodeName: string; attributes: []; - createdAt: number; isArchive: boolean; position: [number, number, number]; } -const collectionSchema: Schema = new Schema({ +const collectionSchema: Schema = new Schema({ projectId: { type: Schema.Types.ObjectId, ref: "Project" }, collectionNodeName: { type: String, required: true }, position: { type: [Number], required: true }, isArchive: { type: Boolean, default: false }, attributes: { type: [], required: true }, - createdAt: { type: Number, default: Date.now() }, -}); +}, + { + timestamps: true, + }); const collectionsModel = (db: any) => { return MainModel(db, "collectionNode", collectionSchema, "collectionNode"); diff --git a/src/shared/model/mvcModel.ts b/src/shared/model/mvcModel.ts index cd0ba95..2bc7e6d 100644 --- a/src/shared/model/mvcModel.ts +++ b/src/shared/model/mvcModel.ts @@ -5,13 +5,10 @@ interface Ifolders extends Document { folderName: string; createdAt: number; } -const folderSchema: Schema = new Schema( - { - folderName: { type: String, required: true }, - createdAt: { type: Date, default: Date.now }, - }, - { _id: false } -); +const folderSchema: Schema = new Schema({ + folderName: { type: String, required: true }, + createdAt: { type: Date, default: Date.now }, +}); export interface IMVCPrject extends Document { projectId: IProject["_id"]; controllers: boolean; @@ -36,6 +33,6 @@ const mvcSchema: Schema = new Schema({ }); const MVCarcModel = (db: any) => { - return MainModel(db, "MVCArc", mvcSchema, "MVCArc"); + return MainModel(db, "MVC", mvcSchema, "MVC"); }; export default MVCarcModel; diff --git a/src/shared/model/projectmodel.ts b/src/shared/model/projectmodel.ts index 97dac12..b9e9d03 100644 --- a/src/shared/model/projectmodel.ts +++ b/src/shared/model/projectmodel.ts @@ -11,6 +11,7 @@ export interface IProject extends Document { typeOfDB: string; DBName: string; architecture: string; + apiType: string; } const projectSchema: Schema = new Schema( { @@ -23,6 +24,10 @@ const projectSchema: Schema = new Schema( typeOfDB: { type: String }, useableLanguage: { type: String }, architecture: { type: String }, + apiType: { + type: String, + enum: ["RESTful", "SOAP", "GraphQL", "RPC", "WebSocket"], + }, members: { type: [String] }, }, { diff --git a/src/shared/services/collectionService.ts b/src/shared/services/collectionService.ts new file mode 100644 index 0000000..aeeafe3 --- /dev/null +++ b/src/shared/services/collectionService.ts @@ -0,0 +1,45 @@ +import ProjectType from "../../shared/model/projectmodel"; +import collectionsModel from "../model/collectionModel"; +interface Iresponse { + status: string; + data?: any; +} +interface IcollectionNode { + projectId: string; + organization: string; + position: [number]; +} +export const collectionNodecreation = async ( + data: IcollectionNode +): Promise => { + const { organization, projectId, position } = data; + try { + const existingProject = await ProjectType(organization).findOne({ + _id: projectId, + // createdBy: userName, + isArchive: false, + }); + if (!existingProject) { + return { status: "project not found" }; + } else { + const newCollectionnode = await collectionsModel(organization).create({ + projectId: projectId, + isArchive: false, + position: position, + }); + if (!newCollectionnode) + return { status: "Collection node creation unsuccessfull" }; + else return { status: "Success", data: newCollectionnode._id }; + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; diff --git a/src/shared/services/projectService.ts b/src/shared/services/projectService.ts new file mode 100644 index 0000000..e5f254a --- /dev/null +++ b/src/shared/services/projectService.ts @@ -0,0 +1,131 @@ +import MVCarcModel from "../../shared/model/mvcModel"; +import ProjectType from "../../shared/model/projectmodel"; +interface Iresponse { + status: string; + data?: any; +} +interface IProject { + useableLanguage: string; + organization: string; + projectName: string; + userName: string; + apiType: string; + architecture: string; + description: string; +} +interface IProjectstructure { + projectId: string; + organization: string; +} +export const projectCreationService = async ( + data: IProject +): Promise => { + const { + organization, + projectName, + useableLanguage, + description, + userName, + apiType, + architecture, + } = data; + try { + const existingProject = await ProjectType(organization).findOne({ + projectName: projectName, + createdBy: userName, + isArchive: false, + }); + if (existingProject) { + return { status: "Project Already Exists" }; + } else { + if (architecture.toLowerCase() === "mvc") { + const newProject = await ProjectType(organization).create({ + projectName, + createdBy: userName, + useableLanguage, + architecture, + apiType: apiType, + description, + }); + if (!newProject) return { status: "Project creation unsuccessfull" }; + const existingProjectinMVC = await MVCarcModel(organization).findOne({ + projectId: newProject._id, + isArchive: false, + }); + if (!existingProjectinMVC) { + const MVCCreation = await MVCarcModel(organization).create({ + projectId: newProject._id, + createdBy: userName, + controllers: true, + routes: true, + models: true, + services: true, + middleware: true, + utils: true, + config: true, + }); + const mvcData = MVCCreation.toObject(); + + const excludedKeys = [ + "projectId", + "_id", + "__v", + "createdBy", + "isArchive", + "folders", + ]; + const folders = Object.keys(mvcData).filter( + (key) => !excludedKeys.includes(key) && mvcData[key] === true + ); + const createdFolders = folders.map((folderName) => ({ + folderName, + createdAt: new Date(), + })); + + MVCCreation.folders.push(...createdFolders); + await MVCCreation.save(); + return { status: "Success", data: newProject._id }; + } else { + return { + status: "Already MVC architecture assigned to this projectId", + }; + } + } else { + return { status: "New architecture" }; + } + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +}; + +export const projectDatas = async (data: IProject): Promise => { + const { organization } = data; + try { + const projectDatas = await ProjectType(organization) + .findOne({ + isArchive: false, + }) + .select("-__v -isArchive -createdAt -updatedAt"); + if (!projectDatas) return { status: "No project found" }; + return { status: "Success", data: projectDatas }; + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +};