- 상품 카탈로그(products/) 신설: 공개 필드(name·pointPrice·이미지)와 재고(total/reserved/safety)를 한 문서로 관리, 목록·상세는 60초 인메모리 캐시로 서빙 - 주문 생성 시 포인트 예약(order_reserve)과 재고 예약을 단일 트랜잭션으로 원자 처리, 주문 ID를 uid_클라이언트멱등키로 고정해 더블탭·재시도 중복 생성 차단 - 주문 상태 머신(reserved→confirmed→preparing→shipped→delivered / cancelled / refunded) 전이 검증과 전이별 capture·release·refund 역거래 원장 기록 - reward HTTP 함수 신설: 지갑·원장 조회, 상품 목록·상세, 교환 자격, 주문 생성·목록·상세·취소 API - 관리자 라우트 추가: 상품 등록·수정, 재고 조정(가용재고 음수 방지), 주문 상태 변경, 포인트 지급·회수 - Firestore 보안규칙(지갑 본인 read, 상품·주문은 API 전용)과 orders 복합 인덱스(uid+createdAt, status+createdAt) 추가 - 상품 4종 시드(seed:rewards)와 상세 이미지 업로드(upload:reward-assets) 스크립트 추가
139 lines
3.6 KiB
JSON
139 lines
3.6 KiB
JSON
{
|
|
// Example (Standard Edition):
|
|
//
|
|
// "indexes": [
|
|
// {
|
|
// "collectionGroup": "widgets",
|
|
// "queryScope": "COLLECTION",
|
|
// "fields": [
|
|
// { "fieldPath": "foo", "arrayConfig": "CONTAINS" },
|
|
// { "fieldPath": "bar", "mode": "DESCENDING" }
|
|
// ]
|
|
// },
|
|
//
|
|
// "fieldOverrides": [
|
|
// {
|
|
// "collectionGroup": "widgets",
|
|
// "fieldPath": "baz",
|
|
// "indexes": [
|
|
// { "order": "ASCENDING", "queryScope": "COLLECTION" }
|
|
// ]
|
|
// },
|
|
// ]
|
|
// ]
|
|
//
|
|
// Example (Enterprise Edition):
|
|
//
|
|
// "indexes": [
|
|
// {
|
|
// "collectionGroup": "reviews",
|
|
// "queryScope": "COLLECTION_GROUP",
|
|
// "apiScope": "MONGODB_COMPATIBLE_API",
|
|
// "density": "DENSE",
|
|
// "multikey": false,
|
|
// "fields": [
|
|
// { "fieldPath": "baz", "mode": "ASCENDING" }
|
|
// ]
|
|
// },
|
|
// {
|
|
// "collectionGroup": "items",
|
|
// "queryScope": "COLLECTION_GROUP",
|
|
// "apiScope": "MONGODB_COMPATIBLE_API",
|
|
// "density": "SPARSE_ANY",
|
|
// "multikey": true,
|
|
// "fields": [
|
|
// { "fieldPath": "baz", "mode": "ASCENDING" }
|
|
// ]
|
|
// },
|
|
// ]
|
|
"indexes": [
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "favoriteTeamCode", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "DESCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "active", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "DESCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "active", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "favoriteTeamCode", "order": "ASCENDING" },
|
|
{ "fieldPath": "active", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "DESCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "favoriteTeamCode", "order": "ASCENDING" },
|
|
{ "fieldPath": "active", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "active", "order": "ASCENDING" },
|
|
{ "fieldPath": "deactivatedAt", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "users",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "favoriteTeamCode", "order": "ASCENDING" },
|
|
{ "fieldPath": "tierPoints", "order": "ASCENDING" },
|
|
{ "fieldPath": "__name__", "order": "ASCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "orders",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "uid", "order": "ASCENDING" },
|
|
{ "fieldPath": "createdAt", "order": "DESCENDING" }
|
|
]
|
|
},
|
|
{
|
|
"collectionGroup": "orders",
|
|
"queryScope": "COLLECTION",
|
|
"fields": [
|
|
{ "fieldPath": "status", "order": "ASCENDING" },
|
|
{ "fieldPath": "createdAt", "order": "DESCENDING" }
|
|
]
|
|
}
|
|
],
|
|
"fieldOverrides": [
|
|
{
|
|
"collectionGroup": "products",
|
|
"fieldPath": "mainImages",
|
|
"indexes": []
|
|
},
|
|
{
|
|
"collectionGroup": "products",
|
|
"fieldPath": "detailImages",
|
|
"indexes": []
|
|
}
|
|
]
|
|
}
|