@primocaredentgroup/convex-campaigns-component 0.3.4 → 0.3.8
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.
- package/convex.config.ts +2 -10
- package/package.json +10 -5
- package/scripts/smoke-test.mjs +0 -171
- package/scripts/sync-from-repo.mjs +0 -42
package/convex.config.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineComponent } from "convex/server";
|
|
2
2
|
|
|
3
3
|
const campaignsComponent = defineComponent("campaigns");
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
// L'host che installa da npm usa: import campaignsComponent from "package/convex.config"
|
|
7
|
-
// e fa app.use(campaignsComponent) - quindi serve il componente.
|
|
8
|
-
const app = defineApp();
|
|
9
|
-
app.use(campaignsComponent, { name: "campaigns" });
|
|
10
|
-
|
|
11
|
-
export default app;
|
|
12
|
-
// Per host npm: import { campaignsComponent } from "package/convex.config"
|
|
13
|
-
export { campaignsComponent };
|
|
5
|
+
export default campaignsComponent;
|
package/package.json
CHANGED
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primocaredentgroup/convex-campaigns-component",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Convex Campaigns backend component for PrimoCore",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "convex.config.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"./convex.config.js": "./convex.config.ts",
|
|
10
|
+
"./convex.config": "./convex.config.ts"
|
|
11
|
+
},
|
|
8
12
|
"files": [
|
|
9
13
|
"convex.config.ts",
|
|
10
14
|
"README.md",
|
|
11
15
|
"CHANGELOG.md",
|
|
12
|
-
"convex/**"
|
|
13
|
-
"scripts/**"
|
|
16
|
+
"convex/**"
|
|
14
17
|
],
|
|
15
18
|
"scripts": {
|
|
16
19
|
"sync:from-repo": "node ./scripts/sync-from-repo.mjs",
|
|
17
20
|
"prepack": "npm run sync:from-repo",
|
|
18
21
|
"test": "tsx --test tests/**/*.test.ts",
|
|
19
22
|
"smoke": "node scripts/smoke-test.mjs",
|
|
20
|
-
"version:patch": "
|
|
23
|
+
"version:patch": "node scripts/bump-version.mjs",
|
|
21
24
|
"publish:component": "npm run version:patch && npm publish"
|
|
22
25
|
},
|
|
23
26
|
"peerDependencies": {
|
|
24
27
|
"convex": "^1.14.0"
|
|
25
28
|
},
|
|
26
29
|
"peerDependenciesMeta": {
|
|
27
|
-
"convex": {
|
|
30
|
+
"convex": {
|
|
31
|
+
"optional": true
|
|
32
|
+
}
|
|
28
33
|
},
|
|
29
34
|
"devDependencies": {
|
|
30
35
|
"convex": "^1.14.0",
|
package/scripts/smoke-test.mjs
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Smoke test per componente campaigns.
|
|
4
|
-
* Chiama le API pubbliche in sequenza per verificare funzionamento end-to-end.
|
|
5
|
-
*
|
|
6
|
-
* L'URL Convex viene letto da (in ordine):
|
|
7
|
-
* 1. CONVEX_URL o VITE_CONVEX_URL (env)
|
|
8
|
-
* 2. .env.local (nella cwd o nelle cartelle parent)
|
|
9
|
-
*
|
|
10
|
-
* Uso:
|
|
11
|
-
* cd /path/alla/repo/convex-campaigns-component # o repo con convex dev
|
|
12
|
-
* npm run smoke
|
|
13
|
-
*
|
|
14
|
-
* # oppure con URL esplicito:
|
|
15
|
-
* CONVEX_URL=https://tuo-deployment.convex.cloud npm run smoke
|
|
16
|
-
*/
|
|
17
|
-
import { ConvexHttpClient } from "convex/browser";
|
|
18
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
19
|
-
import { resolve, dirname } from "node:path";
|
|
20
|
-
import { fileURLToPath } from "node:url";
|
|
21
|
-
|
|
22
|
-
function loadEnvLocal() {
|
|
23
|
-
const dirs = [
|
|
24
|
-
process.cwd(),
|
|
25
|
-
resolve(process.cwd(), ".."),
|
|
26
|
-
resolve(process.cwd(), "../.."),
|
|
27
|
-
resolve(dirname(fileURLToPath(import.meta.url)), ".."),
|
|
28
|
-
];
|
|
29
|
-
for (const dir of dirs) {
|
|
30
|
-
const p = resolve(dir, ".env.local");
|
|
31
|
-
if (existsSync(p)) {
|
|
32
|
-
try {
|
|
33
|
-
const content = readFileSync(p, "utf8");
|
|
34
|
-
for (const line of content.split("\n")) {
|
|
35
|
-
const m = line.match(/^(?:CONVEX_URL|VITE_CONVEX_URL)=(.+)$/);
|
|
36
|
-
if (m) return m[1].trim().replace(/^["']|["']$/g, "");
|
|
37
|
-
}
|
|
38
|
-
} catch {}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const CONVEX_URL =
|
|
45
|
-
process.env.CONVEX_URL ?? process.env.VITE_CONVEX_URL ?? loadEnvLocal();
|
|
46
|
-
const ORG_ID = process.env.SMOKE_ORG_ID ?? "demo-org";
|
|
47
|
-
const CLINIC_IDS = (process.env.SMOKE_CLINIC_IDS ?? "clinic-a,clinic-b")
|
|
48
|
-
.split(",")
|
|
49
|
-
.map((s) => s.trim());
|
|
50
|
-
|
|
51
|
-
if (!CONVEX_URL) {
|
|
52
|
-
console.error(`
|
|
53
|
-
ERRORE: URL Convex non trovato.
|
|
54
|
-
|
|
55
|
-
Opzioni:
|
|
56
|
-
1. Esegui da una cartella con .env.local (creato da "npx convex dev")
|
|
57
|
-
2. Imposta CONVEX_URL:
|
|
58
|
-
CONVEX_URL=https://tuo-deployment.convex.cloud npm run smoke
|
|
59
|
-
3. L'URL si trova nel dashboard Convex o in .env.local dopo convex dev
|
|
60
|
-
`);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const client = new ConvexHttpClient(CONVEX_URL);
|
|
65
|
-
|
|
66
|
-
async function run(name, fn) {
|
|
67
|
-
try {
|
|
68
|
-
const result = await fn();
|
|
69
|
-
console.log(`✓ ${name}`);
|
|
70
|
-
return result;
|
|
71
|
-
} catch (err) {
|
|
72
|
-
console.error(`✗ ${name}:`, err.message);
|
|
73
|
-
throw err;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async function main() {
|
|
78
|
-
console.log("Smoke test campaigns component...");
|
|
79
|
-
console.log("CONVEX_URL:", CONVEX_URL);
|
|
80
|
-
console.log("ORG_ID:", ORG_ID);
|
|
81
|
-
|
|
82
|
-
let campaignId;
|
|
83
|
-
let versionId;
|
|
84
|
-
|
|
85
|
-
if (process.env.SMOKE_SKIP_SEED !== "1") {
|
|
86
|
-
const seedResult = await run("seedDemoData", () =>
|
|
87
|
-
client.mutation("campaigns:seedDemoData", {
|
|
88
|
-
orgId: ORG_ID,
|
|
89
|
-
clinicIds: CLINIC_IDS,
|
|
90
|
-
nPatients: 50,
|
|
91
|
-
}),
|
|
92
|
-
);
|
|
93
|
-
console.log(" inserted:", seedResult?.insertedPatients);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const createResult = await run("upsertCampaign", () =>
|
|
97
|
-
client.mutation("campaigns:upsertCampaign", {
|
|
98
|
-
orgId: ORG_ID,
|
|
99
|
-
name: "Smoke Test Campaign",
|
|
100
|
-
clinicIds: CLINIC_IDS,
|
|
101
|
-
rules: {
|
|
102
|
-
op: "AND",
|
|
103
|
-
rules: [{ fieldKey: "patient.hasCallConsent", operator: "is", value: true }],
|
|
104
|
-
},
|
|
105
|
-
status: "draft",
|
|
106
|
-
}),
|
|
107
|
-
);
|
|
108
|
-
campaignId = createResult?.id;
|
|
109
|
-
|
|
110
|
-
await run("setCampaignLifecycleStatus ready", () =>
|
|
111
|
-
client.mutation("campaigns:setCampaignLifecycleStatus", {
|
|
112
|
-
campaignId,
|
|
113
|
-
status: "ready",
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
const publishResult = await run("publishCampaignVersion", () =>
|
|
118
|
-
client.mutation("campaigns:publishCampaignVersion", {
|
|
119
|
-
campaignId,
|
|
120
|
-
label: "Smoke test",
|
|
121
|
-
}),
|
|
122
|
-
);
|
|
123
|
-
versionId = publishResult?.versionId;
|
|
124
|
-
console.log(" version:", publishResult?.version, "inserted:", publishResult?.inserted);
|
|
125
|
-
|
|
126
|
-
const active = await run("listActiveCampaignsForOrg", () =>
|
|
127
|
-
client.query("campaigns:listActiveCampaignsForOrg", {
|
|
128
|
-
orgId: ORG_ID,
|
|
129
|
-
clinicId: CLINIC_IDS[0],
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
console.log(" campaigns:", active?.length);
|
|
133
|
-
|
|
134
|
-
const audience = await run("getAudiencePage", () =>
|
|
135
|
-
client.query("campaigns:getAudiencePage", {
|
|
136
|
-
versionId,
|
|
137
|
-
limit: 5,
|
|
138
|
-
}),
|
|
139
|
-
);
|
|
140
|
-
console.log(" page length:", audience?.page?.length);
|
|
141
|
-
|
|
142
|
-
const samplePatient = audience?.page?.[0]?.patientId;
|
|
143
|
-
if (samplePatient) {
|
|
144
|
-
await run("recordContactAttempt", () =>
|
|
145
|
-
client.mutation("campaigns:recordContactAttempt", {
|
|
146
|
-
orgId: ORG_ID,
|
|
147
|
-
clinicId: audience.page[0].clinicId,
|
|
148
|
-
patientId: samplePatient,
|
|
149
|
-
campaignId,
|
|
150
|
-
versionId,
|
|
151
|
-
channel: "call",
|
|
152
|
-
outcome: "answered",
|
|
153
|
-
}),
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const memberships = await run("getPatientCampaignMemberships", () =>
|
|
158
|
-
client.query("campaigns:getPatientCampaignMemberships", {
|
|
159
|
-
orgId: ORG_ID,
|
|
160
|
-
patientId: samplePatient ?? "demo-smoke-org-clinic-a-1",
|
|
161
|
-
}),
|
|
162
|
-
);
|
|
163
|
-
console.log(" memberships:", memberships?.length);
|
|
164
|
-
|
|
165
|
-
console.log("\nSmoke test completato.");
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
main().catch((err) => {
|
|
169
|
-
console.error(err);
|
|
170
|
-
process.exit(1);
|
|
171
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { access, cp, mkdir, rm } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = path.dirname(__filename);
|
|
7
|
-
|
|
8
|
-
const packageRoot = path.resolve(__dirname, "..");
|
|
9
|
-
const repoRoot = path.resolve(packageRoot, "..", "..");
|
|
10
|
-
|
|
11
|
-
const sourceComponentDir = path.join(repoRoot, "convex", "components", "campaigns");
|
|
12
|
-
const targetComponentDir = path.join(
|
|
13
|
-
packageRoot,
|
|
14
|
-
"convex",
|
|
15
|
-
"components",
|
|
16
|
-
"campaigns",
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
const sourcePublicApi = path.join(repoRoot, "convex", "campaigns.ts");
|
|
20
|
-
const targetPublicApi = path.join(packageRoot, "convex", "campaigns.ts");
|
|
21
|
-
|
|
22
|
-
async function main() {
|
|
23
|
-
const sourceExists = await access(sourceComponentDir).then(
|
|
24
|
-
() => true,
|
|
25
|
-
() => false,
|
|
26
|
-
);
|
|
27
|
-
if (!sourceExists) {
|
|
28
|
-
console.log("No external monorepo source found, keeping local component files.");
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
await rm(targetComponentDir, { recursive: true, force: true });
|
|
33
|
-
await mkdir(path.dirname(targetComponentDir), { recursive: true });
|
|
34
|
-
await cp(sourceComponentDir, targetComponentDir, { recursive: true });
|
|
35
|
-
await cp(sourcePublicApi, targetPublicApi);
|
|
36
|
-
console.log("Synced campaigns component from repo into npm package.");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
main().catch((error) => {
|
|
40
|
-
console.error("Failed to sync component files:", error);
|
|
41
|
-
process.exit(1);
|
|
42
|
-
});
|