Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { ModelProvider } from 'src/common/model-provider';
import { prompts } from './prompt';

export class FileStructureHandler implements BuildHandler {

readonly id = 'op:FSTRUCT::STATE:GENERATE';

async run(context: BuilderContext, args: unknown): Promise<BuildResult> {
Expand Down
98 changes: 96 additions & 2 deletions backend/src/build-system/node/ux-sitemap-structure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ import { BuildHandler, BuildResult } from 'src/build-system/types';
import { BuilderContext } from 'src/build-system/context';
import { ModelProvider } from 'src/common/model-provider';
import { prompts } from './prompt';
import { Logger } from '@nestjs/common';

// UXSMS: UX Sitemap Structure
export class UXSitemapStructureHandler implements BuildHandler {
readonly id = 'op:UXSMS::STATE:GENERATE';
readonly logger = new Logger('UXSitemapStructureHandler');

async run(context: BuilderContext, args: unknown): Promise<BuildResult> {
console.log('Generating UX Structure Document...');
this.logger.log('Generating UX Structure Document...');

// extract relevant data from the context
const projectName =
context.getData('projectName') || 'Default Project Name';

const prompt = prompts.generateUXDataMapPrompt(
const prompt = prompts.generateUXSiteMapStructrePrompt(
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the typo in method names: 'Structre' should be 'Structure'

The method names generateUXSiteMapStructrePrompt and generateLevel2UXSiteMapStructrePrompt contain a typo. "Structre" should be "Structure". Please correct the method names to prevent any potential issues.

Apply this diff to fix the method names:

// At line 19
-     const prompt = prompts.generateUXSiteMapStructrePrompt(
+     const prompt = prompts.generateUXSiteMapStructurePrompt(

// At line 77
-       const prompt = prompts.generateLevel2UXSiteMapStructrePrompt(
+       const prompt = prompts.generateLevel2UXSiteMapStructurePrompt(

Also applies to: 77-77

projectName,
args as string,
// TODO: change later
Expand All @@ -33,3 +35,95 @@ export class UXSitemapStructureHandler implements BuildHandler {
};
}
}

export class Level2UXSitemapStructureHandler implements BuildHandler {
readonly id = 'op:LEVEL2_UXSMS::STATE:GENERATE';
readonly logger = new Logger('Level2UXSitemapStructureHandler');

async run(context: BuilderContext, args: unknown): Promise<BuildResult> {
this.logger.log('Generating Level 2 UX Sitemap Structure Document...');

// Extract necessary data from the context
const { projectName, sitemapDoc, uxStructureDoc } = args as {
projectName: string;
sitemapDoc: string;
uxStructureDoc: string;
};

// Ensure the UX Structure Document exists
if (!projectName || !sitemapDoc || !uxStructureDoc) {
throw new Error(
'Missing required arguments: projectName, sitemapDoc, or uxStructureDoc.',
);
}

// Extract sections from the UX Structure Document
const sections = this.extractAllSections(uxStructureDoc);
if (sections.length === 0) {
this.logger.error(
'No valid sections found in the UX Structure Document.',
);
return {
success: false,
data: 'No valid sections found in the UX Structure Document.',
};
}

// Process each section with the refined Level 2 prompt
const modelProvider = ModelProvider.getInstance();
const refinedSections = [];

for (const section of sections) {
const prompt = prompts.generateLevel2UXSiteMapStructrePrompt(
projectName,
section.content,
sitemapDoc,
'web', // TODO: Replace with dynamic platform if necessary
);

// Generate refined UX Structure content
const refinedContent = await modelProvider.chatSync(
{ content: prompt },
'gpt-4o-mini',
);

refinedSections.push({
title: section.title,
content: refinedContent,
});
}

// Combine the refined sections into the final document
const refinedDocument = refinedSections
.map((section) => `## **${section.title}**\n${section.content}`)
.join('\n\n');

this.logger.log(refinedDocument);

return {
success: true,
data: refinedDocument,
};
}

/**
* Extracts all sections from a given text.
* @param text The UX Structure Document content.
* @returns Array of extracted sections with title and content.
*/
private extractAllSections(
text: string,
): Array<{ title: string; content: string }> {
const regex = /## \*\*(\d+\.\s.*)\*\*([\s\S]*?)(?=\n## \*\*|$)/g;
const sections = [];
let match;

while ((match = regex.exec(text)) !== null) {
const title = match[1].trim();
const content = match[2].trim();
sections.push({ title, content });
}
Comment on lines +121 to +125
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor to avoid assignment within the while loop condition

Assigning within the while loop condition can lead to less readable code and is generally discouraged. Refactor the loop to improve clarity and maintainability.

Apply this diff to fix the issue:

      let match;

-     while ((match = regex.exec(text)) !== null) {
+     match = regex.exec(text);
+     while (match !== null) {
        const title = match[1].trim();
        const content = match[2].trim();
        sections.push({ title, content });
+       match = regex.exec(text);
      }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while ((match = regex.exec(text)) !== null) {
const title = match[1].trim();
const content = match[2].trim();
sections.push({ title, content });
}
let match;
match = regex.exec(text);
while (match !== null) {
const title = match[1].trim();
const content = match[2].trim();
sections.push({ title, content });
match = regex.exec(text);
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 121-121: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


return sections;
}
}
71 changes: 70 additions & 1 deletion backend/src/build-system/node/ux-sitemap-structure/prompt.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const prompts = {
generateUXDataMapPrompt: (
generateUXSiteMapStructrePrompt: (
projectName: string,
sitemapDoc: string,
platform: string,
Expand Down Expand Up @@ -55,6 +55,75 @@ export const prompts = {
2. What information needs to be displayed and why
3. How the element supports user goals

Make sure is 100% completed. It will be directly be use in development.
`;
},
generateLevel2UXSiteMapStructrePrompt: (
projectName: string,
UXStructure: string,
sitemapDoc: string,
platform: string,
): string => {
Comment on lines +61 to +66
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typo in second method name: "Structre" should be "Structure"

The same typo appears in the second method name.

-  generateLevel2UXSiteMapStructrePrompt: (
+  generateLevel2UXSiteMapStructurePrompt: (
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
generateLevel2UXSiteMapStructrePrompt: (
projectName: string,
UXStructure: string,
sitemapDoc: string,
platform: string,
): string => {
generateLevel2UXSiteMapStructurePrompt: (
projectName: string,
UXStructure: string,
sitemapDoc: string,
platform: string,
): string => {

return `You are an expert UX Designer.
Your task is to analyze and improve a specific part of a page in the provided UX Structure Document.
The goal is to refine the design, layout, and interaction to ensure a seamless user experience and facilitate frontend implementation.
The output should address all aspects of user interaction, content layout, based on the following inputs:

- Project name: ${projectName}
- Sitemap Documentation: ${sitemapDoc}
- UX Structure document: ${UXStructure}
- Platform: ${platform}

Follow these guidelines to analyze requirements from a UX perspective:

### Instructions and Rules:

1, Analyze the Target Section:
Focus on the specific part of the page provided in the UX Structure document.
Identify ways to enhance its layout, interactions, and functionality.
2, Improve UX Details:
Add clarity to component placement and hierarchy.
Specify interactions, behaviors, and dynamic content updates.
Ensure the section aligns with user goals and their journey.
3, You need to identify and define every page/screen required for the application.
4, Detailed Breakdown for Each Page/Screen:
Page Purpose: Clearly state the user goal for the page.
Core Elements:
List all components (e.g., headers, buttons, sidebars) and explain their role on the page.
Include specific interactions and behaviors for each element.
Content Display:
Identify the information that needs to be visible on the page and why it’s essential for the user.
Navigation and Routes:
Specify all frontend routes required to navigate to this page.
Include links or actions that lead to other pages or states.
Restrictions:
Note any restrictions or conditions for accessing the page (e.g., login required, specific user roles).

5, Focus on Detail:
Provide a component-level breakdown for each page, including layouts.
Explain how the design supports user goals and aligns with their journey.

6. For each page/screen in the sitemap:
- How the block should be place on the view?
- What information does the user need to see?
- What elements should be on the page?
- What are all the routes require for the frontend?
- What dynamic content needs to be displayed?
- What are the restriction for the page?

7. Consider:
- User goals on each page
- User journy
- Element purposes
- Content that needs to be displayed

Your reply must start with: "\`\`\`UXStructureMap" and end with "\`\`\`".

Focus on describing the UX Structure from a user experience perspective. For each page:
1. What element appear on each page and why
2. What information needs to be displayed and why
3. How the element supports user goals

Comment on lines +67 to +126
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Reduce duplication by extracting common prompt content

There's significant duplication between the two prompt templates. The only unique content is in the initial section (points 1-2). Consider extracting the common content into a shared template.

Create a shared template function:

const getCommonUXPromptTemplate = () => `
  ### Instructions and Rules:

  4. Detailed Breakdown for Each Page/Screen:
    Page Purpose: ...
    [rest of common content]
`;

const prompts = {
  generateUXSiteMapStructurePrompt: (projectName: string, sitemapDoc: string, platform: string): string => {
    return `You are an expert UX Designer...
    ${getCommonUXPromptTemplate()}
    `;
  },
  
  generateLevel2UXSiteMapStructurePrompt: (projectName: string, UXStructure: string, sitemapDoc: string, platform: string): string => {
    return `You are an expert UX Designer...
    [Level 2 specific content]
    ${getCommonUXPromptTemplate()}
    `;
  }
};

This will:

  1. Reduce code duplication
  2. Make maintenance easier
  3. Ensure consistency between prompts

Make sure is 100% completed. It will be directly be use in development.
`;
},
Expand Down