99 orderBy ,
1010 getDoc ,
1111 Timestamp ,
12+ limit ,
13+ updateDoc ,
1214} from 'firebase/firestore' ;
1315import { db } from '@/lib/firebase' ;
1416
@@ -25,12 +27,6 @@ function dateKeyKST(date = new Date()) {
2527 return kst . toISOString ( ) . slice ( 0 , 10 ) ;
2628}
2729
28- const formatDate = ( d : string | Date | undefined ) => {
29- if ( ! d ) return '' ;
30- if ( typeof d === 'string' ) return d ;
31- return d . toISOString ( ) . split ( 'T' ) [ 0 ] ; // YYYY-MM-DD 형식
32- } ;
33-
3430export const recomputeDailyStat = async ( uid : string ) => {
3531 const dateKey = dateKeyKST ( ) ;
3632
@@ -54,6 +50,10 @@ export const recomputeDailyStat = async (uid: string) => {
5450 /** 3. DailyStat 덮어쓰기 */
5551 const ref = doc ( db , 'users' , uid , 'dailyStats' , dateKey ) ;
5652
53+ /** 4. 연속 잔디 심기 일 수 계산 */
54+ const streakDays = await fetchStreakDays ( uid ) ;
55+ await updateDoc ( doc ( db , 'users' , uid ) , { streakDays } ) ;
56+
5757 await setDoc (
5858 ref ,
5959 {
@@ -109,3 +109,44 @@ export const fetchDailyStatByDate = async (
109109 total : data . total ?? 0 ,
110110 } ;
111111} ;
112+
113+ function prevDateKey ( key : string ) {
114+ const [ y , m , d ] = key . split ( '-' ) . map ( Number ) ;
115+ // UTC로 만들고 하루 빼서 다시 YYYY-MM-DD
116+ const utc = new Date ( Date . UTC ( y , m - 1 , d ) ) ;
117+ utc . setUTCDate ( utc . getUTCDate ( ) - 1 ) ;
118+ return utc . toISOString ( ) . slice ( 0 , 10 ) ;
119+ }
120+
121+ async function fetchStreakDays ( uid : string ) : Promise < number > {
122+ const todayKey = dateKeyKST ( ) ;
123+
124+ // 최근 400일 정도만 읽어도 충분 (1년 스트릭 기준)
125+ const statsRef = collection ( db , 'users' , uid , 'dailyStats' ) ;
126+ const q = query (
127+ statsRef ,
128+ where ( 'date' , '<=' , todayKey ) ,
129+ orderBy ( 'date' , 'desc' ) ,
130+ limit ( 400 )
131+ ) ;
132+
133+ const snap = await getDocs ( q ) ;
134+
135+ // 빠른 조회용 map
136+ const map = new Map < string , number > ( ) ;
137+ snap . docs . forEach ( ( d ) => {
138+ const data = d . data ( ) as DailyStat ;
139+ map . set ( data . date , data . total ?? 0 ) ;
140+ } ) ;
141+
142+ const todayTotal = map . get ( todayKey ) ?? 0 ;
143+ let cursor = todayTotal > 0 ? todayKey : prevDateKey ( todayKey ) ;
144+
145+ let streak = 0 ;
146+ while ( ( map . get ( cursor ) ?? 0 ) > 0 ) {
147+ streak += 1 ;
148+ cursor = prevDateKey ( cursor ) ;
149+ }
150+
151+ return streak ;
152+ }
0 commit comments