@@ -86,19 +86,33 @@ interface DashboardClientProps {
8686export interface ProfileMetrics {
8787 currentStreak : number ;
8888 commitClock : { day : string ; commits : number } [ ] ; // e.g., Sun-Sat daily totals
89- hourlyData ?: { hour : number ; commits : number } [ ] ; // Optional: 0-23 hour distribution
9089}
9190
9291export interface CoderProfile {
9392 peakHourStart : number ;
9493 peakHourEnd : number ;
95- profileName : 'Night Owl 🌙' | ' Early Builder ☀' | 'Weekend Warrior 🚀' | 'Consistent Runner 🏃♂️' ;
94+ profileName : 'Early Builder ☀' | 'Weekend Warrior 🚀' | 'Consistent Runner 🏃♂️' ;
9695 hourlyDistribution : number [ ] ;
9796 activeWeekdays : string [ ] ;
9897}
9998
99+ /**
100+ * Generates a coder profile based on available metrics.
101+ *
102+ * NOTE: Night Owl classification via hourlyData is NOT IMPLEMENTED.
103+ * GitHub's REST API only provides daily contribution granularity. Fetching hourly data
104+ * would require querying individual commits across all repositories, which is:
105+ * - Prohibitively expensive in latency (100s-1000s of requests per user)
106+ * - Infeasible within serverless function timeout constraints (~10 seconds)
107+ * - Not required for daily activity visualization use cases
108+ *
109+ * Instead, we classify developers into 3 profile types:
110+ * - Consistent Runner: High daily commit frequency (streak >= 10)
111+ * - Weekend Warrior: Most commits occur on weekends (>35% of commits)
112+ * - Early Builder: Default for other patterns
113+ */
100114export function generateCoderProfile ( metrics : ProfileMetrics ) : CoderProfile {
101- const { currentStreak, commitClock, hourlyData } = metrics ;
115+ const { currentStreak, commitClock } = metrics ;
102116
103117 let profileName : CoderProfile [ 'profileName' ] = 'Early Builder ☀' ;
104118
@@ -112,45 +126,21 @@ export function generateCoderProfile(metrics: ProfileMetrics): CoderProfile {
112126 }
113127 }
114128
115- // 2. Analyze Hourly Data for Night Owl vs Early Builder
116- let isNightOwl = false ;
117- if ( hourlyData && hourlyData . length > 0 ) {
118- const nightCommits = hourlyData
119- . filter ( ( d ) => d . hour >= 22 || d . hour <= 3 )
120- . reduce ( ( sum , d ) => sum + d . commits , 0 ) ;
121-
122- const morningCommits = hourlyData
123- . filter ( ( d ) => d . hour >= 5 && d . hour <= 10 )
124- . reduce ( ( sum , d ) => sum + d . commits , 0 ) ;
125-
126- isNightOwl = nightCommits > morningCommits ;
127- }
128-
129- // 3. Determine Final Profile Type
129+ // 2. Determine Final Profile Type
130130 if ( currentStreak >= 10 ) {
131131 profileName = 'Consistent Runner 🏃♂️' ;
132132 } else if ( isWeekendWarrior ) {
133133 profileName = 'Weekend Warrior 🚀' ;
134- } else if ( isNightOwl ) {
135- profileName = 'Night Owl 🌙' ;
136134 }
137135
138- // 4 . Populate UI properties based on the derived profile.
136+ // 3 . Populate UI properties based on the derived profile.
139137 // We use smooth curves here without the random 'hash' jitter for a cleaner UI.
140138 let peakHourStart = 9 ;
141139 let peakHourEnd = 17 ;
142140 let hourlyDistribution = new Array ( 24 ) . fill ( 0 ) ;
143141 let activeWeekdays = [ 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' ] ;
144142
145- if ( profileName === 'Night Owl 🌙' ) {
146- peakHourStart = 22 ;
147- peakHourEnd = 2 ;
148- hourlyDistribution = Array . from ( { length : 24 } , ( _ , h ) => {
149- const distFromMidnight = Math . min ( Math . abs ( h - 23 ) , Math . abs ( h + 1 ) ) ;
150- return Math . max ( 8 , Math . round ( 100 - distFromMidnight * 9.5 ) ) ;
151- } ) ;
152- activeWeekdays = [ 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' ] ;
153- } else if ( profileName === 'Early Builder ☀' ) {
143+ if ( profileName === 'Early Builder ☀' ) {
154144 peakHourStart = 6 ;
155145 peakHourEnd = 10 ;
156146 hourlyDistribution = Array . from ( { length : 24 } , ( _ , h ) => {
@@ -309,12 +299,12 @@ function getPersonalityTags(
309299 tags . push ( 'Backend Architect ⚙️' ) ;
310300 }
311301
312- if ( coderProfile . profileName === 'Night Owl 🌙' ) {
313- tags . push ( 'Night Coder 🌙' ) ;
314- } else if ( coderProfile . profileName === 'Early Builder ☀' ) {
302+ if ( coderProfile . profileName === 'Early Builder ☀' ) {
315303 tags . push ( 'Early Builder ☀' ) ;
316304 } else if ( coderProfile . profileName === 'Weekend Warrior 🚀' ) {
317305 tags . push ( 'Weekend Warrior 🚀' ) ;
306+ } else if ( coderProfile . profileName === 'Consistent Runner 🏃♂️' ) {
307+ tags . push ( 'Consistent Runner 🏃♂️' ) ;
318308 }
319309
320310 return tags . slice ( 0 , 3 ) ;
0 commit comments