Skip to content

feat:split bundle and update schema#30

Merged
hexqi merged 4 commits intomainfrom
feat/splitBundle
Apr 29, 2025
Merged

feat:split bundle and update schema#30
hexqi merged 4 commits intomainfrom
feat/splitBundle

Conversation

@zhangjuncao
Copy link
Collaborator

@zhangjuncao zhangjuncao commented Apr 15, 2025

English | 简体中文

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • Built its own designer, fully self-validated

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Background and solution

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Introduced management of component libraries, including creating, updating, deleting, and listing component libraries within the material center.
    • Added the ability to upload and process component bundle files, automatically splitting them into components and packages and updating the component library accordingly.
    • Exposed new API endpoints for component library CRUD operations and bundle uploads.
    • Added material and material history management features with support for querying and updating records.
  • Enhancements

    • Integrated component library package details into app schema data retrieval, making package information accessible via schema APIs.

@coderabbitai
Copy link

coderabbitai bot commented Apr 15, 2025

Walkthrough

This update introduces new controller and service classes to manage component libraries and user components within the material center module. It adds CRUD operations for component libraries, including endpoints and service logic for creating, finding, updating, and deleting entries. For user components, a new controller and service enable the uploading and processing of component bundle files, parsing their contents, and managing related component and package data. The router is updated to register the new endpoints. Additionally, the app schema service is extended to include component library data and package extraction for broader schema management. New services for materials and material histories are also added, providing CRUD operations for these entities.

Changes

File(s) Change Summary
app/controller/material-center/ComponentLibrary.ts Added ComponentController class with async CRUD methods (create, find, update, delete) for managing component libraries via HTTP routes, using Egg.js context and service delegation.
app/controller/material-center/UserComponents.ts Added UserComponentController class with async bundleCreate method for handling component bundle uploads, delegating processing to the service, and including error handling and logging.
app/router/materialCenter/base.ts Registered new API routes for component library CRUD operations and user component bundle creation, mapping them to the appropriate controller methods.
app/service/material-center/ComponentLibrary.ts Introduced ComponentLibrary service class extending DataService, implementing async methods for CRUD operations (create, find, list, update, delete) on the "component-library" resource, handling HTTP requests and URL construction.
app/service/material-center/UserComponents.ts Added UserComponent service class with utilities for string formatting, file stream validation and parsing, bundle splitting, and bulk component creation/updating. Implements logic for processing uploaded bundle files and managing related components and packages.
app/service/app-center/appSchema.ts Extended AppSchema service: added getPackages method, updated setMeta to fetch and store component library data, and included package extraction from component libraries for schema data retrieval.
app/service/material-center/Material.ts Added Material service class extending DataService with async methods for updating and finding materials.
app/service/material-center/MaterialHistories.ts Added MaterialHistories service class extending DataService with async methods for creating, updating, and finding material history records.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Router
    participant ComponentController
    participant ComponentLibraryService

    Client->>Router: POST /component-library
    Router->>ComponentController: create()
    ComponentController->>ComponentLibraryService: create(param)
    ComponentLibraryService-->>ComponentController: result
    ComponentController-->>Client: response

    Client->>Router: GET /component-library
    Router->>ComponentController: find()
    ComponentController->>ComponentLibraryService: find(query)
    ComponentLibraryService-->>ComponentController: result
    ComponentController-->>Client: response

    Client->>Router: PUT /component-library/:id
    Router->>ComponentController: update()
    ComponentController->>ComponentLibraryService: update(param)
    ComponentLibraryService-->>ComponentController: result
    ComponentController-->>Client: response

    Client->>Router: DELETE /component-library/:id
    Router->>ComponentController: delete()
    ComponentController->>ComponentLibraryService: delete({id})
    ComponentLibraryService-->>ComponentController: result
    ComponentController-->>Client: response
Loading
sequenceDiagram
    participant Client
    participant Router
    participant UserComponentController
    participant UserComponentService
    participant ComponentLibraryService

    Client->>Router: POST /component/bundle/create (file upload)
    Router->>UserComponentController: bundleCreate()
    UserComponentController->>UserComponentService: bundleCreate(fileStream)
    UserComponentService->>UserComponentService: validateFileStream(fileStream)
    UserComponentService->>UserComponentService: parseJsonFileStream(fileStream)
    UserComponentService->>UserComponentService: splitMaterials(bundle)
    UserComponentService->>ComponentLibraryService: create/update component libraries
    UserComponentService->>UserComponentService: bulkComponentCreate(components)
    UserComponentService-->>UserComponentController: result
    UserComponentController-->>Client: response
Loading

Poem

In the warren of code, new features appear,
Controllers and services, all hopping near.
Bundles are split, components take flight,
CRUD hops along, everything’s right.
With routes now extended, our center’s robust—
A carrot for progress, in CodeRabbit we trust!
🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3438ee2 and 66aba2b.

📒 Files selected for processing (2)
  • app/service/material-center/Material.ts (1 hunks)
  • app/service/material-center/MaterialHistories.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/service/material-center/MaterialHistories.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/service/material-center/Material.ts
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

