File tree Expand file tree Collapse file tree 5 files changed +62
-0
lines changed
Expand file tree Collapse file tree 5 files changed +62
-0
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ import { Opportunity } from './src/domains/crm/opportunity.object';
55import { Lead } from './src/domains/crm/lead.object' ;
66import { Case } from './src/domains/crm/case.object' ;
77import { Task } from './src/domains/crm/task.object' ;
8+ import { PipelineStatsApi , LeadConvertApi } from './src/server' ;
89
910import { CrmActions } from './src/ui/actions' ;
1011import { CrmDashboards } from './src/ui/dashboards' ;
@@ -26,6 +27,12 @@ export default App.create({
2627 Task
2728 ] ,
2829
30+ // Custom APIs
31+ apis : [
32+ PipelineStatsApi ,
33+ LeadConvertApi
34+ ] ,
35+
2936 // Navigation menu structure
3037 menus : [
3138 {
Original file line number Diff line number Diff line change 1+ import { ApiEndpoint } from '@objectstack/spec' ;
2+
3+ /**
4+ * Custom API: Close Won Opportunities
5+ * A business-specific endpoint that encapsulates complex logic.
6+ * Path: GET /api/v1/crm/stats/pipeline
7+ */
8+ export const PipelineStatsApi = ApiEndpoint . create ( {
9+ name : 'get_pipeline_stats' ,
10+ path : '/api/v1/crm/stats/pipeline' ,
11+ method : 'GET' ,
12+ summary : 'Get Pipeline Statistics' ,
13+ description : 'Returns the total value of open opportunities grouped by stage' ,
14+
15+ type : 'script' ,
16+ target : 'server/scripts/pipeline_stats.ts' , // Hypothetical script path
17+
18+ authRequired : true ,
19+ cacheTtl : 300 , // Cache for 5 minutes
20+ } ) ;
21+
22+ /**
23+ * Custom API: Quick Lead Conversion (RPC Style)
24+ * Path: POST /api/v1/crm/leads/convert
25+ */
26+ export const LeadConvertApi = ApiEndpoint . create ( {
27+ name : 'lead_convert' ,
28+ path : '/api/v1/crm/leads/convert' ,
29+ method : 'POST' ,
30+ summary : 'Convert Lead to Account/Contact' ,
31+
32+ type : 'flow' ,
33+ target : 'flow_lead_conversion_v2' ,
34+
35+ inputMapping : [
36+ { source : 'body.leadId' , target : 'leadRecordId' } ,
37+ { source : 'body.ownerId' , target : 'newOwnerId' }
38+ ]
39+ } ) ;
Original file line number Diff line number Diff line change 1+ export * from './apis' ;
Original file line number Diff line number Diff line change @@ -58,4 +58,8 @@ export const ApiEndpointSchema = z.object({
5858 cacheTtl : z . number ( ) . optional ( ) . describe ( 'Response cache TTL in seconds' ) ,
5959} ) ;
6060
61+ export const ApiEndpoint = Object . assign ( ApiEndpointSchema , {
62+ create : < T extends z . input < typeof ApiEndpointSchema > > ( config : T ) => config ,
63+ } ) ;
64+
6165export type ApiEndpoint = z . infer < typeof ApiEndpointSchema > ;
Original file line number Diff line number Diff line change @@ -144,6 +144,17 @@ export const AppSchema = z.object({
144144 * Example: ["app.access.crm"]
145145 */
146146 requiredPermissions : z . array ( z . string ( ) ) . optional ( ) . describe ( 'Permissions required to access this app' ) ,
147+
148+ /**
149+ * Package Components (For config file convenience)
150+ * In a real monorepo these might be auto-discovered, but here we allow explicit registration.
151+ */
152+ objects : z . array ( z . any ( ) ) . optional ( ) . describe ( 'Objects belonging to this app' ) ,
153+ apis : z . array ( z . any ( ) ) . optional ( ) . describe ( 'Custom APIs belonging to this app' ) ,
154+ } ) ;
155+
156+ export const App = Object . assign ( AppSchema , {
157+ create : < T extends z . input < typeof AppSchema > > ( config : T ) => config ,
147158} ) ;
148159
149160// Main Types
You can’t perform that action at this time.
0 commit comments