@fjell/client-api 4.4.6 → 4.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Instance.d.ts +19 -0
- package/dist/Instance.js +19 -0
- package/dist/Instance.js.map +1 -0
- package/dist/InstanceFactory.d.ts +8 -0
- package/dist/InstanceFactory.js +19 -0
- package/dist/InstanceFactory.js.map +1 -0
- package/dist/Registry.d.ts +15 -0
- package/dist/Registry.js +31 -0
- package/dist/Registry.js.map +1 -0
- package/dist/index.cjs +106 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/examples/README.md +387 -0
- package/examples/enterprise-example.ts +852 -0
- package/examples/multi-level-keys.ts +467 -0
- package/examples/simple-example.ts +346 -0
- package/package.json +4 -3
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
/**
|
|
3
|
+
* Multi-Level Keys Fjell-Client-API Example - Hierarchical Data Operations
|
|
4
|
+
*
|
|
5
|
+
* This example demonstrates advanced usage of fjell-client-api with multi-level
|
|
6
|
+
* hierarchical data structures. It shows how to work with contained items across
|
|
7
|
+
* multiple organizational levels.
|
|
8
|
+
*
|
|
9
|
+
* This example covers:
|
|
10
|
+
* - Multi-level location hierarchies (Organization → Department → Employee)
|
|
11
|
+
* - Nested contained item APIs with location arrays
|
|
12
|
+
* - Cross-hierarchy queries and operations
|
|
13
|
+
* - Location-based data management
|
|
14
|
+
* - Complex API routing with multiple path segments
|
|
15
|
+
*
|
|
16
|
+
* Run this example with: npx tsx examples/multi-level-keys.ts
|
|
17
|
+
*
|
|
18
|
+
* Note: This is a conceptual example showing hierarchical API patterns.
|
|
19
|
+
* In production, use actual fjell-client-api with proper types.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Organizational Hierarchy:
|
|
24
|
+
* Organization (Primary) → Department (Contained) → Employee (Contained)
|
|
25
|
+
*
|
|
26
|
+
* API Structure:
|
|
27
|
+
* - /organizations/{orgId}
|
|
28
|
+
* - /organizations/{orgId}/departments/{deptId}
|
|
29
|
+
* - /organizations/{orgId}/departments/{deptId}/employees/{empId}
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
// ===== Mock Hierarchical API Implementations =====
|
|
33
|
+
|
|
34
|
+
interface MockHierarchicalApi {
|
|
35
|
+
all(query: any, locations?: any[]): Promise<any[]>;
|
|
36
|
+
create(item: any, locations?: any[]): Promise<any>;
|
|
37
|
+
get(key: any): Promise<any>;
|
|
38
|
+
update(key: any, updates: any): Promise<any>;
|
|
39
|
+
remove(key: any): Promise<boolean>;
|
|
40
|
+
action(key: any, action: string, body?: any): Promise<any>;
|
|
41
|
+
find(finder: string, params?: any, locations?: any[]): Promise<any[]>;
|
|
42
|
+
facet(key: any, facet: string, params?: any): Promise<any>;
|
|
43
|
+
allAction(action: string, body?: any, locations?: any[]): Promise<any[]>;
|
|
44
|
+
allFacet(facet: string, params?: any, locations?: any[]): Promise<any>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const createMockHierarchicalApi = (itemType: string, levelDepth: number): MockHierarchicalApi => ({
|
|
48
|
+
async all(query: any, locations?: any[]) {
|
|
49
|
+
const locationPath = locations ? `/${locations.join('/')}` : '';
|
|
50
|
+
console.log(`📊 HierarchicalApi.all(${itemType}) at level ${levelDepth} - path:${locationPath}, query:`, query);
|
|
51
|
+
|
|
52
|
+
const items = Array.from({ length: 3 }, (_, i) => ({
|
|
53
|
+
id: `${itemType}-${i + 1}`,
|
|
54
|
+
name: `${itemType} ${i + 1}`,
|
|
55
|
+
keyType: itemType,
|
|
56
|
+
...(locations && { parentPath: locations })
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
return items;
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
async create(item: any, locations?: any[]) {
|
|
63
|
+
const locationPath = locations ? `/${locations.join('/')}` : '';
|
|
64
|
+
const created = {
|
|
65
|
+
...item,
|
|
66
|
+
id: `${itemType}-${Date.now()}`,
|
|
67
|
+
parentPath: locations
|
|
68
|
+
};
|
|
69
|
+
console.log(`➕ HierarchicalApi.create(${itemType}) at level ${levelDepth} - path:${locationPath}, created:`, created.id);
|
|
70
|
+
return created;
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
async get(key: any) {
|
|
74
|
+
console.log(`🔍 HierarchicalApi.get(${itemType}) at level ${levelDepth} - key:`, key);
|
|
75
|
+
return {
|
|
76
|
+
id: key.id,
|
|
77
|
+
name: `${itemType} ${key.id}`,
|
|
78
|
+
keyType: itemType,
|
|
79
|
+
level: levelDepth
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
async update(key: any, updates: any) {
|
|
84
|
+
console.log(`✏️ HierarchicalApi.update(${itemType}) at level ${levelDepth} - key:`, key, 'updates:', updates);
|
|
85
|
+
return { id: key.id, ...updates, keyType: itemType, level: levelDepth };
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
async remove(key: any) {
|
|
89
|
+
console.log(`🗑️ HierarchicalApi.remove(${itemType}) at level ${levelDepth} - key:`, key);
|
|
90
|
+
return true;
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
async action(key: any, action: string, body?: any) {
|
|
94
|
+
console.log(`⚡ HierarchicalApi.action(${itemType}) at level ${levelDepth} - action:`, action, 'on:', key.id);
|
|
95
|
+
return { success: true, action, result: body, level: levelDepth };
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
async find(finder: string, params?: any, locations?: any[]) {
|
|
99
|
+
const locationPath = locations ? `/${locations.join('/')}` : '';
|
|
100
|
+
console.log(`🔍 HierarchicalApi.find(${itemType}) at level ${levelDepth} - finder:`, finder, 'path:', locationPath);
|
|
101
|
+
return [{
|
|
102
|
+
id: '1',
|
|
103
|
+
name: `Found ${itemType}`,
|
|
104
|
+
keyType: itemType,
|
|
105
|
+
level: levelDepth,
|
|
106
|
+
parentPath: locations
|
|
107
|
+
}];
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
async facet(key: any, facet: string, params?: any) {
|
|
111
|
+
console.log(`📈 HierarchicalApi.facet(${itemType}) at level ${levelDepth} - facet:`, facet, 'on:', key.id);
|
|
112
|
+
return {
|
|
113
|
+
facet,
|
|
114
|
+
level: levelDepth,
|
|
115
|
+
data: { count: 10 + levelDepth, hierarchy: `Level ${levelDepth}` }
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
async allAction(action: string, body?: any, locations?: any[]) {
|
|
120
|
+
const locationPath = locations ? `/${locations.join('/')}` : '';
|
|
121
|
+
console.log(`📦 HierarchicalApi.allAction(${itemType}) at level ${levelDepth} - action:`, action, 'path:', locationPath);
|
|
122
|
+
return [
|
|
123
|
+
{ id: '1', result: 'updated', level: levelDepth },
|
|
124
|
+
{ id: '2', result: 'updated', level: levelDepth }
|
|
125
|
+
];
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
async allFacet(facet: string, params?: any, locations?: any[]) {
|
|
129
|
+
const locationPath = locations ? `/${locations.join('/')}` : '';
|
|
130
|
+
console.log(`📊 HierarchicalApi.allFacet(${itemType}) at level ${levelDepth} - facet:`, facet, 'path:', locationPath);
|
|
131
|
+
return {
|
|
132
|
+
facet,
|
|
133
|
+
level: levelDepth,
|
|
134
|
+
totalCount: 50 + (levelDepth * 10),
|
|
135
|
+
data: `Level ${levelDepth} aggregated results`,
|
|
136
|
+
locationPath
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Demonstrates Organization operations (Primary Items - Level 0)
|
|
143
|
+
*/
|
|
144
|
+
async function demonstrateOrganizationOperations() {
|
|
145
|
+
console.log('\n🚀 === Organization Operations (Primary Items - Level 0) ===');
|
|
146
|
+
|
|
147
|
+
// Conceptual: const orgApi = createPItemApi<Organization, 'organization'>('organization', ['organizations'], config);
|
|
148
|
+
const orgApi = createMockHierarchicalApi('organization', 0);
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
// 1. Get all organizations
|
|
152
|
+
console.log('\n📊 Getting all organizations...');
|
|
153
|
+
const organizations = await orgApi.all({});
|
|
154
|
+
console.log(`Found ${organizations.length} organizations`);
|
|
155
|
+
|
|
156
|
+
// 2. Create a new organization
|
|
157
|
+
console.log('\n➕ Creating a new organization...');
|
|
158
|
+
const newOrg = {
|
|
159
|
+
name: 'TechCorp International',
|
|
160
|
+
type: 'Technology',
|
|
161
|
+
founded: '2020',
|
|
162
|
+
keyType: 'organization'
|
|
163
|
+
};
|
|
164
|
+
const createdOrg = await orgApi.create(newOrg);
|
|
165
|
+
console.log(`Created organization: ${createdOrg.name} (${createdOrg.id})`);
|
|
166
|
+
|
|
167
|
+
// 3. Get organization analytics
|
|
168
|
+
console.log('\n📈 Getting organization analytics...');
|
|
169
|
+
const orgKey = { keyType: 'organization', id: createdOrg.id };
|
|
170
|
+
const analytics = await orgApi.facet(orgKey, 'analytics', {
|
|
171
|
+
metrics: ['employees', 'departments', 'revenue']
|
|
172
|
+
});
|
|
173
|
+
console.log(`Organization analytics:`, analytics);
|
|
174
|
+
|
|
175
|
+
return createdOrg.id;
|
|
176
|
+
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error('❌ Error in organization operations:', error);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Demonstrates Department operations (Contained Items - Level 1)
|
|
185
|
+
*/
|
|
186
|
+
async function demonstrateDepartmentOperations(organizationId: string) {
|
|
187
|
+
console.log('\n🚀 === Department Operations (Contained Items - Level 1) ===');
|
|
188
|
+
|
|
189
|
+
// Conceptual: const deptApi = createCItemApi<Department, 'department', 'organization'>('department', ['organizations', 'departments'], config);
|
|
190
|
+
const deptApi = createMockHierarchicalApi('department', 1);
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
// Organization location for departments
|
|
194
|
+
const orgLocation = [organizationId];
|
|
195
|
+
|
|
196
|
+
// 1. Get all departments in organization
|
|
197
|
+
console.log('\n📊 Getting all departments in organization...');
|
|
198
|
+
const departments = await deptApi.all({ active: true }, orgLocation);
|
|
199
|
+
console.log(`Found ${departments.length} departments in organization`);
|
|
200
|
+
|
|
201
|
+
// 2. Create multiple departments
|
|
202
|
+
console.log('\n➕ Creating departments...');
|
|
203
|
+
const departmentData = [
|
|
204
|
+
{ name: 'Engineering', type: 'Development', budget: 1000000 },
|
|
205
|
+
{ name: 'Marketing', type: 'Business', budget: 500000 },
|
|
206
|
+
{ name: 'Sales', type: 'Revenue', budget: 750000 }
|
|
207
|
+
];
|
|
208
|
+
|
|
209
|
+
const createdDepartments = [];
|
|
210
|
+
for (const deptData of departmentData) {
|
|
211
|
+
const newDept = { ...deptData, keyType: 'department' };
|
|
212
|
+
const created = await deptApi.create(newDept, orgLocation);
|
|
213
|
+
createdDepartments.push(created);
|
|
214
|
+
console.log(`Created department: ${created.name} (${created.id})`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 3. Execute batch operations on departments
|
|
218
|
+
console.log('\n📦 Executing batch budget update...');
|
|
219
|
+
await deptApi.allAction('updateBudgets', {
|
|
220
|
+
adjustment: 0.10, // 10% increase
|
|
221
|
+
reason: 'Annual review'
|
|
222
|
+
}, orgLocation);
|
|
223
|
+
console.log('Batch budget update completed');
|
|
224
|
+
|
|
225
|
+
// 4. Get department analytics
|
|
226
|
+
console.log('\n📊 Getting department analytics...');
|
|
227
|
+
const deptAnalytics = await deptApi.allFacet('budgetAnalysis', {
|
|
228
|
+
period: 'quarterly',
|
|
229
|
+
includeProjections: true
|
|
230
|
+
}, orgLocation);
|
|
231
|
+
console.log(`Department analytics:`, deptAnalytics);
|
|
232
|
+
|
|
233
|
+
// 5. Find departments by criteria
|
|
234
|
+
console.log('\n🔍 Finding high-budget departments...');
|
|
235
|
+
const highBudgetDepts = await deptApi.find('byBudgetRange', {
|
|
236
|
+
minBudget: 600000,
|
|
237
|
+
maxBudget: 2000000
|
|
238
|
+
}, orgLocation);
|
|
239
|
+
console.log(`Found ${highBudgetDepts.length} high-budget departments`);
|
|
240
|
+
|
|
241
|
+
return createdDepartments.map(d => d.id);
|
|
242
|
+
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error('❌ Error in department operations:', error);
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Demonstrates Employee operations (Contained Items - Level 2)
|
|
251
|
+
*/
|
|
252
|
+
async function demonstrateEmployeeOperations(organizationId: string, departmentIds: string[]) {
|
|
253
|
+
console.log('\n🚀 === Employee Operations (Contained Items - Level 2) ===');
|
|
254
|
+
|
|
255
|
+
// Conceptual: const empApi = createCItemApi<Employee, 'employee', 'organization', 'department'>('employee', ['organizations', 'departments', 'employees'], config);
|
|
256
|
+
const empApi = createMockHierarchicalApi('employee', 2);
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const engineeringDeptId = departmentIds[0]; // Engineering department
|
|
260
|
+
const marketingDeptId = departmentIds[1]; // Marketing department
|
|
261
|
+
|
|
262
|
+
// Multi-level location paths
|
|
263
|
+
const engineeringLocation = [organizationId, engineeringDeptId];
|
|
264
|
+
const marketingLocation = [organizationId, marketingDeptId];
|
|
265
|
+
|
|
266
|
+
// 1. Add employees to Engineering department
|
|
267
|
+
console.log('\n👨💻 Adding employees to Engineering department...');
|
|
268
|
+
const engineeringEmployees = [
|
|
269
|
+
{ name: 'Alice Johnson', role: 'Senior Developer', salary: 120000, skills: ['React', 'Node.js'] },
|
|
270
|
+
{ name: 'Bob Smith', role: 'DevOps Engineer', salary: 110000, skills: ['AWS', 'Docker'] },
|
|
271
|
+
{ name: 'Carol Chen', role: 'Tech Lead', salary: 140000, skills: ['Architecture', 'Mentoring'] }
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
for (const empData of engineeringEmployees) {
|
|
275
|
+
const newEmp = { ...empData, keyType: 'employee' };
|
|
276
|
+
const created = await empApi.create(newEmp, engineeringLocation);
|
|
277
|
+
console.log(`Added to Engineering: ${created.name} - ${created.role}`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// 2. Add employees to Marketing department
|
|
281
|
+
console.log('\n📢 Adding employees to Marketing department...');
|
|
282
|
+
const marketingEmployees = [
|
|
283
|
+
{ name: 'David Wilson', role: 'Marketing Manager', salary: 95000, skills: ['Strategy', 'Analytics'] },
|
|
284
|
+
{ name: 'Emma Davis', role: 'Content Creator', salary: 70000, skills: ['Writing', 'Design'] }
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
for (const empData of marketingEmployees) {
|
|
288
|
+
const newEmp = { ...empData, keyType: 'employee' };
|
|
289
|
+
const created = await empApi.create(newEmp, marketingLocation);
|
|
290
|
+
console.log(`Added to Marketing: ${created.name} - ${created.role}`);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 3. Get all employees in Engineering
|
|
294
|
+
console.log('\n📊 Getting all Engineering employees...');
|
|
295
|
+
const engineeringTeam = await empApi.all({ active: true }, engineeringLocation);
|
|
296
|
+
console.log(`Engineering team has ${engineeringTeam.length} employees`);
|
|
297
|
+
|
|
298
|
+
// 4. Cross-department analytics
|
|
299
|
+
console.log('\n📈 Getting cross-department employee analytics...');
|
|
300
|
+
|
|
301
|
+
// Analytics for Engineering department
|
|
302
|
+
const engAnalytics = await empApi.allFacet('teamMetrics', {
|
|
303
|
+
metrics: ['performance', 'skills', 'satisfaction']
|
|
304
|
+
}, engineeringLocation);
|
|
305
|
+
console.log(`Engineering metrics:`, engAnalytics);
|
|
306
|
+
|
|
307
|
+
// Analytics for Marketing department
|
|
308
|
+
const mktAnalytics = await empApi.allFacet('teamMetrics', {
|
|
309
|
+
metrics: ['campaigns', 'creativity', 'results']
|
|
310
|
+
}, marketingLocation);
|
|
311
|
+
console.log(`Marketing metrics:`, mktAnalytics);
|
|
312
|
+
|
|
313
|
+
// 5. Find employees by skills across departments
|
|
314
|
+
console.log('\n🔍 Finding employees with specific skills...');
|
|
315
|
+
|
|
316
|
+
// Find React developers in Engineering
|
|
317
|
+
const reactDevs = await empApi.find('bySkill', { skill: 'React' }, engineeringLocation);
|
|
318
|
+
console.log(`Found ${reactDevs.length} React developers in Engineering`);
|
|
319
|
+
|
|
320
|
+
// Find creative talent in Marketing
|
|
321
|
+
const creatives = await empApi.find('bySkill', { skill: 'Design' }, marketingLocation);
|
|
322
|
+
console.log(`Found ${creatives.length} creative employees in Marketing`);
|
|
323
|
+
|
|
324
|
+
// 6. Execute department-specific actions
|
|
325
|
+
console.log('\n⚡ Executing department-specific actions...');
|
|
326
|
+
|
|
327
|
+
// Performance review for Engineering
|
|
328
|
+
await empApi.allAction('startPerformanceReview', {
|
|
329
|
+
type: 'technical',
|
|
330
|
+
reviewCycle: 'quarterly'
|
|
331
|
+
}, engineeringLocation);
|
|
332
|
+
console.log('Started technical performance reviews for Engineering');
|
|
333
|
+
|
|
334
|
+
// Campaign planning for Marketing
|
|
335
|
+
await empApi.allAction('planCampaign', {
|
|
336
|
+
type: 'product-launch',
|
|
337
|
+
budget: 50000
|
|
338
|
+
}, marketingLocation);
|
|
339
|
+
console.log('Started campaign planning for Marketing');
|
|
340
|
+
|
|
341
|
+
// 7. Individual employee operations
|
|
342
|
+
console.log('\n👤 Individual employee operations...');
|
|
343
|
+
const empKey = { keyType: 'employee', id: 'employee-1' };
|
|
344
|
+
|
|
345
|
+
// Update employee
|
|
346
|
+
const updatedEmp = await empApi.update(empKey, {
|
|
347
|
+
salary: 125000,
|
|
348
|
+
role: 'Principal Developer'
|
|
349
|
+
});
|
|
350
|
+
console.log(`Updated employee: ${updatedEmp.name}`);
|
|
351
|
+
|
|
352
|
+
// Employee-specific action
|
|
353
|
+
await empApi.action(empKey, 'assignProject', {
|
|
354
|
+
projectId: 'proj-123',
|
|
355
|
+
role: 'Technical Lead'
|
|
356
|
+
});
|
|
357
|
+
console.log('Assigned employee to project');
|
|
358
|
+
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error('❌ Error in employee operations:', error);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Demonstrates cross-hierarchy operations and complex queries
|
|
366
|
+
*/
|
|
367
|
+
async function demonstrateCrossHierarchyOperations(organizationId: string) {
|
|
368
|
+
console.log('\n🚀 === Cross-Hierarchy Operations ===');
|
|
369
|
+
|
|
370
|
+
const orgApi = createMockHierarchicalApi('organization', 0);
|
|
371
|
+
const deptApi = createMockHierarchicalApi('department', 1);
|
|
372
|
+
const empApi = createMockHierarchicalApi('employee', 2);
|
|
373
|
+
|
|
374
|
+
try {
|
|
375
|
+
// 1. Organization-wide analytics
|
|
376
|
+
console.log('\n📊 Organization-wide analytics...');
|
|
377
|
+
const orgKey = { keyType: 'organization', id: organizationId };
|
|
378
|
+
const orgAnalytics = await orgApi.facet(orgKey, 'hierarchicalAnalytics', {
|
|
379
|
+
includeSublevels: true,
|
|
380
|
+
metrics: ['totalEmployees', 'departmentCount', 'averageSalary', 'skillsDistribution']
|
|
381
|
+
});
|
|
382
|
+
console.log(`Organization analytics:`, orgAnalytics);
|
|
383
|
+
|
|
384
|
+
// 2. Department-level aggregations
|
|
385
|
+
console.log('\n📈 Department-level aggregations...');
|
|
386
|
+
const orgLocation = [organizationId];
|
|
387
|
+
const deptAggregations = await deptApi.allFacet('aggregatedMetrics', {
|
|
388
|
+
groupBy: ['type', 'budget'],
|
|
389
|
+
calculations: ['sum', 'average', 'count']
|
|
390
|
+
}, orgLocation);
|
|
391
|
+
console.log(`Department aggregations:`, deptAggregations);
|
|
392
|
+
|
|
393
|
+
// 3. Cross-department employee search
|
|
394
|
+
console.log('\n🔍 Cross-department employee search...');
|
|
395
|
+
// Note: In a real implementation, this might be a special endpoint or query
|
|
396
|
+
console.log('Searching for employees across all departments...');
|
|
397
|
+
console.log('(In production, this would use a cross-hierarchy search endpoint)');
|
|
398
|
+
|
|
399
|
+
// 4. Organizational restructuring simulation
|
|
400
|
+
console.log('\n🔄 Organizational restructuring simulation...');
|
|
401
|
+
await orgApi.action(orgKey, 'simulateRestructure', {
|
|
402
|
+
changes: [
|
|
403
|
+
{ type: 'mergeDepartments', source: 'dept-1', target: 'dept-2' },
|
|
404
|
+
{ type: 'createDepartment', name: 'Innovation' }
|
|
405
|
+
]
|
|
406
|
+
});
|
|
407
|
+
console.log('Restructuring simulation completed');
|
|
408
|
+
|
|
409
|
+
} catch (error) {
|
|
410
|
+
console.error('❌ Error in cross-hierarchy operations:', error);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Main function to run the multi-level keys example
|
|
416
|
+
*/
|
|
417
|
+
export async function runMultiLevelKeysExample() {
|
|
418
|
+
console.log('🎯 Fjell-Client-API Multi-Level Keys Example');
|
|
419
|
+
console.log('============================================');
|
|
420
|
+
console.log('Demonstrating hierarchical data operations with multi-level location keys\n');
|
|
421
|
+
|
|
422
|
+
try {
|
|
423
|
+
// Level 0: Create and manage organizations
|
|
424
|
+
const organizationId = await demonstrateOrganizationOperations();
|
|
425
|
+
|
|
426
|
+
if (!organizationId) {
|
|
427
|
+
throw new Error('Failed to create organization');
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Level 1: Create and manage departments within organization
|
|
431
|
+
const departmentIds = await demonstrateDepartmentOperations(organizationId);
|
|
432
|
+
|
|
433
|
+
if (departmentIds.length === 0) {
|
|
434
|
+
throw new Error('Failed to create departments');
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Level 2: Create and manage employees within departments
|
|
438
|
+
await demonstrateEmployeeOperations(organizationId, departmentIds);
|
|
439
|
+
|
|
440
|
+
// Cross-hierarchy operations
|
|
441
|
+
await demonstrateCrossHierarchyOperations(organizationId);
|
|
442
|
+
|
|
443
|
+
console.log('\n✅ Multi-level keys example completed successfully!');
|
|
444
|
+
console.log('\nKey Concepts Demonstrated:');
|
|
445
|
+
console.log('• Hierarchical data organization (Organization → Department → Employee)');
|
|
446
|
+
console.log('• Multi-level location keys for contained items');
|
|
447
|
+
console.log('• Complex API routing with nested path segments');
|
|
448
|
+
console.log('• Cross-hierarchy queries and analytics');
|
|
449
|
+
console.log('• Department and employee-specific operations');
|
|
450
|
+
console.log('• Organizational data management patterns');
|
|
451
|
+
console.log('\nLocation Key Patterns:');
|
|
452
|
+
console.log('• Level 0 (Primary): /organizations/{orgId}');
|
|
453
|
+
console.log('• Level 1 (Contained): /organizations/{orgId}/departments/{deptId}');
|
|
454
|
+
console.log('• Level 2 (Contained): /organizations/{orgId}/departments/{deptId}/employees/{empId}');
|
|
455
|
+
console.log('\nNote: This is a conceptual example showing hierarchical API patterns.');
|
|
456
|
+
console.log('In production, use actual fjell-client-api with proper types.');
|
|
457
|
+
|
|
458
|
+
} catch (error) {
|
|
459
|
+
console.error('❌ Multi-level keys example failed:', error);
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Run the example if this file is executed directly
|
|
465
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
466
|
+
runMultiLevelKeysExample().catch(console.error);
|
|
467
|
+
}
|