Files
reloop-v2/backend/prisma/migrations/20260414093339_phase10_ps_tables/migration.sql
reloop 6ceeee4f3f feat(phase10B): Solved.ac PS 모듈 신규 + bojHandle 등록
- prisma: PsProblem / PsBookmark / PsSyncState 모델, StudyLog.psProblemId
- migration: phase10_ps_tables
- ps/solved-ac.client: axios 클라이언트(rate-limit 3req/s, 지수 백오프 3회)
  searchProblems / getProblem / getUser / getUserProblemStats / getUserTop100
- ps/ps.module + service + controller: search/bookmark/sync 6 endpoint
  - JWT guard, throttler, sync 멱등성 (PsSyncState lastSolvedCount)
  - sync 시 시스템 Subject "PS" 자동 생성, StudyLog bulk insert (중복 skip)
- me/auth: bojHandle / focusUnits PATCH 지원, MeUser 응답 확장
- vitest: solved-ac.client 7 테스트 통과 (4 메서드 + 429 재시도)

Phase 10B DoD 통과.
2026-04-14 18:47:09 +09:00

63 lines
2.3 KiB
SQL

-- AlterTable
ALTER TABLE `study_logs` ADD COLUMN `psProblemId` INTEGER NULL;
-- CreateTable
CREATE TABLE `ps_problems` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`bojId` INTEGER NOT NULL,
`title` VARCHAR(191) NOT NULL,
`titleKo` VARCHAR(191) NULL,
`level` INTEGER NOT NULL,
`tags` JSON NULL,
`acceptedUserCount` INTEGER NULL,
`averageTries` DOUBLE NULL,
`solvedacUpdatedAt` DATETIME(3) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
UNIQUE INDEX `ps_problems_bojId_key`(`bojId`),
INDEX `ps_problems_level_idx`(`level`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `ps_bookmarks` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`psProblemId` INTEGER NOT NULL,
`memo` VARCHAR(191) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
INDEX `ps_bookmarks_userId_idx`(`userId`),
UNIQUE INDEX `ps_bookmarks_userId_psProblemId_key`(`userId`, `psProblemId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `ps_sync_states` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`lastSyncedAt` DATETIME(3) NULL,
`lastSolvedCount` INTEGER NOT NULL DEFAULT 0,
`lastTier` INTEGER NULL,
`updatedAt` DATETIME(3) NOT NULL,
UNIQUE INDEX `ps_sync_states_userId_key`(`userId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateIndex
CREATE INDEX `study_logs_psProblemId_idx` ON `study_logs`(`psProblemId`);
-- AddForeignKey
ALTER TABLE `study_logs` ADD CONSTRAINT `study_logs_psProblemId_fkey` FOREIGN KEY (`psProblemId`) REFERENCES `ps_problems`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `ps_bookmarks` ADD CONSTRAINT `ps_bookmarks_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `ps_bookmarks` ADD CONSTRAINT `ps_bookmarks_psProblemId_fkey` FOREIGN KEY (`psProblemId`) REFERENCES `ps_problems`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `ps_sync_states` ADD CONSTRAINT `ps_sync_states_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;