@mastra/mongodb 1.10.1-alpha.0 → 1.11.0-alpha.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.
- package/CHANGELOG.md +75 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +145 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +145 -40
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts.map +1 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +1 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# @mastra/mongodb
|
|
2
2
|
|
|
3
|
+
## 1.11.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Fixed new observability span writes in MongoDB so `startedAt`, `endedAt`, `createdAt`, and `updatedAt` are stored as native BSON Date objects. Existing string-typed span dates remain readable and date filters support both old string values and new Date values. ([#18366](https://github.com/mastra-ai/mastra/pull/18366))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Added multi-tenant scoping columns (`organizationId`, `projectId`) to the experiments domain so experiment records and per-item results inherit the tenancy bucket of their parent dataset. ([#18388](https://github.com/mastra-ai/mastra/pull/18388))
|
|
12
|
+
|
|
13
|
+
`Experiment`, `ExperimentResult`, `CreateExperimentInput`, and `AddExperimentResultInput` now carry optional `organizationId` / `projectId` fields. `ListExperimentsInput` and `ListExperimentResultsInput` gain a `filters: ExperimentTenancyFilters` block (mirrors `DatasetTenancyFilters`) for scoping queries within a `(organizationId, projectId)` bucket. Tenancy is hydrated from the parent dataset on `createExperiment` and denormalized onto each `ExperimentResult` for efficient tenancy-scoped queries.
|
|
14
|
+
|
|
15
|
+
The corresponding columns are also added to the `mastra_experiments` and `mastra_experiment_results` table schemas. Existing rows backfill to `null`, matching the rest of the dataset-tenancy surface.
|
|
16
|
+
|
|
17
|
+
This release also clarifies the `targetType` contract via JSDoc:
|
|
18
|
+
- `CreateDatasetInput.targetType` remains optional. Datasets without a `TargetType` are **not experiment-eligible** — the experiment runner requires a non-null `CreateExperimentInput.targetType` to resolve an executor.
|
|
19
|
+
- `Experiment.targetType` / `CreateExperimentInput.targetType` stay required. An experiment by definition replays inputs against a specific target.
|
|
20
|
+
|
|
21
|
+
No behavior change for existing OSS-created experiments; the new fields are additive and optional.
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// Create an experiment scoped to a tenancy bucket. When the parent dataset
|
|
27
|
+
// already carries `organizationId` / `projectId`, `runExperiment` hydrates
|
|
28
|
+
// these fields automatically from the dataset record.
|
|
29
|
+
const experiment = await storage.createExperiment({
|
|
30
|
+
name: 'qa-regression',
|
|
31
|
+
datasetId: 'ds_123',
|
|
32
|
+
datasetVersion: 1,
|
|
33
|
+
targetType: 'agent',
|
|
34
|
+
targetId: 'agent_qa',
|
|
35
|
+
totalItems: 10,
|
|
36
|
+
organizationId: 'org_123',
|
|
37
|
+
projectId: 'proj_123',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// List experiments within a tenancy bucket.
|
|
41
|
+
const experiments = await storage.listExperiments({
|
|
42
|
+
pagination: { page: 0, perPage: 20 },
|
|
43
|
+
filters: { organizationId: 'org_123', projectId: 'proj_123' },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// List per-item results within the same bucket.
|
|
47
|
+
const results = await storage.listExperimentResults({
|
|
48
|
+
experimentId: experiment.id,
|
|
49
|
+
pagination: { page: 0, perPage: 50 },
|
|
50
|
+
filters: { organizationId: 'org_123', projectId: 'proj_123' },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- Persist and filter dataset tenancy + candidate identity in storage adapters. ([#18314](https://github.com/mastra-ai/mastra/pull/18314))
|
|
55
|
+
|
|
56
|
+
`createDataset` now persists `organizationId`, `projectId`, `candidateKey`, and `candidateId`. `listDatasets` and `listItems` accept matching tenancy filters. Dataset items inherit `organizationId` / `projectId` from their parent dataset on insert, update, delete, and batch insert/delete — items are never settable per call (item tenancy follows dataset tenancy).
|
|
57
|
+
|
|
58
|
+
All new columns are nullable and added retroactively via each adapter's existing column-migration path; no breaking DDL. Existing rows continue to read and write fine; new writes can choose to stamp tenancy.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
await storage.createDataset({
|
|
62
|
+
name: 'candidates/missing-tool-call/incident-123',
|
|
63
|
+
organizationId: 'org_abc',
|
|
64
|
+
projectId: 'project_xyz',
|
|
65
|
+
candidateKey: 'missing-tool-call',
|
|
66
|
+
candidateId: 'incident-123',
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await storage.listDatasets({
|
|
70
|
+
pagination: { page: 0, perPage: 20 },
|
|
71
|
+
filters: { organizationId: 'org_abc', projectId: 'project_xyz' },
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- Updated dependencies [[`5c4e9a4`](https://github.com/mastra-ai/mastra/commit/5c4e9a4cfb2216bb3ea7f8988ad3727f3b92bb3a), [`25961e3`](https://github.com/mastra-ai/mastra/commit/25961e3260ff3b1464637af8fcdb36210551c39f), [`7b29f33`](https://github.com/mastra-ai/mastra/commit/7b29f332a357a83e555f29e718e5f2fab9979943), [`24912b1`](https://github.com/mastra-ai/mastra/commit/24912b1f855d29ec36af4ef4bde1f7417e20cdf5), [`7686216`](https://github.com/mastra-ai/mastra/commit/7686216f37e74568feddec17cef3c3d24e10e60a), [`975c59a`](https://github.com/mastra-ai/mastra/commit/975c59ae363ee275fc55062392e1ffd2cbccbd53), [`d95f394`](https://github.com/mastra-ai/mastra/commit/d95f394fd24c8411886930d727679c4d5252aa26), [`f3f0c9d`](https://github.com/mastra-ai/mastra/commit/f3f0c9d7c878db5a13177871ce3523a14f14b311)]:
|
|
76
|
+
- @mastra/core@1.46.0-alpha.4
|
|
77
|
+
|
|
3
78
|
## 1.10.1-alpha.0
|
|
4
79
|
|
|
5
80
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-mongodb
|
|
|
3
3
|
description: Documentation for @mastra/mongodb. Use when working with @mastra/mongodb APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/mongodb"
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.11.0-alpha.1"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
package/dist/index.cjs
CHANGED
|
@@ -15,7 +15,7 @@ var skills = require('@mastra/core/storage/domains/skills');
|
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
17
|
var package_default = {
|
|
18
|
-
version: "1.
|
|
18
|
+
version: "1.11.0-alpha.1"};
|
|
19
19
|
var MongoDBFilterTranslator = class extends filter.BaseFilterTranslator {
|
|
20
20
|
getSupportedOperators() {
|
|
21
21
|
return {
|
|
@@ -1930,7 +1930,22 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
1930
1930
|
return [
|
|
1931
1931
|
{ collection: storage.TABLE_DATASETS, keys: { id: 1 }, options: { name: "idx_datasets_id", unique: true } },
|
|
1932
1932
|
{ collection: storage.TABLE_DATASETS, keys: { createdAt: -1, id: 1 }, options: { name: "idx_datasets_createdat_id" } },
|
|
1933
|
+
{
|
|
1934
|
+
collection: storage.TABLE_DATASETS,
|
|
1935
|
+
keys: { organizationId: 1, projectId: 1, createdAt: -1, id: 1 },
|
|
1936
|
+
options: { name: "idx_datasets_tenancy_createdat_id" }
|
|
1937
|
+
},
|
|
1938
|
+
{
|
|
1939
|
+
collection: storage.TABLE_DATASETS,
|
|
1940
|
+
keys: { organizationId: 1, projectId: 1, candidateKey: 1, candidateId: 1 },
|
|
1941
|
+
options: { name: "idx_datasets_tenancy_candidate" }
|
|
1942
|
+
},
|
|
1933
1943
|
{ collection: storage.TABLE_DATASET_ITEMS, keys: { datasetId: 1 }, options: { name: "idx_dataset_items_datasetid" } },
|
|
1944
|
+
{
|
|
1945
|
+
collection: storage.TABLE_DATASET_ITEMS,
|
|
1946
|
+
keys: { organizationId: 1, projectId: 1, datasetId: 1, validTo: 1, isDeleted: 1 },
|
|
1947
|
+
options: { name: "idx_dataset_items_tenancy_list" }
|
|
1948
|
+
},
|
|
1934
1949
|
{
|
|
1935
1950
|
collection: storage.TABLE_DATASET_ITEMS,
|
|
1936
1951
|
keys: { datasetId: 1, validTo: 1 },
|
|
@@ -2008,6 +2023,10 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2008
2023
|
targetIds: typeof row.targetIds === "string" ? storage.safelyParseJSON(row.targetIds) : row.targetIds ?? void 0,
|
|
2009
2024
|
scorerIds: typeof row.scorerIds === "string" ? storage.safelyParseJSON(row.scorerIds) : row.scorerIds ?? void 0,
|
|
2010
2025
|
version: row.version ?? 0,
|
|
2026
|
+
organizationId: row.organizationId ?? null,
|
|
2027
|
+
projectId: row.projectId ?? null,
|
|
2028
|
+
candidateKey: row.candidateKey ?? null,
|
|
2029
|
+
candidateId: row.candidateId ?? null,
|
|
2011
2030
|
createdAt: storage.ensureDate(row.createdAt),
|
|
2012
2031
|
updatedAt: storage.ensureDate(row.updatedAt)
|
|
2013
2032
|
};
|
|
@@ -2017,6 +2036,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2017
2036
|
id: row.id,
|
|
2018
2037
|
datasetId: row.datasetId,
|
|
2019
2038
|
datasetVersion: row.datasetVersion,
|
|
2039
|
+
organizationId: row.organizationId ?? null,
|
|
2040
|
+
projectId: row.projectId ?? null,
|
|
2020
2041
|
input: typeof row.input === "string" ? storage.safelyParseJSON(row.input) : row.input,
|
|
2021
2042
|
groundTruth: typeof row.groundTruth === "string" ? storage.safelyParseJSON(row.groundTruth) : row.groundTruth,
|
|
2022
2043
|
expectedTrajectory: typeof row.expectedTrajectory === "string" ? storage.safelyParseJSON(row.expectedTrajectory) : row.expectedTrajectory,
|
|
@@ -2061,6 +2082,10 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2061
2082
|
targetIds: input.targetIds ?? null,
|
|
2062
2083
|
scorerIds: input.scorerIds ?? null,
|
|
2063
2084
|
version: 0,
|
|
2085
|
+
organizationId: input.organizationId ?? null,
|
|
2086
|
+
projectId: input.projectId ?? null,
|
|
2087
|
+
candidateKey: input.candidateKey ?? null,
|
|
2088
|
+
candidateId: input.candidateId ?? null,
|
|
2064
2089
|
createdAt: now,
|
|
2065
2090
|
updatedAt: now
|
|
2066
2091
|
};
|
|
@@ -2171,7 +2196,12 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2171
2196
|
try {
|
|
2172
2197
|
const { page, perPage: perPageInput } = args.pagination;
|
|
2173
2198
|
const collection = await this.getCollection(storage.TABLE_DATASETS);
|
|
2174
|
-
const
|
|
2199
|
+
const filter = {};
|
|
2200
|
+
if (args.filters?.organizationId !== void 0) filter.organizationId = args.filters.organizationId;
|
|
2201
|
+
if (args.filters?.projectId !== void 0) filter.projectId = args.filters.projectId;
|
|
2202
|
+
if (args.filters?.candidateKey !== void 0) filter.candidateKey = args.filters.candidateKey;
|
|
2203
|
+
if (args.filters?.candidateId !== void 0) filter.candidateId = args.filters.candidateId;
|
|
2204
|
+
const total = await collection.countDocuments(filter);
|
|
2175
2205
|
if (total === 0) {
|
|
2176
2206
|
return { datasets: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
2177
2207
|
}
|
|
@@ -2181,7 +2211,7 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2181
2211
|
return { datasets: [], pagination: { total, page, perPage: perPageForResponse, hasMore: total > 0 } };
|
|
2182
2212
|
}
|
|
2183
2213
|
const limitValue = perPageInput === false ? total : perPage;
|
|
2184
|
-
const rows = await collection.find(
|
|
2214
|
+
const rows = await collection.find(filter).sort({ createdAt: -1, id: 1 }).skip(offset).limit(limitValue).toArray();
|
|
2185
2215
|
return {
|
|
2186
2216
|
datasets: rows.map((row) => this.transformDatasetRow(row)),
|
|
2187
2217
|
pagination: {
|
|
@@ -2225,10 +2255,14 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2225
2255
|
});
|
|
2226
2256
|
}
|
|
2227
2257
|
const newVersion = result.version;
|
|
2258
|
+
const organizationId = result.organizationId ?? null;
|
|
2259
|
+
const projectId = result.projectId ?? null;
|
|
2228
2260
|
await itemsCollection.insertOne({
|
|
2229
2261
|
id,
|
|
2230
2262
|
datasetId: args.datasetId,
|
|
2231
2263
|
datasetVersion: newVersion,
|
|
2264
|
+
organizationId,
|
|
2265
|
+
projectId,
|
|
2232
2266
|
validTo: null,
|
|
2233
2267
|
isDeleted: false,
|
|
2234
2268
|
input: args.input,
|
|
@@ -2251,6 +2285,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2251
2285
|
id,
|
|
2252
2286
|
datasetId: args.datasetId,
|
|
2253
2287
|
datasetVersion: newVersion,
|
|
2288
|
+
organizationId,
|
|
2289
|
+
projectId,
|
|
2254
2290
|
input: args.input,
|
|
2255
2291
|
groundTruth: args.groundTruth,
|
|
2256
2292
|
expectedTrajectory: args.expectedTrajectory,
|
|
@@ -2322,6 +2358,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2322
2358
|
});
|
|
2323
2359
|
}
|
|
2324
2360
|
const newVersion = result.version;
|
|
2361
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2362
|
+
const parentProjectId = result.projectId ?? null;
|
|
2325
2363
|
await itemsCollection.updateOne(
|
|
2326
2364
|
{ id: args.id, validTo: null, isDeleted: false },
|
|
2327
2365
|
{ $set: { validTo: newVersion } }
|
|
@@ -2330,6 +2368,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2330
2368
|
id: args.id,
|
|
2331
2369
|
datasetId: args.datasetId,
|
|
2332
2370
|
datasetVersion: newVersion,
|
|
2371
|
+
organizationId: parentOrganizationId,
|
|
2372
|
+
projectId: parentProjectId,
|
|
2333
2373
|
validTo: null,
|
|
2334
2374
|
isDeleted: false,
|
|
2335
2375
|
input: mergedInput,
|
|
@@ -2351,6 +2391,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2351
2391
|
return {
|
|
2352
2392
|
...existing,
|
|
2353
2393
|
datasetVersion: newVersion,
|
|
2394
|
+
organizationId: parentOrganizationId,
|
|
2395
|
+
projectId: parentProjectId,
|
|
2354
2396
|
input: mergedInput,
|
|
2355
2397
|
groundTruth: mergedGroundTruth,
|
|
2356
2398
|
expectedTrajectory: mergedExpectedTrajectory,
|
|
@@ -2403,15 +2445,21 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2403
2445
|
});
|
|
2404
2446
|
}
|
|
2405
2447
|
const newVersion = result.version;
|
|
2448
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2449
|
+
const parentProjectId = result.projectId ?? null;
|
|
2406
2450
|
await itemsCollection.updateOne({ id, validTo: null, isDeleted: false }, { $set: { validTo: newVersion } });
|
|
2407
2451
|
await itemsCollection.insertOne({
|
|
2408
2452
|
id,
|
|
2409
2453
|
datasetId,
|
|
2410
2454
|
datasetVersion: newVersion,
|
|
2455
|
+
organizationId: parentOrganizationId,
|
|
2456
|
+
projectId: parentProjectId,
|
|
2411
2457
|
validTo: null,
|
|
2412
2458
|
isDeleted: true,
|
|
2413
2459
|
input: existing.input,
|
|
2414
2460
|
groundTruth: existing.groundTruth,
|
|
2461
|
+
expectedTrajectory: existing.expectedTrajectory ?? null,
|
|
2462
|
+
toolMocks: existing.toolMocks ?? null,
|
|
2415
2463
|
requestContext: existing.requestContext,
|
|
2416
2464
|
metadata: existing.metadata,
|
|
2417
2465
|
source: existing.source,
|
|
@@ -2474,11 +2522,15 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2474
2522
|
});
|
|
2475
2523
|
}
|
|
2476
2524
|
const newVersion = result.version;
|
|
2525
|
+
const organizationId = result.organizationId ?? null;
|
|
2526
|
+
const projectId = result.projectId ?? null;
|
|
2477
2527
|
if (itemsWithIds.length > 0) {
|
|
2478
2528
|
const docs = itemsWithIds.map(({ generatedId, itemInput }) => ({
|
|
2479
2529
|
id: generatedId,
|
|
2480
2530
|
datasetId: input.datasetId,
|
|
2481
2531
|
datasetVersion: newVersion,
|
|
2532
|
+
organizationId,
|
|
2533
|
+
projectId,
|
|
2482
2534
|
validTo: null,
|
|
2483
2535
|
isDeleted: false,
|
|
2484
2536
|
input: itemInput.input,
|
|
@@ -2503,6 +2555,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2503
2555
|
id: generatedId,
|
|
2504
2556
|
datasetId: input.datasetId,
|
|
2505
2557
|
datasetVersion: newVersion,
|
|
2558
|
+
organizationId,
|
|
2559
|
+
projectId,
|
|
2506
2560
|
input: itemInput.input,
|
|
2507
2561
|
groundTruth: itemInput.groundTruth,
|
|
2508
2562
|
expectedTrajectory: itemInput.expectedTrajectory,
|
|
@@ -2563,6 +2617,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2563
2617
|
});
|
|
2564
2618
|
}
|
|
2565
2619
|
const newVersion = result.version;
|
|
2620
|
+
const parentOrganizationId = result.organizationId ?? null;
|
|
2621
|
+
const parentProjectId = result.projectId ?? null;
|
|
2566
2622
|
const currentIds = currentItems.map((i) => i.id);
|
|
2567
2623
|
await itemsCollection.updateMany(
|
|
2568
2624
|
{ id: { $in: currentIds }, validTo: null, isDeleted: false },
|
|
@@ -2572,10 +2628,14 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2572
2628
|
id: item.id,
|
|
2573
2629
|
datasetId: input.datasetId,
|
|
2574
2630
|
datasetVersion: newVersion,
|
|
2631
|
+
organizationId: parentOrganizationId,
|
|
2632
|
+
projectId: parentProjectId,
|
|
2575
2633
|
validTo: null,
|
|
2576
2634
|
isDeleted: true,
|
|
2577
2635
|
input: item.input,
|
|
2578
2636
|
groundTruth: item.groundTruth,
|
|
2637
|
+
expectedTrajectory: item.expectedTrajectory ?? null,
|
|
2638
|
+
toolMocks: item.toolMocks ?? null,
|
|
2579
2639
|
requestContext: item.requestContext,
|
|
2580
2640
|
metadata: item.metadata,
|
|
2581
2641
|
source: item.source,
|
|
@@ -2677,6 +2737,8 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
|
|
|
2677
2737
|
const { page, perPage: perPageInput } = args.pagination;
|
|
2678
2738
|
const collection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
|
|
2679
2739
|
const filter = { datasetId: args.datasetId };
|
|
2740
|
+
if (args.filters?.organizationId !== void 0) filter.organizationId = args.filters.organizationId;
|
|
2741
|
+
if (args.filters?.projectId !== void 0) filter.projectId = args.filters.projectId;
|
|
2680
2742
|
if (args.version !== void 0) {
|
|
2681
2743
|
filter.datasetVersion = { $lte: args.version };
|
|
2682
2744
|
filter.$or = [{ validTo: null }, { validTo: { $gt: args.version } }];
|
|
@@ -2831,6 +2893,8 @@ function transformExperimentRow(row) {
|
|
|
2831
2893
|
metadata: parseJsonField(row.metadata) ?? void 0,
|
|
2832
2894
|
datasetId: row.datasetId ?? null,
|
|
2833
2895
|
datasetVersion: row.datasetVersion != null ? Number(row.datasetVersion) : null,
|
|
2896
|
+
organizationId: row.organizationId ?? null,
|
|
2897
|
+
projectId: row.projectId ?? null,
|
|
2834
2898
|
targetType: row.targetType,
|
|
2835
2899
|
targetId: row.targetId,
|
|
2836
2900
|
status: row.status,
|
|
@@ -2851,6 +2915,8 @@ function transformExperimentResultRow(row) {
|
|
|
2851
2915
|
experimentId: row.experimentId,
|
|
2852
2916
|
itemId: row.itemId,
|
|
2853
2917
|
itemDatasetVersion: row.itemDatasetVersion != null ? Number(row.itemDatasetVersion) : null,
|
|
2918
|
+
organizationId: row.organizationId ?? null,
|
|
2919
|
+
projectId: row.projectId ?? null,
|
|
2854
2920
|
input: parseJsonField(row.input),
|
|
2855
2921
|
output: parseJsonField(row.output) ?? null,
|
|
2856
2922
|
groundTruth: parseJsonField(row.groundTruth) ?? null,
|
|
@@ -2889,11 +2955,14 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2889
2955
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { id: 1 }, options: { unique: true } },
|
|
2890
2956
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { datasetId: 1 } },
|
|
2891
2957
|
{ collection: storage.TABLE_EXPERIMENTS, keys: { createdAt: -1, id: 1 } },
|
|
2958
|
+
// Tenancy: leading-tenant indexes for multi-tenant scans (parity with datasets domain).
|
|
2959
|
+
{ collection: storage.TABLE_EXPERIMENTS, keys: { organizationId: 1, projectId: 1 } },
|
|
2892
2960
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { id: 1 }, options: { unique: true } },
|
|
2893
2961
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1 } },
|
|
2894
2962
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, itemId: 1 }, options: { unique: true } },
|
|
2895
2963
|
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { createdAt: -1 } },
|
|
2896
|
-
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, startedAt: 1, id: 1 } }
|
|
2964
|
+
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { experimentId: 1, startedAt: 1, id: 1 } },
|
|
2965
|
+
{ collection: storage.TABLE_EXPERIMENT_RESULTS, keys: { organizationId: 1, projectId: 1 } }
|
|
2897
2966
|
];
|
|
2898
2967
|
}
|
|
2899
2968
|
async createDefaultIndexes() {
|
|
@@ -2935,6 +3004,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2935
3004
|
metadata: input.metadata ?? null,
|
|
2936
3005
|
datasetId: input.datasetId ?? null,
|
|
2937
3006
|
datasetVersion: input.datasetVersion ?? null,
|
|
3007
|
+
organizationId: input.organizationId ?? null,
|
|
3008
|
+
projectId: input.projectId ?? null,
|
|
2938
3009
|
targetType: input.targetType,
|
|
2939
3010
|
targetId: input.targetId,
|
|
2940
3011
|
status: "pending",
|
|
@@ -2958,6 +3029,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
2958
3029
|
metadata: input.metadata,
|
|
2959
3030
|
datasetId: input.datasetId ?? null,
|
|
2960
3031
|
datasetVersion: input.datasetVersion ?? null,
|
|
3032
|
+
organizationId: input.organizationId ?? null,
|
|
3033
|
+
projectId: input.projectId ?? null,
|
|
2961
3034
|
targetType: input.targetType,
|
|
2962
3035
|
targetId: input.targetId,
|
|
2963
3036
|
status: "pending",
|
|
@@ -3059,6 +3132,15 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3059
3132
|
if (args.status) {
|
|
3060
3133
|
filter.status = args.status;
|
|
3061
3134
|
}
|
|
3135
|
+
if (args.filters) {
|
|
3136
|
+
const { organizationId, projectId } = args.filters;
|
|
3137
|
+
if (organizationId !== void 0) {
|
|
3138
|
+
filter.organizationId = organizationId;
|
|
3139
|
+
}
|
|
3140
|
+
if (projectId !== void 0) {
|
|
3141
|
+
filter.projectId = projectId;
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3062
3144
|
const total = await collection.countDocuments(filter);
|
|
3063
3145
|
if (total === 0) {
|
|
3064
3146
|
return { experiments: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
@@ -3119,6 +3201,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3119
3201
|
experimentId: input.experimentId,
|
|
3120
3202
|
itemId: input.itemId,
|
|
3121
3203
|
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
3204
|
+
organizationId: input.organizationId ?? null,
|
|
3205
|
+
projectId: input.projectId ?? null,
|
|
3122
3206
|
input: input.input,
|
|
3123
3207
|
output: input.output ?? null,
|
|
3124
3208
|
groundTruth: input.groundTruth ?? null,
|
|
@@ -3140,6 +3224,8 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3140
3224
|
experimentId: input.experimentId,
|
|
3141
3225
|
itemId: input.itemId,
|
|
3142
3226
|
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
3227
|
+
organizationId: input.organizationId ?? null,
|
|
3228
|
+
projectId: input.projectId ?? null,
|
|
3143
3229
|
input: input.input,
|
|
3144
3230
|
output: input.output ?? null,
|
|
3145
3231
|
groundTruth: input.groundTruth ?? null,
|
|
@@ -3239,6 +3325,15 @@ var MongoDBExperimentsStorage = class _MongoDBExperimentsStorage extends storage
|
|
|
3239
3325
|
if (args.status) {
|
|
3240
3326
|
filter.status = args.status;
|
|
3241
3327
|
}
|
|
3328
|
+
if (args.filters) {
|
|
3329
|
+
const { organizationId, projectId } = args.filters;
|
|
3330
|
+
if (organizationId !== void 0) {
|
|
3331
|
+
filter.organizationId = organizationId;
|
|
3332
|
+
}
|
|
3333
|
+
if (projectId !== void 0) {
|
|
3334
|
+
filter.projectId = projectId;
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3242
3337
|
const total = await collection.countDocuments(filter);
|
|
3243
3338
|
if (total === 0) {
|
|
3244
3339
|
return { results: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
@@ -6876,17 +6971,39 @@ Note: This migration may take some time for large collections.
|
|
|
6876
6971
|
supported: ["batch-with-updates", "insert-only"]
|
|
6877
6972
|
};
|
|
6878
6973
|
}
|
|
6974
|
+
createDateRangeCondition(field, range) {
|
|
6975
|
+
const dateFilter = {};
|
|
6976
|
+
const stringFilter = {};
|
|
6977
|
+
if (range.start) {
|
|
6978
|
+
const operator = range.startExclusive ? "$gt" : "$gte";
|
|
6979
|
+
const start = range.start instanceof Date ? range.start : new Date(range.start);
|
|
6980
|
+
dateFilter[operator] = start;
|
|
6981
|
+
stringFilter[operator] = start.toISOString();
|
|
6982
|
+
}
|
|
6983
|
+
if (range.end) {
|
|
6984
|
+
const operator = range.endExclusive ? "$lt" : "$lte";
|
|
6985
|
+
const end = range.end instanceof Date ? range.end : new Date(range.end);
|
|
6986
|
+
dateFilter[operator] = end;
|
|
6987
|
+
stringFilter[operator] = end.toISOString();
|
|
6988
|
+
}
|
|
6989
|
+
if (Object.keys(dateFilter).length === 0) {
|
|
6990
|
+
return null;
|
|
6991
|
+
}
|
|
6992
|
+
return {
|
|
6993
|
+
$or: [{ [field]: dateFilter }, { [field]: stringFilter }]
|
|
6994
|
+
};
|
|
6995
|
+
}
|
|
6879
6996
|
async createSpan(args) {
|
|
6880
6997
|
const { span } = args;
|
|
6881
6998
|
try {
|
|
6882
|
-
const startedAt = span.startedAt instanceof Date ? span.startedAt
|
|
6883
|
-
const endedAt = span.endedAt instanceof Date ? span.endedAt
|
|
6999
|
+
const startedAt = span.startedAt instanceof Date ? span.startedAt : new Date(span.startedAt);
|
|
7000
|
+
const endedAt = span.endedAt == null ? span.endedAt : span.endedAt instanceof Date ? span.endedAt : new Date(span.endedAt);
|
|
6884
7001
|
const record = {
|
|
6885
7002
|
...span,
|
|
6886
7003
|
startedAt,
|
|
6887
7004
|
endedAt,
|
|
6888
|
-
createdAt:
|
|
6889
|
-
updatedAt:
|
|
7005
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
7006
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
6890
7007
|
};
|
|
6891
7008
|
const collection = await this.getCollection(storage.TABLE_SPANS);
|
|
6892
7009
|
await collection.insertOne(record);
|
|
@@ -7021,15 +7138,15 @@ Note: This migration may take some time for large collections.
|
|
|
7021
7138
|
const { traceId, spanId, updates } = args;
|
|
7022
7139
|
try {
|
|
7023
7140
|
const data = { ...updates };
|
|
7024
|
-
if (data.endedAt instanceof Date) {
|
|
7025
|
-
data.endedAt = data.endedAt
|
|
7141
|
+
if (data.endedAt != null && !(data.endedAt instanceof Date)) {
|
|
7142
|
+
data.endedAt = new Date(data.endedAt);
|
|
7026
7143
|
}
|
|
7027
|
-
if (data.startedAt instanceof Date) {
|
|
7028
|
-
data.startedAt = data.startedAt
|
|
7144
|
+
if (data.startedAt != null && !(data.startedAt instanceof Date)) {
|
|
7145
|
+
data.startedAt = new Date(data.startedAt);
|
|
7029
7146
|
}
|
|
7030
7147
|
const updateData = {
|
|
7031
7148
|
...data,
|
|
7032
|
-
updatedAt:
|
|
7149
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7033
7150
|
};
|
|
7034
7151
|
const collection = await this.getCollection(storage.TABLE_SPANS);
|
|
7035
7152
|
await collection.updateOne({ spanId, traceId }, { $set: updateData });
|
|
@@ -7061,27 +7178,15 @@ Note: This migration may take some time for large collections.
|
|
|
7061
7178
|
const andConditions = [];
|
|
7062
7179
|
if (filters) {
|
|
7063
7180
|
if (filters.startedAt) {
|
|
7064
|
-
const
|
|
7065
|
-
if (
|
|
7066
|
-
|
|
7067
|
-
}
|
|
7068
|
-
if (filters.startedAt.end) {
|
|
7069
|
-
startedAtFilter.$lte = filters.startedAt.end.toISOString();
|
|
7070
|
-
}
|
|
7071
|
-
if (Object.keys(startedAtFilter).length > 0) {
|
|
7072
|
-
mongoFilter.startedAt = startedAtFilter;
|
|
7181
|
+
const startedAtCondition = this.createDateRangeCondition("startedAt", filters.startedAt);
|
|
7182
|
+
if (startedAtCondition) {
|
|
7183
|
+
andConditions.push(startedAtCondition);
|
|
7073
7184
|
}
|
|
7074
7185
|
}
|
|
7075
7186
|
if (filters.endedAt) {
|
|
7076
|
-
const
|
|
7077
|
-
if (
|
|
7078
|
-
|
|
7079
|
-
}
|
|
7080
|
-
if (filters.endedAt.end) {
|
|
7081
|
-
endedAtFilter.$lte = filters.endedAt.end.toISOString();
|
|
7082
|
-
}
|
|
7083
|
-
if (Object.keys(endedAtFilter).length > 0) {
|
|
7084
|
-
andConditions.push({ endedAt: endedAtFilter });
|
|
7187
|
+
const endedAtCondition = this.createDateRangeCondition("endedAt", filters.endedAt);
|
|
7188
|
+
if (endedAtCondition) {
|
|
7189
|
+
andConditions.push(endedAtCondition);
|
|
7085
7190
|
}
|
|
7086
7191
|
}
|
|
7087
7192
|
if (filters.spanType !== void 0) {
|
|
@@ -7289,14 +7394,14 @@ Note: This migration may take some time for large collections.
|
|
|
7289
7394
|
async batchCreateSpans(args) {
|
|
7290
7395
|
try {
|
|
7291
7396
|
const records = args.records.map((record) => {
|
|
7292
|
-
const startedAt = record.startedAt instanceof Date ? record.startedAt
|
|
7293
|
-
const endedAt = record.endedAt instanceof Date ? record.endedAt
|
|
7397
|
+
const startedAt = record.startedAt instanceof Date ? record.startedAt : new Date(record.startedAt);
|
|
7398
|
+
const endedAt = record.endedAt == null ? record.endedAt : record.endedAt instanceof Date ? record.endedAt : new Date(record.endedAt);
|
|
7294
7399
|
return {
|
|
7295
7400
|
...record,
|
|
7296
7401
|
startedAt,
|
|
7297
7402
|
endedAt,
|
|
7298
|
-
createdAt:
|
|
7299
|
-
updatedAt:
|
|
7403
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
7404
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7300
7405
|
};
|
|
7301
7406
|
});
|
|
7302
7407
|
if (records.length > 0) {
|
|
@@ -7321,15 +7426,15 @@ Note: This migration may take some time for large collections.
|
|
|
7321
7426
|
}
|
|
7322
7427
|
const bulkOps = args.records.map((record) => {
|
|
7323
7428
|
const data = { ...record.updates };
|
|
7324
|
-
if (data.endedAt instanceof Date) {
|
|
7325
|
-
data.endedAt = data.endedAt
|
|
7429
|
+
if (data.endedAt != null && !(data.endedAt instanceof Date)) {
|
|
7430
|
+
data.endedAt = new Date(data.endedAt);
|
|
7326
7431
|
}
|
|
7327
|
-
if (data.startedAt instanceof Date) {
|
|
7328
|
-
data.startedAt = data.startedAt
|
|
7432
|
+
if (data.startedAt != null && !(data.startedAt instanceof Date)) {
|
|
7433
|
+
data.startedAt = new Date(data.startedAt);
|
|
7329
7434
|
}
|
|
7330
7435
|
const updateData = {
|
|
7331
7436
|
...data,
|
|
7332
|
-
updatedAt:
|
|
7437
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7333
7438
|
};
|
|
7334
7439
|
return {
|
|
7335
7440
|
updateOne: {
|