-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathobjectstack.config.ts
More file actions
129 lines (117 loc) · 5.58 KB
/
Copy pathobjectstack.config.ts
File metadata and controls
129 lines (117 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { defineStack } from '@objectstack/spec';
import * as objects from './src/objects/index.js';
import * as views from './src/views/index.js';
import * as apps from './src/apps/index.js';
import * as dashboards from './src/dashboards/index.js';
import * as datasets from './src/datasets/index.js';
import * as pages from './src/pages/index.js';
import * as actions from './src/actions/index.js';
import { allHooks } from './src/hooks/index.js';
import { allFlows } from './src/flows/index.js';
import {
SalesRepPosition,
SalesManagerPosition,
FinanceApproverPosition,
SalesUserPermissionSet,
GuestPortalProfile,
} from './src/security/index.js';
import { registerCrmPositionBindings } from './src/security/bind-position-sets.js';
import { CrmSeedData } from './src/data/index.js';
import { CrmDatasource, CrmAnalyticsDatasource } from './src/datasources/crm.datasource.js';
import { CrmTranslationBundle } from './src/translations/crm.translation.js';
/**
* CRM example — a MINIMAL, realistic relational bundle that smoke-tests the
* metadata application loading pipeline: objects/relationships → views →
* app → dashboard (dataset-backed) → hook → one screen-flow wizard → seed.
* Deliberately small so `pnpm dev:crm` boots fast for backend debugging.
*
* NOT a feature showcase: capability breadth (cubes, extensions, apis,
* webhooks, portals, themes, reports, jobs, emails, automation variety)
* lives in examples/app-showcase, whose coverage manifest enforces it.
* For a full enterprise reference see https://github.com/objectstack-ai/hotcrm
*/
export default defineStack({
manifest: {
id: 'com.example.crm',
namespace: 'crm',
version: '4.0.0',
type: 'app',
name: 'CRM (minimal example)',
description: 'Minimal CRM workspace used by the framework to validate the metadata loading pipeline end-to-end.',
// Protocol major this package is authored against (ADR-0087). The kernel
// checks the range at load time and refuses a major-incompatible runtime
// with a structured diagnostic instead of failing deep in a schema parse.
engines: { protocol: '^17' },
},
// Auto-resolved by the CLI; `ui` enables the Studio shell, `automation`
// loads AutomationServicePlugin + node packs so the convert-lead screen
// flow can execute.
requires: ['ui', 'automation'],
// Infrastructure
//
// No `datasourceMapping`. These two datasources are declared to exercise the
// metadata surface, not to route anything: both are `:memory:`, and every
// object here has always been served by the host's `default` store. The
// mapping that used to sit here (`namespace: 'crm'` + `default: true` →
// `crm_primary`) was decorative — `namespace` is deprecated and no object
// sets it, and `crm_primary` had no live driver, so routing fell through to
// `default`. #4462 stopped routing from falling through, because that
// fall-through is what silently put a mapped object's rows in a different
// database than the one it declared. Deleting the rule is what keeps this
// example's behavior IDENTICAL under the new posture; keeping it would move
// the whole app — platform objects included — onto an in-memory database
// that is empty on every boot.
datasources: [CrmDatasource, CrmAnalyticsDatasource],
// Internationalisation
translations: [CrmTranslationBundle],
i18n: {
defaultLocale: 'en',
supportedLocales: ['en', 'zh-CN'],
fallbackLocale: 'en',
},
// Data
objects: Object.values(objects),
// UI
apps: Object.values(apps),
views: Object.values(views),
pages: Object.values(pages),
dashboards: Object.values(dashboards),
datasets: Object.values(datasets),
actions: Object.values(actions),
// Logic
hooks: allHooks,
// ADR-0020: `workflows` retired — record state machines are a
// `state_machine` validation rule on the object (see
// src/objects/opportunity.object.ts). One flow only: the convert-lead
// screen wizard the smoke test drives.
flows: allFlows,
// Security
positions: [SalesRepPosition, SalesManagerPosition, FinanceApproverPosition],
permissions: [SalesUserPermissionSet, GuestPortalProfile],
// No `sharingRules`. The three this app used to declare
// (`share_high_value_opps_with_managers`, `share_active_leads_with_manager`,
// `share_won_deal_activities`) were anchored on `crm_opportunity`,
// `crm_lead` and `crm_activity` — all three `sharingModel:
// 'public_read_write'`. Sharing only ever WIDENS an OWD baseline, so on the
// widest baseline there is nothing to widen: `assertNotInertGrant` refused
// every grant with SHARING_NOT_ENABLED and the boot backfill failed for each
// rule, on every boot, since they were written. They granted nothing and
// were removed under ADR-0049 enforce-or-remove (#9698), the same call
// #9237 made for app-showcase's two.
//
// ⛔ Do not re-add one on a public object — `sharing-rule-object-not-shareable`
// now fails the build, and its message states the two honest fixes. Giving
// this app a LIVE sharing demonstration means giving it a `private` object
// first; that is an access-matrix change (ADR-0090 D6 review), not a rider.
// Seed data
data: CrmSeedData,
});
/**
* [#8060] Ensure the persona position↔permission-set bindings exist after the
* security bootstraps (cannot be a seed — see bind-position-sets.ts). Mirrors
* app-showcase's own `onEnable` wiring.
*/
export const onEnable = async (ctx: unknown): Promise<void> => {
registerCrmPositionBindings(ctx as Parameters<typeof registerCrmPositionBindings>[0]);
};