Seems you are using me but didn't get OPENAI_API_KEY seted in Variables/Secrets for this repo. you could follow readme for more information

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (7)
app/service/material-center/ComponentLibrary.ts (3)

27-32: Add type definition for find method parameter.

The find method parameter is untyped. Adding a proper type definition would improve type safety and code maintainability.

-  async find(param){
+  async find(param: Record<string, any>){
     const query = qs.stringify(param);
     return this.query({
       url: `component-library?${query}`
     });
   }

38-45: Add type definition for update method parameter.

Similar to the find method, the update method parameter should have a proper type definition.

-  async update(param) {
+  async update(param: { id: string | number; [key: string]: any }) {
     const { id } = param;
     return this.query({
       url: `component-library/${id}`,
       method: E_Method.Put,
       data: param
     });
   }

47-52: Make delete method async and add return type.

The delete method is not marked as async, unlike other methods in this class, but it returns a Promise. This inconsistency should be fixed for better code maintenance.

-  delete({ id }){
+  async delete({ id }: { id: string | number }) {
     return this.query({
       url: `component-library/${id}`,
       method: E_Method.Delete
     });
   }
app/service/material-center/UserComponents.ts (4)

82-132: Review concurrency strategy when creating or updating components in bulk.
Using Promise.all is correct here, but consider whether partial failures might leave data in an inconsistent state. You could handle errors more gracefully by rolling back changes or logging detailed error info on failure.

🧰 Tools
🪛 Biome (1.9.4)

[error] 102-106: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


102-106: Use optional chaining to simplify logic.
You can reduce conditional checks by using something like:

- if (component.npm && component.npm.package) {
-   packageName = component.npm.package;
- }
+ packageName = component.npm?.package || '';

This improves readability and consistency with modern JavaScript features.

🧰 Tools
🪛 Biome (1.9.4)

[error] 102-106: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


219-236: Enhance error reporting in parseJsonFileStream.
Though this method properly disposes of the file stream on error, you can add more descriptive messages or logs to help debug parses that fail mid-stream. Logging additional context (e.g., stack traces) can be invaluable.


244-253: Expand file stream validations to check file size limits and encoding.
Currently you only validate MIME type. Large or corrupted files could still cause issues. Consider implementing size limits and verifying character encoding to strengthen security.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cce0e5b and d3fead9.

📒 Files selected for processing (6)
  • app/controller/material-center/ComponentLibrary.ts (1 hunks)
  • app/controller/material-center/UserComponents.ts (1 hunks)
  • app/router/materialCenter/base.ts (1 hunks)
  • app/service/app-center/appSchema.ts (2 hunks)
  • app/service/material-center/ComponentLibrary.ts (1 hunks)
  • app/service/material-center/UserComponents.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
app/service/material-center/ComponentLibrary.ts (2)
app/lib/interface.ts (1)
  • I_CreateComponentLibrary (446-461)
app/service/dataService.ts (1)
  • query (42-75)
app/controller/material-center/ComponentLibrary.ts (1)
app/lib/interface.ts (1)
  • I_CreateComponentLibrary (446-461)
app/service/material-center/UserComponents.ts (3)
app/lib/interface.ts (1)
  • I_Response (37-42)
app/service/dataService.ts (1)
  • query (42-75)
app/lib/ApiError.ts (1)
  • throwApiError (31-33)
🪛 Biome (1.9.4)
app/service/material-center/UserComponents.ts

[error] 102-106: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 177-177: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🔇 Additional comments (1)
app/service/material-center/UserComponents.ts (1)

177-183: Ensure snippet items exist before accessing their nested properties.
While you're already preventing most errors with if (!Array.isArray(snippetItem?.children)) { return }, confirm that snippetItem is never undefined before using snippetItem?.children. This helps avoid edge cases in future refactors.

🧰 Tools
🪛 Biome (1.9.4)

[error] 177-177: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

@github-actions
Copy link

Seems you are using me but didn't get OPENAI_API_KEY seted in Variables/Secrets for this repo. you could follow readme for more information

@github-actions
Copy link

Seems you are using me but didn't get OPENAI_API_KEY seted in Variables/Secrets for this repo. you could follow readme for more information

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (11)
app/service/material-center/Material.ts (2)

25-27: Use the base property in URL construction for consistency.

The update method hardcodes the URL segment 'materials' despite having a class property base defined for this purpose. Using the base property would make the code more maintainable.

return this.query({
-  url: `materials/${id}`,
+  url: `${this.base}/${id}`,
  method: E_Method.Put,
  data: param
});

16-40: Implement additional CRUD operations for completeness.

This service only implements update and find operations but lacks create and delete operations that are typically needed for a complete data service. Consider adding these methods for consistency with other services.

async create(param: MaterialParam): Promise<I_Response> {
  return this.fQuery({
    url: this.base,
    method: E_Method.Post,
    data: param
  });
}

async delete(id: string | number): Promise<I_Response> {
  return this.query({
    url: `${this.base}/${id}`,
    method: E_Method.Delete
  });
}
app/service/material-center/MaterialHistories.ts (3)

24-25: Use the base property in URL construction.

The create method hardcodes the URL segment 'material-histories' despite having a class property base defined for this purpose. Use the base property for better maintainability.

return this.fQuery({
-  url: 'material-histories',
+  url: this.base,
  method: E_Method.Post,
  data: param
}); 

33-35: Use the base property in update method URL.

Similar to the create method, the update method also hardcodes the URL segment 'material-histories' instead of using the base property.

return this.query({
-  url: `material-histories/${id}`,
+  url: `${this.base}/${id}`,
  method: E_Method.Put,
  data: param
});

16-48: Implement delete operation for completeness.

The service implements create, update, and find operations but lacks the delete operation. Consider adding this method for completeness and consistency with RESTful patterns.

async delete(id: string | number): Promise<I_Response> {
  return this.query({
    url: `${this.base}/${id}`,
    method: E_Method.Delete
  });
}
app/service/material-center/UserComponents.ts (6)

58-60: Translate Chinese comments to English.

Non-English comments in the codebase should be translated for consistency and to improve readability for all team members.

- // 查询是否存在组件库
+ // Check if the component library exists

155-157: Use consistent URL construction in all methods.

The update method uses template literals with the base property, while other methods use different approaches. Standardize the URL construction for better maintainability.

return this.fQuery({
-  url: `${this.base}/${id}`,
+  url: `${this.base}/${id}`, // Already correct, just ensure this pattern is used consistently
  method: E_Method.Put,
  data: param
});

101-106: Use optional chaining for nested property access.

Accessing nested properties without optional chaining can lead to runtime errors. The static analysis tool suggests using optional chaining here.

- if (component.npm && component.npm.package) {
-   packageName = component.npm.package;
+ if (component.npm?.package) {
+   packageName = component.npm.package;
🧰 Tools
🪛 Biome (1.9.4)

[error] 102-106: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


82-84: Use proper TypeScript typing for variables.

The variable componentLibraryListResult is explicitly typed as any, which defeats TypeScript's type safety. Use a more specific type instead.

- let componentLibraryListResult: any = [];
+ let componentLibraryListResult: I_Response[] = [];

211-215: Simplify complex conditional expression.

The ternary operation inside another ternary makes the code harder to read. Consider simplifying this to improve readability.

- const matchKey = Array.isArray(comp.component) 
-   ? this.toPascalCase(comp.component[0])
-   : this.toPascalCase(comp.component)
+ let componentName = comp.component;
+ if (Array.isArray(componentName)) {
+   componentName = componentName[0];
+ } else if (typeof componentName !== 'string') {
+   componentName = '';
+ }
+ const matchKey = this.toPascalCase(componentName);

51-78: Add documentation for the bundleCreate method.

This complex method lacks documentation explaining its purpose, parameters, and return value. Add JSDoc comments to improve code readability and maintainability.

+ /**
+  * Creates and updates component libraries and components from a bundle file
+  * @param {ReadStream} fileStream - The file stream containing the component bundle
+  * @returns {Promise<I_Response>} Response with information about created/updated components
+  */
async bundleCreate (fileStream) {
  // ...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 82ee4ae and 3438ee2.

📒 Files selected for processing (3)
  • app/service/material-center/Material.ts (1 hunks)
  • app/service/material-center/MaterialHistories.ts (1 hunks)
  • app/service/material-center/UserComponents.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/service/material-center/MaterialHistories.ts (1)
app/service/dataService.ts (1)
  • query (42-75)
🪛 Biome (1.9.4)
app/service/material-center/UserComponents.ts

[error] 102-106: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 188-188: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🔇 Additional comments (3)
app/service/material-center/Material.ts (1)

23-38: Inconsistent use of query methods.

This class uses this.query for the update method but this.fQuery for the find method without clear reasoning. This inconsistency could lead to different behaviors between methods.

Please verify the difference between query and fQuery methods in the parent class and ensure they're being used appropriately for each operation.

app/service/material-center/MaterialHistories.ts (1)

23-39: Inconsistent use of query methods.

Different HTTP methods use different query functions (this.query vs this.fQuery) without apparent reason. This inconsistency could lead to different behaviors or error handling across methods.

Verify that the parent DataService class provides different behaviors for query and fQuery methods and ensure they're being used correctly.

app/service/material-center/UserComponents.ts (1)

187-188: ⚠️ Potential issue

Fix unsafe optional chaining usage.

The static analysis tool has flagged potential unsafe optional chaining on line 188. If snippets is null, the optional chaining will short-circuit, but the .forEach() method would still be called on undefined, causing a TypeError.

- if(snippets != null && snippets.length != 0){
-   snippets.forEach((snippetItem) => {
+ if(snippets && Array.isArray(snippets) && snippets.length !== 0){
+   snippets.forEach((snippetItem) => {

Likely an incorrect or invalid review comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 188-188: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

@github-actions
Copy link

Seems you are using me but didn't get OPENAI_API_KEY seted in Variables/Secrets for this repo. you could follow readme for more information

@hexqi hexqi merged commit 50d2c6b into main Apr 29, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments