@objectql/starter-basic 1.6.1
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/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/demo.app.yml +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/main.menu.yml +30 -0
- package/dist/modules/kitchen-sink/kitchen_sink.data.yml +18 -0
- package/dist/modules/kitchen-sink/kitchen_sink.object.yml +154 -0
- package/dist/modules/projects/pages/create_project_wizard.page.yml +244 -0
- package/dist/modules/projects/pages/project_detail.page.yml +258 -0
- package/dist/modules/projects/project_approval.workflow.yml +51 -0
- package/dist/modules/projects/project_status.report.yml +39 -0
- package/dist/modules/projects/projects.action.d.ts +104 -0
- package/dist/modules/projects/projects.action.js +363 -0
- package/dist/modules/projects/projects.action.js.map +1 -0
- package/dist/modules/projects/projects.data.yml +13 -0
- package/dist/modules/projects/projects.form.yml +41 -0
- package/dist/modules/projects/projects.hook.d.ts +15 -0
- package/dist/modules/projects/projects.hook.js +302 -0
- package/dist/modules/projects/projects.hook.js.map +1 -0
- package/dist/modules/projects/projects.object.yml +148 -0
- package/dist/modules/projects/projects.permission.yml +141 -0
- package/dist/modules/projects/projects.validation.yml +37 -0
- package/dist/modules/projects/projects.view.yml +35 -0
- package/dist/modules/tasks/tasks.data.yml +23 -0
- package/dist/modules/tasks/tasks.object.yml +34 -0
- package/dist/modules/tasks/tasks.permission.yml +167 -0
- package/dist/pages/dashboard.page.yml +206 -0
- package/dist/pages/landing.page.yml +275 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/kitchen_sink.d.ts +99 -0
- package/dist/types/kitchen_sink.js +3 -0
- package/dist/types/kitchen_sink.js.map +1 -0
- package/dist/types/projects.d.ts +47 -0
- package/dist/types/projects.js +3 -0
- package/dist/types/projects.js.map +1 -0
- package/dist/types/tasks.d.ts +31 -0
- package/dist/types/tasks.js +3 -0
- package/dist/types/tasks.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate_report = exports.bulk_update_status = exports.import_projects = exports.clone = exports.approve = exports.complete = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* complete - Record Action Example
|
|
6
|
+
*
|
|
7
|
+
* Demonstrates:
|
|
8
|
+
* - Fetching and validating current state
|
|
9
|
+
* - Performing atomic updates
|
|
10
|
+
* - Returning structured results
|
|
11
|
+
* - Input parameter usage
|
|
12
|
+
*/
|
|
13
|
+
exports.complete = {
|
|
14
|
+
handler: async ({ id, input, api, user }) => {
|
|
15
|
+
const { comment, completion_date } = input;
|
|
16
|
+
console.log(`[Action] Completing project ${id} by ${user === null || user === void 0 ? void 0 : user.id}`);
|
|
17
|
+
// 1. Validate - Fetch current state
|
|
18
|
+
const project = await api.findOne('projects', id);
|
|
19
|
+
if (!project) {
|
|
20
|
+
throw new Error('Project not found');
|
|
21
|
+
}
|
|
22
|
+
if (project.status === 'completed') {
|
|
23
|
+
throw new Error('Project is already completed');
|
|
24
|
+
}
|
|
25
|
+
// 2. Validate - Check if user has permission
|
|
26
|
+
/*
|
|
27
|
+
if (!user?.isAdmin && project.owner !== user?.id) {
|
|
28
|
+
throw new Error('Only the project owner or admin can complete the project');
|
|
29
|
+
}
|
|
30
|
+
*/
|
|
31
|
+
// 3. Perform update with atomic operation
|
|
32
|
+
const updateData = {
|
|
33
|
+
status: 'completed',
|
|
34
|
+
end_date: completion_date || new Date()
|
|
35
|
+
};
|
|
36
|
+
// Add completion comment to description
|
|
37
|
+
if (comment) {
|
|
38
|
+
updateData.description = project.description
|
|
39
|
+
? `${project.description}\n\n[Completed on ${new Date().toISOString()}]: ${comment}`
|
|
40
|
+
: `[Completed on ${new Date().toISOString()}]: ${comment}`;
|
|
41
|
+
}
|
|
42
|
+
await api.update('projects', id, updateData);
|
|
43
|
+
// 4. Optional: Create completion record or notification
|
|
44
|
+
/*
|
|
45
|
+
await api.create('project_completions', {
|
|
46
|
+
project_id: id,
|
|
47
|
+
completed_by: user?.id,
|
|
48
|
+
completed_at: new Date(),
|
|
49
|
+
comment: comment
|
|
50
|
+
});
|
|
51
|
+
*/
|
|
52
|
+
// 5. Return structured result
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
message: "Project completed successfully",
|
|
56
|
+
project_id: id,
|
|
57
|
+
completed_at: updateData.end_date
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* approve - Record Action with State Transition
|
|
63
|
+
*
|
|
64
|
+
* Demonstrates:
|
|
65
|
+
* - State machine validation
|
|
66
|
+
* - Required input parameters
|
|
67
|
+
* - Business logic enforcement
|
|
68
|
+
*/
|
|
69
|
+
exports.approve = {
|
|
70
|
+
handler: async ({ id, input, api, user }) => {
|
|
71
|
+
const { comment } = input;
|
|
72
|
+
// 1. Validate input
|
|
73
|
+
if (!comment || comment.trim().length === 0) {
|
|
74
|
+
throw new Error('Approval comment is required');
|
|
75
|
+
}
|
|
76
|
+
// 2. Fetch and validate current state
|
|
77
|
+
const project = await api.findOne('projects', id);
|
|
78
|
+
if (!project) {
|
|
79
|
+
throw new Error('Project not found');
|
|
80
|
+
}
|
|
81
|
+
if (project.status !== 'planned') {
|
|
82
|
+
throw new Error('Only projects in "planned" status can be approved');
|
|
83
|
+
}
|
|
84
|
+
// 3. Check budget threshold
|
|
85
|
+
if (project.budget > 100000 && !(user === null || user === void 0 ? void 0 : user.isAdmin)) {
|
|
86
|
+
throw new Error('Projects with budget over $100,000 require admin approval');
|
|
87
|
+
}
|
|
88
|
+
// 4. Perform approval
|
|
89
|
+
await api.update('projects', id, {
|
|
90
|
+
status: 'in_progress',
|
|
91
|
+
approved_by: user === null || user === void 0 ? void 0 : user.id,
|
|
92
|
+
approved_at: new Date(),
|
|
93
|
+
approval_comment: comment
|
|
94
|
+
});
|
|
95
|
+
// 5. Log approval
|
|
96
|
+
console.log(`[Action] Project ${project.name} approved by ${user === null || user === void 0 ? void 0 : user.id}`);
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
message: 'Project approved and moved to in_progress',
|
|
100
|
+
new_status: 'in_progress'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* clone - Record Action with Related Data
|
|
106
|
+
*
|
|
107
|
+
* Demonstrates:
|
|
108
|
+
* - Creating new records based on existing ones
|
|
109
|
+
* - Copying related data
|
|
110
|
+
* - Complex multi-step operations
|
|
111
|
+
*/
|
|
112
|
+
exports.clone = {
|
|
113
|
+
handler: async ({ id, input, api, user }) => {
|
|
114
|
+
const { new_name, copy_tasks = false } = input;
|
|
115
|
+
// 1. Validate input
|
|
116
|
+
if (!new_name || new_name.trim().length === 0) {
|
|
117
|
+
throw new Error('New project name is required');
|
|
118
|
+
}
|
|
119
|
+
// 2. Fetch source project
|
|
120
|
+
const sourceProject = await api.findOne('projects', id);
|
|
121
|
+
if (!sourceProject) {
|
|
122
|
+
throw new Error('Source project not found');
|
|
123
|
+
}
|
|
124
|
+
// 3. Create cloned project
|
|
125
|
+
const clonedData = {
|
|
126
|
+
name: new_name,
|
|
127
|
+
description: `Cloned from: ${sourceProject.name}\n\n${sourceProject.description || ''}`,
|
|
128
|
+
status: 'planned', // Always start as planned
|
|
129
|
+
priority: sourceProject.priority,
|
|
130
|
+
owner: (user === null || user === void 0 ? void 0 : user.id) || sourceProject.owner, // Assign to current user
|
|
131
|
+
budget: sourceProject.budget,
|
|
132
|
+
start_date: sourceProject.start_date
|
|
133
|
+
// Don't copy: end_date, completed status
|
|
134
|
+
};
|
|
135
|
+
const newProject = await api.create('projects', clonedData);
|
|
136
|
+
// 4. Optional: Copy related tasks
|
|
137
|
+
if (copy_tasks) {
|
|
138
|
+
/*
|
|
139
|
+
const tasks = await api.find('tasks', {
|
|
140
|
+
filters: [['project_id', '=', id]]
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
for (const task of tasks) {
|
|
144
|
+
await api.create('tasks', {
|
|
145
|
+
name: task.name,
|
|
146
|
+
description: task.description,
|
|
147
|
+
project_id: newProject._id,
|
|
148
|
+
status: 'pending', // Reset status
|
|
149
|
+
priority: task.priority
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
*/
|
|
153
|
+
}
|
|
154
|
+
console.log(`[Action] Project cloned: ${sourceProject.name} -> ${new_name}`);
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
message: 'Project cloned successfully',
|
|
158
|
+
original_id: id,
|
|
159
|
+
new_project_id: newProject._id,
|
|
160
|
+
tasks_copied: copy_tasks
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* import_projects - Global Action Example
|
|
166
|
+
*
|
|
167
|
+
* Demonstrates:
|
|
168
|
+
* - Batch operations
|
|
169
|
+
* - Data transformation
|
|
170
|
+
* - Error collection
|
|
171
|
+
* - Progress reporting
|
|
172
|
+
*/
|
|
173
|
+
exports.import_projects = {
|
|
174
|
+
handler: async ({ input, api, user }) => {
|
|
175
|
+
const { source, data, file_url } = input;
|
|
176
|
+
console.log(`[Action] Importing projects from ${source} by ${user === null || user === void 0 ? void 0 : user.id}`);
|
|
177
|
+
// 1. Validate input
|
|
178
|
+
if (!data && !file_url) {
|
|
179
|
+
throw new Error('Either data array or file_url must be provided');
|
|
180
|
+
}
|
|
181
|
+
// 2. Fetch data based on source
|
|
182
|
+
let projectsData = data || [];
|
|
183
|
+
if (file_url) {
|
|
184
|
+
// Example: Fetch from URL
|
|
185
|
+
/*
|
|
186
|
+
const response = await fetch(file_url);
|
|
187
|
+
projectsData = await response.json();
|
|
188
|
+
*/
|
|
189
|
+
throw new Error('file_url import not yet implemented');
|
|
190
|
+
}
|
|
191
|
+
// 3. Validate and import each project
|
|
192
|
+
const results = {
|
|
193
|
+
successCount: 0,
|
|
194
|
+
failed: 0,
|
|
195
|
+
errors: []
|
|
196
|
+
};
|
|
197
|
+
for (let i = 0; i < projectsData.length; i++) {
|
|
198
|
+
const projectData = projectsData[i];
|
|
199
|
+
try {
|
|
200
|
+
// Validate required fields
|
|
201
|
+
if (!projectData.name) {
|
|
202
|
+
throw new Error('Project name is required');
|
|
203
|
+
}
|
|
204
|
+
// Set defaults
|
|
205
|
+
const importData = {
|
|
206
|
+
name: projectData.name,
|
|
207
|
+
description: projectData.description || '',
|
|
208
|
+
status: projectData.status || 'planned',
|
|
209
|
+
priority: projectData.priority || 'normal',
|
|
210
|
+
budget: projectData.budget || 0,
|
|
211
|
+
owner: projectData.owner || (user === null || user === void 0 ? void 0 : user.id),
|
|
212
|
+
start_date: projectData.start_date
|
|
213
|
+
};
|
|
214
|
+
// Create project
|
|
215
|
+
await api.create('projects', importData);
|
|
216
|
+
results.successCount++;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
results.failed++;
|
|
220
|
+
results.errors.push({
|
|
221
|
+
row: i + 1,
|
|
222
|
+
name: projectData.name || 'Unknown',
|
|
223
|
+
error: error.message
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
console.log(`[Action] Import completed: ${results.successCount} succeeded, ${results.failed} failed`);
|
|
228
|
+
return {
|
|
229
|
+
success: results.failed === 0,
|
|
230
|
+
message: `Imported ${results.successCount} projects, ${results.failed} failed`,
|
|
231
|
+
...results
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* bulk_update_status - Global Action for Batch Updates
|
|
237
|
+
*
|
|
238
|
+
* Demonstrates:
|
|
239
|
+
* - Operating on multiple records
|
|
240
|
+
* - Validation across multiple items
|
|
241
|
+
* - Transactional operations (if supported)
|
|
242
|
+
*/
|
|
243
|
+
exports.bulk_update_status = {
|
|
244
|
+
handler: async ({ input, api, user }) => {
|
|
245
|
+
const { project_ids, new_status } = input;
|
|
246
|
+
// 1. Validate input
|
|
247
|
+
if (!project_ids || project_ids.length === 0) {
|
|
248
|
+
throw new Error('At least one project ID must be provided');
|
|
249
|
+
}
|
|
250
|
+
if (project_ids.length > 100) {
|
|
251
|
+
throw new Error('Cannot update more than 100 projects at once');
|
|
252
|
+
}
|
|
253
|
+
// 2. Update each project
|
|
254
|
+
// Note: This uses an N+1 query pattern (fetching each project individually)
|
|
255
|
+
// For production with large batches, consider fetching all projects at once:
|
|
256
|
+
// const projects = await api.find('projects', { filters: [['_id', 'in', project_ids]] });
|
|
257
|
+
// However, for this example with a 100-project limit, the current approach
|
|
258
|
+
// provides clearer per-record validation and error handling.
|
|
259
|
+
const results = {
|
|
260
|
+
updated: 0,
|
|
261
|
+
skipped: 0,
|
|
262
|
+
errors: []
|
|
263
|
+
};
|
|
264
|
+
for (const id of project_ids) {
|
|
265
|
+
try {
|
|
266
|
+
const project = await api.findOne('projects', id);
|
|
267
|
+
if (!project) {
|
|
268
|
+
results.errors.push({
|
|
269
|
+
project_id: id,
|
|
270
|
+
error: 'Project not found'
|
|
271
|
+
});
|
|
272
|
+
results.skipped++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
// Validate transition (simplified)
|
|
276
|
+
if (project.status === 'completed' && new_status !== 'completed') {
|
|
277
|
+
results.errors.push({
|
|
278
|
+
project_id: id,
|
|
279
|
+
name: project.name,
|
|
280
|
+
error: 'Cannot change status of completed projects'
|
|
281
|
+
});
|
|
282
|
+
results.skipped++;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
// Perform update
|
|
286
|
+
await api.update('projects', id, { status: new_status });
|
|
287
|
+
results.updated++;
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
results.errors.push({
|
|
291
|
+
project_id: id,
|
|
292
|
+
error: error.message
|
|
293
|
+
});
|
|
294
|
+
results.skipped++;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
console.log(`[Action] Bulk update: ${results.updated} updated, ${results.skipped} skipped`);
|
|
298
|
+
return {
|
|
299
|
+
success: results.skipped === 0,
|
|
300
|
+
message: `Updated ${results.updated} projects, skipped ${results.skipped}`,
|
|
301
|
+
...results
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* generate_report - Global Action for Reporting
|
|
307
|
+
*
|
|
308
|
+
* Demonstrates:
|
|
309
|
+
* - Aggregation and analysis
|
|
310
|
+
* - Data collection across records
|
|
311
|
+
* - Computed results
|
|
312
|
+
*/
|
|
313
|
+
exports.generate_report = {
|
|
314
|
+
handler: async ({ api, user }) => {
|
|
315
|
+
console.log(`[Action] Generating project report for ${user === null || user === void 0 ? void 0 : user.id}`);
|
|
316
|
+
// 1. Fetch all projects (or apply filters)
|
|
317
|
+
const allProjects = await api.find('projects', {});
|
|
318
|
+
// 2. Calculate statistics
|
|
319
|
+
const report = {
|
|
320
|
+
total_projects: allProjects.length,
|
|
321
|
+
by_status: {
|
|
322
|
+
planned: 0,
|
|
323
|
+
in_progress: 0,
|
|
324
|
+
completed: 0
|
|
325
|
+
},
|
|
326
|
+
by_priority: {
|
|
327
|
+
low: 0,
|
|
328
|
+
normal: 0,
|
|
329
|
+
high: 0
|
|
330
|
+
},
|
|
331
|
+
total_budget: 0,
|
|
332
|
+
average_budget: 0,
|
|
333
|
+
generated_at: new Date(),
|
|
334
|
+
generated_by: user === null || user === void 0 ? void 0 : user.id
|
|
335
|
+
};
|
|
336
|
+
// 3. Aggregate data
|
|
337
|
+
allProjects.forEach(project => {
|
|
338
|
+
// Count by status
|
|
339
|
+
const status = project.status || 'planned';
|
|
340
|
+
if (status in report.by_status) {
|
|
341
|
+
report.by_status[status]++;
|
|
342
|
+
}
|
|
343
|
+
// Count by priority
|
|
344
|
+
const priority = project.priority || 'normal';
|
|
345
|
+
if (priority in report.by_priority) {
|
|
346
|
+
report.by_priority[priority]++;
|
|
347
|
+
}
|
|
348
|
+
// Sum budget
|
|
349
|
+
report.total_budget += project.budget || 0;
|
|
350
|
+
});
|
|
351
|
+
// 4. Calculate averages
|
|
352
|
+
report.average_budget = allProjects.length > 0
|
|
353
|
+
? report.total_budget / allProjects.length
|
|
354
|
+
: 0;
|
|
355
|
+
console.log(`[Action] Report generated: ${report.total_projects} projects analyzed`);
|
|
356
|
+
return {
|
|
357
|
+
success: true,
|
|
358
|
+
message: 'Report generated successfully',
|
|
359
|
+
report
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
//# sourceMappingURL=projects.action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.action.js","sourceRoot":"","sources":["../../../src/modules/projects/projects.action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
- _id: PROJ-001
|
|
2
|
+
name: "Website Redesign (From Data)"
|
|
3
|
+
description: "Initial data loaded from projects.data.yml"
|
|
4
|
+
status: "in_progress"
|
|
5
|
+
priority: "high"
|
|
6
|
+
owner: "u-123"
|
|
7
|
+
|
|
8
|
+
- _id: PROJ-002
|
|
9
|
+
name: "Mobile App (From Data)"
|
|
10
|
+
description: "Initial data loaded from projects.data.yml"
|
|
11
|
+
status: "planned"
|
|
12
|
+
priority: "medium"
|
|
13
|
+
owner: "u-999"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: project_main_form
|
|
2
|
+
label: "Project Details"
|
|
3
|
+
type: edit
|
|
4
|
+
object: projects
|
|
5
|
+
description: "Main form for creating and editing projects"
|
|
6
|
+
|
|
7
|
+
layout:
|
|
8
|
+
tabs:
|
|
9
|
+
- label: "General Info"
|
|
10
|
+
sections:
|
|
11
|
+
- label: "Basic Details"
|
|
12
|
+
columns: 2
|
|
13
|
+
fields:
|
|
14
|
+
- name
|
|
15
|
+
- owner
|
|
16
|
+
- status
|
|
17
|
+
- priority
|
|
18
|
+
|
|
19
|
+
- label: "Description"
|
|
20
|
+
columns: 1
|
|
21
|
+
fields:
|
|
22
|
+
- description
|
|
23
|
+
|
|
24
|
+
- label: "Planning"
|
|
25
|
+
sections:
|
|
26
|
+
- label: "Schedule & Budget"
|
|
27
|
+
columns: 2
|
|
28
|
+
fields:
|
|
29
|
+
- start_date
|
|
30
|
+
- end_date
|
|
31
|
+
- budget
|
|
32
|
+
|
|
33
|
+
- label: "Approval Info"
|
|
34
|
+
sections:
|
|
35
|
+
- label: "Audit Trail"
|
|
36
|
+
fields:
|
|
37
|
+
- name: approved_by
|
|
38
|
+
readonly: true
|
|
39
|
+
- name: approved_at
|
|
40
|
+
readonly: true
|
|
41
|
+
- approval_comment
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ObjectHookDefinition } from '@objectql/types';
|
|
2
|
+
import { Projects } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Project Hooks - Comprehensive Example
|
|
5
|
+
*
|
|
6
|
+
* This file demonstrates all major hook patterns according to the ObjectQL specification:
|
|
7
|
+
* 1. Data validation and defaulting (beforeCreate)
|
|
8
|
+
* 2. Query modification for security (beforeFind)
|
|
9
|
+
* 3. State transition validation (beforeUpdate)
|
|
10
|
+
* 4. Change tracking and notifications (afterUpdate)
|
|
11
|
+
* 5. Dependency checking (beforeDelete)
|
|
12
|
+
* 6. Side effects and cleanup (afterDelete)
|
|
13
|
+
*/
|
|
14
|
+
declare const hooks: ObjectHookDefinition<Projects>;
|
|
15
|
+
export default hooks;
|