Skip to content

Conversation

jcobis
Copy link
Collaborator

@jcobis jcobis commented Oct 8, 2025

Description

Implements the Preview Screen for the Mock Data Generator feature.

image

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

jcobis added 6 commits October 8, 2025 15:58
…or API

- Change 'sample_values' to 'sampleValues' in FieldInfo interface to match backend API expectations
- Update all test files to use the new field name
- Resolves 400 Bad Request error when generating faker mappings

The backend API expects 'sampleValues' (camelCase) but frontend was sending 'sample_values' (snake_case), causing the LLM request to fail with 'Invalid request' error.

Fixes CLOUDP-350280
…or API

- Change 'sample_values' to 'sampleValues' in FieldInfo interface to match backend API expectations
- Update all test files to use the new field name
- Resolves 400 Bad Request error when generating faker mappings

The backend API expects 'sampleValues' (camelCase) but frontend was sending 'sample_values' (snake_case), causing the LLM request to fail with 'Invalid request' error.

Fixes CLOUDP-350280
@jcobis jcobis changed the base branch from main to CLOUDP-350280-clean October 8, 2025 21:10
@jcobis jcobis added no release notes Fix or feature not for release notes feat labels Oct 8, 2025
@jcobis jcobis marked this pull request as ready for review October 8, 2025 21:30
@jcobis jcobis requested a review from a team as a code owner October 8, 2025 21:30
@jcobis jcobis requested review from ivandevp and kpamaran and removed request for a team October 8, 2025 21:30
expect(document).to.be.an('object');
expect(document).to.have.property('tags');
expect(document.tags).to.be.an('array').with.length(2);
(document.tags as string[]).forEach((tag: string) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit]: for (const tag of document.tags) makes it a bit more readable. Same at other places

// Default to 1.0 for invalid probability values
let probability = 1.0;
if (
mapping.probability !== undefined &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit]: we can remove this extra guard in favour of number check?

