Skip to content

851: Move leetcode enum to pretty name lookup to backend type generator#869

Open
angelayu0530 wants to merge 3 commits intomainfrom
851
Open

851: Move leetcode enum to pretty name lookup to backend type generator#869
angelayu0530 wants to merge 3 commits intomainfrom
851

Conversation

@angelayu0530
Copy link
Collaborator

@angelayu0530 angelayu0530 commented Mar 19, 2026

851

Description of changes

  • moved enum to rpetty name look up to use backend type generator
  • changed the front implemention to use this

Checklist before review

  • I have done a thorough self-review of the PR
  • Copilot has reviewed my latest changes, and all comments have been fixed and/or closed.
  • If I have made database changes, I have made sure I followed all the db repo rules listed in the wiki here. (check if no db changes)
  • All tests have passed
  • I have successfully deployed this PR to staging
  • I have done manual QA in both dev (and staging if possible) and attached screenshots below.

Screenshots

Dev

https://github.com/user-attachments/assets/e4f9cd77-b09d-4dfa-8554-06e18d3ec2ea
Screenshot 2026-03-19 at 12 16 03 PM
Screenshot 2026-03-19 at 12 15 58 PM

Staging

Screen.Recording.2026-03-19.at.1.45.50.PM.mov

@github-actions
Copy link
Contributor

Available PR Commands

  • /ai - Triggers all AI review commands at once
  • /review - AI review of the PR changes
  • /describe - AI-powered description of the PR
  • /improve - AI-powered suggestions
  • /deploy - Deploy to staging

See: https://github.com/tahminator/codebloom/wiki/CI-Commands

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement, Refactoring


Description

  • Backend now generates Leetcode topic metadata.

  • Introduced new Java TopicMetadataObject and TopicMetadataList.

  • ComplexJSTypesGenerator supports enum-to-object serialization.

  • Frontend topic/index.ts removed, uses generated types.


Diagram Walkthrough

flowchart LR
  A[TopicMetadataObject.java]
  B[TopicMetadataList.java]
  C[ComplexJSTypesGenerator.java]
  D[js/src/lib/api/types/complex.ts (Generated)]
  E[js/src/lib/api/utils/index.ts]
  F[js/src/lib/api/utils/types.ts]
  G[js/src/lib/api/utils/metadata/topic/index.ts (Removed)]

  A & B -- "Define topic metadata" --> C
  C -- "Generates TypeScript" --> D
  D -- "Imports generated types" --> E
  D -- "Imports generated types" --> F
  G -- "Replaced by generated types" --> D
Loading

File Walkthrough

Relevant files
New feature
2 files
TopicMetadataList.java
Adds static map for Leetcode topic metadata.                         
+164/-0 
TopicMetadataObject.java
Introduces Java model for Leetcode topic metadata.             
+14/-0   
Code generation
1 files
ComplexJSTypesGenerator.java
Updates generator to create TypeScript for topic metadata objects.
+88/-2   
Configuration
2 files
DataShape.java
Adds new data shape for enum-to-object serialization.       
+3/-0     
Generator.java
Adds `objectClass` field for specifying generated TypeScript type.
+3/-0     
Refactoring
1 files
index.ts
Updates import path for `TOPIC_METADATA_LIST` to generated file.
+4/-2     
Code removal
1 files
index.ts
Removes manual definition of Leetcode topic metadata.       
+0/-87   
Type definition
1 files
types.ts
Updates QuestionTopicTopicMetadata to use generated
TopicMetadataObject.
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Lombok Annotations

The TopicMetadataObject class is missing required Lombok annotations such as @ToString, @EqualsAndHashCode, and @Jacksonized as per the "Database Repository Best Practices" section in the style guide. While @Setter is correctly omitted for immutable fields, the other annotations are still necessary for consistency and functionality.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
    private final String name;
    private final List<String> aliases;
}
Missing Javadoc

The TopicMetadataList class and its methods (generate, buildMetadata) lack Javadoc comments. Adding Javadoc would improve code clarity and maintainability, especially for a utility class that defines a core lookup mechanism, as suggested in the "Documentation" section of the style guide.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TopicMetadataList {
    public static final Map<LeetcodeTopicEnum, TopicMetadataObject> ENUM_TO_TOPIC_METADATA = generate();

    private static Map<LeetcodeTopicEnum, TopicMetadataObject> generate() {
        return Arrays.stream(LeetcodeTopicEnum.values())
                .collect(Collectors.toMap(
                        topic -> topic, TopicMetadataList::buildMetadata, (a, b) -> a, LinkedHashMap::new));
    }

    private static TopicMetadataObject buildMetadata(LeetcodeTopicEnum topic) {
        return switch (topic) {
            case STACK -> TopicMetadataObject.builder().name("Stack").build();
            case DATA_STREAM ->
                TopicMetadataObject.builder().name("Data Stream").build();
            case REJECTION_SAMPLING ->
                TopicMetadataObject.builder().name("Rejection Sampling").build();
            case GEOMETRY -> TopicMetadataObject.builder().name("Geometry").build();
            case COUNTING -> TopicMetadataObject.builder().name("Counting").build();
            case DESIGN -> TopicMetadataObject.builder().name("Design").build();
            case PROBABILITY_AND_STATISTICS ->
                TopicMetadataObject.builder().name("Probability and Statistics").build();
            case MINIMUM_SPANNING_TREE ->
                TopicMetadataObject.builder()
                        .name("Minimum Spanning Tree")
                        .aliases(List.of("MST"))
                        .build();
            case LINE_SWEEP -> TopicMetadataObject.builder().name("Line Sweep").build();
            case NUMBER_THEORY ->
                TopicMetadataObject.builder().name("Number Theory").build();
            case ROLLING_HASH ->
                TopicMetadataObject.builder().name("Rolling Hash").build();
            case SEGMENT_TREE ->
                TopicMetadataObject.builder().name("Segment Tree").build();
            case BICONNECTED_COMPONENT ->
                TopicMetadataObject.builder().name("Biconnected Component").build();
            case MONOTONIC_STACK ->
                TopicMetadataObject.builder().name("Monotonic Stack").build();
            case ITERATOR -> TopicMetadataObject.builder().name("Iterator").build();
            case QUEUE -> TopicMetadataObject.builder().name("Queue").build();
            case RADIX_SORT -> TopicMetadataObject.builder().name("Radix Sort").build();
            case BUCKET_SORT ->
                TopicMetadataObject.builder().name("Bucket Sort").build();
            case SHELL -> TopicMetadataObject.builder().name("Shell Sort").build();
            case MEMOIZATION ->
                TopicMetadataObject.builder().name("Memoization").build();
            case STRING -> TopicMetadataObject.builder().name("String").build();
            case PREFIX_SUM -> TopicMetadataObject.builder().name("Prefix Sum").build();
            case CONCURRENCY ->
                TopicMetadataObject.builder().name("Concurrency").build();
            case DATABASE ->
                TopicMetadataObject.builder()
                        .name("Database")
                        .aliases(List.of("DB"))
                        .build();
            case SHORTEST_PATH ->
                TopicMetadataObject.builder().name("Shortest Path").build();
            case SORTING -> TopicMetadataObject.builder().name("Sorting").build();
            case LINKED_LIST ->
                TopicMetadataObject.builder().name("Linked List").build();
            case SLIDING_WINDOW ->
                TopicMetadataObject.builder().name("Sliding Window").build();
            case SUFFIX_ARRAY ->
                TopicMetadataObject.builder().name("Suffix Array").build();
            case DOUBLY_LINKED_LIST ->
                TopicMetadataObject.builder().name("Doubly Linked List").build();
            case SIMULATION -> TopicMetadataObject.builder().name("Simulation").build();
            case ORDERED_SET ->
                TopicMetadataObject.builder().name("Ordered Set").build();
            case GRAPH -> TopicMetadataObject.builder().name("Graph").build();
            case MATH -> TopicMetadataObject.builder().name("Math").build();
            case ORDERED_MAP ->
                TopicMetadataObject.builder().name("Ordered Map").build();
            case GAME_THEORY ->
                TopicMetadataObject.builder().name("Game Theory").build();
            case DYNAMIC_PROGRAMMING ->
                TopicMetadataObject.builder()
                        .name("Dynamic Programming")
                        .aliases(List.of("DP"))
                        .build();
            case RECURSION -> TopicMetadataObject.builder().name("Recursion").build();
            case MONOTONIC_QUEUE ->
                TopicMetadataObject.builder().name("Monotonic Queue").build();
            case MATRIX -> TopicMetadataObject.builder().name("Matrix").build();
            case RESERVOIR_SAMPLING ->
                TopicMetadataObject.builder().name("Reservoir Sampling").build();
            case MERGE_SORT -> TopicMetadataObject.builder().name("Merge Sort").build();
            case COMBINATORICS ->
                TopicMetadataObject.builder().name("Combinatorics").build();
            case INTERACTIVE ->
                TopicMetadataObject.builder().name("Interactive").build();
            case BINARY_TREE ->
                TopicMetadataObject.builder().name("Binary Tree").build();
            case RANDOMIZED -> TopicMetadataObject.builder().name("Randomized").build();
            case BITMASK -> TopicMetadataObject.builder().name("Bitmask").build();
            case BREADTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Breadth-First Search")
                        .aliases(List.of("BFS"))
                        .build();
            case STRING_MATCHING ->
                TopicMetadataObject.builder().name("String Matching").build();
            case GREEDY -> TopicMetadataObject.builder().name("Greedy").build();
            case BRAINTEASER ->
                TopicMetadataObject.builder().name("Brainteaser").build();
            case BACKTRACKING ->
                TopicMetadataObject.builder().name("Backtracking").build();
            case BIT_MANIPULATION ->
                TopicMetadataObject.builder().name("Bit Manipulation").build();
            case UNION_FIND -> TopicMetadataObject.builder().name("Union-Find").build();
            case BINARY_SEARCH_TREE ->
                TopicMetadataObject.builder()
                        .name("Binary Search Tree")
                        .aliases(List.of("BST"))
                        .build();
            case TWO_POINTERS ->
                TopicMetadataObject.builder().name("Two Pointers").build();
            case ARRAY -> TopicMetadataObject.builder().name("Array").build();
            case DEPTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Depth-First Search")
                        .aliases(List.of("DFS"))
                        .build();
            case EULERIAN_CIRCUIT ->
                TopicMetadataObject.builder().name("Eulerian Circuit").build();
            case TREE -> TopicMetadataObject.builder().name("Tree").build();
            case BINARY_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Binary Search")
                        .aliases(List.of("BS"))
                        .build();
            case STRONGLY_CONNECTED_COMPONENT ->
                TopicMetadataObject.builder()
                        .name("Strongly Connected Component")
                        .build();
            case ENUMERATION ->
                TopicMetadataObject.builder().name("Enumeration").build();
            case HEAP_PRIORITY_QUEUE ->
                TopicMetadataObject.builder().name("Heap / Priority Queue").build();
            case DIVIDE_AND_CONQUER ->
                TopicMetadataObject.builder().name("Divide and Conquer").build();
            case HASH_FUNCTION ->
                TopicMetadataObject.builder().name("Hash Function").build();
            case HASH_TABLE -> TopicMetadataObject.builder().name("Hash Table").build();
            case TRIE -> TopicMetadataObject.builder().name("Trie").build();
            case TOPOLOGICAL_SORT ->
                TopicMetadataObject.builder().name("Topological Sort").build();
            case QUICKSELECT ->
                TopicMetadataObject.builder().name("Quickselect").build();
            case BINARY_INDEXED_TREE ->
                TopicMetadataObject.builder().name("Binary Indexed Tree").build();
            case COUNTING_SORT ->
                TopicMetadataObject.builder().name("Counting Sort").build();
            case UNKNOWN -> TopicMetadataObject.builder().name("Unknown").build();
        };
    }
}
Untested Code

The PR description indicates that tests have not passed. New logic introduced in TopicMetadataList and the generateEnumToObject method in ComplexJSTypesGenerator should have corresponding unit tests to ensure correctness and prevent regressions. The generateEnumToObject method is even marked @VisibleForTesting, implying it should be tested.

@VisibleForTesting
void generateEnumToObject(Generator generator) throws Exception {
    Map<?, ?> data = (Map<?, ?>) generator.getData();

    if (data.isEmpty()) {
        log.warn("Empty map provided for object generation");
        return;
    }

    Object firstKey = data.keySet().iterator().next();
    if (!(firstKey instanceof Enum)) {
        throw new IllegalArgumentException("Expected Enum key, got: " + firstKey.getClass());
    }

    Enum<?> enumKey = (Enum<?>) firstKey;
    String enumClassName = enumKey.getDeclaringClass().getSimpleName();
    imports.add(enumClassName);

    String objectClass = generator.getObjectClass();

    tsContent
            .append("export const ")
            .append(generator.getName())
            .append(": Record<")
            .append(enumClassName)
            .append(", ")
            .append(objectClass)
            .append("> = {\n");

    for (Map.Entry<?, ?> entry : data.entrySet()) {
        Enum<?> key = (Enum<?>) entry.getKey();
        String jsonValue = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entry.getValue());
        String tsValue = jsonToTypeScript(jsonValue);

        String[] lines = tsValue.split("\n");
        tsContent
                .append("  [")
                .append(enumClassName)
                .append(".")
                .append(key.name())
                .append("]: ")
                .append(lines[0]);

        for (int i = 1; i < lines.length; i++) {
            tsContent.append("\n  ").append(lines[i]);
        }

        tsContent.append(",\n");
    }

    tsContent.append("} as const;\n\n");

    log.info("Generated constant: {}", generator.getName());
}

@angelayu0530 angelayu0530 force-pushed the 851 branch 2 times, most recently from 6ef5873 to 26da6ab Compare March 19, 2026 16:18
@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement, Refactoring


Description

  • Move Leetcode topic metadata to backend.

  • Backend generates TopicMetadataList TypeScript.

  • Frontend consumes generated topic metadata.

  • Centralize topic names and aliases.


Diagram Walkthrough

flowchart LR
    JavaBackend[Backend Java Classes] --> Generator[ComplexJSTypesGenerator];
    Generator -- Generates --> TSFile[js/src/lib/api/types/complex.ts];
    OldFrontendFile[js/src/lib/api/utils/metadata/topic/index.ts] -- Removed --> X;
    Frontend[Frontend Code] --> TSFile;
Loading

File Walkthrough

Relevant files
New feature
2 files
TopicMetadataList.java
Define Leetcode topic metadata mapping                                     
+164/-0 
TopicMetadataObject.java
Create data model for topic metadata                                         
+14/-0   
Code generation
1 files
ComplexJSTypesGenerator.java
Extend generator to create topic metadata TypeScript         
+88/-2   
Configuration changes
2 files
DataShape.java
Add `ENUM_TO_OBJECT` data shape for generator                       
+3/-0     
Generator.java
Add `objectClass` field to generator configuration             
+3/-0     
Refactoring
1 files
index.ts
Update imports to use generated topic metadata                     
+4/-2     
Code removal
1 files
index.ts
Remove hardcoded topic metadata file                                         
+0/-87   
Type definition
1 files
types.ts
Update `QuestionTopicTopicMetadata` to use generated type
+5/-5     

@angelayu0530
Copy link
Collaborator Author

/deploy

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement


Description

  • Centralizes Leetcode topic metadata in backend.

  • Generates TopicMetadataObject TypeScript type.

  • Removes hardcoded topic metadata from frontend.

  • Enhances ComplexJSTypesGenerator for object serialization.


Diagram Walkthrough

flowchart LR
    A[TopicMetadataObject.java] --> B[TopicMetadataList.java]
    B --> C[ComplexJSTypesGenerator.java]
    C -- "Generates TS Type & Constant" --> D[js/src/lib/api/types/complex.ts (generated)]
    E[js/src/lib/api/utils/metadata/topic/index.ts] -- "Removed" --> F[Frontend Cleanup]
    D --> G[js/src/lib/api/utils/index.ts]
    D --> H[js/src/lib/api/utils/types.ts]
Loading

File Walkthrough

Relevant files
New feature
2 files
TopicMetadataList.java
Introduces static map for Leetcode topic enums to their display names
and aliases.
+164/-0 
TopicMetadataObject.java
Defines a new Java model for Leetcode topic metadata with name and
aliases.
+14/-0   
Enhancement
3 files
ComplexJSTypesGenerator.java
Extends the JavaScript type generator to include Leetcode topic
metadata serialization.
+82/-2   
DataShape.java
Adds a new data shape ENUM_TO_OBJECT for generating TypeScript objects
from Java enums.
+3/-0     
Generator.java
Updates the generator configuration to support specifying an object
class for type generation.
+3/-0     
Configuration changes
1 files
index.ts
Updates the import path for TOPIC_METADATA_LIST to use the newly
generated complex types.
+4/-2     
Code removal
1 files
index.ts
Deletes the hardcoded frontend file for Leetcode topic metadata.
+0/-87   
Type definition
1 files
types.ts
Updates QuestionTopicTopicMetadata type to reference the
backend-generated TopicMetadataObject.
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

Move-leetcode-enum-to-pretty-name-lookup-to-backend-type-generator-3197c85563aa808fba5aed57ddbebdb2 - Partially compliant

Compliant requirements:

  • Move Leetcode enum to pretty name lookup logic to the backend type generator.

Non-compliant requirements:

  • Ensure all tests pass.
  • Successfully deploy PR to staging.
  • Perform manual QA in dev and staging.
  • Complete a thorough self-review.

Requires further human verification:

  • Verify that the generated types are correctly consumed by the frontend.
  • Confirm that the UI displays Leetcode topics with their pretty names and aliases as expected.
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Tests

The PR description indicates that tests have not passed or been added. Unit tests for the new TopicMetadataList and the generateEnumToObject method in ComplexJSTypesGenerator are crucial to ensure the correctness and maintainability of the generated TypeScript types. The generateEnumToObject method is marked @VisibleForTesting, suggesting an intention for testing, but no corresponding tests are included in the PR.

@VisibleForTesting
void generateEnumToObject(Generator generator) throws Exception {
    Map<?, ?> data = (Map<?, ?>) generator.getData();

    if (data.isEmpty()) {
        log.warn("Empty map provided for object generation");
        return;
    }

    Object firstKey = data.keySet().iterator().next();
    if (!(firstKey instanceof Enum)) {
        throw new IllegalArgumentException("Expected Enum key, got: " + firstKey.getClass());
    }

    Enum<?> enumKey = (Enum<?>) firstKey;
    String enumClassName = enumKey.getDeclaringClass().getSimpleName();
    imports.add(enumClassName);

    String objectClass = generator.getObjectClass();

    tsContent
            .append("export const ")
            .append(generator.getName())
            .append(": Record<")
            .append(enumClassName)
            .append(", ")
            .append(objectClass)
            .append("> = {\n");

    for (Map.Entry<?, ?> entry : data.entrySet()) {
        Enum<?> key = (Enum<?>) entry.getKey();
        String jsonValue = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entry.getValue());
        String tsValue = jsonToTypeScript(jsonValue);

        String[] lines = tsValue.split("\n");
        tsContent.append("  ").append(key.name()).append(": ").append(lines[0]);

        for (int i = 1; i < lines.length; i++) {
            tsContent.append("\n  ").append(lines[i]);
        }

        tsContent.append(",\n");
    }

    tsContent.append("};\n\n");

    log.info("Generated constant: {}", generator.getName());
}
Documentation

The TopicMetadataList class and its generate() method would benefit from Javadoc comments. This would clarify their purpose, especially how the map of Leetcode topics to metadata is generated, enhancing code readability and adherence to documentation guidelines.

public class TopicMetadataList {
    public static final Map<LeetcodeTopicEnum, TopicMetadataObject> ENUM_TO_TOPIC_METADATA = generate();

