@elevasis/core 0.27.0 → 0.28.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.
@@ -1,96 +1,109 @@
1
- import { z } from 'zod'
2
- import { ResourceIdSchema } from './resources'
3
- import { ModelIdSchema } from './shared'
4
- import { SystemIdSchema } from './systems'
5
-
6
- // ---------------------------------------------------------------------------
7
- // Role schema - one entry per distinct role in the organization's chart.
8
- // Inspired by the EOS Accountability Chart but uses plain-language field names
9
- // throughout. No EOS jargon: "title" (not seatTitle), "responsibilities"
10
- // (not accountabilities), "reportsToId", "heldBy".
11
- //
12
- // Cross-reference enforcement lives in `OrganizationModelSchema.superRefine()`:
13
- // `reportsToId` must resolve to another Role, `responsibleFor` entries must
14
- // resolve to Systems, and agent holders must resolve to Agent Resources.
15
- // Role hierarchy cycle detection is also enforced at the model level.
16
- // ---------------------------------------------------------------------------
17
-
18
- export const RoleIdSchema = ModelIdSchema
19
-
20
- export const HumanRoleHolderSchema = z.object({
21
- kind: z.literal('human'),
22
- userId: z.string().trim().min(1).max(200)
23
- })
24
-
25
- export const AgentRoleHolderSchema = z.object({
26
- kind: z.literal('agent'),
27
- agentId: ResourceIdSchema.meta({ ref: 'resource' })
28
- })
29
-
30
- export const TeamRoleHolderSchema = z.object({
31
- kind: z.literal('team'),
32
- memberIds: z.array(z.string().trim().min(1).max(200)).min(1)
33
- })
34
-
35
- export const RoleHolderSchema = z.discriminatedUnion('kind', [
36
- HumanRoleHolderSchema,
37
- AgentRoleHolderSchema,
38
- TeamRoleHolderSchema
39
- ])
40
-
41
- export const RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSchema).min(1)])
42
-
43
- export const RoleSchema = z.object({
44
- /** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
45
- id: RoleIdSchema,
46
- /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
47
- order: z.number(),
48
- /** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
49
- title: z.string().trim().min(1).max(200),
50
- /**
51
- * List of responsibilities this role owns - plain-language descriptions of
52
- * what the person in this role is accountable for delivering.
53
- * Defaults to empty array so minimal role definitions stay concise.
54
- */
55
- responsibilities: z.array(z.string().trim().max(500)).default([]),
56
- /**
57
- * Optional: ID of another role this role reports to.
58
- * When present, must reference another `roles[].id` in the same organization.
59
- */
60
- reportsToId: RoleIdSchema.meta({ ref: 'role' }).optional(),
61
- /**
62
- * Optional: human, agent, or team holder currently filling this role.
63
- * Agent holders reference OM Resource IDs and are validated at the model level.
64
- */
65
- heldBy: RoleHoldersSchema.optional(),
66
- /**
67
- * Optional Systems this role is accountable for.
68
- * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
69
- */
70
- responsibleFor: z.array(SystemIdSchema.meta({ ref: 'system' })).optional()
71
- })
72
-
73
- // ---------------------------------------------------------------------------
74
- // Roles domain schema - a collection of roles.
75
- // ---------------------------------------------------------------------------
76
-
77
- export const RolesDomainSchema = z
78
- .record(z.string(), RoleSchema)
79
- .refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
80
- message: 'Each role entry id must match its map key'
81
- })
82
- .default({})
83
-
84
- // ---------------------------------------------------------------------------
85
- // Seed - empty by default; adapters populate with real role definitions.
86
- // ---------------------------------------------------------------------------
87
-
88
- export const DEFAULT_ORGANIZATION_MODEL_ROLES: z.infer<typeof RolesDomainSchema> = {}
89
-
90
- export type RoleId = z.infer<typeof RoleIdSchema>
91
- export type HumanRoleHolder = z.infer<typeof HumanRoleHolderSchema>
92
- export type AgentRoleHolder = z.infer<typeof AgentRoleHolderSchema>
93
- export type TeamRoleHolder = z.infer<typeof TeamRoleHolderSchema>
94
- export type RoleHolder = z.infer<typeof RoleHolderSchema>
95
- export type Role = z.infer<typeof RoleSchema>
96
- export type RolesDomain = z.infer<typeof RolesDomainSchema>
1
+ import { z } from 'zod'
2
+ import { ResourceIdSchema } from './resources'
3
+ import { ModelIdSchema } from './shared'
4
+ import { SystemIdSchema } from './systems'
5
+ import { defineDomainRecord } from '../helpers'
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // Role schema - one entry per distinct role in the organization's chart.
9
+ // Inspired by the EOS Accountability Chart but uses plain-language field names
10
+ // throughout. No EOS jargon: "title" (not seatTitle), "responsibilities"
11
+ // (not accountabilities), "reportsToId", "heldBy".
12
+ //
13
+ // Cross-reference enforcement lives in `OrganizationModelSchema.superRefine()`:
14
+ // `reportsToId` must resolve to another Role, `responsibleFor` entries must
15
+ // resolve to Systems, and agent holders must resolve to Agent Resources.
16
+ // Role hierarchy cycle detection is also enforced at the model level.
17
+ // ---------------------------------------------------------------------------
18
+
19
+ export const RoleIdSchema = ModelIdSchema
20
+
21
+ export const HumanRoleHolderSchema = z.object({
22
+ kind: z.literal('human'),
23
+ userId: z.string().trim().min(1).max(200)
24
+ })
25
+
26
+ export const AgentRoleHolderSchema = z.object({
27
+ kind: z.literal('agent'),
28
+ agentId: ResourceIdSchema.meta({ ref: 'resource' })
29
+ })
30
+
31
+ export const TeamRoleHolderSchema = z.object({
32
+ kind: z.literal('team'),
33
+ memberIds: z.array(z.string().trim().min(1).max(200)).min(1)
34
+ })
35
+
36
+ export const RoleHolderSchema = z.discriminatedUnion('kind', [
37
+ HumanRoleHolderSchema,
38
+ AgentRoleHolderSchema,
39
+ TeamRoleHolderSchema
40
+ ])
41
+
42
+ export const RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSchema).min(1)])
43
+
44
+ export const RoleSchema = z.object({
45
+ /** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
46
+ id: RoleIdSchema,
47
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
48
+ order: z.number(),
49
+ /** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
50
+ title: z.string().trim().min(1).max(200),
51
+ /**
52
+ * List of responsibilities this role owns - plain-language descriptions of
53
+ * what the person in this role is accountable for delivering.
54
+ * Defaults to empty array so minimal role definitions stay concise.
55
+ */
56
+ responsibilities: z.array(z.string().trim().max(500)).default([]),
57
+ /**
58
+ * Optional: ID of another role this role reports to.
59
+ * When present, must reference another `roles[].id` in the same organization.
60
+ */
61
+ reportsToId: RoleIdSchema.meta({ ref: 'role' }).optional(),
62
+ /**
63
+ * Optional: human, agent, or team holder currently filling this role.
64
+ * Agent holders reference OM Resource IDs and are validated at the model level.
65
+ */
66
+ heldBy: RoleHoldersSchema.optional(),
67
+ /**
68
+ * Optional Systems this role is accountable for.
69
+ * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
70
+ */
71
+ responsibleFor: z.array(SystemIdSchema.meta({ ref: 'system' })).optional()
72
+ })
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // Roles domain schema - a collection of roles.
76
+ // ---------------------------------------------------------------------------
77
+
78
+ export const RolesDomainSchema = z
79
+ .record(z.string(), RoleSchema)
80
+ .refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
81
+ message: 'Each role entry id must match its map key'
82
+ })
83
+ .default({})
84
+
85
+ // ---------------------------------------------------------------------------
86
+ // Seed - empty by default; adapters populate with real role definitions.
87
+ // ---------------------------------------------------------------------------
88
+
89
+ export const DEFAULT_ORGANIZATION_MODEL_ROLES: z.infer<typeof RolesDomainSchema> = {}
90
+
91
+ /** Validate and return a single role entry. */
92
+ export function defineRole(entry: z.input<typeof RoleSchema>): z.infer<typeof RoleSchema> {
93
+ return RoleSchema.parse(entry)
94
+ }
95
+
96
+ /** Validate and return an id-keyed map of role entries. */
97
+ export function defineRoles(
98
+ entries: readonly z.input<typeof RoleSchema>[]
99
+ ): Record<string, z.infer<typeof RoleSchema>> {
100
+ return defineDomainRecord(RoleSchema, entries)
101
+ }
102
+
103
+ export type RoleId = z.infer<typeof RoleIdSchema>
104
+ export type HumanRoleHolder = z.infer<typeof HumanRoleHolderSchema>
105
+ export type AgentRoleHolder = z.infer<typeof AgentRoleHolderSchema>
106
+ export type TeamRoleHolder = z.infer<typeof TeamRoleHolderSchema>
107
+ export type RoleHolder = z.infer<typeof RoleHolderSchema>
108
+ export type Role = z.infer<typeof RoleSchema>
109
+ export type RolesDomain = z.infer<typeof RolesDomainSchema>