This commit is contained in:
2025-11-14 14:47:26 +00:00
parent 69ecf2c7c1
commit 3b4876793e
104 changed files with 231517 additions and 1029 deletions
+88 -24
View File
@@ -8,7 +8,11 @@ import { useNavigationStore } from '../../stores/navigationStore';
import { DatabaseNameService } from './databaseNameService';
// Dev configuration - only hardcoded value we need
const DEV_SCHOOL_UUID = 'kevlarai';
const DEV_SCHOOL_NAME = 'default';
const DEV_SCHOOL_GROUP = 'development'
const ADMIN_USER_NAME = 'kcar';
const ADMIN_USER_GROUP = 'admin';
interface ShapeState {
parentId: TLShapeId | null;
@@ -29,8 +33,8 @@ interface NodeResponse {
interface NodeDataResponse {
__primarylabel__: string;
unique_id: string;
tldraw_snapshot: string;
uuid_string: string;
node_storage_path: string;
created: string;
merged: string;
state: ShapeState | null;
@@ -47,7 +51,7 @@ interface DefaultNodeResponse {
status: string;
node: {
id: string;
tldraw_snapshot: string;
node_storage_path: string;
type: string;
label: string;
data: NodeDataResponse;
@@ -195,7 +199,7 @@ export class UserNeoDBService {
} as CCCalendarNodeProps;
logger.debug('neo4j-service', '✅ Found calendar node', {
nodeId: calendarNode.id,
tldraw_snapshot: calendarNode.data.tldraw_snapshot
node_storage_path: calendarNode.data.node_storage_path
});
} else {
logger.debug('neo4j-service', '️ No calendar node found');
@@ -224,7 +228,7 @@ export class UserNeoDBService {
} as CCTeacherNodeProps;
logger.debug('neo4j-service', '✅ Found teacher node', {
nodeId: teacherNode.id,
tldraw_snapshot: teacherNode.data.tldraw_snapshot,
node_storage_path: teacherNode.data.node_storage_path,
userDbName,
workerDbName
});
@@ -242,9 +246,9 @@ export class UserNeoDBService {
hasCalendar: !!processedNodes.connectedNodes.calendar,
hasTeacher: !!processedNodes.connectedNodes.teacher,
teacherData: processedNodes.connectedNodes.teacher ? {
unique_id: processedNodes.connectedNodes.teacher.unique_id,
uuid_string: processedNodes.connectedNodes.teacher.uuid_string,
school_db_name: processedNodes.connectedNodes.teacher.school_db_name,
tldraw_snapshot: processedNodes.connectedNodes.teacher.tldraw_snapshot
node_storage_path: processedNodes.connectedNodes.teacher.node_storage_path
} : null
});
@@ -259,8 +263,8 @@ export class UserNeoDBService {
}
}
static getUserDatabaseName(userType: string, username: string): string {
return DatabaseNameService.getUserPrivateDB(userType, username);
static getUserDatabaseName(userType: string, identifier: string): string {
return DatabaseNameService.getUserPrivateDB(userType, identifier);
}
static getSchoolDatabaseName(schoolId: string): string {
@@ -268,10 +272,10 @@ export class UserNeoDBService {
}
static getDefaultSchoolDatabaseName(): string {
return DatabaseNameService.getDevelopmentSchoolDB();
return DatabaseNameService.getStoredSchoolDatabase() || '';
}
static async fetchNodeData(nodeId: string, dbName: string): Promise<{ node_type: string; node_data: NodeResponse['nodes']['userNode'] } | null> {
static async fetchNodeData(nodeId: string, dbName: string): Promise<{ node_type: string; node_data: NodeDataResponse } | null> {
try {
logger.debug('neo4j-service', '🔄 Fetching node data', { nodeId, dbName });
@@ -279,11 +283,11 @@ export class UserNeoDBService {
status: string;
node: {
node_type: string;
node_data: NodeResponse['nodes']['userNode'];
node_data: NodeDataResponse;
};
}>('/database/tools/get-node', {
params: {
unique_id: nodeId,
uuid_string: nodeId,
db_name: dbName
}
});
@@ -300,18 +304,78 @@ export class UserNeoDBService {
}
static getNodeDatabaseName(node: NavigationNode): string {
// Validate that node and node_storage_path exist
if (!node || !node.node_storage_path) {
logger.error('neo4j-service', '❌ Invalid node or missing node_storage_path', {
node: node ? { id: node.id, type: node.type, label: node.label } : null,
hasStoragePath: !!node?.node_storage_path
});
throw new Error('Node is missing required storage path information');
}
// If the node path starts with /node_filesystem/users/, it's in a user database
if (node.tldraw_snapshot.startsWith('/node_filesystem/users/')) {
const parts = node.tldraw_snapshot.split('/');
if (node.node_storage_path.startsWith('users/')) {
const parts = node.node_storage_path.split('/');
const databaseIndex = parts.indexOf('databases');
if (databaseIndex >= 0 && parts.length > databaseIndex + 1) {
return parts[databaseIndex + 1];
}
// parts[3] should be the database name (e.g., cc.users.surfacedashdev3atkevlaraidotcom)
if (parts.length >= 4) {
return parts[3];
}
logger.warn('neo4j-service', '⚠️ Unexpected user path format', { path: node.node_storage_path });
return 'cc.users';
}
// For Supabase Storage paths (cc.public.snapshots/...), determine database based on node type
if (node.node_storage_path.startsWith('cc.public.snapshots/')) {
const parts = node.node_storage_path.split('/');
const nodeType = parts[1]; // e.g., 'User', 'Teacher', 'School'
if (nodeType === 'User') {
return DatabaseNameService.getStoredUserDatabase() || 'cc.users';
} else if (nodeType === 'Teacher' || nodeType === 'Student') {
return DatabaseNameService.getStoredSchoolDatabase() || 'cc.institutes';
} else if (nodeType === 'School') {
return DatabaseNameService.getStoredSchoolDatabase() || 'cc.institutes';
}
}
// For school/worker nodes, extract from the path or use a default
if (node.node_storage_path.startsWith('schools/')) {
const parts = node.node_storage_path.split('/');
const databaseIndex = parts.indexOf('databases');
if (databaseIndex >= 0 && parts.length > databaseIndex + 1) {
return parts[databaseIndex + 1];
}
if (parts.length >= 4) {
return parts[3];
}
const storedSchoolDb = DatabaseNameService.getStoredSchoolDatabase();
if (storedSchoolDb) {
logger.warn('neo4j-service', '⚠️ Falling back to stored school database name', {
path: node.node_storage_path,
storedSchoolDb
});
return storedSchoolDb;
}
logger.warn('neo4j-service', '⚠️ Could not determine school database from path', { path: node.node_storage_path });
return DatabaseNameService.getStoredSchoolDatabase() || 'cc.institutes';
}
// Try to extract from path, but provide fallback
const parts = node.node_storage_path.split('/');
if (parts.length >= 4) {
return parts[3];
}
// For school/worker nodes, extract from the path or use a default
if (node.tldraw_snapshot.includes('/schools/')) {
return `cc.institutes.${DEV_SCHOOL_UUID}`;
}
// Default to user database if we can't determine
return node.tldraw_snapshot.split('/')[3];
// Default fallback
logger.warn('neo4j-service', '⚠️ Using fallback database name', {
path: node.node_storage_path,
nodeType: node.type
});
return 'cc.users'; //TODO: remove hard-coding
}
static async getDefaultNode(context: NodeContext, dbName: string): Promise<NavigationNode | null> {
@@ -334,7 +398,7 @@ export class UserNeoDBService {
if (response.data?.status === 'success' && response.data.node) {
return {
id: response.data.node.id,
tldraw_snapshot: response.data.node.tldraw_snapshot,
node_storage_path: response.data.node.node_storage_path,
type: response.data.node.type,
label: response.data.node.label,
data: response.data.node.data
@@ -387,4 +451,4 @@ export class UserNeoDBService {
throw error;
}
}
}
}