    private static Map<LeetcodeTopicEnum, TopicMetadataObject> generate() {
        return Arrays.stream(LeetcodeTopicEnum.values())
                .collect(Collectors.toMap(
                        topic -> topic, TopicMetadataList::buildMetadata, (a, b) -> a, LinkedHashMap::new));
    }

PR Checklist Incomplete
Several critical items in the PR checklist, including "I have done a thorough self-review of the PR", "All tests have passed", "I have successfully deployed this PR to staging", and "I have done manual QA", are unchecked. These items are essential for ensuring the quality, stability, and readiness of the PR for merging.

@angelayu0530
Copy link
Collaborator Author

/deploy

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement, Refactoring


Description

  • Migrates Leetcode topic metadata to backend.

  • Generates topic metadata TypeScript types.

  • Centralizes topic names and aliases in Java.

  • Removes hardcoded frontend topic metadata.


Diagram Walkthrough

flowchart LR
  JavaBackend["Java Backend (TopicMetadataList)"] --> TSGenerator["TypeScript Generator (ComplexJSTypesGenerator)"];
  TSGenerator -- "Generates TS types" --> Frontend["Frontend (js/src/lib/api/utils)"];
  OldFrontend["Old Frontend Topic Metadata"] -- "Replaced by" --> JavaBackend;
Loading

File Walkthrough

Relevant files
New feature
2 files
TopicMetadataList.java
Centralizes Leetcode topic metadata generation in backend
+164/-0 
TopicMetadataObject.java
Defines Java model for Leetcode topic metadata                     
+14/-0   
Enhancement
3 files
ComplexJSTypesGenerator.java
Extends JS type generator to include topic metadata           
+82/-2   
DataShape.java
Adds new data shape for enum-to-object mapping                     
+3/-0     
Generator.java
Adds `objectClass` field to `Generator` for type specification
+3/-0     
Refactoring
2 files
index.ts
Updates import path for `TOPIC_METADATA_LIST`                       
+4/-2     
types.ts
Updates `QuestionTopicTopicMetadata` to use generated type
+5/-5     
Code removal
1 files
index.ts
Removes old frontend-defined topic metadata list                 
+0/-87   

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Annotations

The TopicMetadataObject class is missing @EqualsAndHashCode and @ToString Lombok annotations, which are generally recommended for database models/objects as per the "Database Repository Best Practices" guidelines. While this is a metadata object, it's good practice for consistency.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
    private final String name;
    private final List<String> aliases;
}
Missing Javadoc

The new jsonToTypeScript method could benefit from Javadoc comments to explain its purpose and functionality, aligning with the "Documentation" guidelines for non-controller classes/functions.

/**
 * Converts Jackson pretty-printed JSON to TypeScript object literal style (unquoted keys, no space before colon).
 */
private String jsonToTypeScript(String json) {
    return json.replaceAll("\"(\\w+)\" : ", "$1: ");
}
Missing Javadoc

