@elevasis/core 0.20.0 → 0.22.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 (77) hide show
  1. package/dist/index.d.ts +524 -6
  2. package/dist/index.js +417 -42
  3. package/dist/knowledge/index.d.ts +151 -1
  4. package/dist/organization-model/index.d.ts +524 -6
  5. package/dist/organization-model/index.js +417 -42
  6. package/dist/test-utils/index.d.ts +270 -1
  7. package/dist/test-utils/index.js +407 -41
  8. package/package.json +5 -5
  9. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +501 -303
  10. package/src/auth/multi-tenancy/permissions.ts +20 -8
  11. package/src/business/README.md +2 -2
  12. package/src/business/acquisition/api-schemas.test.ts +198 -0
  13. package/src/business/acquisition/api-schemas.ts +250 -9
  14. package/src/business/acquisition/build-templates.test.ts +28 -0
  15. package/src/business/acquisition/build-templates.ts +20 -8
  16. package/src/business/acquisition/index.ts +12 -0
  17. package/src/business/acquisition/types.ts +6 -1
  18. package/src/business/clients/api-schemas.test.ts +115 -0
  19. package/src/business/clients/api-schemas.ts +158 -0
  20. package/src/business/clients/index.ts +1 -0
  21. package/src/business/deals/api-schemas.ts +8 -0
  22. package/src/business/index.ts +5 -2
  23. package/src/business/projects/types.ts +19 -0
  24. package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -8
  25. package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -12
  26. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -3
  27. package/src/execution/engine/agent/core/types.ts +25 -15
  28. package/src/execution/engine/agent/index.ts +6 -4
  29. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -18
  30. package/src/execution/engine/index.ts +3 -0
  31. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -0
  32. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -41
  33. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -0
  34. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -0
  35. package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -0
  36. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -0
  37. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -0
  38. package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -0
  39. package/src/execution/engine/workflow/types.ts +7 -0
  40. package/src/integrations/credentials/api-schemas.ts +21 -2
  41. package/src/integrations/credentials/schemas.ts +200 -164
  42. package/src/organization-model/README.md +10 -3
  43. package/src/organization-model/__tests__/defaults.test.ts +6 -0
  44. package/src/organization-model/__tests__/domains/resources.test.ts +188 -0
  45. package/src/organization-model/__tests__/domains/roles.test.ts +402 -347
  46. package/src/organization-model/__tests__/domains/systems.test.ts +193 -0
  47. package/src/organization-model/__tests__/knowledge.test.ts +39 -0
  48. package/src/organization-model/__tests__/prospecting-ssot.test.ts +7 -4
  49. package/src/organization-model/__tests__/resolve.test.ts +1 -1
  50. package/src/organization-model/defaults.ts +24 -3
  51. package/src/organization-model/domains/knowledge.ts +3 -2
  52. package/src/organization-model/domains/prospecting.ts +182 -25
  53. package/src/organization-model/domains/resources.ts +88 -0
  54. package/src/organization-model/domains/roles.ts +93 -55
  55. package/src/organization-model/domains/sales.ts +24 -3
  56. package/src/organization-model/domains/systems.ts +46 -0
  57. package/src/organization-model/icons.ts +1 -0
  58. package/src/organization-model/index.ts +2 -0
  59. package/src/organization-model/organization-model.mdx +33 -14
  60. package/src/organization-model/published.ts +52 -1
  61. package/src/organization-model/schema.ts +121 -0
  62. package/src/organization-model/types.ts +46 -1
  63. package/src/platform/api/types.ts +38 -35
  64. package/src/platform/constants/versions.ts +1 -1
  65. package/src/platform/registry/__tests__/resource-registry.test.ts +2051 -2005
  66. package/src/platform/registry/__tests__/validation.test.ts +1343 -1086
  67. package/src/platform/registry/index.ts +14 -0
  68. package/src/platform/registry/resource-registry.ts +40 -2
  69. package/src/platform/registry/serialization.ts +241 -202
  70. package/src/platform/registry/serialized-types.ts +1 -0
  71. package/src/platform/registry/types.ts +411 -361
  72. package/src/platform/registry/validation.ts +743 -513
  73. package/src/projects/api-schemas.ts +290 -267
  74. package/src/reference/_generated/contracts.md +501 -303
  75. package/src/reference/glossary.md +8 -3
  76. package/src/server.ts +2 -0
  77. package/src/supabase/database.types.ts +121 -0
@@ -6,13 +6,18 @@
6
6
  * - API middleware (via requireOrganizationPermission(key))
7
7
  * - UI hooks (via useOrganizationPermissions().hasPermission(key))
8
8
  *
