@@ -11,15 +11,17 @@ import (
1111 "github.com/codeGROOVE-dev/slacker/pkg/github"
1212 "github.com/codeGROOVE-dev/slacker/pkg/home"
1313 "github.com/codeGROOVE-dev/slacker/pkg/state"
14+ "github.com/codeGROOVE-dev/slacker/pkg/usermapping"
1415 gogithub "github.com/google/go-github/v50/github"
1516)
1617
1718// HomeHandler handles app_home_opened events for a workspace.
1819type HomeHandler struct {
19- slackManager * Manager
20- githubManager * github.Manager
21- configManager * config.Manager
22- stateStore state.Store
20+ slackManager * Manager
21+ githubManager * github.Manager
22+ configManager * config.Manager
23+ stateStore state.Store
24+ reverseMapping * usermapping.ReverseService
2325}
2426
2527// NewHomeHandler creates a new home view handler.
@@ -28,12 +30,14 @@ func NewHomeHandler(
2830 githubManager * github.Manager ,
2931 configManager * config.Manager ,
3032 stateStore state.Store ,
33+ reverseMapping * usermapping.ReverseService ,
3134) * HomeHandler {
3235 return & HomeHandler {
33- slackManager : slackManager ,
34- githubManager : githubManager ,
35- configManager : configManager ,
36- stateStore : stateStore ,
36+ slackManager : slackManager ,
37+ githubManager : githubManager ,
38+ configManager : configManager ,
39+ stateStore : stateStore ,
40+ reverseMapping : reverseMapping ,
3741 }
3842}
3943
@@ -77,36 +81,35 @@ func (h *HomeHandler) tryHandleAppHomeOpened(ctx context.Context, teamID, slackU
7781 return fmt .Errorf ("failed to get Slack client: %w" , err )
7882 }
7983
80- // Get Slack user info to extract email
81- slackUser , err := slackClient .API ().GetUserInfo (slackUserID )
82- if err != nil {
83- // Don't mask invalid_auth errors - let them propagate for retry logic
84- if strings .Contains (err .Error (), "invalid_auth" ) {
85- return fmt .Errorf ("failed to get Slack user info: %w" , err )
86- }
87- slog .Warn ("failed to get Slack user info" , "user_id" , slackUserID , "error" , err )
88- return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
89- }
90-
91- // Extract GitHub username from email (simple heuristic: part before @)
92- // Works for "[email protected] " -> "username" 93- email := slackUser .Profile .Email
94- atIndex := strings .IndexByte (email , '@' )
95- if atIndex <= 0 {
96- slog .Warn ("could not extract GitHub username from Slack email" ,
97- "slack_user_id" , slackUserID ,
98- "email" , email )
99- return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
100- }
101- githubUsername := email [:atIndex ]
102-
10384 // Get all orgs for this workspace
10485 workspaceOrgs := h .workspaceOrgs (teamID )
10586 if len (workspaceOrgs ) == 0 {
10687 slog .Warn ("no workspace orgs found" , "team_id" , teamID )
107- return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
88+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID , nil )
89+ }
90+
91+ // Get config for first org to extract domain and user overrides
92+ cfg , exists := h .configManager .Config (workspaceOrgs [0 ])
93+ if ! exists {
94+ return fmt .Errorf ("no config for org: %s" , workspaceOrgs [0 ])
10895 }
10996
97+ // Update reverse mapping overrides from config
98+ if len (cfg .Users ) > 0 {
99+ h .reverseMapping .SetOverrides (cfg .Users )
100+ }
101+
102+ // Map Slack user to GitHub username
103+ mapping , err := h .reverseMapping .LookupGitHub (ctx , slackClient .API (), slackUserID , workspaceOrgs [0 ], cfg .Global .EmailDomain )
104+ if err != nil {
105+ slog .Warn ("failed to map Slack user to GitHub" ,
106+ "slack_user_id" , slackUserID ,
107+ "error" , err )
108+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID , nil )
109+ }
110+
111+ githubUsername := mapping .GitHubUsername
112+
110113 // Get GitHub client for first org (they all share the same app)
111114 githubClient , ok := h .githubManager .ClientForOrg (workspaceOrgs [0 ])
112115 if ! ok {
@@ -130,14 +133,14 @@ func (h *HomeHandler) tryHandleAppHomeOpened(ctx context.Context, teamID, slackU
130133 slog .Error ("failed to fetch dashboard" ,
131134 "github_user" , githubUsername ,
132135 "error" , err )
133- return h .publishPlaceholderHome (ctx , slackClient , slackUserID )
136+ return h .publishPlaceholderHome (ctx , slackClient , slackUserID , mapping )
134137 }
135138
136139 // Add workspace orgs to dashboard for UI display
137140 dashboard .WorkspaceOrgs = workspaceOrgs
138141
139- // Build Block Kit UI - use first org as primary
140- blocks := home .BuildBlocks (dashboard , workspaceOrgs [0 ])
142+ // Build Block Kit UI - use first org as primary, include debug info
143+ blocks := home .BuildBlocksWithDebug (dashboard , workspaceOrgs [0 ], mapping )
141144
142145 // Publish to Slack
143146 if err := slackClient .PublishHomeView (ctx , slackUserID , blocks ); err != nil {
@@ -177,14 +180,14 @@ func (h *HomeHandler) workspaceOrgs(teamID string) []string {
177180}
178181
179182// publishPlaceholderHome publishes a simple placeholder home view.
180- func (* HomeHandler ) publishPlaceholderHome (ctx context.Context , slackClient * Client , slackUserID string ) error {
183+ func (* HomeHandler ) publishPlaceholderHome (ctx context.Context , slackClient * Client , slackUserID string , mapping * usermapping. ReverseMapping ) error {
181184 slog .Debug ("publishing placeholder home" , "user_id" , slackUserID )
182185
183- blocks := home .BuildBlocks (& home.Dashboard {
186+ blocks := home .BuildBlocksWithDebug (& home.Dashboard {
184187 IncomingPRs : nil ,
185188 OutgoingPRs : nil ,
186189 WorkspaceOrgs : []string {"your-org" },
187- }, "your-org" )
190+ }, "your-org" , mapping )
188191
189192 return slackClient .PublishHomeView (ctx , slackUserID , blocks )
190193}
0 commit comments