@learncard/network-brain-service 4.0.4 → 4.1.1

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 (175) hide show
  1. package/.env.example +14 -0
  2. package/AGENTS.md +16 -0
  3. package/CHANGELOG.md +54 -0
  4. package/config/config.dev.json +5 -0
  5. package/config/config.example.json +5 -0
  6. package/config/config.production.json +5 -0
  7. package/config/config.scouts.dev.json +5 -0
  8. package/config/config.scouts.production.json +5 -0
  9. package/dist/accesslayer/campaign/audience.d.ts +7 -0
  10. package/dist/accesslayer/campaign/audience.d.ts.map +1 -0
  11. package/dist/accesslayer/campaign/create.d.ts +3 -0
  12. package/dist/accesslayer/campaign/create.d.ts.map +1 -0
  13. package/dist/accesslayer/campaign/delete.d.ts +2 -0
  14. package/dist/accesslayer/campaign/delete.d.ts.map +1 -0
  15. package/dist/accesslayer/campaign/read.d.ts +6 -0
  16. package/dist/accesslayer/campaign/read.d.ts.map +1 -0
  17. package/dist/accesslayer/campaign/shared.d.ts +16 -0
  18. package/dist/accesslayer/campaign/shared.d.ts.map +1 -0
  19. package/dist/accesslayer/campaign/state.d.ts +4 -0
  20. package/dist/accesslayer/campaign/state.d.ts.map +1 -0
  21. package/dist/accesslayer/campaign/update.d.ts +3 -0
  22. package/dist/accesslayer/campaign/update.d.ts.map +1 -0
  23. package/dist/accesslayer/credential-share-previews.d.ts +5 -0
  24. package/dist/accesslayer/credential-share-previews.d.ts.map +1 -0
  25. package/dist/accesslayer/profile/delete.d.ts.map +1 -1
  26. package/dist/accesslayer/skill/read.d.ts +12 -2
  27. package/dist/accesslayer/skill/read.d.ts.map +1 -1
  28. package/dist/accesslayer/skill/update.d.ts +11 -1
  29. package/dist/accesslayer/skill/update.d.ts.map +1 -1
  30. package/dist/app.d.ts +4 -0
  31. package/dist/app.d.ts.map +1 -1
  32. package/dist/cache/app-store.caches.d.ts +2 -1
  33. package/dist/cache/app-store.caches.d.ts.map +1 -1
  34. package/dist/config/environment.d.ts +268 -178
  35. package/dist/config/environment.d.ts.map +1 -1
  36. package/dist/config/skillEmbedding.d.ts +70 -0
  37. package/dist/config/skillEmbedding.d.ts.map +1 -0
  38. package/dist/config/skillEmbedding.neo4j.test.d.ts +2 -0
  39. package/dist/config/skillEmbedding.neo4j.test.d.ts.map +1 -0
  40. package/dist/config/stageConfig.d.ts +20 -0
  41. package/dist/config/stageConfig.d.ts.map +1 -1
  42. package/dist/constants/campaigns.d.ts +3 -0
  43. package/dist/constants/campaigns.d.ts.map +1 -0
  44. package/dist/didkit_wasm_bg.wasm +0 -0
  45. package/dist/helpers/app-credential-delivery.helpers.d.ts +4 -0
  46. package/dist/helpers/app-credential-delivery.helpers.d.ts.map +1 -0
  47. package/dist/helpers/app-credential-delivery.helpers.test.d.ts +2 -0
  48. package/dist/helpers/app-credential-delivery.helpers.test.d.ts.map +1 -0
  49. package/dist/helpers/bedrock-embedding.helpers.d.ts +40 -0
  50. package/dist/helpers/bedrock-embedding.helpers.d.ts.map +1 -0
  51. package/dist/helpers/bedrock-embedding.helpers.test.d.ts +2 -0
  52. package/dist/helpers/bedrock-embedding.helpers.test.d.ts.map +1 -0
  53. package/dist/helpers/bedrock-embedding.smoke.test.d.ts +2 -0
  54. package/dist/helpers/bedrock-embedding.smoke.test.d.ts.map +1 -0
  55. package/dist/helpers/boost.helpers.d.ts.map +1 -1
  56. package/dist/helpers/sentry.helpers.d.ts.map +1 -1
  57. package/dist/helpers/sentry.helpers.test.d.ts +2 -0
  58. package/dist/helpers/sentry.helpers.test.d.ts.map +1 -0
  59. package/dist/helpers/skill-embedding.helpers.d.ts +65 -7
  60. package/dist/helpers/skill-embedding.helpers.d.ts.map +1 -1
  61. package/dist/helpers/skill-embedding.helpers.test.d.ts +2 -0
  62. package/dist/helpers/skill-embedding.helpers.test.d.ts.map +1 -0
  63. package/dist/index.js +2 -2
  64. package/dist/models/Campaign.d.ts +10 -0
  65. package/dist/models/Campaign.d.ts.map +1 -0
  66. package/dist/models/CredentialSharePreview.d.ts +14 -0
  67. package/dist/models/CredentialSharePreview.d.ts.map +1 -0
  68. package/dist/models/Integration.d.ts +1 -1
  69. package/dist/models/Profile.d.ts.map +1 -1
  70. package/dist/models/campaign-constraints.d.ts +2 -0
  71. package/dist/models/campaign-constraints.d.ts.map +1 -0
  72. package/dist/models/index.d.ts +2 -0
  73. package/dist/models/index.d.ts.map +1 -1
  74. package/dist/publish-metafile.json +1 -1
  75. package/dist/routes/app-store.d.ts +1 -1
  76. package/dist/routes/app-store.d.ts.map +1 -1
  77. package/dist/routes/boosts.d.ts +24 -4
  78. package/dist/routes/boosts.d.ts.map +1 -1
  79. package/dist/routes/campaigns.d.ts +1411 -0
  80. package/dist/routes/campaigns.d.ts.map +1 -0
  81. package/dist/routes/contracts.d.ts +19 -6
  82. package/dist/routes/contracts.d.ts.map +1 -1
  83. package/dist/routes/credential-share-previews.d.ts +39 -0
  84. package/dist/routes/credential-share-previews.d.ts.map +1 -0
  85. package/dist/routes/credentials.d.ts +4 -1
  86. package/dist/routes/credentials.d.ts.map +1 -1
  87. package/dist/routes/inbox.d.ts +5 -5
  88. package/dist/routes/index.d.ts +4 -0
  89. package/dist/routes/index.d.ts.map +1 -1
  90. package/dist/routes/integrations.d.ts +3 -3
  91. package/dist/routes/profile-manager.d.ts +4 -0
  92. package/dist/routes/profile-manager.d.ts.map +1 -1
  93. package/dist/routes/profiles.d.ts +44 -0
  94. package/dist/routes/profiles.d.ts.map +1 -1
  95. package/dist/routes/skill-frameworks.d.ts +1 -0
  96. package/dist/routes/skill-frameworks.d.ts.map +1 -1
  97. package/dist/routes/skills-semantic-search.test.d.ts +2 -0
  98. package/dist/routes/skills-semantic-search.test.d.ts.map +1 -0
  99. package/dist/routes/skills.d.ts.map +1 -1
  100. package/dist/routes/test.d.ts +3 -1
  101. package/dist/routes/test.d.ts.map +1 -1
  102. package/dist/seed/seedSkillFrameworks.d.ts +1 -0
  103. package/dist/seed/seedSkillFrameworks.d.ts.map +1 -1
  104. package/dist/seed/seedSkillFrameworks.embeddings.test.d.ts +2 -0
  105. package/dist/seed/seedSkillFrameworks.embeddings.test.d.ts.map +1 -0
  106. package/dist/types/app-manifest.d.ts +2 -2
  107. package/dist/types/campaign.d.ts +19 -0
  108. package/dist/types/campaign.d.ts.map +1 -0
  109. package/dist/types/consentflowcontract.d.ts +1 -1
  110. package/dist/types/integration.d.ts +3 -3
  111. package/dist/types/profile.d.ts +9 -0
  112. package/dist/types/profile.d.ts.map +1 -1
  113. package/dist/types/skill.d.ts.map +1 -1
  114. package/package.json +21 -18
  115. package/project.json +15 -1
  116. package/scripts/skill-embeddings-backfill.ts +161 -0
  117. package/serverless-local.yml +4 -0
  118. package/serverless.function-env.cjs +3 -0
  119. package/serverless.local.yml +4 -0
  120. package/serverless.yml +12 -1
  121. package/src/accesslayer/campaign/README.md +174 -0
  122. package/src/accesslayer/campaign/audience.ts +152 -0
  123. package/src/accesslayer/campaign/create.ts +47 -0
  124. package/src/accesslayer/campaign/delete.ts +18 -0
  125. package/src/accesslayer/campaign/read.ts +125 -0
  126. package/src/accesslayer/campaign/shared.ts +92 -0
  127. package/src/accesslayer/campaign/state.ts +80 -0
  128. package/src/accesslayer/campaign/update.ts +50 -0
  129. package/src/accesslayer/credential-share-previews.ts +76 -0
  130. package/src/accesslayer/profile/delete.ts +6 -0
  131. package/src/accesslayer/skill/read.ts +56 -16
  132. package/src/accesslayer/skill/update.ts +43 -1
  133. package/src/app.ts +9 -0
  134. package/src/config/environment.test.ts +208 -0
  135. package/src/config/environment.ts +166 -11
  136. package/src/config/skillEmbedding.neo4j.test.ts +138 -0
  137. package/src/config/skillEmbedding.ts +202 -0
  138. package/src/constants/campaigns.ts +9 -0
  139. package/src/helpers/activity.helpers.ts +3 -3
  140. package/src/helpers/app-credential-delivery.helpers.test.ts +56 -0
  141. package/src/helpers/app-credential-delivery.helpers.ts +11 -0
  142. package/src/helpers/bedrock-embedding.helpers.test.ts +208 -0
  143. package/src/helpers/bedrock-embedding.helpers.ts +243 -0
  144. package/src/helpers/bedrock-embedding.smoke.test.ts +53 -0
  145. package/src/helpers/boost-storage.helpers.test.ts +63 -0
  146. package/src/helpers/boost.helpers.ts +23 -18
  147. package/src/helpers/sentry.helpers.test.ts +56 -0
  148. package/src/helpers/sentry.helpers.ts +4 -3
  149. package/src/helpers/skill-embedding.helpers.test.ts +1044 -0
  150. package/src/helpers/skill-embedding.helpers.ts +611 -123
  151. package/src/models/Campaign.ts +32 -0
  152. package/src/models/CredentialSharePreview.ts +30 -0
  153. package/src/models/Profile.ts +1 -0
  154. package/src/models/campaign-constraints.ts +22 -0
  155. package/src/models/index.ts +29 -1
  156. package/src/routes/app-store.ts +9 -16
  157. package/src/routes/campaigns.ts +179 -0
  158. package/src/routes/credential-share-previews.ts +74 -0
  159. package/src/routes/profiles.ts +7 -0
  160. package/src/routes/skills-semantic-search.test.ts +168 -0
  161. package/src/routes/skills.ts +42 -6
  162. package/src/seed/seedSkillFrameworks.embeddings.test.ts +82 -0
  163. package/src/seed/seedSkillFrameworks.test.ts +6 -0
  164. package/src/seed/seedSkillFrameworks.ts +83 -18
  165. package/src/types/campaign.ts +17 -0
  166. package/src/types/skill.ts +6 -0
  167. package/test/app-credential-delivery.neo4j.spec.ts +110 -0
  168. package/test/campaigns.spec.ts +789 -0
  169. package/test/credential-share-previews.spec.ts +97 -0
  170. package/test/verification/campaigns.ts +49 -0
  171. package/tsconfig.json +13 -13
  172. package/vitest.campaigns.config.ts +21 -0
  173. package/vitest.config.ts +12 -0
  174. package/vitest.inbox-e2e.config.ts +1 -0
  175. package/vitest.integration.config.ts +1 -0