9
- * The DB table `org_rol_permissions` mirrors this constant. Reconciliation
10
- * runs at API boot (insert-or-update only — never auto-delete; see the
11
- * deletion runbook in the auth-role-system doc -- review/auth-role-system/).
9
+ * The DB table `org_rol_permissions` mirrors this constant. There is no
10
+ * runtime reconciler; parity is enforced two ways:
11
+ * 1. Each migration that adds/removes/modifies a permission must INSERT
12
+ * (or UPDATE / DELETE) the corresponding `org_rol_permissions` row in
13
+ * the same transaction.
14
+ * 2. `apps/api/src/auth/multi-tenancy/__tests__/permissions-catalog-sync.integration.test.ts`
15
+ * asserts the TS catalog and the DB rows agree; CI fails on drift.
12
16
  *
13
17
  * Adding a permission:
14
18
  * 1. Add an entry below.
15
- * 2. Add a row to the migration / via reconcilePermissionCatalog at boot.
19
+ * 2. Add a row to the migration (INSERT INTO org_rol_permissions ...) in
20
+ * the same transaction as any policies/grants that reference the key.
16
21
  * 3. Reference it in RLS / middleware as needed.
17
22
  * 4. Optionally grant it to one or more system roles in org_rol_grants.
18
23
  *
@@ -30,15 +35,17 @@ export const PERMISSIONS = {
30
35
  OPERATIONS_READ: 'operations.read',
31
36
  OPERATIONS_MANAGE: 'operations.manage',
32
37
  ACQUISITION_MANAGE: 'acquisition.manage',
33
- PROJECTS_MANAGE: 'projects.manage'
38
+ PROJECTS_MANAGE: 'projects.manage',
39
+ CLIENTS_MANAGE: 'clients.manage'
34
40
  } as const
35
41
 
36
42
  export type PermissionKey = (typeof PERMISSIONS)[keyof typeof PERMISSIONS]
37
43
 
38
44
  /**
39
- * Static metadata for each permission. Mirrored into org_rol_permissions on
40
- * boot reconciliation. is_org_grantable=false means the permission is reserved
41
- * to system roles only custom roles cannot include it (privilege-escalation guard).
45
+ * Static metadata for each permission. Mirrored into org_rol_permissions by
46
+ * a migration `INSERT` in the same transaction as any change to this catalog.
47
+ * is_org_grantable=false means the permission is reserved to system roles
48
+ * only — custom roles cannot include it (privilege-escalation guard).
42
49
  */
43
50
  export interface PermissionDescriptor {
44
51
  key: PermissionKey
@@ -97,6 +104,11 @@ export const PERMISSION_CATALOG: readonly PermissionDescriptor[] = [
97
104
  key: 'projects.manage',
98
105
  description: 'Create, update, and delete project records (prj_projects, prj_milestones, prj_tasks, prj_notes)',
99
106
  isOrgGrantable: false
107
+ },
108
+ {
109
+ key: 'clients.manage',
110
+ description: 'Create, update, and delete client hub records (clients, clt_* satellites)',
111
+ isOrgGrantable: false
100
112
  }
101
113
  ] as const
102
114
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Published base entity contracts for the Elevasis platform. Each entity ships as a TypeScript interface, a matching Zod schema, and an inferred `Input` type, generic over a `<TMeta>` extension slot.
4
4
 
5
- External projects extend these in `foundations/types/entities.ts` to attach project-specific metadata while keeping the canonical shape stable.
5
+ External projects extend these in `core/types/entities.ts` to attach project-specific metadata while keeping the canonical shape stable.
6
6
 
7
7
  ## Published Exports
8
8
 
@@ -49,4 +49,4 @@ export type Deal = BaseDeal
49
49
 
50
50
  The full pattern is documented in the SDK scaffold bundle: `node_modules/@elevasis/sdk/reference/scaffold/recipes/extend-a-base-entity.md`.
51
51
 
