@objectql/create 1.0.0

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 (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +28 -0
  3. package/dist/bin.js +125 -0
  4. package/package.json +27 -0
  5. package/templates/enterprise/CHANGELOG.md +140 -0
  6. package/templates/enterprise/README.md +352 -0
  7. package/templates/enterprise/__tests__/data-api.test.ts +546 -0
  8. package/templates/enterprise/__tests__/data-api.test.ts.backup +526 -0
  9. package/templates/enterprise/__tests__/metadata-api.test.ts +307 -0
  10. package/templates/enterprise/__tests__/metadata-loading.test.ts +250 -0
  11. package/templates/enterprise/jest.config.js +22 -0
  12. package/templates/enterprise/package.json +51 -0
  13. package/templates/enterprise/src/apps/erp.app.yml +4 -0
  14. package/templates/enterprise/src/core/attachment.object.yml +57 -0
  15. package/templates/enterprise/src/core/i18n/en/core.json +60 -0
  16. package/templates/enterprise/src/core/i18n/zh-CN/core.json +60 -0
  17. package/templates/enterprise/src/core/index.ts +24 -0
  18. package/templates/enterprise/src/core/organization.object.yml +78 -0
  19. package/templates/enterprise/src/core/user.object.yml +80 -0
  20. package/templates/enterprise/src/extensions/README.md +56 -0
  21. package/templates/enterprise/src/extensions/user.extension.object.yml +42 -0
  22. package/templates/enterprise/src/extensions/user.ts +26 -0
  23. package/templates/enterprise/src/index.ts +47 -0
  24. package/templates/enterprise/src/modules/crm/README.md +99 -0
  25. package/templates/enterprise/src/modules/crm/crm_account.object.yml +105 -0
  26. package/templates/enterprise/src/modules/crm/crm_contact.object.yml +103 -0
  27. package/templates/enterprise/src/modules/crm/crm_lead.object.yml +148 -0
  28. package/templates/enterprise/src/modules/crm/crm_opportunity.object.yml +128 -0
  29. package/templates/enterprise/src/modules/crm/i18n/en/crm.json +61 -0
  30. package/templates/enterprise/src/modules/crm/i18n/zh-CN/crm.json +61 -0
  31. package/templates/enterprise/src/modules/crm/index.ts +29 -0
  32. package/templates/enterprise/src/modules/finance/README.md +112 -0
  33. package/templates/enterprise/src/modules/finance/finance_budget.object.yml +108 -0
  34. package/templates/enterprise/src/modules/finance/finance_expense.object.yml +151 -0
  35. package/templates/enterprise/src/modules/finance/finance_invoice.object.yml +143 -0
  36. package/templates/enterprise/src/modules/finance/finance_payment.object.yml +96 -0
  37. package/templates/enterprise/src/modules/finance/index.ts +26 -0
  38. package/templates/enterprise/src/modules/hr/README.md +95 -0
  39. package/templates/enterprise/src/modules/hr/hr_department.object.yml +59 -0
  40. package/templates/enterprise/src/modules/hr/hr_employee.object.yml +137 -0
  41. package/templates/enterprise/src/modules/hr/hr_position.object.yml +79 -0
  42. package/templates/enterprise/src/modules/hr/hr_timesheet.object.yml +114 -0
  43. package/templates/enterprise/src/modules/hr/index.ts +26 -0
  44. package/templates/enterprise/src/modules/project/README.md +132 -0
  45. package/templates/enterprise/src/modules/project/index.ts +26 -0
  46. package/templates/enterprise/src/modules/project/project_milestone.object.yml +70 -0
  47. package/templates/enterprise/src/modules/project/project_project.object.yml +135 -0
  48. package/templates/enterprise/src/modules/project/project_task.object.yml +121 -0
  49. package/templates/enterprise/src/modules/project/project_timesheet_entry.object.yml +95 -0
  50. package/templates/enterprise/src/plugins/audit/audit.plugin.ts +23 -0
  51. package/templates/enterprise/src/plugins/audit/index.ts +6 -0
  52. package/templates/enterprise/src/plugins/audit/note.object.yml +3 -0
  53. package/templates/enterprise/src/shared/constants.ts +30 -0
  54. package/templates/enterprise/src/shared/utils.ts +54 -0
  55. package/templates/enterprise/src/shared/validators.ts +47 -0
  56. package/templates/enterprise/src/types/attachment.ts +41 -0
  57. package/templates/enterprise/src/types/crm_account.ts +61 -0
  58. package/templates/enterprise/src/types/crm_contact.ts +61 -0
  59. package/templates/enterprise/src/types/crm_lead.ts +77 -0
  60. package/templates/enterprise/src/types/crm_opportunity.ts +53 -0
  61. package/templates/enterprise/src/types/finance_budget.ts +61 -0
  62. package/templates/enterprise/src/types/finance_expense.ts +65 -0
  63. package/templates/enterprise/src/types/finance_invoice.ts +69 -0
  64. package/templates/enterprise/src/types/finance_payment.ts +49 -0
  65. package/templates/enterprise/src/types/hr_department.ts +37 -0
  66. package/templates/enterprise/src/types/hr_employee.ts +85 -0
  67. package/templates/enterprise/src/types/hr_position.ts +49 -0
  68. package/templates/enterprise/src/types/hr_timesheet.ts +57 -0
  69. package/templates/enterprise/src/types/index.ts +20 -0
  70. package/templates/enterprise/src/types/note.ts +9 -0
  71. package/templates/enterprise/src/types/organization.ts +53 -0
  72. package/templates/enterprise/src/types/project_milestone.ts +41 -0
  73. package/templates/enterprise/src/types/project_project.ts +69 -0
  74. package/templates/enterprise/src/types/project_task.ts +57 -0
  75. package/templates/enterprise/src/types/project_timesheet_entry.ts +45 -0
  76. package/templates/enterprise/src/types/user.ts +65 -0
  77. package/templates/enterprise/tsconfig.json +10 -0
  78. package/templates/enterprise/tsconfig.tsbuildinfo +1 -0
  79. package/templates/hello-world/CHANGELOG.md +33 -0
  80. package/templates/hello-world/README.md +29 -0
  81. package/templates/hello-world/package.json +24 -0
  82. package/templates/hello-world/src/index.ts +58 -0
  83. package/templates/hello-world/tsconfig.json +10 -0
  84. package/templates/starter/CHANGELOG.md +191 -0
  85. package/templates/starter/README.md +17 -0
  86. package/templates/starter/__tests__/projects-hooks-actions.test.ts +490 -0
  87. package/templates/starter/jest.config.js +22 -0
  88. package/templates/starter/package.json +51 -0
  89. package/templates/starter/src/README.pages.md +110 -0
  90. package/templates/starter/src/demo.app.yml +4 -0
  91. package/templates/starter/src/i18n/zh-CN/projects.json +22 -0
  92. package/templates/starter/src/index.ts +55 -0
  93. package/templates/starter/src/modules/kitchen-sink/kitchen_sink.data.yml +18 -0
  94. package/templates/starter/src/modules/kitchen-sink/kitchen_sink.object.yml +156 -0
  95. package/templates/starter/src/modules/projects/project_approval.workflow.yml +51 -0
  96. package/templates/starter/src/modules/projects/projects.action.ts +472 -0
  97. package/templates/starter/src/modules/projects/projects.data.yml +13 -0
  98. package/templates/starter/src/modules/projects/projects.hook.ts +339 -0
  99. package/templates/starter/src/modules/projects/projects.object.yml +148 -0
  100. package/templates/starter/src/modules/projects/projects.permission.yml +141 -0
  101. package/templates/starter/src/modules/projects/projects.validation.yml +37 -0
  102. package/templates/starter/src/modules/tasks/tasks.data.yml +23 -0
  103. package/templates/starter/src/modules/tasks/tasks.object.yml +34 -0
  104. package/templates/starter/src/modules/tasks/tasks.permission.yml +167 -0
  105. package/templates/starter/src/types/index.ts +3 -0
  106. package/templates/starter/src/types/kitchen_sink.ts +101 -0
  107. package/templates/starter/src/types/projects.ts +49 -0
  108. package/templates/starter/src/types/tasks.ts +33 -0
  109. package/templates/starter/tsconfig.json +11 -0
  110. package/templates/starter/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,339 @@
1
+ import { ObjectHookDefinition } from '@objectql/types';
2
+ import { Projects } from '../../types';
3
+
4
+ /**
5
+ * Project Hooks - Comprehensive Example
6
+ *
7
+ * This file demonstrates all major hook patterns according to the ObjectQL specification:
8
+ * 1. Data validation and defaulting (beforeCreate)
9
+ * 2. Query modification for security (beforeFind)
10
+ * 3. State transition validation (beforeUpdate)
11
+ * 4. Change tracking and notifications (afterUpdate)
12
+ * 5. Dependency checking (beforeDelete)
13
+ * 6. Side effects and cleanup (afterDelete)
14
+ */
15
+ const hooks: ObjectHookDefinition<Projects> = {
16
+
17
+ /**
18
+ * beforeCreate - Data Validation & Defaulting
19
+ *
20
+ * Use case:
21
+ * - Set default values
22
+ * - Auto-assign ownership
23
+ * - Validate business rules
24
+ * - Check for duplicates
25
+ */
26
+ beforeCreate: async ({ data, user, api }) => {
27
+ // 1. Auto-assign owner if not specified
28
+ if (data && !data.owner && user?.id) {
29
+ console.log(`[Hook] Projects: Auto-assigning owner ${user.id}`);
30
+ data.owner = String(user.id);
31
+ }
32
+
33
+ // 2. Set default status if not provided
34
+ if (data && !data.status) {
35
+ data.status = 'planned';
36
+ }
37
+
38
+ // 3. Validate required fields
39
+ if (data && (!data.name || data.name.trim().length === 0)) {
40
+ throw new Error('Project name is required');
41
+ }
42
+
43
+ // 4. Validate name length
44
+ if (data && data.name && data.name.length > 100) {
45
+ throw new Error('Project name must be 100 characters or less');
46
+ }
47
+
48
+ // 5. Check for duplicate names (using API)
49
+ if (data && data.name) {
50
+ const existing = await api.count('projects', [['name', '=', data.name]]);
51
+ if (existing > 0) {
52
+ throw new Error(`A project named "${data.name}" already exists`);
53
+ }
54
+ }
55
+
56
+ // 6. Set initial budget if not provided
57
+ if (data && !data.budget) {
58
+ data.budget = 0;
59
+ }
60
+ },
61
+
62
+ /**
63
+ * afterCreate - Side Effects
64
+ *
65
+ * Use case:
66
+ * - Send notifications
67
+ * - Create related records
68
+ * - Log audit trail
69
+ * - Trigger workflows
70
+ */
71
+ afterCreate: async ({ result, user, api, state }) => {
72
+ console.log(`[Hook] Projects: Project created - ${result?.name} by ${user?.id}`);
73
+
74
+ // Example: Create a default task for new projects
75
+ // Uncomment if tasks object exists
76
+ /*
77
+ if (result) {
78
+ await api.create('tasks', {
79
+ name: 'Setup Project',
80
+ project_id: result._id,
81
+ status: 'pending',
82
+ description: 'Initial project setup task'
83
+ });
84
+ }
85
+ */
86
+ },
87
+
88
+ /**
89
+ * beforeFind - Query Filtering for Security
90
+ *
91
+ * Use case:
92
+ * - Enforce multi-tenancy
93
+ * - Apply row-level security
94
+ * - Add default filters
95
+ * - Restrict data access based on user role
96
+ */
97
+ beforeFind: async ({ query, user, api }) => {
98
+ // Example: If not admin, restrict to own projects
99
+ // Uncomment to enable row-level security
100
+ /*
101
+ if (user && !user.isAdmin) {
102
+ // Add filter to only show projects owned by current user
103
+ if (!query.filters) {
104
+ query.filters = [];
105
+ }
106
+ query.filters.push(['owner', '=', user.id]);
107
+ console.log(`[Hook] Projects: Filtering to user ${user.id}'s projects`);
108
+ }
109
+ */
110
+
111
+ // Example: Add default sort
112
+ if (!query.sort) {
113
+ query.sort = [{ field: 'created_at', direction: 'desc' }];
114
+ }
115
+ },
116
+
117
+ /**
118
+ * afterFind - Result Transformation
119
+ *
120
+ * Use case:
121
+ * - Add computed fields
122
+ * - Mask sensitive data
123
+ * - Enrich data from external sources
124
+ * - Transform dates/formats
125
+ */
126
+ afterFind: async ({ result, user }) => {
127
+ // Example: Add computed progress field based on status
128
+ if (Array.isArray(result)) {
129
+ result.forEach((project: any) => {
130
+ switch (project.status) {
131
+ case 'planned':
132
+ project.progress = 0;
133
+ break;
134
+ case 'in_progress':
135
+ project.progress = 50;
136
+ break;
137
+ case 'completed':
138
+ project.progress = 100;
139
+ break;
140
+ default:
141
+ project.progress = 0;
142
+ }
143
+ });
144
+ }
145
+ },
146
+
147
+ /**
148
+ * beforeUpdate - State Transition Validation
149
+ *
150
+ * Use case:
151
+ * - Validate state machine transitions
152
+ * - Check permissions for specific updates
153
+ * - Validate budget changes
154
+ * - Track modifications
155
+ */
156
+ beforeUpdate: async ({ data, previousData, isModified, user, state }) => {
157
+ // 1. Check budget constraints
158
+ if (isModified('budget')) {
159
+ if (data && data.budget != undefined && data.budget < 0) {
160
+ throw new Error('Budget cannot be negative');
161
+ }
162
+
163
+ if (data && data.budget != undefined && previousData && data.budget < (previousData.budget || 0)) {
164
+ console.warn(`[Hook] Projects: Budget reduced from ${previousData.budget} to ${data.budget}`);
165
+
166
+ // Optional: Require approval for budget reduction
167
+ /*
168
+ if ((previousData.budget || 0) - data.budget > 10000) {
169
+ throw new Error('Budget reductions over $10,000 require approval');
170
+ }
171
+ */
172
+ }
173
+ }
174
+
175
+ // 2. Validate status transitions
176
+ if (isModified('status') && previousData) {
177
+ const oldStatus = previousData.status;
178
+ const newStatus = data?.status;
179
+
180
+ // Define valid transitions
181
+ const validTransitions: Record<string, string[]> = {
182
+ 'planned': ['in_progress'],
183
+ 'in_progress': ['completed', 'planned'], // Can go back to planning
184
+ 'completed': [] // Cannot change from completed
185
+ };
186
+
187
+ if (oldStatus && newStatus) {
188
+ const allowed = validTransitions[oldStatus] || [];
189
+ if (!allowed.includes(newStatus)) {
190
+ throw new Error(
191
+ `Invalid status transition: cannot change from "${oldStatus}" to "${newStatus}"`
192
+ );
193
+ }
194
+ }
195
+ }
196
+
197
+ // 3. Require end_date when marking as completed
198
+ if (isModified('status') && data?.status === 'completed') {
199
+ if (!data.end_date && !previousData?.end_date) {
200
+ throw new Error('End date is required when completing a project');
201
+ }
202
+ }
203
+
204
+ // 4. Store change summary in state for afterUpdate hook
205
+ if (isModified('status')) {
206
+ state.statusChanged = true;
207
+ state.oldStatus = previousData?.status;
208
+ state.newStatus = data?.status;
209
+ }
210
+ },
211
+
212
+ /**
213
+ * afterUpdate - Change Notifications & Side Effects
214
+ *
215
+ * Use case:
216
+ * - Send notifications based on changes
217
+ * - Update related records
218
+ * - Trigger workflows
219
+ * - Log audit trail
220
+ */
221
+ afterUpdate: async ({ isModified, data, previousData, result, state, api, user }) => {
222
+ // 1. Notify on status change
223
+ if (state.statusChanged) {
224
+ console.log(
225
+ `[Hook] Projects: Status changed from "${state.oldStatus}" to "${state.newStatus}" by ${user?.id}`
226
+ );
227
+
228
+ // Example: Create notification record
229
+ /*
230
+ if (data.status === 'completed' && previousData?.owner) {
231
+ await api.create('notifications', {
232
+ user_id: previousData.owner,
233
+ message: `Project "${result?.name}" has been completed!`,
234
+ type: 'project_completed',
235
+ link: `/projects/${result?._id}`
236
+ });
237
+ }
238
+ */
239
+ }
240
+
241
+ // 2. Notify on budget changes over threshold
242
+ if (isModified('budget') && previousData) {
243
+ const oldBudget = previousData.budget || 0;
244
+ const newBudget = data?.budget || 0;
245
+ const change = Math.abs(newBudget - oldBudget);
246
+
247
+ if (change > 5000) {
248
+ console.log(
249
+ `[Hook] Projects: Significant budget change detected: ${oldBudget} -> ${newBudget}`
250
+ );
251
+ }
252
+ }
253
+
254
+ // 3. Update related tasks when project is completed
255
+ /*
256
+ if (data.status === 'completed') {
257
+ await api.updateMany('tasks',
258
+ { filters: [['project_id', '=', result._id]] },
259
+ { status: 'completed' }
260
+ );
261
+ }
262
+ */
263
+ },
264
+
265
+ /**
266
+ * beforeDelete - Dependency Checking
267
+ *
268
+ * Use case:
269
+ * - Prevent deletion if dependencies exist
270
+ * - Check permissions
271
+ * - Validate business rules
272
+ */
273
+ beforeDelete: async ({ id, previousData, api, user }) => {
274
+ // 1. Prevent deletion of completed projects
275
+ if (previousData?.status === 'completed') {
276
+ throw new Error('Cannot delete completed projects. Please archive instead.');
277
+ }
278
+
279
+ // 2. Check for dependent tasks
280
+ /*
281
+ const taskCount = await api.count('tasks', [['project_id', '=', id]]);
282
+
283
+ if (taskCount > 0) {
284
+ throw new Error(
285
+ `Cannot delete project: ${taskCount} tasks are still associated with it. ` +
286
+ 'Please delete or reassign tasks first.'
287
+ );
288
+ }
289
+ */
290
+
291
+ // 3. Require admin permission for deletion
292
+ /*
293
+ if (!user?.isAdmin) {
294
+ throw new Error('Only administrators can delete projects');
295
+ }
296
+ */
297
+
298
+ console.log(`[Hook] Projects: Preparing to delete project ${id}`);
299
+ },
300
+
301
+ /**
302
+ * afterDelete - Cleanup & Side Effects
303
+ *
304
+ * Use case:
305
+ * - Delete related records (cascade)
306
+ * - Clean up external resources
307
+ * - Send notifications
308
+ * - Log audit trail
309
+ */
310
+ afterDelete: async ({ id, previousData, api, user }) => {
311
+ console.log(`[Hook] Projects: Project deleted - ${previousData?.name} by ${user?.id}`);
312
+
313
+ // Example: Clean up related data
314
+ /*
315
+ // Delete associated tasks
316
+ await api.deleteMany('tasks', {
317
+ filters: [['project_id', '=', id]]
318
+ });
319
+
320
+ // Delete associated files from S3
321
+ if (previousData?.attachments) {
322
+ for (const attachment of previousData.attachments) {
323
+ await deleteFromS3(attachment.key);
324
+ }
325
+ }
326
+
327
+ // Create audit log
328
+ await api.create('audit_logs', {
329
+ action: 'project_deleted',
330
+ entity_id: id,
331
+ entity_name: previousData?.name,
332
+ user_id: user?.id,
333
+ timestamp: new Date()
334
+ });
335
+ */
336
+ }
337
+ };
338
+
339
+ export default hooks;
@@ -0,0 +1,148 @@
1
+ label: Project
2
+ icon: building-line
3
+ fields:
4
+ name:
5
+ type: text
6
+ required: true
7
+ index: true # Field-level index
8
+
9
+ status:
10
+ options:
11
+ - planned
12
+ - in_progress
13
+ - completed
14
+ defaultValue: planned
15
+ index: true
16
+
17
+ priority:
18
+ options:
19
+ - low
20
+ - normal
21
+ - high
22
+ defaultValue: normal
23
+
24
+ description:
25
+ type: textarea
26
+
27
+ owner:
28
+ type: text
29
+
30
+ budget:
31
+ type: currency
32
+
33
+ start_date:
34
+ type: date
35
+
36
+ end_date:
37
+ type: date
38
+
39
+ approved_by:
40
+ type: text
41
+
42
+ approved_at:
43
+ type: datetime
44
+
45
+ approval_comment:
46
+ type: textarea
47
+
48
+ indexes:
49
+ # Composite index for reporting
50
+ status_priority_idx:
51
+ fields: [status, priority]
52
+
53
+ ai:
54
+ search:
55
+ enabled: true
56
+ fields: [name, description]
57
+ model: text-embedding-3-small
58
+
59
+ actions:
60
+ # Record Actions (operate on specific records)
61
+ complete:
62
+ type: record
63
+ label: Complete Project
64
+ icon: checkbox-circle-line
65
+ confirm_text: "Are you sure you want to complete this project?"
66
+ params:
67
+ comment:
68
+ type: textarea
69
+ label: Completion Comment
70
+ completion_date:
71
+ type: date
72
+ label: Completion Date
73
+
74
+ approve:
75
+ type: record
76
+ label: Approve Project
77
+ icon: shield-check-line
78
+ confirm_text: "Are you sure you want to approve this project?"
79
+ params:
80
+ comment:
81
+ type: textarea
82
+ required: true
83
+ label: Approval Comment
84
+ help_text: "Provide a reason for approving this project"
85
+
86
+ clone:
87
+ type: record
88
+ label: Clone Project
89
+ icon: file-copy-line
90
+ description: Create a copy of this project
91
+ params:
92
+ new_name:
93
+ type: text
94
+ required: true
95
+ label: New Project Name
96
+ copy_tasks:
97
+ type: checkbox
98
+ label: Copy Associated Tasks
99
+ defaultValue: false
100
+
101
+ # Global Actions (operate on collections)
102
+ import_projects:
103
+ type: global
104
+ label: Import Projects
105
+ icon: download-line
106
+ internal: false
107
+ description: Import multiple projects from various sources
108
+ params:
109
+ source:
110
+ required: true
111
+ label: Import Source
112
+ options:
113
+ - csv
114
+ - json
115
+ - api
116
+ data:
117
+ type: textarea
118
+ label: JSON Data
119
+ help_text: "Paste JSON array of projects (optional if using file_url)"
120
+ file_url:
121
+ type: text
122
+ label: File URL
123
+ help_text: "URL to fetch data from (optional if using data field)"
124
+
125
+ bulk_update_status:
126
+ type: global
127
+ label: Bulk Update Status
128
+ icon: edit-box-line
129
+ description: Update status for multiple projects at once
130
+ params:
131
+ project_ids:
132
+ type: textarea
133
+ required: true
134
+ label: Project IDs
135
+ help_text: "List of project IDs"
136
+ new_status:
137
+ required: true
138
+ label: New Status
139
+ options:
140
+ - planned
141
+ - in_progress
142
+ - completed
143
+
144
+ generate_report:
145
+ type: global
146
+ label: Generate Project Report
147
+ icon: file-chart-line
148
+ description: Generate statistical report of all projects
@@ -0,0 +1,141 @@
1
+ name: projects_permission
2
+ object: projects
3
+ description: "Comprehensive access control rules for Project object"
4
+
5
+ # Roles (defined in demo.app.yml, referenced here)
6
+ # This list documents which system roles have permissions on this object
7
+ roles:
8
+ - admin
9
+ - manager
10
+ - developer
11
+ - user
12
+ - viewer
13
+
14
+ # Object-level permissions (CRUD)
15
+ object_permissions:
16
+ create: [admin, manager]
17
+ read: [admin, manager, developer, user, viewer]
18
+ update: [admin, manager]
19
+ delete: [admin]
20
+ view_all: [admin] # Admins can see all projects
21
+ modify_all: [admin] # Admins can edit all projects
22
+
23
+ # Field-level security
24
+ field_permissions:
25
+ budget:
26
+ read: [admin, manager]
27
+ update: [admin] # Only admin can change budget
28
+
29
+ approved_by:
30
+ read: [admin, manager, user]
31
+ update: [] # Read-only, set by system/workflow
32
+
33
+ approved_at:
34
+ read: [admin, manager, user]
35
+ update: []
36
+
37
+ approval_comment:
38
+ read: [admin, manager, user]
39
+ update: [admin, manager]
40
+
41
+ # Record-level rules for dynamic access control
42
+ record_rules:
43
+ - name: owner_full_access
44
+ priority: 100
45
+ description: Project owner has full access to their projects
46
+ condition:
47
+ type: simple
48
+ field: owner
49
+ operator: "="
50
+ value: $current_user.id
51
+ permissions:
52
+ read: true
53
+ update: true
54
+ delete: true
55
+
56
+ - name: public_read_access
57
+ priority: 10
58
+ description: Completed projects are publicly readable
59
+ condition:
60
+ type: simple
61
+ field: status
62
+ operator: "="
63
+ value: completed
64
+ permissions:
65
+ read: true
66
+ update: false
67
+ delete: false
68
+
69
+ # Sharing rules
70
+ sharing_rules:
71
+ - name: manual_share
72
+ type: manual
73
+ description: Users can manually share projects with team members
74
+ enabled: true
75
+ permissions:
76
+ read: true
77
+ update: false
78
+ delete: false
79
+
80
+ # Action permissions
81
+ action_permissions:
82
+ approve:
83
+ execute: [admin, manager]
84
+ conditions:
85
+ - field: status
86
+ operator: "="
87
+ value: in_progress
88
+
89
+ complete:
90
+ execute: [admin, manager]
91
+
92
+ clone:
93
+ execute: [admin, manager, developer]
94
+
95
+ import_projects:
96
+ execute: [admin]
97
+ rate_limit:
98
+ requests_per_hour: 10
99
+
100
+ bulk_update_status:
101
+ execute: [admin, manager]
102
+
103
+ # View permissions
104
+ view_permissions:
105
+ all_projects:
106
+ access: [admin, manager, developer, user, viewer]
107
+ field_restrictions:
108
+ budget:
109
+ visible_to: [admin, manager]
110
+
111
+ # Row-level security
112
+ row_level_security:
113
+ enabled: true
114
+ default_rule:
115
+ field: owner
116
+ operator: "="
117
+ value: $current_user.id
118
+ exceptions:
119
+ - role: admin
120
+ bypass: true
121
+ - role: manager
122
+ condition:
123
+ type: simple
124
+ field: status
125
+ operator: "!="
126
+ value: completed
127
+
128
+ # Audit trail
129
+ audit:
130
+ enabled: true
131
+ events:
132
+ - permission_grant
133
+ - permission_revoke
134
+ - access_denied
135
+ - sensitive_field_access
136
+ retention_days: 365
137
+ alerts:
138
+ - event: access_denied
139
+ threshold: 5
140
+ window_minutes: 10
141
+ notify: [admin]
@@ -0,0 +1,37 @@
1
+ name: projects_validation
2
+ object: projects
3
+ description: "Validation rules for Projects"
4
+
5
+ rules:
6
+ - name: valid_date_range
7
+ type: cross_field
8
+ ai_context:
9
+ intent: "Ensure project timeline is valid"
10
+ business_rule: "Projects cannot end before they start"
11
+ rule:
12
+ field: end_date
13
+ operator: ">="
14
+ compare_to: start_date
15
+ message: "End Date must be after Start Date"
16
+
17
+ - name: positive_budget
18
+ type: field
19
+ rule:
20
+ field: budget
21
+ operator: ">="
22
+ value: 0
23
+ message: "Budget cannot be negative"
24
+
25
+ - name: comment_required_if_high_budget
26
+ type: conditional
27
+ description: "Description is required for high budget projects"
28
+ ai_context:
29
+ business_rule: "High value projects (>10k) must have a detailed description"
30
+ condition:
31
+ field: budget
32
+ operator: ">"
33
+ value: 10000
34
+ rule:
35
+ field: description
36
+ operator: "not_empty"
37
+ message: "Description is required for high budget projects (> $10,000)"
@@ -0,0 +1,23 @@
1
+ - _id: TASK-001
2
+ name: "Design Homepage Mockups"
3
+ project: "PROJ-001"
4
+ due_date: "2024-12-31"
5
+ completed: false
6
+
7
+ - _id: TASK-002
8
+ name: "Setup CI/CD Pipeline"
9
+ project: "PROJ-001"
10
+ due_date: "2024-11-15"
11
+ completed: true
12
+
13
+ - _id: TASK-003
14
+ name: "Draft App Requirements"
15
+ project: "PROJ-002"
16
+ due_date: "2025-01-20"
17
+ completed: false
18
+
19
+ - _id: TASK-004
20
+ name: "Choose Tech Stack"
21
+ project: "PROJ-002"
22
+ due_date: "2025-01-10"
23
+ completed: true