Skip to content

Commit 880a99e

Browse files
committed
feat: add CRM server implementation with ObjectStack integration and logging
1 parent b1366ab commit 880a99e

File tree

5 files changed

+199
-39
lines changed

5 files changed

+199
-39
lines changed

examples/crm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"scripts": {
1313
"build": "objectstack compile objectstack.config.ts dist/objectstack.json",
14-
"dev": "objectstack dev"
14+
"start": "tsx server.ts"
1515
},
1616
"dependencies": {
1717
"@objectstack/spec": "^0.8.0"

examples/crm/server.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
import { ObjectKernel } from '@objectstack/core';
3+
import { ObjectQLPlugin } from '@objectstack/objectql';
4+
import { AppPlugin, DriverPlugin } from '@objectstack/runtime';
5+
import { HonoServerPlugin } from '@objectstack/plugin-hono-server';
6+
import { InMemoryDriver } from '@objectstack/driver-memory';
7+
import config from './objectstack.config';
8+
import { pino } from 'pino';
9+
10+
async function startServer() {
11+
const logger = pino({
12+
level: 'info',
13+
transport: {
14+
target: 'pino-pretty',
15+
options: {
16+
colorize: true
17+
}
18+
}
19+
});
20+
21+
logger.info('Starting CRM Server...');
22+
23+
try {
24+
// Initialize Kernel
25+
const kernel = new ObjectKernel({
26+
logger,
27+
});
28+
29+
// 1. Core Engine (ObjectQL)
30+
const qlPlugin = new ObjectQLPlugin();
31+
kernel.use(qlPlugin);
32+
33+
// 2. Data Driver (Memory)
34+
const memoryDriver = new InMemoryDriver();
35+
const driverPlugin = new DriverPlugin(memoryDriver);
36+
kernel.use(driverPlugin);
37+
38+
// 3. Application (crm_app from config)
39+
// The config export from defineStack is treated as an App Bundle or Manifest
40+
const appPlugin = new AppPlugin(config);
41+
kernel.use(appPlugin);
42+
43+
// 4. HTTP Server
44+
const serverPlugin = new HonoServerPlugin({ port: 3000 });
45+
kernel.use(serverPlugin);
46+
47+
// Bootstrap
48+
await kernel.bootstrap();
49+
50+
logger.info('✅ CRM Server is running on http://localhost:3000');
51+
logger.info(' GraphQL: http://localhost:3000/graphql');
52+
53+
} catch (error) {
54+
logger.error(error, 'Failed to start server');
55+
process.exit(1);
56+
}
57+
}
58+
59+
startServer();

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"scripts": {
1919
"dev": "pnpm --filter @object-ui/console dev",
2020
"dev:console": "pnpm --filter @object-ui/console dev",
21+
"dev:crm": "pnpm --filter @object-ui/example-crm start",
2122
"build": "turbo run build",
2223
"pretest": "turbo run build --filter=@object-ui/types --filter=@object-ui/core --filter=@object-ui/react --filter=@object-ui/components --filter=@object-ui/fields --filter=@object-ui/layout --filter=@object-ui/plugin-kanban --filter=@object-ui/plugin-charts --filter=@object-ui/plugin-form --filter=@object-ui/plugin-grid --filter=@object-ui/plugin-dashboard",
2324
"test": "turbo run test",
@@ -114,8 +115,9 @@
114115
}
115116
},
116117
"dependencies": {
118+
"@objectstack/plugin-hono-server": "^0.8.0",
117119
"coverage-v8": "0.0.1-security",
118-
"pino": "^10.3.0",
120+
"pino": "^8.21.0",
119121
"pino-pretty": "^13.1.3"
120122
},
121123
"msw": {

packages/plugin-form/src/ObjectForm.msw.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ const BASE_URL = process.env.OBJECTSTACK_API_URL || 'http://test-api.com';
1919
const mockSchema = ContactObject;
2020

2121
const mockRecord = {
22-
_id: 'rec_123',
23-
name: 'Alice Smith',
22+
_id: '1',
23+
name: 'Alice Johnson',
2424
email: 'alice@example.com',
25-
status: 'Customer'
25+
status: 'Active'
2626
};
2727

2828
// --- MSW Setup ---
@@ -57,7 +57,7 @@ const handlers = [
5757
// Mock Record Fetch: GET /api/v1/data/:object/:id
5858
http.get(`${BASE_URL}/api/v1/data/:object/:id`, ({ params }) => {
5959
const { object, id } = params;
60-
if (object === 'contact' && id === 'rec_123') {
60+
if (object === 'contact' && id === '1') {
6161
return HttpResponse.json(mockRecord);
6262
}
6363
return new HttpResponse(null, { status: 404 });
@@ -111,7 +111,7 @@ describe('ObjectForm with ObjectStack/MSW', () => {
111111
type: 'object-form',
112112
objectName: 'contact',
113113
mode: 'edit',
114-
recordId: 'rec_123'
114+
recordId: '1'
115115
}}
116116
dataSource={dataSource}
117117
/>
@@ -120,7 +120,7 @@ describe('ObjectForm with ObjectStack/MSW', () => {
120120
// Initial load of schema logic + data fetch
121121
await waitFor(() => {
122122
// Changed from 'Full Name' to 'Name'
123-
expect(screen.getByRole('textbox', { name: /Name/i })).toHaveValue('Alice Smith');
123+
expect(screen.getByRole('textbox', { name: /Name/i })).toHaveValue('Alice Johnson');
124124
}, { timeout: 2000 }); // Give slight buffer for network mock
125125

126126
// Changed from 'Email Address' to 'Email'

0 commit comments

Comments
 (0)