Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ services:
mysql:
image: mysql:8.0
container_name: caquick-mysql
# MySQL 8 기본 caching_sha2_password 가 prisma client(현 6.x)에서
# 일부 환경에서 sha256_password 로 잘못 인식되어 연결이 실패하는 케이스가
# 있어 mysql_native_password 로 통일한다. 새로 생성되는 사용자도 동일 plugin.
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: CaQuick
Expand Down
6 changes: 6 additions & 0 deletions docker/mysql/init/01-grant-shadow-db.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
-- Prisma migrate dev는 shadow database를 임시 생성/삭제하므로
-- caquick 유저에게 DB 생성 권한을 부여한다.
GRANT ALL PRIVILEGES ON *.* TO 'caquick'@'%';

-- prisma client 6.x가 일부 환경에서 caching_sha2_password를
-- sha256_password로 잘못 인식하는 호환 이슈가 있어 native_password로 통일.
-- (docker-compose의 --default-authentication-plugin과 이중 안전망)
ALTER USER 'caquick'@'%' IDENTIFIED WITH mysql_native_password BY 'caquick';

FLUSH PRIVILEGES;
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
"prisma:migrate:create": "prisma migrate dev --create-only",
"prisma:migrate:deploy": "prisma migrate deploy",
"prisma:studio": "prisma studio",
"prisma:seed": "prisma db seed",
"graphql:codegen": "graphql-codegen --config codegen.yml",
"graphql:docs": "spectaql -c spectaql.yml",
"prepare": "husky"
},
"prisma": {
"seed": "ts-node -r tsconfig-paths/register prisma/seed.ts"
},
"dependencies": {
"@apollo/server": "^5.5.0",
"@as-integrations/express5": "^1.1.2",
Expand Down
82 changes: 82 additions & 0 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* 마이페이지 검증용 시드 데이터.
*
* 실행: yarn prisma:seed
*
* - 기존 시드 영역(seed-user-* 이메일, [SEED] * 매장명)을 정리한 뒤 재삽입한다 (idempotent).
* - production 환경에서는 자동 차단된다.
*
* 발급된 테스트 accountId가 콘솔에 출력되며, GraphQL Playground에서 dev 토큰
* 발급 헬퍼(POST /auth/dev/issue-token)와 함께 사용한다.
*/
import { PrismaClient } from '@prisma/client';

import { seedCustomDrafts } from './seed/custom-drafts';
import { resetSeedScope } from './seed/idempotent';
import { seedNotifications } from './seed/notifications';
import { seedOrders } from './seed/orders';
import { seedRecentViews } from './seed/recent-views';
import { seedReviews } from './seed/reviews';
import { seedSearchHistory } from './seed/search-history';
import { seedStores } from './seed/stores';
import { seedUsers } from './seed/users';
import { seedWishlist } from './seed/wishlist';

async function main(): Promise<void> {
if (process.env.NODE_ENV === 'production') {
throw new Error('seed는 production 환경에서 실행할 수 없습니다.');
}

const prisma = new PrismaClient();
try {
log('기존 시드 영역 정리 중...');
await resetSeedScope(prisma);

log('유저 + 프로필 시드 중...');
const users = await seedUsers(prisma);

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

log('주문 + 아이템 시드 중...');
const orders = await seedOrders(prisma, { users, stores });

log('리뷰 시드 중...');
await seedReviews(prisma, { users, stores, orders });

log('찜 시드 중...');
await seedWishlist(prisma, { users, stores });

log('최근 본 상품 시드 중...');
await seedRecentViews(prisma, { users, stores });

log('알림 시드 중...');
await seedNotifications(prisma, { users });

log('커스텀 드래프트 시드 중...');
await seedCustomDrafts(prisma, { users, stores });

log('검색 히스토리 시드 중...');
await seedSearchHistory(prisma, { users });

log('완료. 발급된 테스트 계정:');
for (const u of users) {
const status =
u.name === null
? '온보딩 미완료 (needsProfile=true 검증용)'
: '온보딩 완료';
log(` - accountId=${u.id.toString()} email=${u.email} (${status})`);
}
} finally {
await prisma.$disconnect();
}
}

function log(message: string): void {
console.log(`[seed] ${message}`);
}

main().catch((err: unknown) => {
console.error('[seed] 실패:', err);
process.exit(1);
});
31 changes: 31 additions & 0 deletions prisma/seed/custom-drafts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 시드 커스텀 드래프트 (user1, 2건). customDraftCount=2.
*/
import type { PrismaClient } from '@prisma/client';

import type { SeededStores } from './stores';
import type { SeededUser } from './users';

export async function seedCustomDrafts(
prisma: PrismaClient,
ctx: { users: SeededUser[]; stores: SeededStores },
): Promise<void> {
const user1 = ctx.users[0];
if (!user1) throw new Error('seedUsers must run before seedCustomDrafts');
const [p1, , p3] = ctx.stores.products;

await prisma.customDraft.createMany({
data: [
{
account_id: user1.id,
product_id: p1.id,
status: 'IN_PROGRESS',
},
{
account_id: user1.id,
product_id: p3.id,
status: 'READY_FOR_ORDER',
},
],
});
}
Loading
Loading