@@ -0,0 +1,97 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { TRPCError } from '@trpc/server';
3
+
4
+ const owner = { profileId: 'owner-1', did: 'did:key:owner', displayName: 'Owner' };
5
+ const storage = vi.hoisted(() => ({
6
+ create: vi.fn(
7
+ async (ownerId: string, preview: { id?: string }): Promise<string | null> =>
8
+ preview.id ?? '5b58ff0c-bb55-4f25-a2a5-b4de3778c649'
9
+ ),
10
+ get: vi.fn(async (_id: string, _shareUri: string) => null as unknown),
11
+ delete: vi.fn(async (_ownerId: string, _id: string) => false),
12
+ }));
13
+ const sentry = vi.hoisted(() => ({
14
+ trpcMiddleware: vi.fn(() => async (options: { next: () => unknown }) => options.next()),
15
+ setUser: vi.fn(),
16
+ configureScope: vi.fn(),
17
+ }));
18
+ vi.mock('@accesslayer/credential-share-previews', () => ({
19
+ createCredentialSharePreview: storage.create,
20
+ getCredentialSharePreview: storage.get,
21
+ deleteCredentialSharePreview: storage.delete,
22
+ }));
23
+ vi.mock('@accesslayer/profile/read', () => ({ getProfileByDid: vi.fn(async () => owner) }));
24
+ vi.mock('@sentry/serverless', () => ({
25
+ Handlers: { trpcMiddleware: sentry.trpcMiddleware },
26
+ setUser: sentry.setUser,
27
+ configureScope: sentry.configureScope,
28
+ }));
29
+ import { credentialSharePreviewsRouter } from '../src/routes/credential-share-previews';
30
+
31
+ const caller = (user?: { did: string; isChallengeValid: boolean }) =>
32
+ credentialSharePreviewsRouter.createCaller({
33
+ domain: 'network.example.com',
34
+ tenant: { id: 'default' },
35
+ ...(user ? { user } : {}),
36
+ } as never);
37
+ const authenticated = { did: owner.did, isChallengeValid: true };
38
+ const id = '5b58ff0c-bb55-4f25-a2a5-b4de3778c649';
39
+ const shareUri = 'urn:encrypted:opaque';
40
+
41
+ describe('credential share previews route', () => {
42
+ beforeEach(() => {
43
+ vi.clearAllMocks();
44
+ storage.get.mockResolvedValue(null);
45
+ storage.delete.mockResolvedValue(false);
46
+ storage.create.mockImplementation(async (_owner, preview) => preview.id ?? id);
47
+ });
48
+
49
+ it('requires authentication and rejects private fields in published metadata', async () => {
50
+ const preview = {
51
+ name: 'Badge',
52
+ issuer: 'Issuer',
53
+ image: 'https://cdn.example/badge.png',
54
+ shareUri,
55
+ };
56
+ await expect(caller().publish(preview)).rejects.toMatchObject({ code: 'UNAUTHORIZED' });
57
+ await expect(
58
+ caller(authenticated).publish({ ...preview, credential: { id: 'private' } } as never)
59
+ ).rejects.toBeInstanceOf(TRPCError);
60
+ });
61
+
62
+ it('rejects unauthenticated deletion', async () => {
63
+ await expect(caller().delete({ id })).rejects.toMatchObject({ code: 'UNAUTHORIZED' });
64
+ });
65
+
66
+ it('reports missing refreshes with the machine-readable recovery code', async () => {
67
+ storage.create.mockResolvedValueOnce(null);
68
+ await expect(
69
+ caller(authenticated).publish({ id, name: 'Badge', issuer: 'Issuer', shareUri })
70
+ ).rejects.toMatchObject({ code: 'NOT_FOUND' });
71
+ });
72
+
73
+ it('fails closed if storage returns non-public fields', async () => {
74
+ storage.get.mockResolvedValueOnce({
75
+ name: 'Badge',
76
+ issuer: 'Issuer',
77
+ seed: 'must-never-be-returned',
78
+ shareUri,
79
+ ownerProfileId: owner.profileId,
80
+ createdAt: new Date(0).toISOString(),
81
+ updatedAt: new Date(0).toISOString(),
82
+ });
83
+ await expect(caller().get({ id, shareUri })).rejects.toMatchObject({
84
+ code: 'INTERNAL_SERVER_ERROR',
85
+ });
86
+ });
87
+
88
+ it('requires both public lookup keys and reports missing previews', async () => {
89
+ await expect(caller().get({ id } as never)).rejects.toBeInstanceOf(TRPCError);
90
+ await expect(caller().get({ id: 'not-a-uuid', shareUri })).rejects.toBeInstanceOf(
91
+ TRPCError
92
+ );
93
+ await expect(caller().get({ id, shareUri })).rejects.toMatchObject({
94
+ code: 'NOT_FOUND',
95
+ });
96
+ });
97
+ });
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Real signed SDK requests against an owned Linux verification stack.
3
+ * Positive admin/data coverage lives in campaigns.spec.ts (disposable Neo4j): the
4
+ * default stack intentionally grants no campaign administration to test actors.
5
+ *
6
+ * bun run --cwd apps/learn-card-app lc verify script \
7
+ * services/learn-card-network/brain-service/test/verification/campaigns.ts --dir <owned-dir>
8
+ */
9
+ import type { VerificationScript } from '../../../../../apps/learn-card-app/scripts/verification/script';
10
+
11
+ const script: VerificationScript = async v => {
12
+ const learner = await v.sdk(v.actors.learner);
13
+ const other = await v.sdk(v.actors.recipient);
14
+ const campaignId = 'verification-denied-campaign';
15
+
16
+ await v.step(null, 'campaign-sdk-authorization', async () => {
17
+ v.expect(await learner.invoke.campaignsIsAdmin()).toBe(false);
18
+ await v
19
+ .expect(
20
+ learner.invoke.campaignsCreate({
21
+ id: campaignId,
22
+ name: 'Not authorized',
23
+ channels: ['inApp'],
24
+ message: { title: 'Denied' },
25
+ })
26
+ )
27
+ .rejects.toThrow(/Campaign administrator access required/);
28
+ await v
29
+ .expect(other.invoke.campaignsList())
30
+ .rejects.toThrow(/Campaign administrator access required/);
31
+ });
32
+
33
+ await v.step(null, 'campaign-sdk-user-isolation', async () => {
34
+ v.expect(await learner.invoke.getMyCampaigns()).toEqual([]);
35
+ v.expect(await other.invoke.getMyCampaigns()).toEqual([]);
36
+ v.expect(await learner.invoke.recordCampaignEvent(campaignId, 'shown')).toBe(false);
37
+ await v
38
+ .expect(learner.invoke.enrollInCampaign(campaignId))
39
+ .rejects.toThrow(/Campaign not found/);
40
+ });
41
+
42
+ return {
43
+ authorization: 'passed',
44
+ userIsolation: 'passed',
45
+ adminDataCoverage: 'separate Neo4j integration suite',
46
+ };
47
+ };
48
+
49
+ export default script;
package/tsconfig.json CHANGED
@@ -16,20 +16,20 @@
16
16
  "emitDeclarationOnly": true,