The new TopicMetadataList class and its generate and buildMetadata methods could benefit from Javadoc comments to clarify their purpose and how the topic metadata is generated, as per the "Documentation" guidelines.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TopicMetadataList {
    public static final Map<LeetcodeTopicEnum, TopicMetadataObject> ENUM_TO_TOPIC_METADATA = generate();

    private static Map<LeetcodeTopicEnum, TopicMetadataObject> generate() {
        return Arrays.stream(LeetcodeTopicEnum.values())
                .collect(Collectors.toMap(
                        topic -> topic, TopicMetadataList::buildMetadata, (a, b) -> a, LinkedHashMap::new));
    }

    private static TopicMetadataObject buildMetadata(LeetcodeTopicEnum topic) {
        return switch (topic) {
            case STACK -> TopicMetadataObject.builder().name("Stack").build();
            case DATA_STREAM ->
                TopicMetadataObject.builder().name("Data Stream").build();
            case REJECTION_SAMPLING ->
                TopicMetadataObject.builder().name("Rejection Sampling").build();
            case GEOMETRY -> TopicMetadataObject.builder().name("Geometry").build();
            case COUNTING -> TopicMetadataObject.builder().name("Counting").build();
            case DESIGN -> TopicMetadataObject.builder().name("Design").build();
            case PROBABILITY_AND_STATISTICS ->
                TopicMetadataObject.builder().name("Probability and Statistics").build();
            case MINIMUM_SPANNING_TREE ->
                TopicMetadataObject.builder()
                        .name("Minimum Spanning Tree")
                        .aliases(List.of("MST"))
                        .build();
            case LINE_SWEEP -> TopicMetadataObject.builder().name("Line Sweep").build();
            case NUMBER_THEORY ->
                TopicMetadataObject.builder().name("Number Theory").build();
            case ROLLING_HASH ->
                TopicMetadataObject.builder().name("Rolling Hash").build();
            case SEGMENT_TREE ->
                TopicMetadataObject.builder().name("Segment Tree").build();
            case BICONNECTED_COMPONENT ->
                TopicMetadataObject.builder().name("Biconnected Component").build();
            case MONOTONIC_STACK ->
                TopicMetadataObject.builder().name("Monotonic Stack").build();
            case ITERATOR -> TopicMetadataObject.builder().name("Iterator").build();
            case QUEUE -> TopicMetadataObject.builder().name("Queue").build();
            case RADIX_SORT -> TopicMetadataObject.builder().name("Radix Sort").build();
            case BUCKET_SORT ->
                TopicMetadataObject.builder().name("Bucket Sort").build();
            case SHELL -> TopicMetadataObject.builder().name("Shell Sort").build();
            case MEMOIZATION ->
                TopicMetadataObject.builder().name("Memoization").build();
            case STRING -> TopicMetadataObject.builder().name("String").build();
            case PREFIX_SUM -> TopicMetadataObject.builder().name("Prefix Sum").build();
            case CONCURRENCY ->
                TopicMetadataObject.builder().name("Concurrency").build();
            case DATABASE ->
                TopicMetadataObject.builder()
                        .name("Database")
                        .aliases(List.of("DB"))
                        .build();
            case SHORTEST_PATH ->
                TopicMetadataObject.builder().name("Shortest Path").build();
            case SORTING -> TopicMetadataObject.builder().name("Sorting").build();
            case LINKED_LIST ->
                TopicMetadataObject.builder().name("Linked List").build();
            case SLIDING_WINDOW ->
                TopicMetadataObject.builder().name("Sliding Window").build();
            case SUFFIX_ARRAY ->
                TopicMetadataObject.builder().name("Suffix Array").build();
            case DOUBLY_LINKED_LIST ->
                TopicMetadataObject.builder().name("Doubly Linked List").build();
            case SIMULATION -> TopicMetadataObject.builder().name("Simulation").build();
            case ORDERED_SET ->
                TopicMetadataObject.builder().name("Ordered Set").build();
            case GRAPH -> TopicMetadataObject.builder().name("Graph").build();
            case MATH -> TopicMetadataObject.builder().name("Math").build();
            case ORDERED_MAP ->
                TopicMetadataObject.builder().name("Ordered Map").build();
            case GAME_THEORY ->
                TopicMetadataObject.builder().name("Game Theory").build();
            case DYNAMIC_PROGRAMMING ->
                TopicMetadataObject.builder()
                        .name("Dynamic Programming")
                        .aliases(List.of("DP"))
                        .build();
            case RECURSION -> TopicMetadataObject.builder().name("Recursion").build();
            case MONOTONIC_QUEUE ->
                TopicMetadataObject.builder().name("Monotonic Queue").build();
            case MATRIX -> TopicMetadataObject.builder().name("Matrix").build();
            case RESERVOIR_SAMPLING ->
                TopicMetadataObject.builder().name("Reservoir Sampling").build();
            case MERGE_SORT -> TopicMetadataObject.builder().name("Merge Sort").build();
            case COMBINATORICS ->
                TopicMetadataObject.builder().name("Combinatorics").build();
            case INTERACTIVE ->
                TopicMetadataObject.builder().name("Interactive").build();
            case BINARY_TREE ->
                TopicMetadataObject.builder().name("Binary Tree").build();
            case RANDOMIZED -> TopicMetadataObject.builder().name("Randomized").build();
            case BITMASK -> TopicMetadataObject.builder().name("Bitmask").build();
            case BREADTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Breadth-First Search")
                        .aliases(List.of("BFS"))
                        .build();
            case STRING_MATCHING ->
                TopicMetadataObject.builder().name("String Matching").build();
            case GREEDY -> TopicMetadataObject.builder().name("Greedy").build();
            case BRAINTEASER ->
                TopicMetadataObject.builder().name("Brainteaser").build();
            case BACKTRACKING ->
                TopicMetadataObject.builder().name("Backtracking").build();
            case BIT_MANIPULATION ->
                TopicMetadataObject.builder().name("Bit Manipulation").build();
            case UNION_FIND -> TopicMetadataObject.builder().name("Union-Find").build();
            case BINARY_SEARCH_TREE ->
                TopicMetadataObject.builder()
                        .name("Binary Search Tree")
                        .aliases(List.of("BST"))
                        .build();
            case TWO_POINTERS ->
                TopicMetadataObject.builder().name("Two Pointers").build();
            case ARRAY -> TopicMetadataObject.builder().name("Array").build();
            case DEPTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Depth-First Search")
                        .aliases(List.of("DFS"))
                        .build();
            case EULERIAN_CIRCUIT ->
                TopicMetadataObject.builder().name("Eulerian Circuit").build();
            case TREE -> TopicMetadataObject.builder().name("Tree").build();
            case BINARY_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Binary Search")
                        .aliases(List.of("BS"))
                        .build();
            case STRONGLY_CONNECTED_COMPONENT ->
                TopicMetadataObject.builder()
                        .name("Strongly Connected Component")
                        .build();
            case ENUMERATION ->
                TopicMetadataObject.builder().name("Enumeration").build();
            case HEAP_PRIORITY_QUEUE ->
                TopicMetadataObject.builder().name("Heap / Priority Queue").build();
            case DIVIDE_AND_CONQUER ->
                TopicMetadataObject.builder().name("Divide and Conquer").build();
            case HASH_FUNCTION ->
                TopicMetadataObject.builder().name("Hash Function").build();
            case HASH_TABLE -> TopicMetadataObject.builder().name("Hash Table").build();
            case TRIE -> TopicMetadataObject.builder().name("Trie").build();
            case TOPOLOGICAL_SORT ->
                TopicMetadataObject.builder().name("Topological Sort").build();
            case QUICKSELECT ->
                TopicMetadataObject.builder().name("Quickselect").build();
            case BINARY_INDEXED_TREE ->
                TopicMetadataObject.builder().name("Binary Indexed Tree").build();
            case COUNTING_SORT ->
                TopicMetadataObject.builder().name("Counting Sort").build();
            case UNKNOWN -> TopicMetadataObject.builder().name("Unknown").build();
        };
    }
}

@angelayu0530
Copy link
Collaborator Author

/deploy

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement


Description

  • Centralize Leetcode topic metadata in backend.

  • Generate TypeScript topic types and constants.

  • Enhance frontend-backend type consistency.

  • Remove hardcoded topic data from frontend.


Diagram Walkthrough

flowchart LR
    A[Backend Java Code] -- "Defines Topic Metadata" --> B[TopicMetadataList.java]
    B -- "Used by" --> C[ComplexJSTypesGenerator.java]
    C -- "Generates TypeScript" --> D[js/src/lib/api/types/complex.ts]
    D -- "Consumed by Frontend" --> E[js/src/lib/api/utils/index.ts]
    F[Old Frontend Topic Metadata] -- "Removed" --> G[No longer exists]
Loading

File Walkthrough

Relevant files
New feature
2 files
TopicMetadataList.java
Introduces a static map for Leetcode topic enums to their display
names and aliases.
+166/-0 
TopicMetadataObject.java
Defines an immutable Java model for Leetcode topic metadata, including
name and optional aliases.
+14/-0   
Enhancement
3 files
ComplexJSTypesGenerator.java
Extends the TypeScript generator to include Leetcode topic metadata,
serializing Java objects to TypeScript constants.
+93/-8   
DataShape.java
Adds a new ENUM_TO_OBJECT data shape for the TypeScript generator,
enabling serialization of enum-to-object maps.
+3/-0     
Generator.java
Updates the Generator class with an objectClass field to specify the
TypeScript type for generated object maps.
+3/-0     
Configuration changes
1 files
index.ts
Updates imports to use the newly generated TOPIC_METADATA_LIST from
the backend.
+4/-2     
Code removal
1 files
index.ts
Deletes the hardcoded frontend file that previously defined Leetcode
topic metadata.
+0/-87   
Type definition
1 files
types.ts
Modifies the QuestionTopicTopicMetadata type to reference the
backend-generated TopicMetadataObject.
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Javadoc

Consider adding a class-level Javadoc to TopicMetadataList to explain its purpose and how the ENUM_TO_TOPIC_METADATA map is generated and used. This would improve clarity for future maintainers.

