()
| 642 | Effect.annotateCurrentSpan({ |
| 643 | "app.query.ttype": a.ttype, |
| 644 | "app.query.mode": a.mode, |
| 645 | "db.response.returned_rows": Array.isArray(r) ? r.length : 1 |
| 646 | }) |
| 647 | ), |
| 648 | Effect.tap(() => recordQueryRead), |
| 649 | Effect.withSpan("Repository.query", { |
| 650 | kind: "client", |
| 651 | attributes: { "app.entity": name } |
| 652 | }, { captureStackTrace: false }) |
| 653 | ) |
| 654 | }) as any |
| 655 | |
| 656 | const validateSample = Effect.fn("Repository.validateSample", { attributes: { "app.entity": name } })( |
| 657 | function*(options?: { |
| 658 | percentage?: number |
| 659 | maxItems?: number |
| 660 | }) { |
| 661 | const percentage = options?.percentage ?? 0.1 // default 10% |
| 662 | const maxItems = options?.maxItems |
| 663 | |
| 664 | // 1. get all IDs with projection (bypasses main schema decode) |
| 665 | const allIds = yield* store |
| 666 | .filter({ |
| 667 | t: null as unknown as Encoded, |
| 668 | select: [idKey as keyof Encoded] |
| 669 | }) |
| 670 | .pipe(Effect.withSpan("Repository.filter", { |
| 671 | kind: "client", |
| 672 | attributes: { "app.entity": name } |
| 673 | }, { captureStackTrace: false })) |
| 674 | |
| 675 | // 2. random subset |
| 676 | const shuffled = [...allIds].sort(() => Math.random() - 0.5) |
| 677 | const sampleSize = Math.min( |
| 678 | maxItems ?? Infinity, |
| 679 | Math.ceil(allIds.length * percentage) |
| 680 | ) |
| 681 | const sample = shuffled.slice(0, sampleSize) |
| 682 | |
| 683 | // 3. validate each item |
| 684 | const errors: ValidationError[] = [] |
| 685 | |
| 686 | for (const item of sample) { |
| 687 | const id = item[idKey] |
| 688 | const rawResult = yield* store.find(id).pipe( |
| 689 | Effect.withSpan("Repository.find", { |
| 690 | kind: "client", |
| 691 | attributes: { "app.entity": name, "app.entity.id": id } |
| 692 | }, { captureStackTrace: false }) |
| 693 | ) |
| 694 | |
| 695 | if (Option.isNone(rawResult)) continue |
| 696 | |
| 697 | const rawData = rawResult.value as Encoded |
| 698 | const jitMResult = mapFrom(rawData) // apply jitM |
| 699 | |
| 700 | const decodeResult = yield* S.decodeEffectConcurrently(schema)(jitMResult).pipe( |
| 701 | Effect.result, |
no test coverage detected
searching dependent graphs…