17
17
  "sourceMap": true,
18
18
  "rootDir": ".",
19
- "baseUrl": ".",
20
19
  "paths": {
21
- "@accesslayer/*": ["src/accesslayer/*"],
22
- "@cache": ["src/cache/index.ts"],
23
- "@cache/*": ["src/cache/*"],
24
- "@environment": ["src/config/environment.ts"],
25
- "@helpers/*": ["src/helpers/*"],
26
- "@instance": ["src/instance.ts"],
27
- "@models": ["src/models/index.ts"],
28
- "@routes": ["src/routes/index.ts"],
29
- "@routes/*": ["src/routes/*"],
30
- "types/*": ["src/types/*"],
31
- "@services/*": ["src/services/*"],
32
- "@tracing": ["src/tracing/index.ts"]
20
+ "src/*": ["./src/*"],
21
+ "@accesslayer/*": ["./src/accesslayer/*"],
22
+ "@cache": ["./src/cache/index.ts"],
23
+ "@cache/*": ["./src/cache/*"],
24
+ "@environment": ["./src/config/environment.ts"],
25
+ "@helpers/*": ["./src/helpers/*"],
26
+ "@instance": ["./src/instance.ts"],
27
+ "@models": ["./src/models/index.ts"],
28
+ "@routes": ["./src/routes/index.ts"],
29
+ "@routes/*": ["./src/routes/*"],
30
+ "types/*": ["./src/types/*"],
31
+ "@services/*": ["./src/services/*"],
32
+ "@tracing": ["./src/tracing/index.ts"]
33
33
  },