52
- The canonical template demo lives at `external/_template/foundations/types/entities.ts`.
52
+ The canonical template demo lives at `external/_template/core/types/entities.ts`.
@@ -10,10 +10,12 @@ import {
10
10
  AddCompaniesToListRequestSchema,
11
11
  AddContactsToListRequestSchema,
12
12
  AcqArtifactOwnerKindSchema,
13
+ AcqListDetailResponseSchema,
13
14
  AcqContactResponseSchema,
14
15
  AcqContactStatusSchema,
15
16
  AcqEmailValidSchema,
16
17
  AcqListResponseSchema,
18
+ AcqListStatusResponseSchema,
17
19
  BuildPlanSnapshotSchema,
18
20
  CreateArtifactRequestSchema,
19
21
  CreateCompanyRequestSchema,
@@ -32,12 +34,15 @@ import {
32
34
  DealTaskResponseSchema,
33
35
  ExecuteActionRequestSchema,
34
36
  IcpRubricSchema,
37
+ GetListQuerySchema,
35
38
  ListArtifactsQuerySchema,
36
39
  ListCompaniesQuerySchema,
37
40
  ListContactsQuerySchema,
38
41
  ListDealsQuerySchema,
39
42
  ListDealTasksDueQuerySchema,
40
43
  ListMembersQuerySchema,
44
+ ListReadQuerySchema,
45
+ ListRecordsQuerySchema,
41
46
  ListStatusSchema,
42
47
  PipelineStageSchema,
43
48
  ScrapingConfigSchema,
@@ -856,6 +861,24 @@ describe('DealDetailResponseSchema (forward-compat)', () => {
856
861
  expect(DealDetailResponseSchema.safeParse(withContact).success).toBe(true)
857
862
  })
858
863
 
864
+ it('accepts thin client lineage refs on deal detail responses', () => {
865
+ expect(
866
+ DealDetailResponseSchema.safeParse({
867
+ ...baseDeal,
868
+ client_id: VALID_UUID,
869
+ lineage: {
870
+ list: null,
871
+ projects: [],
872
+ client: {
873
+ id: VALID_UUID,
874
+ name: 'Acme Client',
875
+ status: 'active'
876
+ }
877
+ }
878
+ }).success
879
+ ).toBe(true)
880
+ })
881
+
859
882
  it('accepts extra unknown fields at top level (not strict)', () => {
860
883
  expect(DealDetailResponseSchema.safeParse({ ...baseDeal, futureField: 'value' }).success).toBe(true)
861
884
  })
@@ -1601,6 +1624,91 @@ describe('ListMembersQuerySchema', () => {
1601
1624
  })
1602
1625
  })
1603
1626
 
1627
+ // ---------------------------------------------------------------------------
1628
+ // ListReadQuerySchema
1629
+ // ---------------------------------------------------------------------------
1630
+
1631
+ describe('ListReadQuerySchema', () => {
1632
+ it('accepts SDK list filters and coerces pagination', () => {
1633
+ const result = ListReadQuerySchema.safeParse({
1634
+ status: 'launched',
1635
+ batch: 'batch-2026-05',
1636
+ vertical: 'veterinary',
1637
+ limit: '25',
1638
+ offset: '50'
1639
+ })
1640
+
1641
+ expect(result.success).toBe(true)
1642
+ if (result.success) {
1643
+ expect(result.data).toMatchObject({ limit: 25, offset: 50 })
1644
+ }
1645
+ })
1646
+
1647
+ it('keeps pagination optional for backward-compatible list reads', () => {
1648
+ expect(ListReadQuerySchema.safeParse({}).success).toBe(true)
1649
+ })
1650
+
1651
+ it('rejects unknown fields (strict mode)', () => {
1652
+ expect(ListReadQuerySchema.safeParse({ includeDeals: true }).success).toBe(false)
1653
+ })
1654
+ })
1655
+
1656
+ // ---------------------------------------------------------------------------
1657
+ // GetListQuerySchema
1658
+ // ---------------------------------------------------------------------------
1659
+
1660
+ describe('GetListQuerySchema', () => {
1661
+ it('defaults to thin deal refs and omits progress unless requested', () => {
1662
+ const result = GetListQuerySchema.safeParse({})
1663
+
1664
+ expect(result.success).toBe(true)
1665
+ if (result.success) {
1666
+ expect(result.data).toEqual({ includeDeals: true, includeProgress: false, dealLimit: 25 })
1667
+ }
1668
+ })
1669
+
1670
+ it('coerces boolean include flags from query strings', () => {
1671
+ const result = GetListQuerySchema.safeParse({
1672
+ includeDeals: 'false',
1673
+ includeProgress: 'true',
1674
+ dealLimit: '10'
1675
+ })
1676
+
1677
+ expect(result.success).toBe(true)
1678
+ if (result.success) {
1679
+ expect(result.data).toEqual({ includeDeals: false, includeProgress: true, dealLimit: 10 })
1680
+ }
1681
+ })
1682
+
1683
+ it('rejects unknown fields (strict mode)', () => {
1684
+ expect(GetListQuerySchema.safeParse({ depth: 2 }).success).toBe(false)
1685
+ })
1686
+ })
1687
+
1688
+ // ---------------------------------------------------------------------------
1689
+ // ListRecordsQuerySchema
1690
+ // ---------------------------------------------------------------------------
1691
+
1692
+ describe('ListRecordsQuerySchema', () => {
1693
+ it('accepts contact records for DTC decision-maker enrichment', () => {
1694
+ const result = ListRecordsQuerySchema.safeParse({
1695
+ entity: 'contact',
1696
+ stage: 'decision-makers-enriched'
1697
+ })
1698
+
1699
+ expect(result.success).toBe(true)
1700
+ })
1701
+
1702
+ it('keeps company records valid for qualified and uploaded stages', () => {
1703
+ expect(ListRecordsQuerySchema.safeParse({ entity: 'company', stage: 'qualified' }).success).toBe(true)
1704
+ expect(ListRecordsQuerySchema.safeParse({ entity: 'company', stage: 'uploaded' }).success).toBe(true)
1705
+ })
1706
+
1707
+ it('still rejects unrelated stage/entity combinations', () => {
1708
+ expect(ListRecordsQuerySchema.safeParse({ entity: 'contact', stage: 'qualified' }).success).toBe(false)
1709
+ })
1710
+ })
1711
+
1604
1712
  // ---------------------------------------------------------------------------
