Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,90 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
class OpenRankDashboard {
|
||||
-currentTab: string
|
||||
-mode: string
|
||||
-charts: object
|
||||
-mockData: object
|
||||
-projectState: object
|
||||
+init()
|
||||
+setupEventListeners()
|
||||
+setupTabNavigation()
|
||||
+switchTab(tab: string)
|
||||
+switchMode(mode: string)
|
||||
+loadMockData()
|
||||
+initCharts()
|
||||
+generateMockData()
|
||||
}
|
||||
|
||||
class Overview {
|
||||
+updateStats()
|
||||
+updateRankingTable()
|
||||
+initDistributionChart()
|
||||
+initActivityChart()
|
||||
}
|
||||
|
||||
class Repositories {
|
||||
+updateRepositoryGrid()
|
||||
+filterRepositories(filter: string)
|
||||
+onViewRepoDetails(repoName: string)
|
||||
+onViewRepoContributions(repoName: string)
|
||||
+showRepoDetails(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class Developers {
|
||||
+displayDeveloperAnalysis(developers: array)
|
||||
+filterDevelopers(keyword: string)
|
||||
}
|
||||
|
||||
class Network {
|
||||
+initNetworkGraph()
|
||||
}
|
||||
|
||||
class CodeReview {
|
||||
+setupCodeReviewPage()
|
||||
+loadExampleCode()
|
||||
+runCodeLinting()
|
||||
+simulatePylintAnalysis(code: string)
|
||||
+displayLintResults(score: number, issues: array)
|
||||
+resetCodeReviewResults()
|
||||
}
|
||||
|
||||
class Settings {
|
||||
+setupConfigListeners()
|
||||
+updateConfig(id: string, value: any)
|
||||
}
|
||||
|
||||
class ProjectMode {
|
||||
+buildProjectListFromGlobal()
|
||||
+renderProjectList(keyword: string)
|
||||
+renderApproxProject(fullName: string, days: number)
|
||||
+mountProjectView(snapshot: object)
|
||||
+triggerFullProjectCalculation(fullName: string)
|
||||
+autoTriggerFull(fullName: string, days: number)
|
||||
+pollTask(taskId: string, fullName: string, silent: boolean)
|
||||
}
|
||||
|
||||
OpenRankDashboard --> Overview: contains
|
||||
OpenRankDashboard --> Repositories: contains
|
||||
OpenRankDashboard --> Developers: contains
|
||||
OpenRankDashboard --> Network: contains
|
||||
OpenRankDashboard --> CodeReview: contains
|
||||
OpenRankDashboard --> Settings: contains
|
||||
OpenRankDashboard --> ProjectMode: contains
|
||||
|
||||
class DataLoader {
|
||||
+fetchProjectOverview(owner: string, repo: string)
|
||||
+fetchRepoDetails(owner: string, repo: string)
|
||||
+fetchContributors(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class UIHelper {
|
||||
+showNotification(message: string, type: string)
|
||||
+updateLastUpdateTime()
|
||||
+pushURLState()
|
||||
+hydrateFromURL()
|
||||
}
|
||||
|
||||
OpenRankDashboard --> DataLoader: uses
|
||||
OpenRankDashboard --> UIHelper: uses
|
||||
@ -0,0 +1,166 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
%% 核心算法类
|
||||
class OpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
+ calculate(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): Promise~OpenRankResult[]~
|
||||
- buildGraph(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): void
|
||||
- iterativeCalculation(): Promise~void~
|
||||
- generateResults(): OpenRankResult[]
|
||||
+ getCalculationStatus(): CalculationStatus
|
||||
+ getGraphStats()
|
||||
+ cleanup(): void
|
||||
}
|
||||
|
||||
class ProjectOpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
- weightingFramework: WeightingFramework
|
||||
+ calculateProjectOpenRank(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): Promise~OpenRankResult[]~
|
||||
- buildProjectGraph(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): void
|
||||
- computeCodeImpactPools(pr: any, totalLines: number, filesChanged: number, ...): object
|
||||
}
|
||||
|
||||
class SimpleGraph {
|
||||
+ nodes: Map~string, GraphNode~
|
||||
+ edges: GraphEdge[]
|
||||
- adjacencyList: Map~string, Set~string~~
|
||||
- incomingEdges: Map~string, GraphEdge[]~
|
||||
- outgoingEdges: Map~string, GraphEdge[]~
|
||||
+ addNode(node: GraphNode): void
|
||||
+ addEdge(edge: GraphEdge): void
|
||||
+ getNode(id: string): GraphNode | undefined
|
||||
+ getNeighbors(nodeId: string): GraphNode[]
|
||||
+ getIncomingEdges(nodeId: string): GraphEdge[]
|
||||
+ getOutgoingEdges(nodeId: string): GraphEdge[]
|
||||
+ clear(): void
|
||||
+ getStats()
|
||||
+ isConnected(): boolean
|
||||
+ getDegree(nodeId: string)
|
||||
+ getNodesByType(type: string): GraphNode[]
|
||||
}
|
||||
|
||||
%% 数据收集类
|
||||
class ProjectData {
|
||||
issues: IssueData[]
|
||||
pullRequests: PullRequestData[]
|
||||
}
|
||||
class GitHubDataCollector {
|
||||
- config: GitHubConfig
|
||||
- baseUrl: string
|
||||
+ collectProjectData(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~ProjectData~
|
||||
- listIssues(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- listPulls(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- collectIssueData(repo: GitHubRepo, issueIds: number[], events: any[]): Promise~IssueData[]~
|
||||
- collectPullRequestData(repo: GitHubRepo, prIds: number[], events: any[]): Promise~PullRequestData[]~
|
||||
}
|
||||
|
||||
%% API服务类
|
||||
class APIServer {
|
||||
- app: Express.Application
|
||||
- calculationCache: Record~string, CalcCacheEntry~
|
||||
- projectCache: Record~string, ProjectSnapshotCacheEntry~
|
||||
- tasks: Record~string, TaskEntry~
|
||||
+ start(): void
|
||||
- cleanupCaches(): void
|
||||
- createTask(): TaskEntry
|
||||
- getTask(id: string): TaskEntry | null
|
||||
- updateTask(id: string, patch: Partial~TaskEntry~): void
|
||||
}
|
||||
|
||||
%% 数据库类
|
||||
class MySQLConnection {
|
||||
+ pool: Pool
|
||||
+ closePool(): Promise~void~
|
||||
}
|
||||
|
||||
%% 接口和类型
|
||||
class ActivityData {
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
orgId?: number
|
||||
orgName?: string
|
||||
actorId: number
|
||||
actorLogin: string
|
||||
issueComment: number
|
||||
openIssue: number
|
||||
openPull: number
|
||||
reviewComment: number
|
||||
mergedPull: number
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
class IssueData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
}
|
||||
|
||||
class PullRequestData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
mergedAt?: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed' | 'merged'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
filesChanged?: number
|
||||
additions?: number
|
||||
deletions?: number
|
||||
}
|
||||
|
||||
class GraphNode {
|
||||
id: string
|
||||
type: NodeType
|
||||
platform: PlatformType
|
||||
name: string
|
||||
openrank: number
|
||||
lastOpenrank: number
|
||||
initValue: number
|
||||
retentionFactor: number
|
||||
converged: boolean
|
||||
metadata?: Record~string, any~
|
||||
}
|
||||
|
||||
class GraphEdge {
|
||||
source: string
|
||||
target: string
|
||||
weight: number
|
||||
type: 'activity' | 'belong' | 'reverse_belong' | 'reverse_activity'
|
||||
activityDetails?: any
|
||||
}
|
||||
|
||||
%% 关系
|
||||
OpenRankCalculator --> SimpleGraph: uses
|
||||
ProjectOpenRankCalculator --> SimpleGraph: uses
|
||||
APIServer --> OpenRankCalculator: calls
|
||||
APIServer --> ProjectOpenRankCalculator: calls
|
||||
APIServer --> GitHubDataCollector: uses
|
||||
APIServer --> MySQLConnection: uses
|
||||
OpenRankCalculator --> ActivityData: processes
|
||||
ProjectOpenRankCalculator --> IssueData: processes
|
||||
ProjectOpenRankCalculator --> PullRequestData: processes
|
||||
SimpleGraph --> GraphNode: contains
|
||||
SimpleGraph --> GraphEdge: contains
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,135 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- checkUI: CheckUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToCodeAssessmentPage()
|
||||
}
|
||||
|
||||
class CheckUI <<boundary>> {
|
||||
- pylint: Pylint
|
||||
- currentAssessment: CodeAssessment
|
||||
+ showCodeAssessmentPage()
|
||||
+ uploadCodeToBeTested(code: CodeFile): boolean
|
||||
+ displayAssessmentResult(result: AssessmentResult)
|
||||
}
|
||||
|
||||
class Pylint <<control>> {
|
||||
- database: DateBase
|
||||
+ assessCodeQuality(code: CodeFile): AssessmentResult
|
||||
+ generateQualityReport(assessment: AssessmentResult): QualityReport
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- codeAssessments: List<CodeAssessment>
|
||||
- qualityScores: List<QualityScore>
|
||||
- assessmentHistory: List<AssessmentHistory>
|
||||
+ storeCodeScore(assessment: CodeAssessment): boolean
|
||||
+ getAssessmentHistory(codeId: String): List<AssessmentHistory>
|
||||
+ getAverageQualityScore(projectId: String): double
|
||||
}
|
||||
|
||||
class CodeFile <<entity>> {
|
||||
- codeId: String
|
||||
- fileName: String
|
||||
- filePath: String
|
||||
- language: String
|
||||
- content: String
|
||||
- size: long
|
||||
+ getCodeId(): String
|
||||
+ getFileName(): String
|
||||
+ getLanguage(): String
|
||||
+ getContent(): String
|
||||
}
|
||||
|
||||
class AssessmentResult <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeId: String
|
||||
- qualityScore: double
|
||||
- issues: List<CodeIssue>
|
||||
- assessmentTime: Date
|
||||
+ getQualityScore(): double
|
||||
+ getIssues(): List<CodeIssue>
|
||||
+ generateSummary(): String
|
||||
}
|
||||
|
||||
class CodeAssessment <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeFile: CodeFile
|
||||
- result: AssessmentResult
|
||||
- assessmentDate: Date
|
||||
+ getAssessmentId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getResult(): AssessmentResult
|
||||
}
|
||||
|
||||
class CodeIssue <<entity>> {
|
||||
- issueId: String
|
||||
- type: String
|
||||
- severity: String
|
||||
- lineNumber: int
|
||||
- description: String
|
||||
- suggestion: String
|
||||
+ getIssueId(): String
|
||||
+ getType(): String
|
||||
+ getSeverity(): String
|
||||
+ getDescription(): String
|
||||
}
|
||||
|
||||
class QualityScore <<entity>> {
|
||||
- scoreId: String
|
||||
- codeId: String
|
||||
- overallScore: double
|
||||
- maintainabilityScore: double
|
||||
- reliabilityScore: double
|
||||
- efficiencyScore: double
|
||||
+ getOverallScore(): double
|
||||
+ getMaintainabilityScore(): double
|
||||
+ calculateCompositeScore(): double
|
||||
}
|
||||
|
||||
class QualityReport <<entity>> {
|
||||
- reportId: String
|
||||
- assessmentId: String
|
||||
- summary: String
|
||||
- detailedAnalysis: String
|
||||
- recommendations: List<String>
|
||||
+ generateReport(): String
|
||||
+ exportAsPDF(): void
|
||||
}
|
||||
|
||||
class AssessmentHistory <<entity>> {
|
||||
- historyId: String
|
||||
- codeId: String
|
||||
- assessmentDate: Date
|
||||
- qualityScore: double
|
||||
- trend: String
|
||||
+ getHistoryId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getQualityScore(): double
|
||||
+ calculateTrend(): String
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> CheckUI : "跳转"
|
||||
CheckUI --> Pylint : "调用测评"
|
||||
Pylint --> DateBase : "存储分数"
|
||||
Pylint ..> AssessmentResult : "生成"
|
||||
DateBase "1" *-- "many" CodeAssessment : "存储"
|
||||
DateBase "1" *-- "many" QualityScore : "包含"
|
||||
DateBase "1" *-- "many" AssessmentHistory : "记录历史"
|
||||
CodeAssessment "1" *-- "1" CodeFile : "测评"
|
||||
CodeAssessment "1" *-- "1" AssessmentResult : "包含结果"
|
||||
AssessmentResult "1" *-- "many" CodeIssue : "包含问题"
|
||||
AssessmentResult "1" *-- "1" QualityScore : "关联分数"
|
||||
Pylint ..> QualityReport : "生成报告"
|
||||
|
||||
|
||||
@enduml
|
||||
Binary file not shown.
Loading…
Reference in new issue