From 7100842179c4f17ff601db821a7c08364da6c956 Mon Sep 17 00:00:00 2001 From: gahusb Date: Fri, 3 Jul 2026 12:48:42 +0900 Subject: [PATCH] =?UTF-8?q?feat(phase3a):=20ai-usage=EC=97=90=20music=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20+=20music=5Ftracks=C2=B7CHECK=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - lib/ai-usage.ts: MUSIC_DAILY_LIMIT=1 추가, AiService 타입에 'music' 포함 - lib/__tests__/ai-usage.test.ts: MUSIC_DAILY_LIMIT 상수 검증 테스트 추가 - supabase/migrations/2026-07-03-phase3a-music.sql: music_tracks 테이블, CHECK 확장, service_settings 정리 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01AAtcmKKtqDUe4NyVgy1aLQ --- lib/__tests__/ai-usage.test.ts | 5 +++- lib/ai-usage.ts | 3 ++- .../migrations/2026-07-03-phase3a-music.sql | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 supabase/migrations/2026-07-03-phase3a-music.sql diff --git a/lib/__tests__/ai-usage.test.ts b/lib/__tests__/ai-usage.test.ts index 0e1419f..ee833f1 100644 --- a/lib/__tests__/ai-usage.test.ts +++ b/lib/__tests__/ai-usage.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { kstDayStartISO, SAJU_DAILY_LIMIT, TAROT_DAILY_LIMIT } from '../ai-usage'; +import { kstDayStartISO, SAJU_DAILY_LIMIT, TAROT_DAILY_LIMIT, MUSIC_DAILY_LIMIT } from '../ai-usage'; describe('kstDayStartISO', () => { it('KST 자정을 UTC로 환산한다 (KST 15:00 UTC = 당일 00:00 KST)', () => { @@ -14,4 +14,7 @@ describe('kstDayStartISO', () => { expect(SAJU_DAILY_LIMIT).toBe(1); expect(TAROT_DAILY_LIMIT).toBe(3); }); + it('음악 일일 제한 상수', () => { + expect(MUSIC_DAILY_LIMIT).toBe(1); + }); }); diff --git a/lib/ai-usage.ts b/lib/ai-usage.ts index cba8c1b..977ca65 100644 --- a/lib/ai-usage.ts +++ b/lib/ai-usage.ts @@ -2,7 +2,8 @@ import type { SupabaseClient } from '@supabase/supabase-js'; export const SAJU_DAILY_LIMIT = 1; export const TAROT_DAILY_LIMIT = 3; -export type AiService = 'saju' | 'tarot'; +export const MUSIC_DAILY_LIMIT = 1; +export type AiService = 'saju' | 'tarot' | 'music'; /** KST(UTC+9) 자정을 UTC ISO로. 오늘 사용량 집계 하한. */ export function kstDayStartISO(now: Date): string { diff --git a/supabase/migrations/2026-07-03-phase3a-music.sql b/supabase/migrations/2026-07-03-phase3a-music.sql new file mode 100644 index 0000000..53ff02b --- /dev/null +++ b/supabase/migrations/2026-07-03-phase3a-music.sql @@ -0,0 +1,23 @@ +-- Phase 3a (2026-07-03): 음악 회원 저장 + 사용량 로그 확장 + 음악 숨김 해제 +-- 의존성: 2026-07-02-phase2-saju-tarot.sql(ai_usage_log 생성) 적용 후 실행 +-- 적용: 클라우드 Supabase + NAS self-host 양쪽 + +CREATE TABLE IF NOT EXISTS music_tracks ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + title text, + story text, + lyrics text, + style text, + audio_url text, + task_id text, + created_at timestamptz NOT NULL DEFAULT now() +); +ALTER TABLE music_tracks ENABLE ROW LEVEL SECURITY; +CREATE POLICY music_select_own ON music_tracks FOR SELECT USING (auth.uid() = user_id); + +-- ai_usage_log CHECK에 'music' 추가 (phase2의 인라인 CHECK auto-name 제거 후 재정의) +ALTER TABLE ai_usage_log DROP CONSTRAINT IF EXISTS ai_usage_log_service_check; +ALTER TABLE ai_usage_log ADD CONSTRAINT ai_usage_log_service_check CHECK (service IN ('saju','tarot','music')); + +DELETE FROM service_settings WHERE id = 'music';