@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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/demo.app.yml +4 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +18 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/main.menu.yml +30 -0
  8. package/dist/modules/kitchen-sink/kitchen_sink.data.yml +18 -0
  9. package/dist/modules/kitchen-sink/kitchen_sink.object.yml +154 -0
  10. package/dist/modules/projects/pages/create_project_wizard.page.yml +244 -0
  11. package/dist/modules/projects/pages/project_detail.page.yml +258 -0
  12. package/dist/modules/projects/project_approval.workflow.yml +51 -0
  13. package/dist/modules/projects/project_status.report.yml +39 -0
  14. package/dist/modules/projects/projects.action.d.ts +104 -0
  15. package/dist/modules/projects/projects.action.js +363 -0
  16. package/dist/modules/projects/projects.action.js.map +1 -0
  17. package/dist/modules/projects/projects.data.yml +13 -0
  18. package/dist/modules/projects/projects.form.yml +41 -0
  19. package/dist/modules/projects/projects.hook.d.ts +15 -0
  20. package/dist/modules/projects/projects.hook.js +302 -0
  21. package/dist/modules/projects/projects.hook.js.map +1 -0
  22. package/dist/modules/projects/projects.object.yml +148 -0
  23. package/dist/modules/projects/projects.permission.yml +141 -0
  24. package/dist/modules/projects/projects.validation.yml +37 -0
  25. package/dist/modules/projects/projects.view.yml +35 -0
  26. package/dist/modules/tasks/tasks.data.yml +23 -0
  27. package/dist/modules/tasks/tasks.object.yml +34 -0
  28. package/dist/modules/tasks/tasks.permission.yml +167 -0
  29. package/dist/pages/dashboard.page.yml +206 -0
  30. package/dist/pages/landing.page.yml +275 -0
  31. package/dist/types/index.d.ts +3 -0
  32. package/dist/types/index.js +20 -0
  33. package/dist/types/index.js.map +1 -0
  34. package/dist/types/kitchen_sink.d.ts +99 -0
  35. package/dist/types/kitchen_sink.js +3 -0
  36. package/dist/types/kitchen_sink.js.map +1 -0
  37. package/dist/types/projects.d.ts +47 -0
  38. package/dist/types/projects.js +3 -0
  39. package/dist/types/projects.js.map +1 -0
  40. package/dist/types/tasks.d.ts +31 -0
  41. package/dist/types/tasks.js +3 -0
  42. package/dist/types/tasks.js.map +1 -0
  43. 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;