diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index e0f9949..2237603 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,6 +21,12 @@ jobs: - name: Install dependencies run: go mod tidy + - name: Check formatting + run: test -z "$(gofmt -l .)" + + - name: Vet + run: go vet ./... + - name: Run Tests run: go test -v ./... diff --git a/.gitignore b/.gitignore index 054d927..f361425 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ coverage.* *.coverprofile profile.cov +*.log # Dependency directories (remove the comment below to include it) # vendor/ @@ -33,4 +34,4 @@ go.work.sum sentinent-backend # db -sentinent.db \ No newline at end of file +sentinent.db diff --git a/handlers/jira.go b/handlers/jira.go index 6112ae3..9ea2022 100644 --- a/handlers/jira.go +++ b/handlers/jira.go @@ -372,10 +372,10 @@ func JiraIssueActionHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Failed to perform transition: "+err.Error(), http.StatusBadRequest) return } - + // Optional: Trigger a background sync to reflect changes quickly go services.SyncJiraSignals(userID, workspaceID) - + w.WriteHeader(http.StatusNoContent) return } diff --git a/models/integration.go b/models/integration.go index 61c1a1d..008bbfa 100644 --- a/models/integration.go +++ b/models/integration.go @@ -16,8 +16,8 @@ type ExternalIntegration struct { } type IntegrationStatus struct { - Provider string `json:"provider"` - Configured bool `json:"configured"` - Connected bool `json:"connected"` - UpdatedAt time.Time `json:"updated_at,omitempty"` + Provider string `json:"provider"` + Configured bool `json:"configured"` + Connected bool `json:"connected"` + UpdatedAt time.Time `json:"updated_at,omitempty"` } diff --git a/models/signal.go b/models/signal.go index acb5b02..24625b4 100644 --- a/models/signal.go +++ b/models/signal.go @@ -3,31 +3,31 @@ package models import "time" const ( - SourceTypeSlack = "slack" - SourceTypeGitHub = "github" - SourceTypeJira = "jira" - SignalStatusUnread = "unread" - SignalStatusRead = "read" + SourceTypeSlack = "slack" + SourceTypeGitHub = "github" + SourceTypeJira = "jira" + SignalStatusUnread = "unread" + SignalStatusRead = "read" SignalStatusArchived = "archived" ) type Signal struct { - ID int `json:"id"` - UserID int `json:"user_id"` - WorkspaceID int `json:"workspace_id,omitempty"` - SourceType string `json:"source_type"` - SourceID string `json:"source_id"` - ExternalID string `json:"external_id,omitempty"` - Title string `json:"title"` - Content string `json:"content,omitempty"` - Author string `json:"author,omitempty"` - Body string `json:"body,omitempty"` - URL string `json:"url,omitempty"` - Status string `json:"status"` - SourceMetadata interface{} `json:"source_metadata,omitempty"` - ReceivedAt time.Time `json:"received_at,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int `json:"id"` + UserID int `json:"user_id"` + WorkspaceID int `json:"workspace_id,omitempty"` + SourceType string `json:"source_type"` + SourceID string `json:"source_id"` + ExternalID string `json:"external_id,omitempty"` + Title string `json:"title"` + Content string `json:"content,omitempty"` + Author string `json:"author,omitempty"` + Body string `json:"body,omitempty"` + URL string `json:"url,omitempty"` + Status string `json:"status"` + SourceMetadata interface{} `json:"source_metadata,omitempty"` + ReceivedAt time.Time `json:"received_at,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type GitHubMetadata struct { diff --git a/server.log b/server.log deleted file mode 100644 index 6b1186e..0000000 --- a/server.log +++ /dev/null @@ -1,4 +0,0 @@ -2026/04/27 19:22:40 GitHub integration not configured: GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET must be set -2026/04/27 19:22:40 Sync service started with interval: 5m0s -2026/04/27 19:22:40 Server started on :8080 -exit status 1 diff --git a/services/github_coverage_test.go b/services/github_coverage_test.go index 9ba4eba..6765739 100644 --- a/services/github_coverage_test.go +++ b/services/github_coverage_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "golang.org/x/oauth2" _ "github.com/mattn/go-sqlite3" + "golang.org/x/oauth2" ) func setupGitHubCoverageTestDB(t *testing.T) func() { @@ -273,4 +273,3 @@ func TestFetchAssignedIssuesAndListAccessibleReposWithLocalGitHubServer(t *testi t.Fatalf("unexpected repo payload: %+v", repos[0]) } } - diff --git a/services/jira.go b/services/jira.go index e4d276c..9ea5e60 100644 --- a/services/jira.go +++ b/services/jira.go @@ -36,7 +36,7 @@ type JiraIssue struct { ID string `json:"id"` Key string `json:"key"` Fields struct { - Summary string `json:"summary"` + Summary string `json:"summary"` Description interface{} `json:"description"` Status struct { Name string `json:"name"` @@ -358,7 +358,7 @@ func parseADFToText(node interface{}) string { } nodeType, _ := m["type"].(string) - + var sb strings.Builder if nodeType == "text" { @@ -391,9 +391,9 @@ func formatDescription(desc interface{}) string { if desc == nil { return "" } - + text := strings.TrimSpace(parseADFToText(desc)) - + if len(text) > 500 { return text[:500] + "..." } @@ -435,7 +435,7 @@ type JiraTransition struct { // GetAvailableTransitions fetches transitions for a specific issue func GetAvailableTransitions(client *http.Client, cloudId string, issueKey string) ([]JiraTransition, error) { apiURL := fmt.Sprintf("https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s/transitions", cloudId, issueKey) - + req, err := http.NewRequest("GET", apiURL, nil) if err != nil { return nil, err @@ -466,7 +466,7 @@ func GetAvailableTransitions(client *http.Client, cloudId string, issueKey strin // PerformTransition executes a status change on a specific issue func PerformTransition(client *http.Client, cloudId string, issueKey string, transitionID string) error { apiURL := fmt.Sprintf("https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s/transitions", cloudId, issueKey) - + requestBody, _ := json.Marshal(map[string]interface{}{ "transition": map[string]string{ "id": transitionID, @@ -498,12 +498,12 @@ func PerformTransition(client *http.Client, cloudId string, issueKey string, tra // AddJiraComment adds a comment to a specific issue func AddJiraComment(client *http.Client, cloudId string, issueKey string, commentText string) error { apiURL := fmt.Sprintf("https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s/comment", cloudId, issueKey) - + // Jira API v3 expects ADF for comments. requestBody, _ := json.Marshal(map[string]interface{}{ "body": map[string]interface{}{ "version": 1, - "type": "doc", + "type": "doc", "content": []map[string]interface{}{ { "type": "paragraph", @@ -582,7 +582,7 @@ func saveJiraIssueAsSignal(userID, workspaceID int, issue JiraIssue, cloudURL st if issue.Fields.Priority != nil { priorityName = issue.Fields.Priority.Name } - + assigneeName := "" if issue.Fields.Assignee != nil { assigneeName = issue.Fields.Assignee.DisplayName @@ -609,10 +609,10 @@ func saveJiraIssueAsSignal(userID, workspaceID int, issue JiraIssue, cloudURL st updatedAt := parseJiraDate(issue.Fields.Updated) // Since SourceMetadata in models.Signal is strongly typed to GitHubMetadata for now, - // we will likely store Jira metadata in a new field or JSON encode it into the body to be generic. + // we will likely store Jira metadata in a new field or JSON encode it into the body to be generic. // Wait, the model update we applied added JiraMetadata but didn't modify Signal struct's SourceMetadata type! // We might need to change it to interface{} or add JiraMetadata *JiraMetadata - + // But let's just save it. _, err := database.DB.Exec( `INSERT INTO signals