Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
@@ -0,0 +1,30 @@
import { UseGetProductVersions } from "@repo/apis/core/shop/product-version/flat/get/use-get-product-versions";
import { Select } from "@repo/ui/components";

const SelectVersion = ({ productId }: { productId: string }) => {
const { data, isLoading } = UseGetProductVersions({
params: {
productId,
},
});

const handleChange = (value: string) => {
console.log(value)
}

return (
<Select
id="version-select"
onValueChange={handleChange}
placeholder="Select a version"
size="lg"
loading={isLoading}
options={data?.data?.data?.map((item) => ({
label: item.version,
value: item.id.toString()
})) || []}
/>
);
};

export { SelectVersion };
8 changes: 4 additions & 4 deletions apps/core/app/dashboard/products/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { Button } from "@repo/ui/components";
import { TabGeneral } from "./_components/tabGeneral";
import Version from "./_components/version/version";

import { SelectVersion } from "./_components/select-version";
const CreateProductPage = () => {
const methods = useForm<{ price: string; discount: number | null }>();
const { handleSubmit } = methods;
Expand All @@ -31,9 +31,9 @@ const CreateProductPage = () => {

{/* Actions */}
<div className="flex items-center gap-3 shrink-0">
<div>select version</div>
<Button variant="secondary">Save as Draft</Button>
<Button type="submit">Submit to Review</Button>
<div><SelectVersion productId="1" /></div>
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

Hardcoded productId in SelectVersion component

The SelectVersion component is initialized with a fixed productId="1", which may not be appropriate for a product creation flow where the ID is typically generated after creation. Consider using a more dynamic approach or clarifying why a fixed ID is used here.

- <div><SelectVersion productId="1" /></div>
+ <div><SelectVersion productId={productData?.id} /></div>

If this is intentional (e.g., for selecting versions of an existing product template), please add a code comment explaining this design decision.

📝 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
<div><SelectVersion productId="1" /></div>
<div><SelectVersion productId={productData?.id} /></div>

<div><Button variant="secondary" size={"lg"}>Save as Draft</Button></div>
<div><Button type="submit" size={"lg"}>Submit to Review</Button></div>
</div>
</div>
{/* Content */}
Expand Down
40 changes: 35 additions & 5 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"prettier": "^3.3.2",
"turbo": "2.0.6"
},
"packageManager": "yarn@1.22.22",
"packageManager": "bun@1.1.19",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Package manager changed from Yarn to Bun

The package manager has been switched from Yarn 1.22.22 to Bun 1.1.19, which is a significant change that could affect development workflows and CI/CD pipelines.


🏁 Script executed:

#!/bin/bash
# Check if there are any remaining Yarn-specific files or configurations
find . -name "yarn.lock" -o -name ".yarnrc" -o -name ".yarn" -type d

# Check if lockfile has been properly updated to Bun format
test -f "bun.lockb" && echo "Bun lockfile exists" || echo "Bun lockfile missing"

# Check CI configuration for Yarn references
find .github -type f -name "*.yml" -o -name "*.yaml" | xargs grep -l "yarn" || echo "No Yarn references in GitHub workflows"

Length of output: 291


Address remaining Yarn artifacts and update CI workflows

There are residual Yarn configurations that need to be cleaned up now that you’ve switched to Bun:

  • yarn.lock still exists at the repo root (and indirectly in node_modules).
  • The GitHub Actions workflow (.github/workflows/build-and-merge.yml) still invokes Yarn.
  • Although bun.lockb is present, CI and docs may still reference Yarn install commands.

Please remove or replace all Yarn-specific files and commands:

  • Delete yarn.lock (and any stray .yarnrc or .yarn/ directories).
  • Update your CI workflows to use bun install (or bun CLI) instead of yarn.
  • Review project documentation and scripts (e.g., README, any Makefiles) for Yarn references and switch them to Bun.

"engines": {
"node": ">=18"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { apiResponseSchema } from "#schema/api-response-schema";
import { z } from "zod";

// Request
export const getProductVersionsRequestSchemaTransformed = z
.object({
productId: z.string(),
})
.transform((data) => ({
product_id: data.productId,
}));

// Response
export const getProductVersionsResponseSchemaTransofrmed = apiResponseSchema.extend({
data: z.array(z.object({
version: z.string(),
id: z.number(),
})),
}).transform((data) => data);

export const getProductVersionsSchema = {
response: getProductVersionsResponseSchemaTransofrmed,
request: getProductVersionsRequestSchemaTransformed,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { coreApi } from "#instance/core-api";
import path from "path";
import { ApiResponse } from "@repo/apis/types/api.types";
import { requestHandler } from "@repo/apis/utils/request-handler";
import { getProductVersionsSchema as schema } from "./get-product-versions.schema";
import {
GetProductVersionsRequest,
GetProductVersionsResponse,
GetProductVersionsResponseTransformed,
} from "./get-product-versions.types";

const getProductVersionsURL = () => path.join("/shop/product-version/flat/");

export const getProductVersions = async (
props: GetProductVersionsRequest,
): Promise<ApiResponse<GetProductVersionsResponseTransformed>> => {
const payloadParsed = schema.request.parse(props);
const URL = getProductVersionsURL();

const response = await requestHandler(
() => coreApi.get<GetProductVersionsResponse>(URL, { params: payloadParsed }),
schema.response._def.schema,
{
isMock: true,
},
);
Comment on lines +20 to +26
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Hardcoded mock flag may prevent real API calls

The isMock: true setting will always return mock data instead of making real API calls. This might be intentional during development but could cause issues in production.


🏁 Script executed:

#!/bin/bash
# Check if there are any environment variables configured for controlling mock mode
grep -r "NEXT_PUBLIC_MOCK" --include="*.{ts,js,tsx,jsx,json}" .
# Also check if other API functions use this pattern
grep -r "isMock:" --include="*.{ts,js,tsx,jsx}" --after-context=1 packages/apis/src/services/

Length of output: 157


I want to inspect how isMock is handled inside requestHandler to confirm whether it truly forces mock data in all environments. Let’s locate its definition and usage:


🏁 Script executed:

#!/bin/bash
# Find where requestHandler is imported
grep -R "import .*requestHandler" -n packages/apis/src

# Locate requestHandler’s implementation
grep -R "export function requestHandler" -n packages/apis/src || grep -R "const requestHandler" -n packages/apis/src

Length of output: 2170


To confirm how the isMock flag is handled inside requestHandler, let’s inspect its implementation:


🏁 Script executed:

#!/bin/bash
# Show how many lines we have and preview the implementation of requestHandler
wc -l packages/apis/src/utils/request-handler.ts
sed -n '1,200p' packages/apis/src/utils/request-handler.ts

Length of output: 1148


Remove hardcoded mock flag in get-product-versions

The isMock: true option here will always short-circuit into mock mode—skipping real API calls even in production. Instead, derive mock behavior from an environment variable or NODE_ENV.

• File: packages/apis/src/services/core/shop/product-version/flat/get/get-product-versions.ts (lines 20–26)
• Change this:

const response = await requestHandler(
  () => coreApi.get<GetProductVersionsResponse>(URL, { params: payloadParsed }),
  schema.response._def.schema,
  { isMock: true },
);

to something like:

const response = await requestHandler(
  () => coreApi.get<GetProductVersionsResponse>(URL, { params: payloadParsed }),
  schema.response._def.schema,
  { isMock: process.env.NEXT_PUBLIC_MOCK === 'true' },
);

or guard by environment:

{ isMock: process.env.NODE_ENV === 'development' }



const dataParsed = schema.response.parse(response.data);

return { ...response, data: dataParsed };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { z } from "zod";
import { getProductVersionsSchema } from "./get-product-versions.schema";

// Response
export type GetProductVersionsRequest = z.input<typeof getProductVersionsSchema.request>;

export type GetProductVersionsRequestTransofrmed = z.infer<
typeof getProductVersionsSchema.request
>;

// Request
export type GetProductVersionsResponse = z.input<typeof getProductVersionsSchema.response>;

export type GetProductVersionsResponseTransformed = z.infer<
typeof getProductVersionsSchema.response
>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
ApiError,
ApiResponse,
UseQueryProps,
WithParams,
} from "@repo/apis/types/api.types";
import { useQuery } from "@tanstack/react-query";
import { getProductVersions } from "./get-product-versions";
import {
GetProductVersionsRequest,
GetProductVersionsResponseTransformed,
} from "./get-product-versions.types";

export type UseGetProductVersionsProps = UseQueryProps<
ApiResponse<GetProductVersionsResponseTransformed>,
WithParams<GetProductVersionsRequest>
>;

export const getProductVersionsQueryKey = () => ["getProductVersions"];
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

Query key should include dependency parameters

The query key doesn't include any parameters that the API depends on, such as the product ID. This could lead to cache collisions if multiple components fetch versions for different products.

-export const getProductVersionsQueryKey = () => ["getProductVersions"];
+export const getProductVersionsQueryKey = (params: GetProductVersionsRequest) => ["getProductVersions", params];

Then update the queryKey usage:

-  queryKey: getProductVersionsQueryKey(),
+  queryKey: getProductVersionsQueryKey(params),
📝 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
export const getProductVersionsQueryKey = () => ["getProductVersions"];
-export const getProductVersionsQueryKey = () => ["getProductVersions"];
+export const getProductVersionsQueryKey = (params: GetProductVersionsRequest) => ["getProductVersions", params];
- queryKey: getProductVersionsQueryKey(),
+ queryKey: getProductVersionsQueryKey(params),


export const UseGetProductVersions = (props: UseGetProductVersionsProps) => {
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

Hook naming should follow React conventions

React hook names should use camelCase and start with 'use', not uppercase 'Use'. This convention helps tools like ESLint identify hooks properly.

-export const UseGetProductVersions = (props: UseGetProductVersionsProps) => {
+export const useGetProductVersions = (props: UseGetProductVersionsProps) => {
📝 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
export const UseGetProductVersions = (props: UseGetProductVersionsProps) => {
export const useGetProductVersions = (props: UseGetProductVersionsProps) => {

const { params, ...resProps } = props;

const query = useQuery<ApiResponse<GetProductVersionsResponseTransformed>, ApiError>({
queryKey: getProductVersionsQueryKey(),
queryFn: () => getProductVersions(params),
...resProps,
});

return query;
};
6 changes: 2 additions & 4 deletions packages/apis/turbo/generators/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ export default function generator(plop: PlopTypes.NodePlopAPI): void {
default: "core",
},
{
type: "list",
type: "input",
name: "path",
message: "Select the API path from Swagger JSON:",
choices: swaggerPaths.length > 0 ? swaggerPaths : ["No paths available"],
when: () => swaggerPaths.length > 0,
message: "Enter the API path:"
},
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

Improved flexibility but created dead code

Changing from a list selection to free text input for API paths provides more flexibility for developers but may lead to inconsistency in path formats.

The swaggerPaths variable is now unused but the function to load it is still being called on line 20. This creates dead code that should be removed:

-  const swaggerPaths = loadSwaggerPaths("./swagger.json");

Since the Swagger paths are no longer used for providing choices in the prompt, this function call is unnecessary.

📝 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
type: "input",
name: "path",
message: "Select the API path from Swagger JSON:",
choices: swaggerPaths.length > 0 ? swaggerPaths : ["No paths available"],
when: () => swaggerPaths.length > 0,
message: "Enter the API path:"
},
function configGenerator() {
- const swaggerPaths = loadSwaggerPaths("./swagger.json");
return {
prompts: [
{
type: "input",
name: "path",
message: "Enter the API path:"
},
]
};
}

],
actions(data) {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/molecules/label-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const LabelWraper = React.forwardRef<
<Label
ref={ref}
htmlFor={id}
className=" px-1 flex gap-1 text-muted-foreground mb-2"
className=" px-1 flex gap-1 text-muted-foreground"
{...props}
>
<Typography component="span" variant="label/sm">{label}</Typography>
Expand Down
9 changes: 8 additions & 1 deletion packages/ui/src/components/molecules/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface SelectProps extends RadixSelectProps {
size?: "sm" | "md" | "lg";
helperText?: string;
options: Option[];
loading?: boolean;
}

const Select = ({
Expand All @@ -48,6 +49,7 @@ const Select = ({
error,
helperText,
size,
loading,
...props
}: SelectProps) => {
const serializedOptions = React.useMemo(() => {
Expand Down Expand Up @@ -93,7 +95,12 @@ const Select = ({
className={labelWraperClassName}
>
<BaseSelect value={value} {...props}>
<BaseSelectTrigger className={className} size={size} error={!!error}>
<BaseSelectTrigger
className={className}
size={size}
error={!!error}
loading={loading}
>
<BaseSelectValue placeholder={placeholder} />
</BaseSelectTrigger>
{serializedOptionsKeyArr.length ? (
Expand Down