Table of Contents
Architecture Diagram - PR Review Utility
ποΈ System Architecture (Phase 1)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER / BROWSER β
β http://localhost:5000 β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PRESENTATION LAYER β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β HTML/JavaScript UI (wwwroot/) β β
β β ββββββββββββββββββ βββββββββββββββ ββββββββββββββββ β β
β β β Index.cshtml β β site.css β β pr-viewer.js β β β
β β β (Bootstrap 5) β β (Styling) β β (UI Logic) β β β
β β ββββββββββββββββββ βββββββββββββββ ββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β HTTP Requests
β (GET/POST)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONTROLLER LAYER β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β HomeController PRController (API) β β
β β βββββββββββββββ ββββββββββββββββββββββββββ β
β β β Index() β β GET /api/pr/{id} ββ β
β β β Returns UI β β GET /api/pr/{id}/diff ββ β
β β β β β GET /api/pr/{id}/raw ββ β
β β βββββββββββββββ β GET /api/pr/{id}/exportββ β
β β ββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β Calls Services
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SERVICE LAYER β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β IBitBucketService (Interface) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β BitBucketService (Implementation) β β β
β β β β β β
β β β β’ GetPullRequestAsync() β β β
β β β β’ GetPullRequestDiffAsync() β β β
β β β β’ GetRawDiffAsync() β β β
β β β β’ ParseDiff() - Internal parser β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β HTTP Client
β + Basic Auth
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β EXTERNAL API β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β BitBucket REST API v2.0 β β
β β https://api.bitbucket.org/2.0 β β
β β β β
β β Endpoints Used: β β
β β β’ /repositories/{ws}/{repo}/pullrequests/{id} β β
β β β’ /repositories/{ws}/{repo}/pullrequests/{id}/diff β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Data Flow Diagram
User Action: "Fetch PR #42 from repo 'my-app'"
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 1. UI: pr-viewer.js β
β - Validate inputs β
β - Show loading spinner β
β - Make AJAX call β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β GET /api/pr/my-app/42
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 2. Controller: PRController β
β - Receive request β
β - Call service β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β GetPullRequestAsync("my-app", 42)
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 3. Service: BitBucketService β
β - Build API URL β
β - Add authentication β
β - Make HTTP request β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β GET https://api.bitbucket.org/...
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 4. BitBucket API β
β - Authenticate β
β - Fetch PR data β
β - Return JSON β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β JSON Response
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 5. Service: BitBucketService β
β - Parse JSON β
β - Transform to model β
β - Return PullRequest object β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β PullRequest object
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 6. Controller: PRController β
β - Serialize to JSON β
β - Return HTTP 200 OK β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β JSON Response
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β 7. UI: pr-viewer.js β
β - Parse response β
β - Update DOM β
β - Display PR details β
β - Hide loading spinner β
βββββββββββββββββββββββββββββββββββββββββββ
π Authentication Flow
βββββββββββββββββββββββββββββββββββββββββββ
β appsettings.json β
β { β
β "Username": "john@example.com", β
β "AppPassword": "ATBBxxx..." β
β } β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β Startup reads config
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β BitBucketConfig (Dependency Injection) β
β - Injected into BitBucketService β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β On each request
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β BitBucketService β
β credentials = Base64(username:password)β
β Header: Authorization: Basic {creds} β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
β HTTP Request with header
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β BitBucket API β
β - Validates credentials β
β - Returns data or 401 β
βββββββββββββββββββββββββββββββββββββββββββ
π Component Interaction Map
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Startup.cs β
β β’ Configures Services β
β β’ Registers HttpClient β
β β’ Binds BitBucketConfig β
β β’ Sets up MVC + API β
βββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββΊ HomeController βββΊ Returns Index.cshtml
β (Main UI)
β
ββββΊ PRController βββ¬βββΊ GetPullRequest()
β ββββΊ GetPullRequestDiff()
β ββββΊ GetRawDiff()
β ββββΊ ExportDiff()
β β
β β All methods call βΌ
β β
ββββΊ BitBucketService ββββββ
β
ββββΊ GetPullRequestAsync()
β ββββΊ HTTP GET to BitBucket
β
ββββΊ GetPullRequestDiffAsync()
β ββββΊ GetRawDiffAsync()
β ββββΊ ParseDiff()
β
ββββΊ GetRawDiffAsync()
ββββΊ HTTP GET to BitBucket
ποΈ File Organization Map
PRReviewUtility/
β
βββ Frontend (User sees this)
β βββ wwwroot/
β βββ js/pr-viewer.js ββββΊ Calls API endpoints
β βββ css/site.css ββββββββΊ Styles UI
β
βββ Backend (Server side)
β βββ Controllers/
β β βββ HomeController βββββΊ Serves UI
β β βββ PRController βββββββΊ Handles API requests
β β
β βββ Services/
β β βββ BitBucketService βββΊ Talks to BitBucket
β β
β βββ Models/
β βββ PullRequest ββββββββΊ PR data structure
β βββ DiffFile βββββββββββΊ Diff data structure
β βββ BitBucketConfig ββββΊ Configuration model
β
βββ Views/
β βββ Home/Index.cshtml ββββββΊ Main UI page
β βββ Shared/_Layout.cshtml βββΊ Bootstrap layout
β
βββ Configuration/
βββ appsettings.json βββββββΊ BitBucket credentials
βββ Startup.cs βββββββββββββΊ App configuration
βββ Program.cs βββββββββββββΊ Entry point
π― Request Flow for "Export Diff"
User clicks "Export Diff" button
β
βΌ
βββββββββββββββββββββββββββββββββββ
β JavaScript (pr-viewer.js) β
β exportBtn.click() β β
β window.location.href = β
β /api/pr/{repo}/{id}/export β
ββββββββββ¬βββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββ
β PRController.ExportDiff() β
β 1. Get PR details β
β 2. Get raw diff β
β 3. Build text file content β
β 4. Create file with metadata β
ββββββββββ¬βββββββββββββββββββββββββ
β
β return File(bytes, "text/plain", filename)
βΌ
βββββββββββββββββββββββββββββββββββ
β Browser β
β Downloads file: β
β "PR-42-my-app-diff.txt" β
βββββββββββββββββββββββββββββββββββ
π State Management
βββββββββββββββββββββββββββββββββββββββββββ
β JavaScript State (pr-viewer.js) β
β β
β β’ currentRepository: string β
β β’ currentPrId: number β
β β’ rawDiffText: string β
β β’ diff: object (files array) β
β β
β No persistence - resets on page reload β
βββββββββββββββββββββββββββββββββββββββββββ
Server is stateless:
β’ No session storage
β’ No cookies
β’ Each request independent
π Scalability Design
Current (Phase 1):
ββββββββββββ
β Browser β βββΊ Single .NET App βββΊ BitBucket API
ββββββββββββ
Future Phases:
ββββββββββββ βββββββββββββββ
β Browser β βββΊ Load Balancer ββ€ .NET App 1 ββββ
ββββββββββββ βββββββββββββββ€ β
β .NET App 2 ββββΌβββΊ BitBucket
βββββββββββββββ β
β
ββββββββββββββββ β
β Redis Cache βββ
ββββββββββββββββ
π¨ UI Component Structure
Index.cshtml (Main Page)
β
βββ Form Section
β βββ Repository Input
β βββ PR ID Input
β βββ Fetch Button
β
βββ Loading Spinner (hidden by default)
β
βββ Error Alert (hidden by default)
β
βββ PR Details Card (shown after fetch)
β βββ Title, Author, Branches
β βββ State Badge
β βββ Action Buttons
β βββ Export Diff
β βββ Toggle Raw Diff
β
βββ Files List Section
β βββ For each file:
β βββ File name
β βββ Status badge
β βββ Stats (+/-)
β βββ View button
β βββ Expandable diff content
β
βββ Raw Diff Section (toggle)
βββ Copy button
βββ Pre-formatted diff text
π Performance Characteristics
| Operation | Expected Time | Notes | |-----------|---------------|-------| | App Startup | < 3 seconds | Cold start | | Page Load | < 1 second | Static files cached | | API Request | 2-5 seconds | Depends on PR size | | Diff Parse | < 1 second | Client-side processing | | Export | Instant | No processing needed |
π Notes
- All diagrams are for Phase 1 implementation
- Phase 2 will add Rule Engine service layer
- Phase 3 will add AI Integration service layer
- System is designed for horizontal scaling
- Stateless design enables load balancing
Architecture diagrams for PR Review Utility v1.0