@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ObjectQL Contributors (https://github.com/objectql)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @objectql/create
2
+
3
+ The easiest way to get started with ObjectQL.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npm create @objectql@latest
9
+ ```
10
+
11
+ Follow the prompts to create your new ObjectQL application.
12
+
13
+ ## Arguments
14
+
15
+ You can also pass arguments directly:
16
+
17
+ ```bash
18
+ npm create @objectql@latest <project-name> --template <template-name>
19
+ ```
20
+
21
+ - `<project-name>`: Name of the project directory.
22
+ - `--template`: Template to use (e.g. `hello-world` or `showcase`).
23
+
24
+ ## Features
25
+
26
+ - **Embedded Templates**: No internet connection required to fetch templates.
27
+ - **Auto-Cleanup**: Automatically cleans up `package.json` configurations (strips `private: true`, resolves workspace versions).
28
+ - **Interactive**: Uses `enquirer` for a smooth interactive experience if no arguments are provided.
package/dist/bin.js ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const path = __importStar(require("path"));
42
+ const fs = __importStar(require("fs-extra"));
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ const enquirer_1 = __importDefault(require("enquirer"));
45
+ const { prompt } = enquirer_1.default;
46
+ const program = new commander_1.Command();
47
+ program
48
+ .name('create-objectql')
49
+ .description('Scaffold a new ObjectQL project')
50
+ .argument('[directory]', 'Directory to create the project in')
51
+ .option('-t, --template <name>', 'Template to use (hello-world, starter, enterprise)')
52
+ .action(async (directory, options) => {
53
+ console.log(chalk_1.default.bold.blue('โšก ObjectStack AI - Project Scaffolder'));
54
+ // 1. Resolve Target Directory
55
+ let targetDir = directory;
56
+ if (!targetDir) {
57
+ const response = await prompt({
58
+ type: 'input',
59
+ name: 'dir',
60
+ message: 'Where should we create the project?',
61
+ initial: 'my-app'
62
+ });
63
+ targetDir = response.dir;
64
+ }
65
+ const root = path.resolve(process.cwd(), targetDir);
66
+ // 2. Resolve Template Source (Embedded)
67
+ // The templates are located in ../templates relative to the dist/bin.js file
68
+ // dist/bin.js -> ../templates -> package-root/templates
69
+ let templateName = options.template;
70
+ if (!templateName) {
71
+ const response = await prompt({
72
+ type: 'select',
73
+ name: 'template',
74
+ message: 'Select a starter template:',
75
+ choices: [
76
+ { message: 'Standard Project (Recommended)', name: 'starter' },
77
+ { message: 'Enterprise ERP System', name: 'enterprise' },
78
+ { message: 'Minimal (Hello World)', name: 'hello-world' }
79
+ ]
80
+ });
81
+ templateName = response.template;
82
+ }
83
+ // Legacy mapping or aliasing if needed
84
+ if (templateName === 'project-tracker')
85
+ templateName = 'starter';
86
+ const templatePath = path.resolve(__dirname, '../templates', templateName);
87
+ if (!fs.existsSync(templatePath)) {
88
+ console.error(chalk_1.default.red(`โŒ Template '${templateName}' not found in package.`));
89
+ console.error(chalk_1.default.gray(`Path looked for: ${templatePath}`));
90
+ process.exit(1);
91
+ }
92
+ // 3. Copy Files
93
+ console.log(`\nCreating project in ${chalk_1.default.green(root)}...`);
94
+ await fs.ensureDir(root);
95
+ await fs.copy(templatePath, root);
96
+ // 4. Update package.json (De-monorepo)
97
+ const pkgPath = path.join(root, 'package.json');
98
+ if (fs.existsSync(pkgPath)) {
99
+ const pkg = await fs.readJson(pkgPath);
100
+ delete pkg.private;
101
+ delete pkg.repository;
102
+ const updateDeps = (deps) => {
103
+ if (!deps)
104
+ return;
105
+ for (const key in deps) {
106
+ if (deps[key] === 'workspace:*') {
107
+ deps[key] = 'latest';
108
+ }
109
+ }
110
+ };
111
+ updateDeps(pkg.dependencies);
112
+ updateDeps(pkg.devDependencies);
113
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
114
+ }
115
+ // 5. Initialize Git
116
+ try {
117
+ await fs.writeFile(path.join(root, '.gitignore'), `node_modules/\ndist/\n*.log\n.DS_Store\n*.sqlite3\n.env\n.env.local\n`);
118
+ }
119
+ catch { }
120
+ console.log(chalk_1.default.green('\nโœ… Done! Now run:\n'));
121
+ console.log(chalk_1.default.cyan(` cd ${targetDir}`));
122
+ console.log(chalk_1.default.cyan(` npm install`));
123
+ console.log(chalk_1.default.cyan(` npm start`));
124
+ });
125
+ program.parse(process.argv);
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@objectql/create",
3
+ "version": "1.0.0",
4
+ "description": "Create ObjectQL apps with one command",
5
+ "bin": {
6
+ "create-objectql": "./dist/bin.js"
7
+ },
8
+ "files": [
9
+ "dist",
10
+ "templates"
11
+ ],
12
+ "dependencies": {
13
+ "chalk": "^4.1.2",
14
+ "commander": "^11.0.0",
15
+ "enquirer": "^2.4.1",
16
+ "fs-extra": "^11.3.3"
17
+ },
18
+ "devDependencies": {
19
+ "@types/fs-extra": "^11.0.4",
20
+ "@types/node": "^20.0.0",
21
+ "typescript": "^5.0.0"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc && node scripts/copy-templates.js",
25
+ "copy-templates": "node scripts/copy-templates.js"
26
+ }
27
+ }
@@ -0,0 +1,140 @@
1
+ # @objectql/starter-enterprise
2
+
3
+ ## 1.8.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Release version 1.8.4 with latest improvements and bug fixes
8
+ - Updated dependencies
9
+ - @objectql/types@1.8.4
10
+ - @objectql/core@1.8.4
11
+ - @objectql/platform-node@1.8.4
12
+ - @objectql/driver-sql@1.8.4
13
+
14
+ ## 1.8.3
15
+
16
+ ### Patch Changes
17
+
18
+ - Release patch version 1.8.3
19
+
20
+ Small version update with latest improvements and bug fixes.
21
+
22
+ - Updated dependencies
23
+ - @objectql/core@1.8.3
24
+ - @objectql/driver-sql@1.8.3
25
+ - @objectql/types@1.8.3
26
+ - @objectql/platform-node@1.8.3
27
+
28
+ ## 1.8.2
29
+
30
+ ### Patch Changes
31
+
32
+ - Patch release v1.8.2 - Small version update with latest improvements
33
+ - Updated dependencies
34
+ - @objectql/core@1.8.2
35
+ - @objectql/driver-sql@1.8.2
36
+ - @objectql/types@1.8.2
37
+ - @objectql/platform-node@1.8.2
38
+
39
+ ## 1.8.1
40
+
41
+ ### Patch Changes
42
+
43
+ - Patch release with documentation updates and bug fixes
44
+ - Updated dependencies
45
+ - @objectql/core@1.8.1
46
+ - @objectql/driver-sql@1.8.1
47
+ - @objectql/types@1.8.1
48
+ - @objectql/platform-node@1.8.1
49
+
50
+ ## 1.8.0
51
+
52
+ ### Minor Changes
53
+
54
+ - Release minor version 1.8.0
55
+
56
+ ### Patch Changes
57
+
58
+ - Updated dependencies
59
+ - @objectql/core@1.8.0
60
+ - @objectql/driver-sql@2.0.0
61
+ - @objectql/types@2.0.0
62
+ - @objectql/platform-node@2.0.0
63
+
64
+ ## 1.7.3
65
+
66
+ ### Patch Changes
67
+
68
+ - Release patch version 1.7.3 with latest improvements and bug fixes
69
+ - Updated dependencies
70
+ - @objectql/core@1.7.3
71
+ - @objectql/driver-sql@1.7.3
72
+ - @objectql/types@1.7.3
73
+ - @objectql/platform-node@1.7.3
74
+
75
+ ## 1.7.2
76
+
77
+ ### Patch Changes
78
+
79
+ - Release patch version 1.7.2
80
+ - Updated dependencies
81
+ - @objectql/driver-sql@1.7.2
82
+ - @objectql/core@1.7.2
83
+ - @objectql/platform-node@1.7.2
84
+ - @objectql/types@1.7.2
85
+
86
+ ## 1.7.1
87
+
88
+ ### Patch Changes
89
+
90
+ - Release small version update with latest improvements
91
+ - Updated dependencies
92
+ - @objectql/core@1.7.1
93
+ - @objectql/driver-sql@1.7.1
94
+ - @objectql/types@1.7.1
95
+ - @objectql/platform-node@1.7.1
96
+
97
+ ## 1.7.0
98
+
99
+ ### Minor Changes
100
+
101
+ - Release version 1.7.0 with improvements and bug fixes:
102
+ - Updated default port for ObjectQL Studio to 5555
103
+ - Improved port listening logic in Studio
104
+ - Enhanced stability and performance
105
+
106
+ ## 1.6.1
107
+
108
+ ### Patch Changes
109
+
110
+ - Updated dependencies
111
+ - @objectql/core@1.6.1
112
+ - @objectql/platform-node@1.6.1
113
+ - @objectql/driver-sql@1.6.1
114
+ - @objectql/types@1.6.1
115
+
116
+ ## 1.8.0
117
+
118
+ ### Patch Changes
119
+
120
+ - Updated dependencies
121
+ - @objectql/core@1.6.0
122
+ - @objectql/driver-sql@1.6.0
123
+ - @objectql/types@1.6.0
124
+ - @objectql/platform-node@1.6.0
125
+
126
+ ## 1.0.0
127
+
128
+ ### Added
129
+
130
+ - Initial release with enterprise-scale metadata organization example
131
+ - Core module with user, organization, and attachment objects
132
+ - CRM module with account, contact, opportunity, and lead objects
133
+ - HR module with employee, department, position, and timesheet objects
134
+ - Finance module with invoice, payment, expense, and budget objects
135
+ - Project module with project, task, milestone, and timesheet entry objects
136
+ - Extension pattern demonstration with user extensions
137
+ - Comprehensive documentation for each module
138
+ - Shared utilities, constants, and validators
139
+ - Module index files for clean exports
140
+ - README with best practices and architecture guidance
@@ -0,0 +1,352 @@
1
+ # Enterprise-Scale Metadata Organization
2
+
3
+ This example demonstrates **best practices for organizing metadata** in large-scale ObjectQL projects, suitable for enterprise applications with hundreds of objects and complex business domains.
4
+
5
+ ## ๐Ÿ“‹ Problem Statement
6
+
7
+ When building large applications, poor metadata organization leads to:
8
+ - **Difficulty finding objects** - scattered files with no clear structure
9
+ - **Merge conflicts** - multiple teams editing the same files
10
+ - **Unclear ownership** - no way to know which team owns which domain
11
+ - **Deployment risks** - can't deploy modules independently
12
+ - **Maintenance burden** - hard to understand relationships between objects
13
+
14
+ ## ๐ŸŽฏ Solution: Domain-Driven Structure
15
+
16
+ This example shows a **modular, domain-based** organization pattern that scales to enterprise needs.
17
+
18
+ ```
19
+ src/
20
+ โ”œโ”€โ”€ core/ # Shared/Foundation Layer
21
+ โ”‚ โ”œโ”€โ”€ objects/ # Base objects used across domains
22
+ โ”‚ โ”‚ โ”œโ”€โ”€ user.object.yml
23
+ โ”‚ โ”‚ โ”œโ”€โ”€ organization.object.yml
24
+ โ”‚ โ”‚ โ””โ”€โ”€ attachment.object.yml
25
+ โ”‚ โ”œโ”€โ”€ i18n/
26
+ โ”‚ โ”‚ โ”œโ”€โ”€ en/
27
+ โ”‚ โ”‚ โ””โ”€โ”€ zh-CN/
28
+ โ”‚ โ””โ”€โ”€ index.ts
29
+ โ”‚
30
+ โ”œโ”€โ”€ modules/ # Business Domain Modules
31
+ โ”‚ โ”œโ”€โ”€ crm/ # Customer Relationship Module
32
+ โ”‚ โ”‚ โ”œโ”€โ”€ objects/
33
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ crm_account.object.yml
34
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ crm_contact.object.yml
35
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ crm_opportunity.object.yml
36
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ crm_lead.object.yml
37
+ โ”‚ โ”‚ โ”œโ”€โ”€ actions/
38
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ convert-lead.action.ts
39
+ โ”‚ โ”‚ โ”œโ”€โ”€ hooks/
40
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ opportunity.hooks.ts
41
+ โ”‚ โ”‚ โ”œโ”€โ”€ i18n/
42
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ en/
43
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ zh-CN/
44
+ โ”‚ โ”‚ โ”œโ”€โ”€ README.md
45
+ โ”‚ โ”‚ โ””โ”€โ”€ index.ts
46
+ โ”‚ โ”‚
47
+ โ”‚ โ”œโ”€โ”€ hr/ # Human Resources Module
48
+ โ”‚ โ”‚ โ”œโ”€โ”€ objects/
49
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ hr_employee.object.yml
50
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ hr_department.object.yml
51
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ hr_position.object.yml
52
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ hr_timesheet.object.yml
53
+ โ”‚ โ”‚ โ”œโ”€โ”€ actions/
54
+ โ”‚ โ”‚ โ”œโ”€โ”€ hooks/
55
+ โ”‚ โ”‚ โ”œโ”€โ”€ i18n/
56
+ โ”‚ โ”‚ โ”œโ”€โ”€ README.md
57
+ โ”‚ โ”‚ โ””โ”€โ”€ index.ts
58
+ โ”‚ โ”‚
59
+ โ”‚ โ”œโ”€โ”€ finance/ # Finance & Accounting Module
60
+ โ”‚ โ”‚ โ”œโ”€โ”€ objects/
61
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ finance_invoice.object.yml
62
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ finance_payment.object.yml
63
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ finance_expense.object.yml
64
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ finance_budget.object.yml
65
+ โ”‚ โ”‚ โ”œโ”€โ”€ actions/
66
+ โ”‚ โ”‚ โ”œโ”€โ”€ hooks/
67
+ โ”‚ โ”‚ โ”œโ”€โ”€ i18n/
68
+ โ”‚ โ”‚ โ”œโ”€โ”€ README.md
69
+ โ”‚ โ”‚ โ””โ”€โ”€ index.ts
70
+ โ”‚ โ”‚
71
+ โ”‚ โ””โ”€โ”€ project/ # Project Management Module
72
+ โ”‚ โ”œโ”€โ”€ objects/
73
+ โ”‚ โ”‚ โ”œโ”€โ”€ project_project.object.yml
74
+ โ”‚ โ”‚ โ”œโ”€โ”€ project_task.object.yml
75
+ โ”‚ โ”‚ โ”œโ”€โ”€ project_milestone.object.yml
76
+ โ”‚ โ”‚ โ””โ”€โ”€ project_timesheet_entry.object.yml
77
+ โ”‚ โ”œโ”€โ”€ actions/
78
+ โ”‚ โ”œโ”€โ”€ hooks/
79
+ โ”‚ โ”œโ”€โ”€ i18n/
80
+ โ”‚ โ”œโ”€โ”€ README.md
81
+ โ”‚ โ””โ”€โ”€ index.ts
82
+ โ”‚
83
+ โ”œโ”€โ”€ extensions/ # Custom Extensions/Overrides
84
+ โ”‚ โ”œโ”€โ”€ user.extension.object.yml
85
+ โ”‚ โ””โ”€โ”€ README.md
86
+ โ”‚
87
+ โ”œโ”€โ”€ shared/ # Shared Utilities
88
+ โ”‚ โ”œโ”€โ”€ constants.ts
89
+ โ”‚ โ”œโ”€โ”€ validators.ts
90
+ โ”‚ โ””โ”€โ”€ utils.ts
91
+ โ”‚
92
+ โ””โ”€โ”€ index.ts # Application Entry Point
93
+ ```
94
+
95
+ ## ๐Ÿ—๏ธ Architecture Principles
96
+
97
+ ### 1. **Separation of Concerns**
98
+ Each module is self-contained with its own:
99
+ - Object definitions (`.object.yml`)
100
+ - Business logic (actions & hooks)
101
+ - Translations (i18n)
102
+ - Documentation
103
+
104
+ ### 2. **Clear Dependencies**
105
+ ```
106
+ Application Layer (modules/*)
107
+ โ†“
108
+ Foundation Layer (core/*)
109
+ โ†“
110
+ External Plugins
111
+ ```
112
+
113
+ ### 3. **Team Ownership**
114
+ Each module can be owned by a different team:
115
+ - `modules/crm/` โ†’ Sales Team
116
+ - `modules/hr/` โ†’ HR Team
117
+ - `modules/finance/` โ†’ Finance Team
118
+
119
+ ### 4. **Independent Deployment**
120
+ Modules can be:
121
+ - Developed in parallel
122
+ - Tested independently
123
+ - Deployed as feature flags
124
+ - Extracted to separate packages
125
+
126
+ ## ๐Ÿ“ฆ Module Structure
127
+
128
+ Each module follows this pattern:
129
+
130
+ ```
131
+ modules/[domain]/
132
+ โ”œโ”€โ”€ objects/ # Domain object definitions
133
+ โ”œโ”€โ”€ actions/ # Custom actions (*.action.ts)
134
+ โ”œโ”€โ”€ hooks/ # Lifecycle hooks (*.hooks.ts)
135
+ โ”œโ”€โ”€ i18n/ # Module-specific translations
136
+ โ”‚ โ”œโ”€โ”€ en/
137
+ โ”‚ โ””โ”€โ”€ zh-CN/
138
+ โ”œโ”€โ”€ README.md # Module documentation
139
+ โ””โ”€โ”€ index.ts # Module exports
140
+ ```
141
+
142
+ ## ๐Ÿ”— Object Naming Conventions
143
+
144
+ ### Prefixing Strategy
145
+ For large projects, consider prefixing object names:
146
+
147
+ ```yaml
148
+ # โŒ Bad: Name collision risk
149
+ name: task
150
+
151
+ # โœ… Good: Clear module ownership
152
+ name: project_task
153
+ ```
154
+
155
+ **When to prefix:**
156
+ - โœ… When multiple modules might have similar concepts
157
+ - โœ… In multi-tenant or plugin architectures
158
+ - โŒ When it's clearly a core shared object (e.g., `user`, `organization`)
159
+
160
+ ### File Naming
161
+ ```
162
+ [object_name].object.yml # Object definition
163
+ [object_name].action.ts # Actions for this object
164
+ [object_name].hooks.ts # Hooks for this object
165
+ [object_name].data.yml # Seed data (optional)
166
+ ```
167
+
168
+ ## ๐ŸŒ Internationalization at Scale
169
+
170
+ ### Three-Layer Strategy
171
+
172
+ 1. **Core Layer** (`core/i18n/`)
173
+ - Shared objects (user, organization)
174
+ - Common UI labels
175
+
176
+ 2. **Module Layer** (`modules/[domain]/i18n/`)
177
+ - Domain-specific objects
178
+ - Business terminology
179
+
180
+ 3. **Extension Layer** (`extensions/i18n/`)
181
+ - Customer-specific customizations
182
+ - Regional variants
183
+
184
+ ### Example Structure
185
+ ```
186
+ core/i18n/
187
+ en/
188
+ user.json
189
+ organization.json
190
+ zh-CN/
191
+ user.json
192
+ organization.json
193
+
194
+ modules/crm/i18n/
195
+ en/
196
+ account.json
197
+ opportunity.json
198
+ zh-CN/
199
+ account.json
200
+ opportunity.json
201
+ ```
202
+
203
+ ## ๐Ÿ” Index & Performance Strategy
204
+
205
+ ### Field-Level Indexes (Simple)
206
+ For single-column lookups:
207
+ ```yaml
208
+ fields:
209
+ email:
210
+ type: text
211
+ unique: true # Creates unique index
212
+ status:
213
+ type: select
214
+ index: true # Creates regular index
215
+ ```
216
+
217
+ ### Composite Indexes (Advanced)
218
+ Define at object root for multi-column queries:
219
+ ```yaml
220
+ indexes:
221
+ # For query: WHERE status = 'open' ORDER BY created_at DESC
222
+ status_created_idx:
223
+ fields: [status, created_at]
224
+
225
+ # For unique constraint: UNIQUE(company_id, email)
226
+ company_email_unique:
227
+ fields: [company_id, email]
228
+ unique: true
229
+ ```
230
+
231
+ ### Index Strategy by Module
232
+
233
+ **High-Traffic Modules** (CRM, Finance):
234
+ - Add indexes on every filter field
235
+ - Use composite indexes for common query patterns
236
+ - Monitor query performance regularly
237
+
238
+ **Low-Traffic Modules** (HR, Admin):
239
+ - Basic indexes on primary lookup fields
240
+ - Add more as needed based on usage
241
+
242
+ ## ๐Ÿงฉ Extension Pattern
243
+
244
+ Use extensions to customize objects without modifying core definitions:
245
+
246
+ **Core Definition** (`core/objects/user.object.yml`):
247
+ ```yaml
248
+ name: user
249
+ fields:
250
+ name: { type: text }
251
+ email: { type: text }
252
+ ```
253
+
254
+ **Extension** (`extensions/user.extension.object.yml`):
255
+ ```yaml
256
+ name: user # Same name triggers merge
257
+ fields:
258
+ # Add custom field
259
+ employee_id:
260
+ type: text
261
+ label: Employee ID
262
+
263
+ # Override existing field
264
+ email:
265
+ required: true
266
+ unique: true
267
+ ```
268
+
269
+ ## ๐Ÿงช Testing Strategy
270
+
271
+ ### Unit Tests
272
+ Test individual object schemas:
273
+ ```typescript
274
+ // modules/crm/objects/__tests__/account.test.ts
275
+ describe('Account Object', () => {
276
+ it('should have required fields', () => {
277
+ const account = loadObject('account');
278
+ expect(account.fields.name.required).toBe(true);
279
+ });
280
+ });
281
+ ```
282
+
283
+ ### Integration Tests
284
+ Test module interactions:
285
+ ```typescript
286
+ // modules/crm/__tests__/integration.test.ts
287
+ describe('CRM Module', () => {
288
+ it('should convert lead to opportunity', async () => {
289
+ // Test cross-object logic
290
+ });
291
+ });
292
+ ```
293
+
294
+ ## ๐Ÿ“Š Real-World Size Reference
295
+
296
+ | Project Size | Objects | Modules | Teams | Structure |
297
+ |--------------|---------|---------|-------|-----------|
298
+ | **Small** (Startup) | 10-30 | 1-2 | 1 | Flat `/objects/` |
299
+ | **Medium** (Scale-up) | 30-100 | 3-5 | 2-3 | `/modules/` by domain |
300
+ | **Large** (Enterprise) | 100-500 | 8-15 | 5-10 | `/modules/` + `/plugins/` |
301
+ | **Very Large** (Platform) | 500+ | 15+ | 10+ | Monorepo with packages |
302
+
303
+ ## ๐Ÿš€ Migration Path
304
+
305
+ ### From Flat to Modular
306
+
307
+ 1. **Analyze** - Group objects by business domain
308
+ 2. **Create** - Create module directories
309
+ 3. **Move** - Relocate objects to appropriate modules
310
+ 4. **Test** - Verify imports and references still work
311
+ 5. **Document** - Update README files
312
+
313
+ ### Gradual Approach
314
+ You don't have to reorganize everything at once:
315
+ ```
316
+ src/
317
+ โ”œโ”€โ”€ objects/ # Legacy flat structure (deprecated)
318
+ โ”œโ”€โ”€ modules/ # New modular structure
319
+ โ”‚ โ””โ”€โ”€ crm/ # Start with one module
320
+ โ””โ”€โ”€ index.ts # Loads from both
321
+ ```
322
+
323
+ ## ๐Ÿ’ก Pro Tips
324
+
325
+ 1. **Start Simple** - Don't over-engineer for 10 objects. Use modules when you hit 30-50 objects.
326
+
327
+ 2. **Document Boundaries** - Each module README should explain:
328
+ - What business domain it covers
329
+ - Key objects and relationships
330
+ - Team ownership
331
+ - Dependencies on other modules
332
+
333
+ 3. **Avoid Circular Dependencies** - Use shared objects in `core/` to break cycles.
334
+
335
+ 4. **Version Control** - Use `.gitignore` to exclude generated files:
336
+ ```
337
+ dist/
338
+ *.generated.ts
339
+ node_modules/
340
+ ```
341
+
342
+ 5. **Code Generation** - Run `objectql generate` to create TypeScript types for each module separately.
343
+
344
+ ## ๐Ÿ“š See Also
345
+
346
+ - [Data Modeling Guide](../../../docs/guide/data-modeling.md)
347
+ - [Plugin Development](../../../docs/guide/plugins.md)
348
+ - [ObjectQL Architecture](../../../docs/guide/architecture.md)
349
+
350
+ ## ๐Ÿค Contributing
351
+
352
+ This is a living example. If you have suggestions for enterprise-scale patterns, please open an issue or PR!