34
34
  "esModuleInterop": true,
35
35
  "allowSyntheticDefaultImports": true,
@@ -0,0 +1,21 @@
1
+ import { createRequire } from 'node:module';
2
+
3
+ import { createVitestConfig, serviceIntegrationPreset } from '../../../vitest.shared';
4
+
5
+ const require = createRequire(import.meta.url);
6
+
7
+ export default createVitestConfig(serviceIntegrationPreset, {
8
+ test: {
9
+ globalSetup: './test-setup.ts',
10
+ include: ['test/campaigns.spec.ts'],
11
+ alias: { '@instance': require.resolve('./test/helpers/mock-instance.ts') },
12
+ env: {
13
+ IS_E2E_TEST: 'true',
14
+ DOMAIN_NAME: 'localhost%3A3000',
15
+ SEED: 'a'.repeat(64),
16
+ CAMPAIGN_ADMIN_PROFILE_IDS: 'campaign-admin',
17
+ TRACE_CONSOLE: 'false',
18
+ NEO4J_SKIP_INDICES: 'true',
19
+ },
20
+ },
21
+ });
package/vitest.config.ts CHANGED
@@ -16,6 +16,7 @@ export default createVitestConfig(brainServicePreset, {
16
16
  NEO4J_SKIP_INDICES: 'true',
17
17
  },
18
18
  include: [
19
+ 'test/credential-share-previews.spec.ts',
19
20
  'test/share-link-*.unit.spec.ts',
20
21
  'test/share-content-client.*.spec.ts',
21
22
  'test/uri-helpers.spec.ts',
@@ -24,6 +25,7 @@ export default createVitestConfig(brainServicePreset, {
24
25
  'test/openapi.spec.ts',
25
26
  'src/helpers/posthog.helpers.test.ts',
26
27
  'src/helpers/rateLimit.helpers.test.ts',
28
+ 'src/helpers/sentry.helpers.test.ts',
27
29
  'src/helpers/credentialSubject.helpers.test.ts',
28
30
  'src/helpers/inbox-batch.helpers.test.ts',
29
31
  'src/helpers/inbox-queue.helpers.test.ts',
@@ -50,6 +52,7 @@ export default createVitestConfig(brainServicePreset, {
50
52
  'src/helpers/signingAuthority.helpers.test.ts',
51
53
  'src/helpers/status-list.helpers.test.ts',
52
54
  'src/helpers/boost-storage.helpers.test.ts',
55
+ 'src/helpers/app-credential-delivery.helpers.test.ts',
53
56
  'src/accesslayer/credential/create.test.ts',
54
57
  'src/accesslayer/inbox-batch/schema.test.ts',
55
58
  'src/helpers/inbox-encryption.helpers.test.ts',
@@ -57,6 +60,15 @@ export default createVitestConfig(brainServicePreset, {
57
60
  'src/helpers/contact-method.helpers.test.ts',
58
61
  'src/services/delivery/adapters/postmark.adapter.test.ts',
59
62
  'src/helpers/inbox-maintenance.helpers.test.ts',
63
+ 'src/helpers/bedrock-embedding.helpers.test.ts',
64
+ 'src/helpers/skill-embedding.helpers.test.ts',
65
+ 'src/seed/seedSkillFrameworks.embeddings.test.ts',
66
+ // Opt-in, local-only Neo4j check of the embedding compare-and-set; skipped unless
67
+ // SKILL_EMBEDDING_TEST_NEO4J_URI points at localhost.
68
+ 'src/config/skillEmbedding.neo4j.test.ts',
69
+ 'src/routes/skills-semantic-search.test.ts',
70
+ // Opt-in, paid, real-AWS smoke test; skipped unless SKILL_EMBEDDING_BEDROCK_SMOKE=true.
71
+ 'src/helpers/bedrock-embedding.smoke.test.ts',
60
72
  ],
61
73
  },
62
74
  });
@@ -13,6 +13,7 @@ export default createVitestConfig(serviceIntegrationPreset, {
13
13
  'test/inbox-batch.spec.ts',
14
14
  'test/atomic-counter.e2e.ts',
15
15
  'test/credential-storage.neo4j.spec.ts',
16
+ 'test/app-credential-delivery.neo4j.spec.ts',
16
17
  'test/inbox.spec.ts',
17
18
  ],
18
19
  alias: { '@instance': require.resolve('./test/helpers/mock-instance.ts') },
@@ -19,6 +19,7 @@ export default createVitestConfig(serviceIntegrationPreset, {
19
19
  CREDENTIAL_REFRESH_ENABLED: 'true',
20
20
  LOGIN_PROVIDER_DID: 'did:key:z6Mko9uYxDPk2BetRRziLz1xHN8nR5zQWdNjytKNDPcygHJP',
21
21
  APP_STORE_ADMIN_PROFILE_IDS: 'app-store-admin',
22
+ CAMPAIGN_ADMIN_PROFILE_IDS: 'campaign-admin',
22
23
  TRACE_CONSOLE: 'false',
23
24
  },
24
25
  },