public final class TopicMetadataList {
    private TopicMetadataList() {}
Test Coverage

The generateEnumToObject method is marked with @VisibleForTesting, indicating it's intended to be tested. However, no new tests are included in the PR to cover this new generation logic or the TopicMetadataList data. Adding unit tests for these components would ensure correctness and prevent regressions.

@VisibleForTesting
void generateEnumToObject(Generator generator) throws Exception {
    Map<?, ?> data = (Map<?, ?>) generator.getData();

    if (data.isEmpty()) {
        log.warn("Empty map provided for object generation");
        return;
    }

    Object firstKey = data.keySet().iterator().next();
    if (!(firstKey instanceof Enum)) {
        throw new IllegalArgumentException("Expected Enum key, got: " + firstKey.getClass());
    }

    Enum<?> enumKey = (Enum<?>) firstKey;
    String enumClassName = enumKey.getDeclaringClass().getSimpleName();
    imports.add(enumClassName);

    String objectClass = generator.getObjectClass();

    tsContent
            .append("export const ")
            .append(generator.getName())
            .append(": Record<")
            .append(enumClassName)
            .append(", ")
            .append(objectClass)
            .append(RECORD_BODY_OPEN);

    for (Map.Entry<?, ?> entry : data.entrySet()) {
        Enum<?> key = (Enum<?>) entry.getKey();
        String jsonValue = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entry.getValue());
        String tsValue = jsonToTypeScript(jsonValue);

        String[] lines = tsValue.split("\n");
        tsContent.append("  ").append(key.name()).append(": ").append(lines[0]);

        for (int i = 1; i < lines.length; i++) {
            tsContent.append("\n  ").append(lines[i]);
        }

        tsContent.append(",\n");
    }

    tsContent.append(CLOSE_BLOCK);

    log.info("Generated constant: {}", generator.getName());
}

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement


Description

  • Backend now generates Leetcode topic metadata.

  • Frontend consumes auto-generated topic types.

  • Removed hardcoded topic metadata from frontend.

  • Centralized topic data definition in backend.


Diagram Walkthrough

flowchart LR
  A[Backend TopicMetadataList] --> B{ComplexJSTypesGenerator};
  B -- "Generates TS" --> C[Frontend Topic Metadata];
Loading

File Walkthrough

Relevant files
Enhancement
5 files
TopicMetadataList.java
Introduced backend definition for Leetcode topic metadata
+166/-0 
TopicMetadataObject.java
Defined Java model for Leetcode topic metadata objects     
+14/-0   
ComplexJSTypesGenerator.java
Extended JavaScript type generator to support object serialization for
topic metadata
+93/-8   
DataShape.java
Added new data shape for enum-to-object type generation   
+3/-0     
Generator.java
Added objectClass field to generator for specifying TypeScript type
names
+3/-0     
Configuration changes
1 files
index.ts
Updated frontend imports to use generated topic metadata 
+4/-2     
Refactoring
1 files
index.ts
Removed hardcoded Leetcode topic metadata file                     
+0/-87   
Typesafety
1 files
types.ts
Updated topic metadata type alias to use generated object
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Lombok Annotations

The TopicMetadataObject class is missing @ToString, @EqualsAndHashCode, and @Jacksonized annotations. While this object is not a direct database entity, the "Database Repository Best Practices" guidelines specify these as "Required annotations" for Java database models, which this class closely resembles in its role as a data transfer object for type generation. Adding these would ensure consistency with existing patterns.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
    private final String name;
    private final List<String> aliases;
}
Test Coverage

The PR introduces a new generateEnumToObject method and integrates TopicMetadataList into the ComplexJSTypesGenerator. While the method is marked with @VisibleForTesting, the PR diff does not include new or updated test cases specifically for this new generation logic. Adding dedicated tests would ensure the correctness of the generated TypeScript types and prevent regressions.

@VisibleForTesting
void generateEnumToObject(Generator generator) throws Exception {
    Map<?, ?> data = (Map<?, ?>) generator.getData();

    if (data.isEmpty()) {
        log.warn("Empty map provided for object generation");
        return;
    }

    Object firstKey = data.keySet().iterator().next();
    if (!(firstKey instanceof Enum)) {
        throw new IllegalArgumentException("Expected Enum key, got: " + firstKey.getClass());
    }

    Enum<?> enumKey = (Enum<?>) firstKey;
    String enumClassName = enumKey.getDeclaringClass().getSimpleName();
    imports.add(enumClassName);

    String objectClass = generator.getObjectClass();

    tsContent
            .append("export const ")
            .append(generator.getName())
            .append(": Record<")
            .append(enumClassName)
            .append(", ")
            .append(objectClass)
            .append(RECORD_BODY_OPEN);

    for (Map.Entry<?, ?> entry : data.entrySet()) {
        Enum<?> key = (Enum<?>) entry.getKey();
        String jsonValue = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entry.getValue());
        String tsValue = jsonToTypeScript(jsonValue);

        String[] lines = tsValue.split("\n");
        tsContent.append("  ").append(key.name()).append(": ").append(lines[0]);

        for (int i = 1; i < lines.length; i++) {
            tsContent.append("\n  ").append(lines[i]);
        }

        tsContent.append(",\n");
    }

    tsContent.append(CLOSE_BLOCK);

    log.info("Generated constant: {}", generator.getName());
}

@angelayu0530
Copy link
Collaborator Author

/deploy

@angelayu0530 angelayu0530 force-pushed the 851 branch 2 times, most recently from fed5882 to 67e4383 Compare March 20, 2026 14:41
@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement


Description

  • Backend generates LeetCode topic metadata.

  • Frontend consumes generated topic metadata.

  • Enhances type safety and single source of truth.

  • Removes hardcoded topic data from frontend.


Diagram Walkthrough

flowchart LR
  A[LeetcodeTopicEnum] --> B{TopicMetadataList.java};
  B -- "defines metadata for" --> C[TopicMetadataObject.java];
  B -- "provides data to" --> D[ComplexJSTypesGenerator.java];
  D -- "generates TypeScript types" --> E[js/src/lib/api/types/complex.ts];
  E -- "consumed by" --> F[js/src/lib/api/utils/index.ts];
  E -- "consumed by" --> G[js/src/lib/api/utils/types.ts];
  H[js/src/lib/api/utils/metadata/topic/index.ts] -- "removed" --> I[Frontend Cleanup];
Loading

File Walkthrough

Relevant files
Enhancement
5 files
TopicMetadataList.java
Introduces backend-generated LeetCode topic metadata map 
+166/-0 
TopicMetadataObject.java
Defines data structure for LeetCode topic metadata             
+14/-0   
ComplexJSTypesGenerator.java
Extends generator to create TypeScript for topic metadata
+93/-8   
DataShape.java
Adds new data shape for enum-to-object mapping                     
+3/-0     
Generator.java
Adds field for specifying object class in type generation
+3/-0     
Tests
1 files
ComplexJSTypesGeneratorTest.java
Adds tests for new topic metadata generation logic             
+52/-0   
Configuration changes
1 files
index.ts
Updates import path for topic metadata list                           
+4/-2     
Cleanup
1 files
index.ts
Removes hardcoded LeetCode topic metadata                               
+0/-87   
Typesafety
1 files
types.ts
Updates topic metadata type to use backend-generated definition
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@github-actions
Copy link
Contributor

Title

851: Move leetcode enum to pretty name lookup to backend type generator


PR Type

Enhancement, Refactoring, Tests


Description

  • Migrates Leetcode topic metadata to backend generation.

  • Introduces TopicMetadataList and TopicMetadataObject Java classes.

  • Enhances ComplexJSTypesGenerator for object serialization.

  • Removes hardcoded topic metadata from frontend.


Diagram Walkthrough

flowchart LR
  JavaTopicMetadata["Java Topic Metadata (TopicMetadataList, TopicMetadataObject)"] --> ComplexJSTypesGenerator["ComplexJSTypesGenerator"]
  ComplexJSTypesGenerator -- "Generates TS types" --> GeneratedTSComplexTypes["Generated TS Complex Types (complex.ts)"]
  GeneratedTSComplexTypes -- "Used by" --> FrontendUtils["Frontend Utilities (index.ts, types.ts)"]
Loading

File Walkthrough

Relevant files
Enhancement
6 files
TopicMetadataList.java
Defines backend Leetcode topic metadata lookup and mapping.
+168/-0 
TopicMetadataObject.java
Creates Java model for topic metadata with TypeScript type definition.
+17/-0   
TagMetadataList.java
Adds TypeScript type definition for Tag metadata and makes map
unmodifiable.
+10/-1   
ComplexJSTypesGenerator.java
Extends generator to include topic metadata and refactors string
generation.
+90/-14 
DataShape.java
Adds new `ENUM_TO_OBJECT` data shape for the generator.   
+3/-0     
Generator.java
Adds `objectClass` field to support object generation.     
+3/-0     
Tests
1 files
ComplexJSTypesGeneratorTest.java
Adds tests for topic metadata generation and list integrity.
+52/-0   
Refactoring
3 files
index.ts
Updates frontend imports to use generated topic metadata.
+4/-2     
index.ts
Removes hardcoded Leetcode topic metadata file.                   
+0/-87   
types.ts
Updates topic metadata type to reference the generated backend type.
+5/-5     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Annotations

The TopicMetadataObject class is missing some of the "Required annotations" as per the Database Repository Best Practices. Specifically, @ToString, @EqualsAndHashCode, and @Jacksonized are not present. While the class is immutable and may not directly require @Setter, these annotations are generally recommended for consistency and potential future use cases like logging, object comparison, or deserialization.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
    public static final String TS_TYPE =
            "export type TopicMetadataObject = {\n" + "  name: string;\n" + "  aliases?: string[];\n" + "};\n\n";

    private final String name;
    private final List<String> aliases;
}
Documentation

The TopicMetadataList class and its methods, particularly generate() and buildMetadata(), could benefit from Javadoc comments. The buildMetadata method contains a long switch statement that defines the mapping logic, and clear documentation would enhance readability and maintainability for other developers, aligning with the documentation guidelines for non-controller classes.

package org.patinanetwork.codebloom.common.db.models.question.topic;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public final class TopicMetadataList {
    private TopicMetadataList() {}

    public static final Map<LeetcodeTopicEnum, TopicMetadataObject> ENUM_TO_TOPIC_METADATA =
            Collections.unmodifiableMap(generate());

    private static Map<LeetcodeTopicEnum, TopicMetadataObject> generate() {
        return Arrays.stream(LeetcodeTopicEnum.values())
                .collect(Collectors.toMap(
                        topic -> topic, TopicMetadataList::buildMetadata, (a, b) -> a, LinkedHashMap::new));
    }

    private static TopicMetadataObject buildMetadata(LeetcodeTopicEnum topic) {
        return switch (topic) {
            case STACK -> TopicMetadataObject.builder().name("Stack").build();
            case DATA_STREAM ->
                TopicMetadataObject.builder().name("Data Stream").build();
            case REJECTION_SAMPLING ->
                TopicMetadataObject.builder().name("Rejection Sampling").build();
            case GEOMETRY -> TopicMetadataObject.builder().name("Geometry").build();
            case COUNTING -> TopicMetadataObject.builder().name("Counting").build();
            case DESIGN -> TopicMetadataObject.builder().name("Design").build();
            case PROBABILITY_AND_STATISTICS ->
                TopicMetadataObject.builder().name("Probability and Statistics").build();
            case MINIMUM_SPANNING_TREE ->
                TopicMetadataObject.builder()
                        .name("Minimum Spanning Tree")
                        .aliases(List.of("MST"))
                        .build();
            case LINE_SWEEP -> TopicMetadataObject.builder().name("Line Sweep").build();
            case NUMBER_THEORY ->
                TopicMetadataObject.builder().name("Number Theory").build();
            case ROLLING_HASH ->
                TopicMetadataObject.builder().name("Rolling Hash").build();
            case SEGMENT_TREE ->
                TopicMetadataObject.builder().name("Segment Tree").build();
            case BICONNECTED_COMPONENT ->
                TopicMetadataObject.builder().name("Biconnected Component").build();
            case MONOTONIC_STACK ->
                TopicMetadataObject.builder().name("Monotonic Stack").build();
            case ITERATOR -> TopicMetadataObject.builder().name("Iterator").build();
            case QUEUE -> TopicMetadataObject.builder().name("Queue").build();
            case RADIX_SORT -> TopicMetadataObject.builder().name("Radix Sort").build();
            case BUCKET_SORT ->
                TopicMetadataObject.builder().name("Bucket Sort").build();
            case SHELL -> TopicMetadataObject.builder().name("Shell Sort").build();
            case MEMOIZATION ->
                TopicMetadataObject.builder().name("Memoization").build();
            case STRING -> TopicMetadataObject.builder().name("String").build();
            case PREFIX_SUM -> TopicMetadataObject.builder().name("Prefix Sum").build();
            case CONCURRENCY ->
                TopicMetadataObject.builder().name("Concurrency").build();
            case DATABASE ->
                TopicMetadataObject.builder()
                        .name("Database")
                        .aliases(List.of("DB"))
                        .build();
            case SHORTEST_PATH ->
                TopicMetadataObject.builder().name("Shortest Path").build();
            case SORTING -> TopicMetadataObject.builder().name("Sorting").build();
            case LINKED_LIST ->
                TopicMetadataObject.builder().name("Linked List").build();
            case SLIDING_WINDOW ->
                TopicMetadataObject.builder().name("Sliding Window").build();
            case SUFFIX_ARRAY ->
                TopicMetadataObject.builder().name("Suffix Array").build();
            case DOUBLY_LINKED_LIST ->
                TopicMetadataObject.builder().name("Doubly Linked List").build();
            case SIMULATION -> TopicMetadataObject.builder().name("Simulation").build();
            case ORDERED_SET ->
                TopicMetadataObject.builder().name("Ordered Set").build();
            case GRAPH -> TopicMetadataObject.builder().name("Graph").build();
            case MATH -> TopicMetadataObject.builder().name("Math").build();
            case ORDERED_MAP ->
                TopicMetadataObject.builder().name("Ordered Map").build();
            case GAME_THEORY ->
                TopicMetadataObject.builder().name("Game Theory").build();
            case DYNAMIC_PROGRAMMING ->
                TopicMetadataObject.builder()
                        .name("Dynamic Programming")
                        .aliases(List.of("DP"))
                        .build();
            case RECURSION -> TopicMetadataObject.builder().name("Recursion").build();
            case MONOTONIC_QUEUE ->
                TopicMetadataObject.builder().name("Monotonic Queue").build();
            case MATRIX -> TopicMetadataObject.builder().name("Matrix").build();
            case RESERVOIR_SAMPLING ->
                TopicMetadataObject.builder().name("Reservoir Sampling").build();
            case MERGE_SORT -> TopicMetadataObject.builder().name("Merge Sort").build();
            case COMBINATORICS ->
                TopicMetadataObject.builder().name("Combinatorics").build();
            case INTERACTIVE ->
                TopicMetadataObject.builder().name("Interactive").build();
            case BINARY_TREE ->
                TopicMetadataObject.builder().name("Binary Tree").build();
            case RANDOMIZED -> TopicMetadataObject.builder().name("Randomized").build();
            case BITMASK -> TopicMetadataObject.builder().name("Bitmask").build();
            case BREADTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Breadth-First Search")
                        .aliases(List.of("BFS"))
                        .build();
            case STRING_MATCHING ->
                TopicMetadataObject.builder().name("String Matching").build();
            case GREEDY -> TopicMetadataObject.builder().name("Greedy").build();
            case BRAINTEASER ->
                TopicMetadataObject.builder().name("Brainteaser").build();
            case BACKTRACKING ->
                TopicMetadataObject.builder().name("Backtracking").build();
            case BIT_MANIPULATION ->
                TopicMetadataObject.builder().name("Bit Manipulation").build();
            case UNION_FIND -> TopicMetadataObject.builder().name("Union-Find").build();
            case BINARY_SEARCH_TREE ->
                TopicMetadataObject.builder()
                        .name("Binary Search Tree")
                        .aliases(List.of("BST"))
                        .build();
            case TWO_POINTERS ->
                TopicMetadataObject.builder().name("Two Pointers").build();
            case ARRAY -> TopicMetadataObject.builder().name("Array").build();
            case DEPTH_FIRST_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Depth-First Search")
                        .aliases(List.of("DFS"))
                        .build();
            case EULERIAN_CIRCUIT ->
                TopicMetadataObject.builder().name("Eulerian Circuit").build();
            case TREE -> TopicMetadataObject.builder().name("Tree").build();
            case BINARY_SEARCH ->
                TopicMetadataObject.builder()
                        .name("Binary Search")
                        .aliases(List.of("BS"))
                        .build();
            case STRONGLY_CONNECTED_COMPONENT ->
                TopicMetadataObject.builder()
                        .name("Strongly Connected Component")
                        .build();
            case ENUMERATION ->
                TopicMetadataObject.builder().name("Enumeration").build();
            case HEAP_PRIORITY_QUEUE ->
                TopicMetadataObject.builder().name("Heap / Priority Queue").build();
            case DIVIDE_AND_CONQUER ->
                TopicMetadataObject.builder().name("Divide and Conquer").build();
            case HASH_FUNCTION ->
                TopicMetadataObject.builder().name("Hash Function").build();
            case HASH_TABLE -> TopicMetadataObject.builder().name("Hash Table").build();
            case TRIE -> TopicMetadataObject.builder().name("Trie").build();
            case TOPOLOGICAL_SORT ->
                TopicMetadataObject.builder().name("Topological Sort").build();
            case QUICKSELECT ->
                TopicMetadataObject.builder().name("Quickselect").build();
            case BINARY_INDEXED_TREE ->
                TopicMetadataObject.builder().name("Binary Indexed Tree").build();
            case COUNTING_SORT ->
                TopicMetadataObject.builder().name("Counting Sort").build();
            case UNKNOWN -> TopicMetadataObject.builder().name("Unknown").build();
        };
    }
}

@angelayu0530
Copy link
Collaborator Author

/deploy

Copy link
Owner

Choose a reason for hiding this comment

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

Move this to the org.patinanetwork.codebloom.shared package

Comment on lines +11 to +16
public static final String TS_TYPE = "export type TagMetadataObject = {\n"
+ " shortName: string;\n"
+ " name: string;\n"
+ " apiKey: string;\n"
+ " alt: string;\n"
+ "};\n\n";
Copy link
Owner

Choose a reason for hiding this comment

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

make this a multi line string so it's easier to edit & parse (with .stripIdent() to normalize the zero-point pad size)

@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
public static final String TS_TYPE =
"export type TopicMetadataObject = {\n" + " name: string;\n" + " aliases?: string[];\n" + "};\n\n";
Copy link
Owner

Choose a reason for hiding this comment

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

make this a multi line string so it's easier to edit & parse (with .stripIdent() to normalize the zero-point pad size)

Comment on lines +30 to +33
private static final String EXPORT_TYPE_PREFIX = "export type ";
private static final String TYPE_BODY_OPEN = " = {\n";
private static final String CLOSE_BLOCK = "};\n\n";
private static final String RECORD_BODY_OPEN = "> = {\n";
Copy link
Owner

Choose a reason for hiding this comment

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

do you still need these

@Getter
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TopicMetadataObject {
Copy link
Owner

Choose a reason for hiding this comment

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

it might be good to create an interface called TypableObject that exports a getTsType method so we can inforce a shared way to get the type out (as well as some useful documentation about how it should work)

Comment on lines 96 to 99
} else if (generator.getDataShape() == DataShape.ENUM_TO_STRING_VALUE_MAP) {
generateEnumToStringValueMap(generator);
} else if (generator.getDataShape() == DataShape.ENUM_TO_TAG_METADATA) {
generateEnumToTagMetadata(generator);
Copy link
Owner

Choose a reason for hiding this comment

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

can these be removed now

Comment on lines +339 to +344
/**
* Converts Jackson pretty-printed JSON to TypeScript object literal style (unquoted keys, no space before colon).
*/
private String jsonToTypeScript(String json) {
return json.replaceAll("\"(\\w+)\" : ", "$1: ");
}
Copy link
Owner

Choose a reason for hiding this comment

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

i think you can just make a call to prettier on that specific file after writing to it and it will handle the rest / keep more complexity out of the type generator

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