Refactor edgeService and socket-server controllers to improve foreign key resolution and event handling
- Updated edgeService to enhance foreign key resolution logic and added detailed logging for debugging. - Refactored socket-server controllers to replace emitToSenderAndAdmins with emitToRoom for better room-based event handling. - Removed unnecessary console logs and improved code readability across various services. - Introduced room management functions (joinRoom, leaveRoom) to streamline socket event handling. - Cleaned up commented-out code and organized imports for clarity.
This commit is contained in:
@@ -151,7 +151,7 @@ export const updateCollectionController = async (
|
||||
position,
|
||||
};
|
||||
const result = await updatecollection(data);
|
||||
console.log('result: ', result);
|
||||
|
||||
switch (result.status) {
|
||||
case "User not found":
|
||||
res.status(404).json({ message: "User not found" });
|
||||
|
||||
@@ -41,7 +41,7 @@ export const edgeCreationController = async (
|
||||
userId: userId as string,
|
||||
};
|
||||
const result = await edgecreation(data);
|
||||
console.log('result: ', result);
|
||||
|
||||
|
||||
switch (result.status) {
|
||||
case "User not found":
|
||||
@@ -117,7 +117,7 @@ export const allEdgesController = async (
|
||||
userId: userId as string,
|
||||
};
|
||||
const result = await Alledges(data);
|
||||
console.log('result:all edge ', result);
|
||||
|
||||
|
||||
switch (result.status) {
|
||||
case "User not found":
|
||||
|
||||
@@ -64,27 +64,27 @@ export const projectCreationController = async (
|
||||
architecture,
|
||||
};
|
||||
const result = await projectCreationService(data);
|
||||
if (result.status === "Success") {
|
||||
const fetchResult = await folderProject(
|
||||
subBkd,
|
||||
projectName,
|
||||
language,
|
||||
apiProtocol,
|
||||
application,
|
||||
architecture
|
||||
);
|
||||
if (fetchResult) {
|
||||
res.status(200).json({
|
||||
message: "Project creation unsuccessfull",
|
||||
projectId: result.data,
|
||||
});
|
||||
// return { status: "Success", data: fetchResult.data };
|
||||
} else {
|
||||
res.status(500).json({
|
||||
message: "error",
|
||||
});
|
||||
}
|
||||
}
|
||||
// if (result.status === "Success") {
|
||||
// const fetchResult = await folderProject(
|
||||
// subBkd,
|
||||
// projectName,
|
||||
// language,
|
||||
// apiProtocol,
|
||||
// application,
|
||||
// architecture
|
||||
// );
|
||||
// if (fetchResult) {
|
||||
// res.status(200).json({
|
||||
// message: "Project creation unsuccessfull",
|
||||
// projectId: result.data,
|
||||
// });
|
||||
// // return { status: "Success", data: fetchResult.data };
|
||||
// } else {
|
||||
// res.status(500).json({
|
||||
// message: "error",
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
switch (result.status) {
|
||||
case "Project Already Exists":
|
||||
res.status(403).json({
|
||||
@@ -270,7 +270,7 @@ export const accessAproject = async (
|
||||
userId: userId as string,
|
||||
projectId,
|
||||
});
|
||||
console.log('result.data: ', result);
|
||||
|
||||
switch (result.status) {
|
||||
case "No project found":
|
||||
res.status(200).json({});
|
||||
|
||||
@@ -22,6 +22,7 @@ interface IAttributes {
|
||||
isArchive: boolean;
|
||||
isIdentifier: boolean;
|
||||
primary?: boolean;
|
||||
keyType?: string;
|
||||
key: string;
|
||||
type: IattributeTypes;
|
||||
refKey?: object;
|
||||
@@ -60,7 +61,7 @@ const attributeSchema = new Schema<IAttributes>({
|
||||
key: { type: String, required: true },
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
// required: true,
|
||||
enum: [
|
||||
"string",
|
||||
"number",
|
||||
@@ -82,7 +83,8 @@ const attributeSchema = new Schema<IAttributes>({
|
||||
refKey: { type: Object },
|
||||
default: { type: Schema.Types.Mixed },
|
||||
unique: { type: Boolean },
|
||||
primary: { type: Boolean },
|
||||
// primary: { type: Boolean },
|
||||
keyType: { type: String },
|
||||
index: { type: Boolean },
|
||||
isArchive: { type: Boolean, default: false },
|
||||
isIdentifier: { type: Boolean, default: false },
|
||||
|
||||
@@ -165,7 +165,7 @@ export const Nodecreation = async (
|
||||
});
|
||||
if (existingCollection)
|
||||
return { status: "CollectionName already exists" };
|
||||
let attributes = [{ key: "auto_id", type: "string" }];
|
||||
let attributes = [{ key: "auto_id", type: "string" ,keyType:"primary"}];
|
||||
const newAttributes = attributes;
|
||||
const updatedAttributesMap = new Map<string, any>();
|
||||
|
||||
@@ -190,10 +190,16 @@ export const Nodecreation = async (
|
||||
const models = [newCollectionnode.collectionName];
|
||||
const finalResult = {
|
||||
collectionNodeId: newCollectionnode._id,
|
||||
fieldId: (newCollectionnode.attributes[0] as any)._id,
|
||||
models,
|
||||
};
|
||||
console.log("finalResult: ", finalResult);
|
||||
// fieldId: (newCollectionnode.attributes[0] as any)._id,
|
||||
// models,
|
||||
type:newCollectionnode.type,
|
||||
position:newCollectionnode.position,
|
||||
data:{
|
||||
collectionName:newCollectionnode.collectionName,
|
||||
collectionData:newCollectionnode.attributes,
|
||||
}
|
||||
};
|
||||
// console.log("finalResult: ", finalResult);
|
||||
const models1 = [
|
||||
{
|
||||
name: newCollectionnode.collectionName,
|
||||
@@ -210,12 +216,12 @@ export const Nodecreation = async (
|
||||
projectName: existingProject.projectName, // 👈 take from DB
|
||||
models1,
|
||||
};
|
||||
console.log("fileData: ", fileData);
|
||||
// console.log("fileData: ", fileData);
|
||||
try {
|
||||
const fileResponse = await modelNodeFile(fileData);
|
||||
console.log("📦 File backend response:", fileResponse);
|
||||
// console.log("📦 File backend response:", fileResponse);
|
||||
} catch (err) {
|
||||
console.error("⚠️ File backend error:", err);
|
||||
// console.error("⚠️ File backend error:", err);
|
||||
}
|
||||
return { status: "Success", data: finalResult };
|
||||
}
|
||||
@@ -251,7 +257,8 @@ export const updatecollection = async (
|
||||
collectionName,
|
||||
userId,
|
||||
} = data;
|
||||
console.log("data:node ", data);
|
||||
console.log('data: nodeupdate', data);
|
||||
|
||||
try {
|
||||
const ExistingUser = await userModel(organization).findOne({
|
||||
_id: userId,
|
||||
@@ -276,7 +283,6 @@ export const updatecollection = async (
|
||||
}
|
||||
|
||||
function updateModelName(oldName: string, newBaseName: string): string {
|
||||
console.log("newBaseName: ", newBaseName);
|
||||
const [prefix, ...suffixParts] = oldName.split("_");
|
||||
|
||||
if (suffixParts.length > 0) {
|
||||
@@ -287,44 +293,119 @@ export const updatecollection = async (
|
||||
return newBaseName;
|
||||
}
|
||||
|
||||
const newBaseName = collectionName as string;
|
||||
const referencedEdges = await collectionsModel(organization).find({
|
||||
isArchive: false,
|
||||
projectId,
|
||||
attributes: {
|
||||
$elemMatch: {
|
||||
"refKey.collection_id": new mongoose.Types.ObjectId(
|
||||
collectionNodeId
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
// const referencedEdges = await collectionsModel(organization).find({
|
||||
// isArchive: false,
|
||||
// projectId,
|
||||
// attributes: {
|
||||
// $elemMatch: {
|
||||
// "refKey.collection_id": new mongoose.Types.ObjectId(
|
||||
// collectionNodeId
|
||||
// ),
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
console.log("referencedEdges: ", referencedEdges);
|
||||
if (referencedEdges.length) {
|
||||
for (const doc of referencedEdges) {
|
||||
let updated = false;
|
||||
// console.log('referencedEdges: ', referencedEdges);
|
||||
// if (referencedEdges.length) {
|
||||
// for (const doc of referencedEdges) {
|
||||
// let updated = false;
|
||||
|
||||
for (const attr of doc.attributes) {
|
||||
const refKey = attr.refKey as any;
|
||||
if (
|
||||
refKey?.collection_id?.toString() === collectionNodeId.toString()
|
||||
) {
|
||||
const oldName = attr.key;
|
||||
const newKey = updateModelName(oldName, newBaseName);
|
||||
console.log("newKey: ", newKey);
|
||||
attr.key = newKey;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
// for (const attr of doc.attributes) {
|
||||
// const refKey = attr.refKey as any;
|
||||
// if (
|
||||
// refKey?.collection_id?.toString() === collectionNodeId.toString()
|
||||
// ) {
|
||||
// const newBaseName = collectionName as string;
|
||||
// const oldName = attr.key;
|
||||
// const newKey = updateModelName(oldName, newBaseName);
|
||||
// attr.key = newKey;
|
||||
// updated = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (updated) {
|
||||
await doc.save();
|
||||
}
|
||||
}
|
||||
// if (updated) {
|
||||
// await doc.save();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
async function updateReferencedKeysRecursively(
|
||||
organization: string,
|
||||
projectId: string,
|
||||
collectionNodeId: any,
|
||||
collectionName: string,
|
||||
visited = new Set<string>()
|
||||
): Promise<void> {
|
||||
if (visited.has(collectionNodeId)) return;
|
||||
visited.add(collectionNodeId);
|
||||
|
||||
const referencedEdges = await collectionsModel(organization).find({
|
||||
isArchive: false,
|
||||
projectId,
|
||||
$or: [
|
||||
{ "attributes.refKey.collection_id": new mongoose.Types.ObjectId(collectionNodeId) },
|
||||
{ "attributes.refKey.collection_id": collectionNodeId },
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
console.log('referencedEdges: ', referencedEdges);
|
||||
console.log(
|
||||
`🔍 Found ${referencedEdges.length} referencing collections for '${collectionName}'`
|
||||
);
|
||||
|
||||
for (const doc of referencedEdges) {
|
||||
let updated = false;
|
||||
|
||||
for (const attr of doc.attributes) {
|
||||
const refKey = attr.refKey as any;
|
||||
|
||||
if (refKey?.collection_id?.toString() === collectionNodeId.toString()) {
|
||||
const oldName = attr.key;
|
||||
const newBaseName = collectionName;
|
||||
const newKey = updateModelName(oldName, newBaseName);
|
||||
|
||||
attr.key = newKey;
|
||||
updated = true;
|
||||
|
||||
console.log(
|
||||
`🔁 Updated key in '${doc.collectionName}': ${oldName} → ${newKey} (ref to '${collectionName}')`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
await doc.save();
|
||||
console.log(`✅ Saved changes in '${doc.collectionName}'`);
|
||||
}
|
||||
|
||||
// 🔁 Recursive update if the collection itself has a valid name
|
||||
if (doc.collectionName) {
|
||||
await updateReferencedKeysRecursively(
|
||||
organization,
|
||||
projectId,
|
||||
doc._id,
|
||||
doc.collectionName,
|
||||
visited
|
||||
);
|
||||
} else {
|
||||
console.warn(`⚠️ Skipped recursion for ${doc._id} (no collectionName)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
const currentCollectionName =
|
||||
collectionName || existingCollection.collectionName;
|
||||
|
||||
await updateReferencedKeysRecursively(
|
||||
organization,
|
||||
projectId,
|
||||
collectionNodeId,
|
||||
currentCollectionName
|
||||
);
|
||||
|
||||
|
||||
const oldName = existingCollection.collectionName;
|
||||
const newName = collectionName;
|
||||
|
||||
const collectionNameupdate = await collectionsModel(
|
||||
organization
|
||||
).findOneAndUpdate(
|
||||
@@ -348,25 +429,25 @@ export const updatecollection = async (
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
// console.log('collectionNameupdate: ', collectionNameupdate);
|
||||
// console.log('collectionNameupdate: ', collectionNameupdate);
|
||||
if (collectionNameupdate) {
|
||||
// ✅ If name changed, trigger file rename
|
||||
if (collectionNameupdate && oldName !== newName) {
|
||||
console.log(`Renaming model file from ${oldName} → ${newName}`);
|
||||
// if (collectionNameupdate && oldName !== newName) {
|
||||
// console.log(`Renaming model file from ${oldName} → ${newName}`);
|
||||
|
||||
await updateFilename({
|
||||
projectName: existingProject.projectName,
|
||||
// await updateFilename({
|
||||
// projectName: existingProject.projectName,
|
||||
|
||||
oldModelName: existingCollection.collectionName,
|
||||
newModelName: collectionName as string,
|
||||
});
|
||||
}
|
||||
// oldModelName: existingCollection.collectionName,
|
||||
// newModelName: collectionName as string,
|
||||
// });
|
||||
// }
|
||||
|
||||
return {
|
||||
status: "Success",
|
||||
data: {
|
||||
collectionNameupdate: collectionNameupdate,
|
||||
updateFileds: referencedEdges,
|
||||
// updateFileds: referencedEdges,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
@@ -699,6 +780,7 @@ export const UpdateAttributes = async (
|
||||
});
|
||||
if (!existingCollection) return { status: "Collection not found" };
|
||||
|
||||
let referencedEdges;
|
||||
for (const attr of attributes) {
|
||||
const fieldId = attr.fieldId;
|
||||
if (attr.type === "Object") {
|
||||
@@ -710,7 +792,7 @@ export const UpdateAttributes = async (
|
||||
attributeparentId: fieldId,
|
||||
isArchive: false,
|
||||
});
|
||||
console.log("existingsubcollection: ", existingsubcollection);
|
||||
|
||||
if (!existingsubcollection) {
|
||||
const fieldnamefind = await collectionsModel(organization).findOne(
|
||||
{
|
||||
@@ -742,70 +824,100 @@ export const UpdateAttributes = async (
|
||||
};
|
||||
}
|
||||
}
|
||||
const referencedEdges = await collectionsModel(organization).find({
|
||||
isArchive: false,
|
||||
projectId,
|
||||
attributes: {
|
||||
$elemMatch: {
|
||||
"refKey.collection_id": new mongoose.Types.ObjectId(
|
||||
collectionNodeId
|
||||
),
|
||||
"refKey.fieldId": new mongoose.Types.ObjectId(fieldId),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log("referencedEdges: ", referencedEdges);
|
||||
if (referencedEdges.length) {
|
||||
for (const doc of referencedEdges) {
|
||||
let updated = false;
|
||||
if (attr.type) {
|
||||
referencedEdges = await collectionsModel(organization)
|
||||
.find({
|
||||
isArchive: false,
|
||||
projectId,
|
||||
attributes: {
|
||||
$elemMatch: {
|
||||
"refKey.collection_id": new mongoose.Types.ObjectId(
|
||||
collectionNodeId
|
||||
),
|
||||
"refKey.fieldId": new mongoose.Types.ObjectId(fieldId),
|
||||
},
|
||||
},
|
||||
})
|
||||
.select("attributes projectId collectionName type");
|
||||
|
||||
// for (const oldattr of doc.attributes) {
|
||||
// console.log("oldattr: ", oldattr);
|
||||
// const refKey = oldattr.refKey as any;
|
||||
// if (
|
||||
// refKey?.collection_id?.toString() ===
|
||||
// collectionNodeId.toString() &&
|
||||
// refKey?.fieldId?.toString() === fieldId.toString()
|
||||
// ) {
|
||||
// const oldType = oldattr.type;
|
||||
// const newType = attr.type;
|
||||
if (referencedEdges.length) {
|
||||
for (const doc of referencedEdges) {
|
||||
let updated = false;
|
||||
try {
|
||||
for (const oldattr of doc.attributes) {
|
||||
const refKey = oldattr.refKey as any;
|
||||
if (
|
||||
refKey?.collection_id?.toString() ===
|
||||
collectionNodeId.toString() &&
|
||||
refKey?.fieldId?.toString() === fieldId.toString()
|
||||
) {
|
||||
const oldType = oldattr.type;
|
||||
const newType = attr.type;
|
||||
oldattr.type = newType as any;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("oldType:", oldType, "→ newType:", newType);
|
||||
if (updated) {
|
||||
doc.markModified("attributes");
|
||||
await doc.save();
|
||||
}
|
||||
} catch (err: any) {
|
||||
return { status: "Validation Error", data: err.message };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // ✅ Update directly
|
||||
// oldattr.type = newType as any;
|
||||
if (attr.key) {
|
||||
function updateModelName(
|
||||
oldName: string,
|
||||
newBaseName: string
|
||||
): string {
|
||||
const firstUnderscoreIndex = oldName.indexOf("_");
|
||||
|
||||
// updated = true;
|
||||
// }
|
||||
// }
|
||||
if (firstUnderscoreIndex === -1) {
|
||||
return newBaseName;
|
||||
}
|
||||
|
||||
// if (updated) {
|
||||
// doc.markModified("attributes");
|
||||
// console.log("hi");
|
||||
// await doc.save();
|
||||
// console.log("hello");
|
||||
// console.log("doc: ", doc);
|
||||
// }
|
||||
let prefix = oldName.slice(0, firstUnderscoreIndex);
|
||||
|
||||
if (!prefix || prefix === "undefined" || prefix === "") {
|
||||
prefix = existingCollection?.collectionName as string;
|
||||
// console.log(`⚠️ Prefix invalid, fallback used: ${prefix}`);
|
||||
}
|
||||
return `${prefix}_${newBaseName}`;
|
||||
}
|
||||
|
||||
referencedEdges = await collectionsModel(organization)
|
||||
.find({
|
||||
isArchive: false,
|
||||
projectId,
|
||||
attributes: {
|
||||
$elemMatch: {
|
||||
"refKey.fieldId": new mongoose.Types.ObjectId(fieldId),
|
||||
},
|
||||
},
|
||||
})
|
||||
.select("attributes projectId collectionName type");
|
||||
|
||||
if (referencedEdges.length) {
|
||||
for (const doc of referencedEdges) {
|
||||
let updated = false;
|
||||
|
||||
try {
|
||||
for (const oldattr of doc.attributes) {
|
||||
console.log("oldattr: ", oldattr);
|
||||
const refKey = oldattr.refKey as any;
|
||||
if (
|
||||
refKey?.collection_id?.toString() ===
|
||||
collectionNodeId.toString() &&
|
||||
refKey?.fieldId?.toString() === fieldId.toString()
|
||||
) {
|
||||
const oldType = oldattr.type;
|
||||
const newType = attr.type;
|
||||
oldattr.type = newType as any;
|
||||
if (refKey?.fieldId?.toString() === fieldId.toString()) {
|
||||
const oldName = oldattr.key;
|
||||
const updateName = attr.key;
|
||||
const newKey = updateModelName(oldName, updateName);
|
||||
oldattr.key = newKey;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
doc.markModified("attributes");
|
||||
await doc.save();
|
||||
}
|
||||
} catch (err: any) {
|
||||
@@ -839,9 +951,9 @@ export const UpdateAttributes = async (
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
console.log("editCollection", editCollection);
|
||||
// console.log("editCollection", editCollection);
|
||||
}
|
||||
return { status: "Success" };
|
||||
return { status: "Success", data: referencedEdges };
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
@@ -1142,23 +1254,24 @@ export const DuplicateAttributes = async (
|
||||
(attr: any) => attr.key.toLowerCase() === attrKey.toLowerCase()
|
||||
);
|
||||
|
||||
console.log("existingAttr: ", existingAttr);
|
||||
if (existingAttr) {
|
||||
let counter = 1;
|
||||
let newKey = `${attrKey}(${counter})`;
|
||||
console.log("attrKey: ", attrKey);
|
||||
console.log("newKey: ", newKey);
|
||||
|
||||
while (
|
||||
existingCollection.attributes.some(
|
||||
(attr: any) => attr.key === newKey
|
||||
)
|
||||
) {
|
||||
console.log("hi");
|
||||
counter++;
|
||||
newKey = `${attrKey}(${counter})`;
|
||||
console.log("newKey: ", newKey);
|
||||
}
|
||||
|
||||
// existingCollection.attributes.push({
|
||||
// key: newKey,
|
||||
// type: existingAttr.type,
|
||||
// isArchive: false,
|
||||
// });
|
||||
} else {
|
||||
return { status: "Attribute doesnot match" };
|
||||
}
|
||||
@@ -1230,7 +1343,6 @@ export const DelAttributes = async (
|
||||
data: IAttributesDel
|
||||
): Promise<Iresponse> => {
|
||||
const { organization, userId, projectId, collectionNodeId, fieldId } = data;
|
||||
console.log("data: ", data);
|
||||
|
||||
try {
|
||||
const existingUser = await userModel(organization).findOne({
|
||||
@@ -1251,7 +1363,6 @@ export const DelAttributes = async (
|
||||
isArchive: false,
|
||||
"attributes._id": new mongoose.Types.ObjectId(fieldId),
|
||||
});
|
||||
console.log("existingCollection: ", existingCollection);
|
||||
if (!existingCollection) return { status: "Collection not found" };
|
||||
|
||||
const attribute = existingCollection.attributes.find(
|
||||
@@ -1315,7 +1426,6 @@ export const addAttributes = async (
|
||||
): Promise<Iresponse> => {
|
||||
const { organization, projectId, userId, collectionNodeId, attributes } =
|
||||
data;
|
||||
console.log("data: ", data);
|
||||
|
||||
try {
|
||||
const existingUser = await userModel(organization).findOne({
|
||||
@@ -1343,7 +1453,6 @@ export const addAttributes = async (
|
||||
const duplicate = existingAttributes.find(
|
||||
(exAttr) => exAttr.key === attr.key && !exAttr.isArchive
|
||||
);
|
||||
console.log("duplicate: ", duplicate);
|
||||
if (duplicate) {
|
||||
return { status: `Attribute "${attr.key}" already exists` };
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@ interface IEdgeDelete {
|
||||
userId: string;
|
||||
edgeId: string;
|
||||
}
|
||||
interface Attribute {
|
||||
interface IAttribute {
|
||||
_id?: string;
|
||||
key: string;
|
||||
type: string;
|
||||
keyType?: string;
|
||||
isArchive: boolean;
|
||||
|
||||
refKey?: {
|
||||
@@ -38,6 +40,7 @@ interface Attribute {
|
||||
}
|
||||
export const edgecreation = async (data: IEdge): Promise<Iresponse> => {
|
||||
const { organization, projectId, from, to, cardinality, userId } = data;
|
||||
console.log("data:edge ", data);
|
||||
|
||||
try {
|
||||
const ExistingUser = await userModel(organization).findOne({
|
||||
@@ -82,49 +85,84 @@ export const edgecreation = async (data: IEdge): Promise<Iresponse> => {
|
||||
const collectionName = existingFromCollection.collectionName;
|
||||
const fieldName = from.field;
|
||||
|
||||
const newFieldKey = `${collectionName}_${capitalizeFirst(fieldName)}`;
|
||||
// const newFieldKey = `${collectionName}_${capitalizeFirst(fieldName)}`;
|
||||
// console.log("newFieldKey: ", newFieldKey);
|
||||
|
||||
const fromField = existingFromCollection.attributes.find(
|
||||
(attr: any) => attr.key === from.field
|
||||
);
|
||||
if (!fromField) {
|
||||
return { status: "From field not found" };
|
||||
}
|
||||
|
||||
const fromFieldId = [fromField].map((attr: any) => attr?._id)[0];
|
||||
console.log("fromFieldId: ", fromFieldId);
|
||||
const resolvedKey = await resolveForeignKey(
|
||||
organization,
|
||||
existingFromCollection,
|
||||
fromField as any
|
||||
);
|
||||
console.log("resolvedKey: ", resolvedKey);
|
||||
|
||||
|
||||
const newFieldKey = `${resolvedKey.sourceCollectionName}_${capitalizeFirst(
|
||||
resolvedKey.sourceFieldName
|
||||
)}`;
|
||||
|
||||
console.log('newFieldKey: ', newFieldKey);
|
||||
const fieldType = normalizeType(fromField?.type);
|
||||
// console.log("fieldType: ", fieldType);
|
||||
|
||||
const fieldExists = existingToCollection.attributes.some(
|
||||
(attr: any) => attr.key === newFieldKey
|
||||
);
|
||||
console.log('fieldExists: ', fieldExists);
|
||||
// const keyType =
|
||||
// fromField?.keyType === "primary" ? "foreign" : fromField?.keyType;
|
||||
// console.log('keyType: ', keyType);
|
||||
|
||||
if (!fieldExists) {
|
||||
const newAttribute: any = {
|
||||
key: newFieldKey,
|
||||
type: fieldType,
|
||||
keyType: resolvedKey.keyType,
|
||||
|
||||
refKey: {
|
||||
collection_id: existingFromCollection._id,
|
||||
fieldId: fromFieldId,
|
||||
// collection_id: existingFromCollection._id,
|
||||
// fieldId: fromFieldId,
|
||||
collection_id: resolvedKey.sourceCollectionId,
|
||||
fieldId: resolvedKey.sourceFieldId,
|
||||
},
|
||||
};
|
||||
const fieldExists = existingToCollection.attributes.some(
|
||||
(attr: any) => attr.key === newFieldKey
|
||||
);
|
||||
|
||||
existingToCollection.attributes.push(newAttribute);
|
||||
console.log('newAttribute: ', newAttribute);
|
||||
if (!fieldExists) {
|
||||
existingToCollection.attributes.push(newAttribute);
|
||||
await existingToCollection.save();
|
||||
|
||||
console.log(
|
||||
`✅ Added new foreign key '${newFieldKey}' in '${existingToCollection.collectionName}' referencing '${resolvedKey.sourceCollectionName}.${resolvedKey.sourceFieldName}'`
|
||||
);
|
||||
} else {
|
||||
console.log(`⚠️ Field '${newFieldKey}' already exists in '${existingToCollection.collectionName}'`);
|
||||
}
|
||||
// existingToCollection.attributes.push(newAttribute);
|
||||
|
||||
// existingToCollection.attributes = existingToCollection.attributes.map(
|
||||
// (attr: any) => ({
|
||||
// ...attr,
|
||||
// type: normalizeType(attr.type),
|
||||
// })
|
||||
// );
|
||||
|
||||
existingToCollection.attributes = existingToCollection.attributes.map(
|
||||
(attr: any) => ({
|
||||
...attr,
|
||||
type: normalizeType(attr.type),
|
||||
})
|
||||
// await existingToCollection.save();
|
||||
console.log("existingToCollection: ", existingToCollection);
|
||||
const savedToCollection = await collectionsModel(organization).findById(
|
||||
existingToCollection._id
|
||||
);
|
||||
const lastAttr = savedToCollection?.attributes?.at(-1);
|
||||
|
||||
await existingToCollection.save();
|
||||
const savedToCollection = await collectionsModel(organization).findById(existingToCollection._id);
|
||||
const lastAttr = savedToCollection?.attributes?.at(-1);
|
||||
|
||||
const fieldIdTo = (lastAttr as any)?._id;
|
||||
console.log('fieldIdTo: ', fieldIdTo);
|
||||
const fieldIdTo = (lastAttr as any)?._id;
|
||||
|
||||
// console.log(
|
||||
// `Field ${newFieldKey} (type: ${fieldType}) added to TO collection with reference to ${existingFromCollection._id}`
|
||||
@@ -132,8 +170,12 @@ console.log('fieldIdTo: ', fieldIdTo);
|
||||
|
||||
const newEdge = {
|
||||
projectId,
|
||||
from: { collection_id: existingFromCollection._id, field: from.field,fieldId:fromFieldId },
|
||||
to: { collection_id: existingToCollection._id ,fieldId:fieldIdTo},
|
||||
from: {
|
||||
collection_id: existingFromCollection._id,
|
||||
field: from.field,
|
||||
fieldId: fromFieldId,
|
||||
},
|
||||
to: { collection_id: existingToCollection._id, fieldId: fieldIdTo },
|
||||
cardinality,
|
||||
createdAt: new Date(),
|
||||
};
|
||||
@@ -208,7 +250,6 @@ export const Alledges = async (data: IAllEdge): Promise<Iresponse> => {
|
||||
};
|
||||
export const deleteEdge = async (data: IEdgeDelete): Promise<Iresponse> => {
|
||||
const { organization, projectId, edgeId, userId } = data;
|
||||
console.log('data:edge ', data);
|
||||
|
||||
try {
|
||||
const ExistingUser = await userModel(organization).findOne({
|
||||
@@ -264,7 +305,6 @@ export const deleteEdge = async (data: IEdgeDelete): Promise<Iresponse> => {
|
||||
console.log("Matched attribute not found in array");
|
||||
}
|
||||
} else {
|
||||
// console.log('No attribute matches the given collection_id');
|
||||
return { status: "No deleted in matched Document" };
|
||||
}
|
||||
}
|
||||
@@ -312,3 +352,133 @@ const normalizeType = (type: any): string => {
|
||||
|
||||
return "string"; // fallback
|
||||
};
|
||||
interface IResolvedKey {
|
||||
keyType: string;
|
||||
sourceCollectionName: string;
|
||||
sourceCollectionId: string;
|
||||
sourceFieldId: string;
|
||||
sourceFieldName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the true origin of a foreign key.
|
||||
* If "fromField" is a foreign key, it recursively traces back
|
||||
* to its original primary field and returns its reference info.
|
||||
*/
|
||||
// export const resolveForeignKey = async (
|
||||
// organization: string,
|
||||
// fromCollection: any,
|
||||
// fromField: IAttribute
|
||||
// ): Promise<IResolvedKey> => {
|
||||
// if (!fromField) {
|
||||
// return {
|
||||
// keyType: "normal",
|
||||
// sourceCollectionName: fromCollection.collectionName,
|
||||
// sourceCollectionId: fromCollection._id?.toString?.() || "",
|
||||
// sourceFieldId: "",
|
||||
// sourceFieldName: "",
|
||||
// };
|
||||
// }
|
||||
// let keyType = fromField?.keyType || "normal";
|
||||
// let sourceCollectionName = fromCollection.collectionName;
|
||||
// let sourceCollectionId = fromCollection._id?.toString?.() || "";
|
||||
// let sourceFieldId = fromField?._id?.toString?.() || "";
|
||||
// let sourceFieldName = fromField?.key || "";
|
||||
|
||||
// // 🔁 If the field is foreign → trace back to original primary
|
||||
// if (fromField?.keyType === "foreign" && fromField?.refKey) {
|
||||
// const refCol = await collectionsModel(organization).findById(
|
||||
// fromField.refKey.collection_id
|
||||
// );
|
||||
|
||||
// if (refCol) {
|
||||
// const primaryAttr = (refCol.attributes as IAttribute[]).find(
|
||||
// (attr) => attr?._id?.toString?.() === fromField.refKey?.fieldId
|
||||
// );
|
||||
|
||||
// if (primaryAttr) {
|
||||
// console.log("🔁 Tracing back to original primary field...");
|
||||
|
||||
// // Recursive call to ensure multi-level tracing
|
||||
// return await resolveForeignKey(organization, refCol, primaryAttr);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // ✅ If the field is primary, mark the propagated key as foreign
|
||||
// if (fromField?.keyType === "primary") {
|
||||
// keyType = "foreign";
|
||||
// }
|
||||
|
||||
// return {
|
||||
// keyType,
|
||||
// sourceCollectionName,
|
||||
// sourceCollectionId,
|
||||
// sourceFieldId,
|
||||
// sourceFieldName,
|
||||
// };
|
||||
// };
|
||||
export const resolveForeignKey = async (
|
||||
organization: string,
|
||||
fromCollection: any,
|
||||
fromField?: IAttribute
|
||||
): Promise<IResolvedKey> => {
|
||||
if (!fromField || !fromCollection) {
|
||||
return {
|
||||
keyType: "normal",
|
||||
sourceCollectionName: fromCollection?.collectionName || "",
|
||||
sourceCollectionId: fromCollection?._id?.toString?.() || "",
|
||||
sourceFieldId: "",
|
||||
sourceFieldName: "",
|
||||
};
|
||||
}
|
||||
|
||||
let keyType = fromField.keyType || "normal";
|
||||
let sourceCollectionName = fromCollection.collectionName;
|
||||
let sourceCollectionId = fromCollection._id?.toString?.() || "";
|
||||
let sourceFieldId = fromField._id?.toString?.() || "";
|
||||
let sourceFieldName = fromField.key || "";
|
||||
|
||||
// 🔁 Recursive tracing for both FOREIGN and SECONDARY with refKey
|
||||
if (
|
||||
(fromField.keyType === "foreign" || fromField.keyType === "secondary") &&
|
||||
fromField.refKey
|
||||
) {
|
||||
const refCol = await collectionsModel(organization).findById(
|
||||
fromField.refKey.collection_id
|
||||
);
|
||||
|
||||
if (refCol) {
|
||||
const refField = (refCol.attributes as IAttribute[]).find(
|
||||
(attr) => attr?._id?.toString?.() === fromField.refKey?.fieldId
|
||||
);
|
||||
|
||||
if (refField) {
|
||||
console.log(
|
||||
`🔁 Tracing ${fromField.keyType} key ${fromField.key} → ${refCol.collectionName}.${refField.key}`
|
||||
);
|
||||
// Recursive call — trace until primary
|
||||
return await resolveForeignKey(organization, refCol, refField);
|
||||
} else {
|
||||
console.warn(
|
||||
`⚠️ Field not found for refKey.fieldId: ${fromField.refKey?.fieldId}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.warn(
|
||||
`⚠️ Collection not found for refKey.collection_id: ${fromField.refKey?.collection_id}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Convert primary to foreign for propagation
|
||||
if (fromField.keyType === "primary") keyType = "foreign";
|
||||
|
||||
return {
|
||||
keyType,
|
||||
sourceCollectionName,
|
||||
sourceCollectionId,
|
||||
sourceFieldId,
|
||||
sourceFieldName,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -32,9 +32,7 @@ export const folderProject = async (
|
||||
return result;
|
||||
};
|
||||
const FILE_BACKEND_URL = process.env.FILE_BACKEND_URL;
|
||||
console.log('FILE_BACKEND_URL: ', FILE_BACKEND_URL);
|
||||
export const modelNodeFile = async (data: { projectName: string; models1: any[] }) => {
|
||||
console.log('data:test ', data);
|
||||
const FILE_BACKEND_URL = process.env.FILE_BACKEND_URL;
|
||||
if (!FILE_BACKEND_URL) throw new Error("❌ FILE_BACKEND_URL not set");
|
||||
|
||||
|
||||
@@ -229,7 +229,6 @@ export const projectDatas = async (data: IgetProject): Promise<Iresponse> => {
|
||||
})
|
||||
.skip(skipdata)
|
||||
.limit(limitdata);
|
||||
console.log('projectDatas: ', projectDatas);
|
||||
if (!projectDatas) return { status: "No project found" };
|
||||
|
||||
// const formattedProjects = projectDatas.map((proj: any) => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
FinalResponse,
|
||||
validateFields,
|
||||
} from "../utils/socketfunctionHelpers";
|
||||
import { emitToSenderAndAdmins } from "../utils/emitEventResponse";
|
||||
import { emitToRoom } from "../utils/emitEventResponse";
|
||||
import { deleteEdge, edgecreation } from "../../shared/services/edgeService";
|
||||
import {
|
||||
addAttributes,
|
||||
@@ -31,14 +31,20 @@ export const CollectionHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionCreateResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionCreateResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await Nodecreation(data);
|
||||
@@ -63,15 +69,15 @@ export const CollectionHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionCreateResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
console.log('room: ', room);
|
||||
emitToRoom(io, socket, room, EVENTS.collectionCreateResponse, response);
|
||||
}
|
||||
};
|
||||
export const CollectionUpdateHandleEvent = async (
|
||||
event: string,
|
||||
@@ -87,18 +93,24 @@ export const CollectionUpdateHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionUpdateResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionUpdateResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await updatecollection(data);
|
||||
console.log('result: ', result);
|
||||
|
||||
const status = typeof result?.status === "string" ? result.status : "unknown";
|
||||
|
||||
const messages: Record<string, { message: string }> = {
|
||||
@@ -107,10 +119,9 @@ export const CollectionUpdateHandleEvent = async (
|
||||
"User not found": { message: "User not found" },
|
||||
"Collection not found": { message: "Collection not found" },
|
||||
"Invalid ID": { message: "nvalid ID provided" },
|
||||
|
||||
};
|
||||
const result_Datas =
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
|
||||
const response = FinalResponse(
|
||||
status,
|
||||
@@ -119,15 +130,14 @@ export const CollectionUpdateHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionUpdateResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(io, socket, room, EVENTS.collectionUpdateResponse, response);
|
||||
}
|
||||
};
|
||||
|
||||
export const CollectioDeleteHandleEvent = async (
|
||||
@@ -144,14 +154,20 @@ export const CollectioDeleteHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await delCollection(data);
|
||||
@@ -174,15 +190,14 @@ export const CollectioDeleteHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionDeleteResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(io, socket, room, EVENTS.collectionDeleteResponse, response);
|
||||
}
|
||||
};
|
||||
export const CollectioDuplicateHandleEvent = async (
|
||||
event: string,
|
||||
@@ -198,14 +213,20 @@ export const CollectioDuplicateHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await DuplicateCollection(data);
|
||||
@@ -229,15 +250,14 @@ export const CollectioDuplicateHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionDuplicateResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(io, socket, room, EVENTS.collectionDuplicateResponse, response);
|
||||
}
|
||||
};
|
||||
export const setAttributesHandleEvent = async (
|
||||
event: string,
|
||||
@@ -258,14 +278,20 @@ export const setAttributesHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeSetResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeSetResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await addAttributes(data);
|
||||
@@ -288,15 +314,20 @@ export const setAttributesHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeSetResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeSetResponse,
|
||||
response
|
||||
);
|
||||
}
|
||||
};
|
||||
export const AttributesDeleteHandleEvent = async (
|
||||
event: string,
|
||||
@@ -317,14 +348,20 @@ export const AttributesDeleteHandleEvent = async (
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeDeleteResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await DelAttributes(data);
|
||||
@@ -342,9 +379,7 @@ export const AttributesDeleteHandleEvent = async (
|
||||
const result_Datas =
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
const result1_Datas =
|
||||
(status === "Success") && result?.data
|
||||
? result.data
|
||||
: undefined;
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
const response = FinalResponse(
|
||||
status,
|
||||
socket,
|
||||
@@ -352,15 +387,20 @@ export const AttributesDeleteHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeDeleteResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeDeleteResponse,
|
||||
response
|
||||
);
|
||||
}
|
||||
};
|
||||
export const AttributesUpdateHandleEvent = async (
|
||||
event: string,
|
||||
@@ -372,22 +412,24 @@ export const AttributesUpdateHandleEvent = async (
|
||||
}
|
||||
) => {
|
||||
if (event !== EVENTS.collectionAttributeUpdate || !data?.organization) return;
|
||||
const requiredFields = [
|
||||
"collectionNodeId",
|
||||
"projectId",
|
||||
"organization",
|
||||
];
|
||||
const requiredFields = ["collectionNodeId", "projectId", "organization"];
|
||||
const missingFields = validateFields(data, requiredFields);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeUpdateResponse,
|
||||
ErrorResponse(missingFields, socket, data.organization),
|
||||
connectedUsersByOrg
|
||||
);
|
||||
let room: string | undefined;
|
||||
|
||||
if (data?.projectId) {
|
||||
room = data.projectId.toString();
|
||||
}
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeUpdateResponse,
|
||||
ErrorResponse(missingFields, socket, room)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const result = await UpdateAttributes(data);
|
||||
@@ -402,9 +444,7 @@ export const AttributesUpdateHandleEvent = async (
|
||||
const msg = messages[status] || { message: "Internal server error" };
|
||||
|
||||
const result_Datas =
|
||||
(status === "Success") && result?.data
|
||||
? result.data
|
||||
: undefined;
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
const response = FinalResponse(
|
||||
status,
|
||||
socket,
|
||||
@@ -412,13 +452,18 @@ export const AttributesUpdateHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
let room: string | undefined;
|
||||
if (data?.projectId) {
|
||||
room = data?.projectId;
|
||||
}
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
socket,
|
||||
data.organization,
|
||||
EVENTS.collectionAttributeUpdateResponse,
|
||||
response,
|
||||
connectedUsersByOrg
|
||||
);
|
||||
if (room) {
|
||||
emitToRoom(
|
||||
io,
|
||||
socket,
|
||||
room,
|
||||
EVENTS.collectionAttributeUpdateResponse,
|
||||
response
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,7 +37,6 @@ export const edgeHandleEvent = async (
|
||||
}
|
||||
const result = await edgecreation(data);
|
||||
|
||||
console.log('result: ', result);
|
||||
const status = typeof result?.status === "string" ? result.status : "unknown";
|
||||
|
||||
const messages: Record<string, { message: string }> = {
|
||||
@@ -55,7 +54,6 @@ export const edgeHandleEvent = async (
|
||||
const msg = messages[status] || { message: "Internal server error" };
|
||||
const result_Datas =
|
||||
status === "Success" && result?.data ? result.data : undefined;
|
||||
console.log('result_Datas: ', result_Datas);
|
||||
|
||||
const response = FinalResponse(
|
||||
status,
|
||||
@@ -64,7 +62,6 @@ export const edgeHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
console.log('response: ', response);
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
@@ -104,7 +101,6 @@ export const deleteEdgeHandleEvent = async (
|
||||
return;
|
||||
}
|
||||
const result = await deleteEdge(data);
|
||||
console.log('result: ', result);
|
||||
const status = typeof result?.status === "string" ? result.status : "unknown";
|
||||
|
||||
const messages: Record<string, { message: string }> = {
|
||||
@@ -122,7 +118,6 @@ export const deleteEdgeHandleEvent = async (
|
||||
messages,
|
||||
result_Datas
|
||||
);
|
||||
console.log('response: ', response);
|
||||
|
||||
emitToSenderAndAdmins(
|
||||
io,
|
||||
|
||||
@@ -48,7 +48,6 @@ export const projectHandleEvent = async (
|
||||
}
|
||||
const subBkd = process.env.FILE_BACKEND_URL;
|
||||
if (!subBkd) {
|
||||
console.log('!subBkd: ', subBkd);
|
||||
// res.status(500).json({
|
||||
// message: "mainBkdUrl not configured",
|
||||
// });
|
||||
@@ -186,7 +185,6 @@ export const projectDeleteHandleEvent = async (
|
||||
return;
|
||||
}
|
||||
const result = await DeleteProject(data);
|
||||
console.log('result: ', result);
|
||||
const status = typeof result?.status === "string" ? result.status : "unknown";
|
||||
|
||||
const messages: Record<string, { message: string }> = {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Server, Socket } from "socket.io";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { eventHandlerMap } from "../events/eventHandaler";
|
||||
import { existingUserData } from "../../shared/services/AuthService";
|
||||
import { joinRoom, leaveRoom } from "../utils/room";
|
||||
|
||||
interface UserPayload {
|
||||
userId: string;
|
||||
@@ -111,12 +112,30 @@ export const SocketServer = async (io: Server) => {
|
||||
organization,
|
||||
});
|
||||
// console.log(`✅ Connected to namespace ${nspName}: ${socket.id}`);
|
||||
socket.on("joinRoom", (data) => {
|
||||
if (!data?.projectId) {
|
||||
console.warn("❌ joinRoom missing projectId or versionId");
|
||||
return;
|
||||
}
|
||||
joinRoom(io, socket, {
|
||||
projectId: data.projectId,
|
||||
|
||||
// Common event handler
|
||||
userId,
|
||||
organization,
|
||||
});
|
||||
});
|
||||
// Group api socket event creation and some bug modification
|
||||
// ✅ Optional leave room listener
|
||||
socket.on("leaveRoom", (data) => {
|
||||
if (!data?.projectId) return;
|
||||
leaveRoom(io, socket, {
|
||||
projectId: data.projectId,
|
||||
organization,
|
||||
userId,
|
||||
});
|
||||
});
|
||||
socket.onAny((event: string, data: any, callback: any) => {
|
||||
// console.log("🔥 Incoming socket event:", event);
|
||||
const handler = eventHandlerMap[event];
|
||||
// console.log("handler:", handler ? "✅ found" : "❌ undefined");
|
||||
if (handler) {
|
||||
handler(event, socket, io, data, connectedUsersByOrg, callback);
|
||||
} else {
|
||||
|
||||
@@ -91,11 +91,11 @@ export const emitToRoom = (
|
||||
organization: result.organization,
|
||||
};
|
||||
|
||||
console.log("🔥 EMIT TO ROOM:");
|
||||
console.log("➡️ Event: ", event);
|
||||
// console.log("🔥 EMIT TO ROOM:");
|
||||
// console.log("➡️ Event: ", event);
|
||||
console.log("📦 Full result input: ", result); // 👉 what you passed from observer
|
||||
console.log("📤 Final payload being emitted: ", payload); // 👉 actual emitted payload
|
||||
console.log("🏠 Room: ", room);
|
||||
// console.log("📤 Final payload being emitted: ", payload); // 👉 actual emitted payload
|
||||
// console.log("🏠 Room: ", room);
|
||||
|
||||
socket.to(room).emit(event, payload);
|
||||
|
||||
|
||||
125
src/socket-server/utils/room.ts
Normal file
125
src/socket-server/utils/room.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import { Server, Socket } from "socket.io";
|
||||
import { emitToRoom } from "./emitEventResponse";
|
||||
import userModel from "../../shared/model/userModel";
|
||||
import { EVENTS } from "../events/events";
|
||||
|
||||
const userFollowMap = new Map<string, string>(); // socketId -> followingUser
|
||||
|
||||
interface JoinRoomInput { projectId: string; userId: string; organization: string; }
|
||||
interface LeaveRoomInput { projectId: string; userId: string; organization: string; }
|
||||
|
||||
// Build room data including followingUser
|
||||
// export async function buildRoomDatas(socket: Socket, projectId: string, organization: string) {
|
||||
// let roomDatas: { roomName: string; Users: string[]; UsersDetails: any[] } | null = null;
|
||||
// const rooms = socket.nsp.adapter.rooms;
|
||||
|
||||
// for (const [roomName, socketsSet] of rooms) {
|
||||
// if (socket.nsp.sockets.get(roomName)) continue; // skip personal room
|
||||
|
||||
// // Collect all users in the room
|
||||
// const roomUsers = [...socketsSet].map(id => {
|
||||
// const s = socket.nsp.sockets.get(id);
|
||||
// return {
|
||||
// userId: s?.data.userId || id,
|
||||
// socketId: id // store socketId for followUser map lookup
|
||||
// };
|
||||
// });
|
||||
|
||||
// const userIds = roomUsers.map(u => u.userId);
|
||||
|
||||
// const usersFromDB = await userModel(organization).find({ _id: { $in: userIds }, isArchive: false });
|
||||
|
||||
// const userdatas = usersFromDB.flatMap(user => {
|
||||
// const userCams = cameraFromDB.filter(cam => cam.userId.toString() === user._id.toString());
|
||||
|
||||
// // find the socketId of this user in the room
|
||||
// const userSocketId = roomUsers.find(u => u.userId === user._id.toString())?.socketId;
|
||||
// const followingUser = userSocketId ? userFollowMap.get(userSocketId) || null : null;
|
||||
|
||||
// if (userCams.length === 0) {
|
||||
// return [{
|
||||
// userId: user._id.toString(),
|
||||
// userName: user.userName,
|
||||
// projectId,
|
||||
// versionId: "",
|
||||
// camData: { position: { x:0, y:40, z:30 }, rotation: { x:0, y:0, z:0 }, target: { x:0, y:0, z:0 } },
|
||||
// followingUser
|
||||
// }];
|
||||
// }
|
||||
|
||||
// return userCams.map(cam => ({
|
||||
// userId: user._id.toString(),
|
||||
// userName: user.userName,
|
||||
// projectId: cam.projectId.toString(),
|
||||
// versionId: cam.versionId?.toString() || "",
|
||||
// camData: { position: cam.position, rotation: cam.rotation, target: cam.target },
|
||||
// followingUser
|
||||
// }));
|
||||
// });
|
||||
|
||||
// roomDatas = { roomName, Users: roomUsers.map(u => u.userId), UsersDetails: userdatas };
|
||||
// break; // only process the first room
|
||||
// }
|
||||
|
||||
// return roomDatas || { roomName: projectId, Users: [], UsersDetails: [] };
|
||||
// }
|
||||
|
||||
|
||||
// Join Room
|
||||
export const joinRoom = async (io: Server, socket: Socket, data: JoinRoomInput) => {
|
||||
const { projectId, organization, userId } = data;
|
||||
socket.data.userId = userId;
|
||||
const room = `${projectId}`;
|
||||
await socket.join(room);
|
||||
|
||||
// const roomDatas = await buildRoomDatas(socket, projectId, organization);
|
||||
|
||||
// emitToRoom(io, socket, room, EVENTS.roomUserData_v1, {
|
||||
// // data: roomDatas,
|
||||
// socketId: socket.id
|
||||
// });
|
||||
|
||||
return room;
|
||||
};
|
||||
|
||||
// Leave Room
|
||||
export const leaveRoom = async (io: Server, socket: Socket, data: LeaveRoomInput) => {
|
||||
const { projectId, userId, organization } = data;
|
||||
const room = `${projectId}`;
|
||||
socket.leave(room);
|
||||
|
||||
// const roomDatas = await buildRoomDatas(socket, projectId, organization);
|
||||
|
||||
// emitToRoom(io, socket, room, EVENTS.roomUserData_v1, {
|
||||
// data: roomDatas || { roomName: projectId, Users: [], UsersDetails: [] },
|
||||
// message: `${userId} left the room`,
|
||||
// socketId: socket.id
|
||||
// });
|
||||
|
||||
userFollowMap.delete(socket.id);
|
||||
|
||||
return room;
|
||||
};
|
||||
|
||||
// Follow User
|
||||
// export const setupFollowUser = (io: Server, socket: Socket) => {
|
||||
// socket.on(EVENTS.roomUserData_setV1, async (data: { projectId: string; followingUser: string; organization: string }) => {
|
||||
// const { projectId, followingUser, organization } = data;
|
||||
|
||||
// userFollowMap.set(socket.id, followingUser);
|
||||
|
||||
// const roomDatas = await buildRoomDatas(socket, projectId, organization);
|
||||
// const room = `${projectId}`;
|
||||
|
||||
// // emitToRoom(io, socket, room, EVENTS.roomUserData_v1, {
|
||||
// // data: roomDatas,
|
||||
// // socketId: socket.id
|
||||
// // });
|
||||
|
||||
// // console.log(`User ${socket.data.userId} followed: ${followingUser}`);
|
||||
// });
|
||||
|
||||
// socket.on("disconnect", () => {
|
||||
// userFollowMap.delete(socket.id);
|
||||
// });
|
||||
// };
|
||||
Reference in New Issue
Block a user