Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
753a833
feat(region): Region 마스터 모델·마이그레이션 추가 (1·2차 계층 + Store.region_id)
chanwoo7 Jun 17, 2026
da15f1c
feat(region): 수도권 지역 시드(생성기·JSON·seed) + 시드 매장 region 연결
chanwoo7 Jun 17, 2026
735e155
feat(region): 지역 조회/검색 GraphQL API + 테스트
chanwoo7 Jun 17, 2026
dbf2f4a
Merge pull request #144 from CaQuick/feat/region-master
chanwoo7 Jun 17, 2026
0f33849
feat(store): 인기 매장 리스트 API (popularStores·실시간 랭킹 집계) + 테스트
chanwoo7 Jun 17, 2026
4ea7aeb
fix(store): 랭킹 집계 soft-delete 주문 제외 + 케이크 이미지 take 제한 (Codex P2 반영)
chanwoo7 Jun 17, 2026
b7993e9
Merge pull request #145 from CaQuick/feat/popular-stores
chanwoo7 Jun 17, 2026
5434436
feat(store): 매장 찜 토글(멱등) + 인기 매장 isWishlisted (옵셔널 JWT 가드)
chanwoo7 Jun 17, 2026
f80aaa5
fix(auth): OptionalJwtAuthGuard를 AuthGlobalModule provider/export에 등록…
chanwoo7 Jun 17, 2026
fd387f6
fix(store): 매장 찜을 USER 계정으로 제한 (Codex P2 - 랭킹 무결성 보호)
chanwoo7 Jun 17, 2026
52e1d5a
Merge pull request #146 from CaQuick/feat/store-wishlist
chanwoo7 Jun 17, 2026
ff3b8ff
feat(pickup): 홈 전역 픽업 날짜/시간 슬롯 (pickupCalendar/pickupTimeSlots) + KST 유틸
chanwoo7 Jun 17, 2026
7d896ef
Merge pull request #147 from CaQuick/feat/pickup-slots
chanwoo7 Jun 17, 2026
334e8e6
fix: 릴리즈 리뷰 반영 (pickup 당일 마감 CLOSED, region 시드 upsert 정규화, keyword 경계…
chanwoo7 Jun 18, 2026
f1128cc
Merge pull request #149 from CaQuick/fix/release-review-followups
chanwoo7 Jun 18, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,6 @@ caquick_ddl.sql
src/features/example/*

.figma/

# 지역 시드 원본 CSV (대용량 공공데이터, 파싱 산출 regions.generated.json 만 커밋)
prisma/seed/data/*.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- AlterTable
ALTER TABLE `store` ADD COLUMN `region_id` BIGINT UNSIGNED NULL;

-- CreateTable
CREATE TABLE `region` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`parent_id` BIGINT UNSIGNED NULL,
`level` TINYINT UNSIGNED NOT NULL,
`name` VARCHAR(80) NOT NULL,
`slug` VARCHAR(120) NOT NULL,
`sort_order` INTEGER NOT NULL DEFAULT 0,
`is_active` BOOLEAN NOT NULL DEFAULT true,
`center_lat` DECIMAL(10, 7) NULL,
`center_lng` DECIMAL(10, 7) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL,
`deleted_at` DATETIME(3) NULL,

UNIQUE INDEX `region_slug_key`(`slug`),
INDEX `idx_region_parent_sort`(`parent_id`, `sort_order`),
INDEX `idx_region_level_active`(`level`, `is_active`),
INDEX `idx_region_deleted_at`(`deleted_at`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateIndex
CREATE INDEX `idx_store_region_id` ON `store`(`region_id`);

-- AddForeignKey
ALTER TABLE `region` ADD CONSTRAINT `region_parent_id_fkey` FOREIGN KEY (`parent_id`) REFERENCES `region`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `store` ADD CONSTRAINT `store_region_id_fkey` FOREIGN KEY (`region_id`) REFERENCES `region`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
Comment on lines +2 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

운영 반영 시 store FK 추가 구간의 잠금 리스크를 분리 배포로 완화해 주세요.

store에 컬럼 추가(Line 2) 후 인덱스(Line 27)와 FK(Line 33)를 같은 변경 세트로 적용하면, 실제 운영 데이터량에서 메타데이터 락/검증 스캔으로 쓰기 지연이 발생할 수 있습니다. region_id 컬럼·인덱스 선배포 → 데이터 검증 → 저부하 시간 FK 적용의 단계적 적용 계획이 필요합니다.
As per coding guidelines, prisma/**: "파괴적 변경이나 운영 반영 시 위험한 변경은 명확히 지적하세요."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prisma/migrations/20260617194530_add_region_and_store_region/migration.sql`
around lines 2 - 33, The migration combines adding the region_id column to the
store table with creating its index and foreign key constraint in a single
operation, which risks locking issues on production with large datasets. Split
this into two separate migrations: the first migration should include adding the
region_id column to store and creating the index idx_store_region_id, plus the
self-referencing foreign key constraint region_parent_id_fkey on the region
table. Create a second migration in a separate file to add the
store_region_id_fkey foreign key constraint that links store.region_id to
region.id, scheduled to run during low-traffic periods after data validation.

Source: Coding guidelines

42 changes: 42 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,43 @@ model AuthRefreshSession {
@@map("auth_refresh_session")
}

/**
* =========================
* Region (지역 마스터)
* - level 1 = 1차 광역그룹 (예: 서울 북부, 경기 남부, 인천)
* - level 2 = 2차 시군구 (예: 강남구, 수원시영통구, 강화군)
* - 동(洞)을 직접 보유한 표준 시군구를 2차로 채택. parent_id로 1차에 귀속.
* =========================
*/

model Region {
id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
parent_id BigInt? @db.UnsignedBigInt // null = 1차 광역그룹

level Int @db.UnsignedTinyInt
name String @db.VarChar(80)
slug String @unique @db.VarChar(120)
sort_order Int @default(0)
is_active Boolean @default(true) @db.TinyInt

// 현재위치 기반 추천용 중심좌표. 좌표 데이터는 후속 확보 → 초기엔 비어 있을 수 있음
center_lat Decimal? @db.Decimal(10, 7)
center_lng Decimal? @db.Decimal(10, 7)

created_at DateTime @default(now()) @db.DateTime(3)
updated_at DateTime @updatedAt @db.DateTime(3)
deleted_at DateTime? @db.DateTime(3)

parent Region? @relation("RegionTree", fields: [parent_id], references: [id])
children Region[] @relation("RegionTree")
stores Store[]

@@index([parent_id, sort_order], map: "idx_region_parent_sort")
@@index([level, is_active], map: "idx_region_level_active")
@@index([deleted_at], map: "idx_region_deleted_at")
@@map("region")
}

/**
* =========================
* 2) Store
Expand All @@ -297,6 +334,9 @@ model Store {
address_district String? @db.VarChar(80)
address_neighborhood String? @db.VarChar(80)

// 지역 필터용 2차 시군구(Region level 2). 기존 address_* free-text는 표시·역호환 유지
region_id BigInt? @db.UnsignedBigInt

latitude Decimal? @db.Decimal(10, 7)
longitude Decimal? @db.Decimal(10, 7)

Expand All @@ -316,6 +356,7 @@ model Store {
deleted_at DateTime? @db.DateTime(3)

seller_account Account @relation("StoreSellerAccount", fields: [seller_account_id], references: [id])
region Region? @relation(fields: [region_id], references: [id])

business_hours StoreBusinessHour[]
special_closures StoreSpecialClosure[]
Expand All @@ -333,6 +374,7 @@ model Store {
@@index([seller_account_id], map: "idx_store_seller")
@@index([store_name], map: "idx_store_name")
@@index([address_city, address_district, address_neighborhood], map: "idx_store_region")
@@index([region_id], map: "idx_store_region_id")
@@index([deleted_at], map: "idx_store_deleted_at")
@@map("store")
}
Expand Down
4 changes: 4 additions & 0 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { resetSeedScope } from './seed/idempotent';
import { seedNotifications } from './seed/notifications';
import { seedOrders } from './seed/orders';
import { seedRecentViews } from './seed/recent-views';
import { seedRegions } from './seed/regions';
import { seedReviews } from './seed/reviews';
import { seedSearchHistory } from './seed/search-history';
import { seedStores } from './seed/stores';
Expand All @@ -35,6 +36,9 @@ async function main(): Promise<void> {
log('유저 + 프로필 시드 중...');
const users = await seedUsers(prisma);

log('지역 마스터 시드 중...');
await seedRegions(prisma);

log('매장 + 상품 시드 중...');
const stores = await seedStores(prisma);

Expand Down
Loading
Loading