[Schema, API 리뷰] 상품 Q&A

 

Schema

  • productQuestion

  • productAnswer

API

  • 상품 Q&A 리스트

  • 상품 문의 등록

  • 상품 문의 수정

  • 상품 문의 삭제

  • 상품 답변 저장

  • 상품 답변 삭제

 

Postman collection

Schema, API 리뷰 (상품 Q&A).postman_collection.json

 

productQuestion Schema

[ { "parentId": "products", "typeId": "nodeType", "tid": "productQuestion", "typeName": "Product Question", "repositoryType": "node", "eviction": 0, "standaloneIndex": false, "microservice": "products", "propertyTypes": [ { "pid": "id", "name": "ID", "valueType": "LONG", "idable": true, "idType": "hash", "indexable": true, "orderNo": 10 }, { "pid": "siteProduct", "name": "상품", "valueType": "REFERENCE", "indexable": true, "referenceType": "siteProduct", "orderNo": 20 }, { "pid": "product", "name": "상품", "valueType": "REFERENCE", "indexable": true, "referenceType": "product", "defaultValue": "{{:siteProduct.baseProduct}}", "orderNo": 20 }, { "pid": "customer", "name": "회원", "valueType": "REFERENCE", "indexable": true, "referenceType": "customer", "defaultValue": "", "orderNo": 30 }, { "pid": "questionType", "name": "문의유형", "valueType": "CODE", "indexable": true, "orderNo": 40, "code": [ { "value": "delivery", "label": "배송" }, { "value": "product", "label": "상품" }, { "value": "returnCancel", "label": "반품/취소" }, { "value": "exchange", "label": "교환/변경" }, { "value": "etc", "label": "기타" } ] }, { "pid": "subject", "name": "제목", "valueType": "STRING", "indexable": true, "labelable": true, "orderNo": 50 }, { "pid": "contents", "name": "내용", "valueType": "TEXT", "orderNo": 60 }, { "pid": "displayStatus", "name": "전시상태", "valueType": "CODE", "indexable": true, "orderNo": 70, "code": [ { "value": "secret", "label": "비밀글" }, { "value": "public", "label": "공개" }, { "value": "blind", "label": "블라인드" } ], "defaultValue": "public" }, { "pid": "questionStatus", "name": "문의상태", "valueType": "CODE", "indexable": true, "orderNo": 80, "code": [ { "value": "waiting", "label": "답변대기" }, { "value": "completed", "label": "답변완료" } ], "defaultValue": "waiting" }, { "pid": "emailNotification", "name": "Email 알림", "valueType": "BOOLEAN", "indexable": true, "orderNo": 90, "defaultValue": "false" }, { "pid": "email", "name": "Email", "valueType": "PART", "indexable": true, "partIndex": true, "referenceType": "email", "orderNo": 100 }, { "pid": "owner", "name": "등록자", "valueType": "REFERENCE", "indexable": true, "referenceType": "user", "orderNo": 110 }, { "pid": "created", "name": "등록일", "valueType": "DATE", "indexable": true, "orderNo": 120 }, { "pid": "modifier", "name": "등록자", "valueType": "REFERENCE", "indexable": true, "referenceType": "user", "orderNo": 130 }, { "pid": "changed", "name": "수정일", "valueType": "DATE", "indexable": true, "orderNo": 140 }, { "pid": "vendor", "name": "공급사", "valueType": "REFERENCE", "indexable": true, "referenceType": "vendor", "defaultValue": "{{:siteProduct.baseProduct.vendor}}", "orderNo": 150 }, { "pid": "seller", "name": "판매사", "valueType": "REFERENCE", "indexable": true, "referenceType": "seller", "defaultValue": "{{:siteProduct.baseProduct.seller}}", "orderNo": 160 }, { "pid": "site", "name": "사이트", "valueType": "REFERENCE", "indexable": true, "referenceType": "site", "defaultValue": "{{:siteProduct.site}}", "orderNo": 170 }, { "pid": "answers", "name": "답변 리스트", "valueType": "REFERENCED", "referenceType": "productAnswer", "referenceValue": "productQuestion", "filter": "answerStatus_matching=completed", "orderNo": 180 } ], "events": [ { "event": "create", "name": "Create", "eventActions": [ { "action": "setData", "actionName": "Set Data", "actionType": "service", "actionBody": "productQuestionService.setData", "beforeAction": true, "orderNo": 1 } ] }, { "event": "update", "name": "Update", "eventActions": [ { "action": "checkOwner", "actionName": "Check Owner", "actionType": "service", "actionBody": "productQuestionService.checkOwner", "beforeAction": true, "orderNo": 1 } ] }, { "event": "delete", "name": "Delete", "eventActions": [ { "action": "checkOwner", "actionName": "Check Owner", "actionType": "service", "actionBody": "productQuestionService.checkOwner", "beforeAction": true, "orderNo": 1 } ] } ] } ]

 

public void setData(ExecuteContext context) { if (context.getHttpRequest() == null) return; String contextPath = ContextUtils.getApiContextPath(context.getHttpRequest()); if (!StringUtils.equals(contextPath, "svc")) return; context.getNode().put("customer", SessionHelper.getCustomerNo()); }

 

//문의 등록자 체크 public void checkOwner(ExecuteContext context) { if (context.getHttpRequest() == null) return; String contextPath = ContextUtils.getApiContextPath(context.getHttpRequest()); if (!StringUtils.equals(contextPath, "svc")) return; Node node = nodeService.getNode("productQuestion", context.getId()); if (node == null) { throw new ApiException("404", "상품문의가 존재하지 않습니다."); } if (!StringUtils.equals(SessionHelper.getCustomerNo(), node.getStringValue("customer"))) { throw new ApiException("400", "상품문의를 " + context.getEvent() + "할 수 없습니다."); } }

 

productAnswer Schema

 

 

 

상품 Q&A 리스트

  • apiType : service

  • 상품에 대한 문의 리스트

  • 문의의 전시상태 blind 제외

  • 문의의 전시상태가 secret 이면

    • 로그인 세션 사용자와 문의 등록자 체크

    • 다르면 제목 “비밀글 입니다”, 내용, 답변 비 노출

GET {{protocol}}://{{hostname}}:{{port}}/svc/productQna/list

 

Result

 

 

 

상품 문의 등록

  • apiType : service

  • 로그인 회원만 등록 가능

POST {{protocol}}://{{hostname}}:{{port}}/svc/productQna/create

 

상품 문의 수정

  • apiType : service

  • 로그인 회원만 수정 가능

  • 문의 등록한 본인 체크

POST {{protocol}}://{{hostname}}:{{port}}/svc/productQna/update

 

상품 문의 삭제

  • apiType : service

  • 로그인 회원만 삭제 가능

  • 문의 등록한 본인 체크

 

상품 답변 저장

  • apiType : admin

  • 상품문의에 대하여 담당자가 답변을 등록/수정

  • 답변대기로 임의 저장 가능

  • 답변 상태가 completed 이면 문의 상태를 답변완료 처리

상품 답변 삭제

  • apiType : admin

  • 담당자가 답변을 삭제