1605
1713
  // AcqListResponseSchema (forward-compat)
1606
1714
  // ---------------------------------------------------------------------------
@@ -1632,6 +1740,96 @@ describe('AcqListResponseSchema (forward-compat)', () => {
1632
1740
  })
1633
1741
  })
1634
1742
 
1743
+ // ---------------------------------------------------------------------------
1744
+ // AcqListDetailResponseSchema
1745
+ // ---------------------------------------------------------------------------
1746
+
1747
+ describe('AcqListDetailResponseSchema', () => {
1748
+ const baseList = {
1749
+ id: VALID_UUID,
1750
+ organizationId: VALID_UUID,
1751
+ name: 'Test List',
1752
+ description: null,
1753
+ batchIds: [],
1754
+ instantlyCampaignId: null,
1755
+ status: 'draft' as const,
1756
+ metadata: {},
1757
+ launchedAt: null,
1758
+ completedAt: null,
1759
+ createdAt: ISO_TS,
1760
+ scrapingConfig: {},
1761
+ icp: {},
1762
+ pipelineConfig: {}
1763
+ }
1764
+
1765
+ it('accepts thin lineage deal refs on list detail responses', () => {
1766
+ expect(
1767
+ AcqListDetailResponseSchema.safeParse({
1768
+ ...baseList,
1769
+ lineage: {
1770
+ deals: {
1771
+ total: 1,
1772
+ refs: [
1773
+ {
1774
+ id: VALID_UUID,
1775
+ contactEmail: 'lead@example.com',
1776
+ stageKey: 'proposal',
1777
+ stateKey: null,
1778
+ sourceType: 'outreach',
1779
+ lastActivityAt: ISO_TS
1780
+ }
1781
+ ],
1782
+ truncated: false
1783
+ }
1784
+ }
1785
+ }).success
1786
+ ).toBe(true)
1787
+ })
1788
+
1789
+ it('accepts optional progress on list detail responses', () => {
1790
+ expect(
1791
+ AcqListDetailResponseSchema.safeParse({
1792
+ ...baseList,
1793
+ progress: {
1794
+ totalMembers: 0,
1795
+ totalCompanies: 0,
1796
+ byCompanyStage: {},
1797
+ byContactStage: {}
1798
+ }
1799
+ }).success
1800
+ ).toBe(true)
1801
+ })
1802
+ })
1803
+
1804
+ // ---------------------------------------------------------------------------
1805
+ // AcqListStatusResponseSchema
1806
+ // ---------------------------------------------------------------------------
1807
+
1808
+ describe('AcqListStatusResponseSchema', () => {
1809
+ it('accepts a portfolio summary across acquisition lists', () => {
1810
+ expect(
1811
+ AcqListStatusResponseSchema.safeParse({
1812
+ totalLists: 1,
1813
+ totalCompanies: 10,
1814
+ totalContacts: 5,
1815
+ totalDeals: 2,
1816
+ byStatus: { launched: 1 },
1817
+ lists: [
1818
+ {
1819
+ listId: VALID_UUID,
1820
+ name: 'Pipeline',
1821
+ status: 'launched',
1822
+ totalCompanies: 10,
1823
+ totalContacts: 5,
1824
+ totalDeals: 2,
1825
+ createdAt: ISO_TS
1826
+ }
1827
+ ]
1828
+ }).success
1829
+ ).toBe(true)
1830
+ })
1831
+ })
1832
+
1635
1833
  // ---------------------------------------------------------------------------
1636
1834
  // AcqContactResponseSchema (forward-compat)
1637
1835
  // ---------------------------------------------------------------------------