Comment on lines 615 to 629
if (probability < 1.0) {
// Use Math.random for conditional field inclusion
if (Math.random() < probability) {
const fakerValue = generateFakerValue(mapping);
if (fakerValue !== undefined) {
result[fieldName] = fakerValue;
}
}
} else {
// Normal field inclusion
const fakerValue = generateFakerValue(mapping);
if (fakerValue !== undefined) {
result[fieldName] = fakerValue;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This make it slightly more readable

Suggested change
if (probability < 1.0) {
// Use Math.random for conditional field inclusion
if (Math.random() < probability) {
const fakerValue = generateFakerValue(mapping);
if (fakerValue !== undefined) {
result[fieldName] = fakerValue;
}
}
} else {
// Normal field inclusion
const fakerValue = generateFakerValue(mapping);
if (fakerValue !== undefined) {
result[fieldName] = fakerValue;
}
}
const shouldIncludeField = probability >= 1.0 || Math.random() < probability;
const fakerValue = generateFakerValue(mapping);
if (fakerValue !== undefined && shouldIncludeField) {
result[fieldName] = fakerValue;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Comment on lines 683 to 712
try {
if ('mongoType' in elementType) {
// Array of primitives
const mapping = elementType as FakerFieldMapping;
const value = generateFakerValue(mapping);
if (value !== undefined) {
result.push(value);
}
} else if ('type' in elementType && elementType.type === 'array') {
// Nested array (e.g., matrix[][]) - append another [] to the path
const fieldPath = currentFieldPath + '[]';
const nestedArrayValue = constructArrayValues(
elementType as ArrayStructure,
fieldName,
arrayLengthMap,
fieldPath
);
result.push(nestedArrayValue);
} else {
// Array of objects
const objectValue = constructDocumentValues(
elementType as DocumentStructure,
arrayLengthMap,
currentFieldPath
);
result.push(objectValue);
}
} catch {
continue;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can not we reuse constructDocumentValues here to get the data for the array? Array eventually will be a list of scalar or nested array or document - which is all handled by constructDocumentValues?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into this, but to reuse constructDocumentValues, we'd have to wrap elements in a temporary structure like { element: elementType } and then also extract the result after calling. This creates extra object overhead, and we'd have to break it up by case anyway due to having to conditionally construct the temp structures

Copy link
Collaborator

@mabaasit mabaasit Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my comment was wrong as it mentioned to reuse constructDocumentValues. I actually meant everything else inside for ... of loop. I tried to clean it up a bit and tested it only with your test cases. If this feels good enough to you, feel free to add it or we can continue:

function computeValue(
  elementType: ArrayStructure | FakerFieldMapping | DocumentStructure,
  arrayLengthMap: ArrayLengthMap,
  currentPath: string,
) {
  try {
    if ('mongoType' in elementType) {
      // It's a field mapping
      const mapping = elementType as FakerFieldMapping;

      // Default to 1.0 for invalid probability values
      let probability = 1.0;
      if (
        typeof mapping.probability === 'number' &&
        mapping.probability >= 0 &&
        mapping.probability <= 1
      ) {
        probability = mapping.probability;
      }

      const shouldIncludeField =
        probability >= 1.0 || Math.random() < probability;
      if (shouldIncludeField) {
        return generateFakerValue(mapping);
      }
    } else if ('type' in elementType && elementType.type === 'array') {
      return constructArrayValues(
        elementType as ArrayStructure,
        arrayLengthMap,
        `${currentPath}[]`
      );
    } else {
      return constructDocumentValues(
        elementType as DocumentStructure,
        arrayLengthMap,
        currentPath
      );
    }
  } catch {
    //
  }
}

/**
 * Construct actual document values from document structure.
 * Mirrors renderDocumentCode but executes faker calls instead of generating code.
 */
function constructDocumentValues(
  structure: DocumentStructure,
  arrayLengthMap: ArrayLengthMap = {},
  currentPath: string = ''
) {
  const result: Document = {};
  for (const [fieldName, value] of Object.entries(structure)) {
    const newPath = currentPath ? `${currentPath}.${fieldName}` : fieldName;
    const val = computeValue(value, arrayLengthMap, newPath);
    if (val !== undefined) {
      result[fieldName] = val;
    }
  }
  return result;
}

/**
 * Construct array values from array structure.
 * Mirrors renderArrayCode but executes faker calls instead of generating code.
 */
function constructArrayValues(
  arrayStructure: ArrayStructure,
  arrayLengthMap: ArrayLengthMap,
  currentPath: string
) {
  const elementType = arrayStructure.elementType;

  // Get array length for this dimension
  let arrayLength = DEFAULT_ARRAY_LENGTH;
  if (arrayLengthMap[currentPath] !== undefined) {
    arrayLength = arrayLengthMap[currentPath];
  }
  const result: unknown[] = [];
  for (let i = 0; i < arrayLength; i++) {
    result.push(
      computeValue(elementType, arrayLengthMap, currentPath)
    );
  }
  return result;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, will do! Great recommendation, thank you!

Base automatically changed from CLOUDP-350280-clean to main October 9, 2025 15:25
@jcobis jcobis requested review from addaleax and mabaasit October 9, 2025 17:01
…godb-js/compass into mock-data-generator-preview-screen-2
@Copilot Copilot AI review requested due to automatic review settings October 9, 2025 17:44
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Implements the Preview Screen for the Mock Data Generator feature by updating schema field property naming and adding document generation capabilities.

  • Updated field property naming from sample_values to sampleValues for consistency with JavaScript naming conventions
  • Implemented document generation functionality with generateDocument function and related utilities
  • Added PreviewScreen component to display sample generated documents

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
transform-schema-to-field-info.ts Updated property name from sample_values to sampleValues
transform-schema-to-field-info.spec.ts Updated test expectations to use sampleValues property
schema-analysis-types.ts Updated type definition and documentation to use sampleValues
to-simplified-field-info.spec.ts Updated test data to use sampleValues property
script-generation-utils.ts Added document generation functions and faker execution utilities
script-generation-utils.spec.ts Added comprehensive tests for document generation functionality
preview-screen.tsx New component that displays generated sample documents
mock-data-generator-modal.tsx Integrated PreviewScreen component into modal workflow
mock-data-generator-modal.spec.tsx Updated test data to use sampleValues property
collection-header.spec.tsx Updated test data to use sampleValues property

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@jcobis jcobis requested a review from kpamaran October 9, 2025 17:47
@jcobis jcobis changed the title feat(compass-collection): Preview Screen for Mock Data Generator – CLOUDP-333857 feat(compass-collection): Preview Screen for Mock Data Generator CLOUDP-333857 Oct 9, 2025
@jcobis jcobis changed the title feat(compass-collection): Preview Screen for Mock Data Generator CLOUDP-333857 feat(compass-collection): Preview Screen for Mock Data Generator CLOUDP-333857 Oct 14, 2025
@jcobis jcobis merged commit d57efe3 into main Oct 14, 2025
54 of 55 checks passed
@jcobis jcobis deleted the mock-data-generator-preview-screen-2 branch October 14, 2025 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat no release notes Fix or feature not for release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants