feat(medusa): Add metadata to Product Category (#5599)

*  feat(migrations): add metadata column to product_category table in database to store additional information about each product category

*  feat(product-category.ts): add metadata field to ProductCategory model to store additional details
📝 docs(product-category.ts): add documentation for new metadata field in ProductCategory model

*  feat(product-category.ts): add metadata field to ProductCategoryInput type to support additional data

*  feat(ProductCategory.ts): add optional metadata field to ProductCategory model to store additional details

*  feat(product-categories): add metadata field to product categories for additional information storage
📝 docs(product-categories): add documentation for new metadata field in product categories

*  feat(product-categories): add 'metadata' field to default and allowed product category fields for enhanced data tracking

*  feat(product-category.ts): add metadata support to product categories
🔧 refactor(product-category.ts): import setMetadata from utils to handle metadata setting in a more efficient way

*  feat(models): add metadata field to AdminPostProductCategoriesCategoryReq and AdminPostProductCategoriesReq models to store additional information

* 📝 docs(api-reference): add metadata field to ProductCategory schema in both admin and store specs
🔧 fix(api-reference): make metadata field required in ProductCategory schema to ensure data consistency

* Create nine-fishes-matter.md

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Bastien
2023-11-16 20:37:02 +01:00
committed by GitHub
parent 57573ed4d7
commit b3093c3e3d
14 changed files with 110 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
---
"@medusajs/medusa": patch
"@medusajs/client-types": patch
---
feat(medusa): Add `metadata` to Product Category

View File

@@ -32,4 +32,8 @@ export interface AdminPostProductCategoriesCategoryReq {
* The rank of the category in the tree node (starting from 0)
*/
rank?: number
/**
* An optional set of key-value pairs to hold additional information.
*/
metadata?: Record<string, any>
}

View File

@@ -28,4 +28,8 @@ export interface AdminPostProductCategoriesReq {
* The ID of the parent product category
*/
parent_category_id?: string
/**
* An optional set of key-value pairs to hold additional information.
*/
metadata?: Record<string, any>
}

View File

@@ -65,4 +65,8 @@ export interface ProductCategory {
* The date with timezone at which the resource was updated.
*/
updated_at: string
/**
* An optional key-value map with additional details
*/
metadata: Record<string, any> | null
}

View File

@@ -1,4 +1,4 @@
import { IsNotEmpty, IsString } from "class-validator"
import { IsNotEmpty, IsString, IsObject, IsOptional } from "class-validator"
import { Request, Response } from "express"
import { EntityManager } from "typeorm"
@@ -122,12 +122,22 @@ export default async (req: Request, res: Response) => {
* parent_category_id:
* type: string
* description: The ID of the parent product category
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* externalDocs:
* description: "Learn about the metadata attribute, and how to delete and update it."
* url: "https://docs.medusajs.com/development/entities/overview#metadata-attribute"
*/
// eslint-disable-next-line max-len
export class AdminPostProductCategoriesReq extends AdminProductCategoriesReqBase {
@IsString()
@IsNotEmpty()
name: string
@IsObject()
@IsOptional()
metadata?: Record<string, unknown>
}
export class AdminPostProductCategoriesParams extends FindParams {}

View File

@@ -149,6 +149,7 @@ export const defaultProductCategoryFields = [
"parent_category_id",
"created_at",
"updated_at",
"metadata",
]
/**

View File

@@ -1,4 +1,11 @@
import { IsOptional, IsString, IsInt, Min, IsNotEmpty } from "class-validator"
import {
IsOptional,
IsString,
IsInt,
Min,
IsNotEmpty,
IsObject,
} from "class-validator"
import { Request, Response } from "express"
import { EntityManager } from "typeorm"
@@ -123,6 +130,12 @@ export default async (req: Request, res: Response) => {
* rank:
* type: number
* description: The rank of the category in the tree node (starting from 0)
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* externalDocs:
* description: "Learn about the metadata attribute, and how to delete and update it."
* url: "https://docs.medusajs.com/development/entities/overview#metadata-attribute"
*/
// eslint-disable-next-line max-len
export class AdminPostProductCategoriesCategoryReq extends AdminProductCategoriesReqBase {
@@ -140,6 +153,10 @@ export class AdminPostProductCategoriesCategoryReq extends AdminProductCategorie
@IsNotEmpty()
@Min(0)
rank?: number
@IsObject()
@IsOptional()
metadata?: Record<string, unknown>
}
export class AdminPostProductCategoriesCategoryParams extends FindParams {}

View File

@@ -60,6 +60,7 @@ export const defaultStoreProductCategoryFields = [
"created_at",
"updated_at",
"rank",
"metadata",
]
export const allowedStoreProductCategoryFields = [
@@ -71,6 +72,7 @@ export const allowedStoreProductCategoryFields = [
"created_at",
"updated_at",
"rank",
"metadata",
]
/**

View File

@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm"
export class AddMetadataToProductCategory1699564794649 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "product_category" ADD COLUMN "metadata" jsonb NULL;`
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "product_category" DROP COLUMN "metadata"`
)
}
}

View File

@@ -1,6 +1,7 @@
import { generateEntityId } from "../utils/generate-entity-id"
import { BaseEntity } from "../interfaces/models/base-entity"
import { kebabCase } from "lodash"
import { DbAwareColumn } from "../utils/db-aware-column"
import { Product } from "."
import {
BeforeInsert,
@@ -64,6 +65,9 @@ export class ProductCategory extends BaseEntity {
@Column({ nullable: false, default: 0 })
rank: number
@DbAwareColumn({ type: "jsonb", nullable: true })
metadata: Record<string, unknown>
@ManyToMany(() => Product, { cascade: ["remove", "soft-remove"] })
@JoinTable({
name: ProductCategory.productCategoryProductJoinTable,
@@ -105,6 +109,7 @@ export class ProductCategory extends BaseEntity {
* - id
* - is_active
* - is_internal
* - metadata
* - mpath
* - name
* - parent_category_id
@@ -173,4 +178,12 @@ export class ProductCategory extends BaseEntity {
* description: The date with timezone at which the resource was updated.
* type: string
* format: date-time
* metadata:
* description: An optional key-value map with additional details
* nullable: true
* type: object
* example: {car: "white"}
* externalDocs:
* description: "Learn about the metadata attribute, and how to delete and update it."
* url: "https://docs.medusajs.com/development/entities/overview#metadata-attribute"
*/

View File

@@ -16,7 +16,7 @@ import {
tempReorderRank,
UpdateProductCategoryInput,
} from "../types/product-category"
import { buildQuery, nullableValue } from "../utils"
import { buildQuery, nullableValue, setMetadata } from "../utils"
type InjectedDependencies = {
manager: EntityManager
@@ -229,6 +229,12 @@ class ProductCategoryService extends TransactionBaseService {
this.productCategoryRepo_
)
const { metadata, ...rest } = productCategoryInput
if (metadata) {
productCategory.metadata = setMetadata(productCategory, metadata)
}
const conditions = this.fetchReorderConditions(
productCategory,
productCategoryInput

View File

@@ -17,6 +17,7 @@ type ProductCategoryInput = {
parent_category_id?: string | null
parent_category?: ProductCategory | null
rank?: number
metadata?: Record<string, unknown>
}
export type CreateProductCategoryInput = ProductCategoryInput & {

View File

@@ -12,6 +12,7 @@ required:
- id
- is_active
- is_internal
- metadata
- mpath
- name
- parent_category_id
@@ -84,3 +85,13 @@ properties:
description: The date with timezone at which the resource was updated.
type: string
format: date-time
metadata:
description: An optional key-value map with additional details
nullable: true
type: object
example:
car: white
externalDocs:
description: Learn about the metadata attribute, and how to delete and update it.
url: >-
https://docs.medusajs.com/development/entities/overview#metadata-attribute

View File

@@ -12,6 +12,7 @@ required:
- id
- is_active
- is_internal
- metadata
- mpath
- name
- parent_category_id
@@ -84,3 +85,13 @@ properties:
description: The date with timezone at which the resource was updated.
type: string
format: date-time
metadata:
description: An optional key-value map with additional details
nullable: true
type: object
example:
car: white
externalDocs:
description: Learn about the metadata attribute, and how to delete and update it.
url: >-
https://docs.medusajs.com/development/entities/overview#metadata-attribute