Skip to content

Commit 9bc2b6a

Browse files
committed
feat: Add Analytics Dashboard with deployment insights and enhanced UI
✨ New Features: - Analytics Dashboard with interactive charts and deployment metrics - Cross-environment deployment trend analysis and success rate tracking - Dynamic chart theming that adapts to all 4 theme modes (light/dark/pink/neon) - LinkedIn footer integration with professional branding 🔧 Critical Bug Fixes: - Fixed deployment count discrepancy (analytics vs history showing different counts) - Corrected environment directory path in deployment-history-service - Enhanced rollback filtering logic with isRollbackOperation() helper function - Fixed success rate calculation using proper status string matching 🎨 UI/UX Improvements: - Simplified main menu design - Added comprehensive search and filtering in deployment history - Implemented CSS modules for better style organization - Enhanced theme system with Chart.js color injection 🗑️ Code Cleanup: - Removed unused components - Consolidated search functionality into deployment history - Simplified routing structure for better navigation ✅ Testing & Quality: - Fixed rollback service test expectations to match actual API interface - All 630 unit tests now passing - Comprehensive validation through smoke tests and infrastructure tests 📚 Documentation: - Updated README with Analytics Dashboard feature - Enhanced USAGE-GUIDE with detailed analytics documentation - Updated DEVELOPER_ARCHITECTURE with new service architecture 🚀 Production Ready: - Successfully deployed and validated on Azure App Service - All analytics API endpoints working correctly - Multi-environment support confirmed
1 parent 8ae9d28 commit 9bc2b6a

File tree

15 files changed

+1045
-1522
lines changed

15 files changed

+1045
-1522
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ A modern React-based Azure App Service application that converts [Mermaid](https
1515
- **Smart Validation & Auto-Fix**: Real-time ERD validation with one-click fixes for common issues ([see all validations](docs/VALIDATION-AND-AUTOFIX.md))
1616
- **Relationship Support**: One-to-many relationships and junction tables for many-to-many
1717
- **Global Choice Integration**: Map to existing choice sets or create new ones
18+
- **Analytics Dashboard**: Interactive deployment insights with success rates, deployment trends, and rollback frequency visualization across all environments
1819
- **Deployment History & Rollback**: Persistent storage with Azure Blob Storage - track all deployments with modular rollback, choose exactly what to remove (relationships, entities, solution, publisher)
1920
- **Zero-Trust Security**: Managed identity authentication with no stored secrets
2021
- **Dev Proxy Integration**: Test API failures, rate limiting, and offline development ([see Dev Proxy Testing Guide](docs/DEV-PROXY-TESTING.md))
21-
- **Multiple Themes**: Light mode, dark mode, pink mode 💖, and retro neon mode 🌈✨
22+
- **Multiple Themes**: Light mode, dark mode, pink mode 💖, and retro neon mode 🌈✨ with dynamic chart theming
2223

2324
## Architecture
2425

docs/DEVELOPER_ARCHITECTURE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ graph TB
7777
ValidationSvc[Validation Service<br/>ERD Parsing & CDM Detect]
7878
DeploymentSvc[Deployment Service<br/>Solution Orchestration]
7979
DeploymentHistorySvc[Deployment History Service<br/>Tracking & Retrieval]
80+
AnalyticsSvc[Analytics Service<br/>Deployment Insights & Metrics]
8081
PublisherSvc[Publisher Service<br/>Publisher Management]
8182
ChoicesSvc[Global Choices Service<br/>Option Set Management]
8283
SolutionSvc[Solution Service<br/>Solution Operations]
@@ -137,10 +138,12 @@ graph TB
137138
138139
DeploymentCtrl --> DeploymentSvc
139140
DeploymentCtrl --> DeploymentHistorySvc
141+
DeploymentCtrl --> AnalyticsSvc
140142
DeploymentSvc --> DataverseRepo
141143
DeploymentSvc --> ConfigRepo
142144
DeploymentHistorySvc --> DeploymentFiles
143145
DeploymentHistorySvc --> IndexFiles
146+
AnalyticsSvc --> DeploymentHistorySvc
144147
145148
ConfigCtrl --> ConfigRepo
146149
@@ -167,7 +170,7 @@ graph TB
167170
168171
class UI,Router,Context,Services,Components,HistoryModal frontend
169172
class HTTP,Logger,CORS,Error,Stream,WizardCtrl,ValidationCtrl,DeploymentCtrl,AdminCtrl,ConfigCtrl backend
170-
class ValidationSvc,DeploymentSvc,DeploymentHistorySvc,PublisherSvc,ChoicesSvc,SolutionSvc,DataverseRepo,ConfigRepo service
173+
class ValidationSvc,DeploymentSvc,DeploymentHistorySvc,AnalyticsSvc,PublisherSvc,ChoicesSvc,SolutionSvc,DataverseRepo,ConfigRepo service
171174
class Dataverse,EntraID,ManagedIdentity,Parser,DataverseClient,PowerPlatform external
172175
class DeploymentFiles,IndexFiles storage
173176
```

docs/USAGE-GUIDE.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,55 @@ The rollback system is **environment-aware**:
161161
- Each environment maintains its own deployment history
162162
- Rollback buttons only appear for eligible deployments in each environment
163163

164+
## Analytics Dashboard
165+
166+
The Analytics Dashboard provides comprehensive insights into your deployment patterns and success metrics across all environments. Access it from the main menu to visualize your deployment history.
167+
168+
![Analytics Dashboard](media/analytics-dashboard.png)
169+
170+
### Key Metrics & Visualizations
171+
172+
The dashboard displays several key performance indicators:
173+
174+
**Success Rate Overview:**
175+
- Total deployments across all environments
176+
- Success vs. failure rates with visual breakdown
177+
- Deployment trend analysis over time
178+
179+
**Interactive Charts:**
180+
- **Deployment Trends**: Line chart showing deployment frequency over the last 7 days
181+
- **Success Rate Distribution**: Pie chart displaying successful vs. failed deployments
182+
- **Rollback Frequency**: Statistics on rollback operations and their frequency
183+
184+
**Multi-Environment Analytics:**
185+
- Cross-environment deployment aggregation
186+
- Environment-specific metrics and comparisons
187+
- Filtering options to focus on specific environments
188+
189+
### Theme-Aware Visualizations
190+
191+
The dashboard charts automatically adapt to your selected theme:
192+
- **Light Mode**: Professional blue/purple color scheme
193+
- **Dark Mode**: High-contrast colors optimized for dark backgrounds
194+
- **Pink Mode**: Pink-themed color palette
195+
- **Neon Mode**: Vibrant cyan/magenta neon colors
196+
197+
All charts use dynamic color injection to ensure perfect visibility regardless of your theme preference.
198+
199+
### Using the Analytics Dashboard
200+
201+
1. **Navigate**: Click "Analytics Dashboard" from the main menu
202+
2. **Review Metrics**: View overall success rates and deployment counts
203+
3. **Analyze Trends**: Use the trend chart to identify deployment patterns
204+
4. **Monitor Health**: Track rollback frequency to assess deployment quality
205+
5. **Theme Integration**: Charts automatically update when you change themes
206+
207+
The analytics help you:
208+
- **Monitor Deployment Health**: Track success rates and identify issues
209+
- **Identify Patterns**: Understand deployment frequency and timing
210+
- **Measure Impact**: See rollback rates and deployment stability
211+
- **Cross-Environment Insights**: Compare performance across dev/test/prod environments
212+
164213
## Intelligent Validation & Auto-Corrections
165214

166215
The React application includes sophisticated validation that provides real-time feedback and intelligent fixes:

scripts/setup-secretless.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ $localDevSecret = $existingSecrets | Where-Object { $_.displayName -eq "Local De
194194

195195
if ($localDevSecret) {
196196
Write-Warning "A 'Local Development Secret' already exists. Skipping secret creation."
197-
Write-Info "If you need a new secret, manually delete the old one first or create via Azure Portal."
198197
$clientSecret = $null
199198
} else {
200199
# Create new client secret (valid for 1 year)

src/backend/services/analytics-service.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,31 @@ function getDhs() {
99
return _dhs;
1010
}
1111

12+
// Helper function to determine if a deployment is a rollback operation
13+
function isRollbackOperation(deployment) {
14+
const status = String(deployment.status || '').toLowerCase();
15+
const operationType = String(deployment.summary?.operationType || '').toLowerCase();
16+
const deploymentMethod = String(deployment.metadata?.deploymentMethod || '').toLowerCase();
17+
18+
// Check for rollback status OR rollback operation type
19+
return status === 'rolled-back' ||
20+
status === 'rolled back' ||
21+
status === 'rollback' ||
22+
operationType === 'rollback' ||
23+
deploymentMethod === 'rollback';
24+
}
25+
1226
async function getDeploymentTrends() {
1327
// Query deployment history and return aggregated counts per day (last 30 days)
1428
const all = await getDhs().getAllDeploymentsFromAllEnvironments();
29+
// Filter out rollback entries - only count actual deployments
30+
const deployments = all.filter(d => !isRollbackOperation(d));
31+
1532
const byDay = {};
1633
const now = Date.now();
1734
const msPerDay = 24 * 60 * 60 * 1000;
1835

19-
all.forEach(d => {
36+
deployments.forEach(d => {
2037
const ts = new Date(d.timestamp || d.createdAt || now).toISOString().slice(0, 10);
2138
byDay[ts] = (byDay[ts] || 0) + 1;
2239
});
@@ -33,15 +50,20 @@ async function getDeploymentTrends() {
3350

3451
async function getSuccessRates() {
3552
const all = await getDhs().getAllDeploymentsFromAllEnvironments();
36-
const total = all.length;
37-
const success = all.filter(d => String(d.status).toLowerCase() === 'succeeded').length;
53+
// Filter out rollback entries - only count actual deployments
54+
const deployments = all.filter(d => !isRollbackOperation(d));
55+
const total = deployments.length;
56+
const success = deployments.filter(d => String(d.status).toLowerCase() === 'success').length;
3857
return { total, success, successRate: total === 0 ? 0 : success / total };
3958
}
4059

4160
async function getRollbackFrequency() {
4261
const all = await getDhs().getAllDeploymentsFromAllEnvironments();
43-
const rollbacks = all.filter(d => String(d.status).toLowerCase() === 'rolled-back' || String(d.status).toLowerCase() === 'rolled back').length;
44-
return { total: all.length, rollbacks, rollbackRate: all.length === 0 ? 0 : rollbacks / all.length };
62+
// Filter out rollback entries for total count - only count actual deployments
63+
const deployments = all.filter(d => !isRollbackOperation(d));
64+
// Count rollback operations separately
65+
const rollbacks = all.filter(d => isRollbackOperation(d)).length;
66+
return { total: deployments.length, rollbacks, rollbackRate: deployments.length === 0 ? 0 : rollbacks / deployments.length };
4567
}
4668

4769
module.exports = {

src/backend/services/deployment-history-service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,8 @@ class DeploymentHistoryService extends BaseService {
326326
async getAllEnvironments() {
327327
return this.executeOperation('getAllEnvironments', async () => {
328328
try {
329-
// List all index files
330-
const indexFiles = await this.storage.list('indexes/', { extension: '_index.json' });
329+
// List all index files - they are in the root of the storage directory, not in 'indexes/' subfolder
330+
const indexFiles = await this.storage.list('', { extension: '_index.json' });
331331

332332
const environments = [];
333333
for (const indexFile of indexFiles) {

src/frontend/.tsbuildinfo

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/frontend/src/App.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import { MainMenu } from './components/MainMenu';
66
import { RollbackPage } from './components/RollbackPage';
77
import { ErrorBoundary } from './components/ui/ErrorBoundary';
88
import { AnalyticsDashboard } from './components/analytics/AnalyticsDashboard';
9-
import { EnhancedSearch } from './components/search/EnhancedSearch';
10-
import { TemplateManagement } from './components/templates/TemplateManagement';
119
import { ThemeProvider, useTheme } from './context/ThemeContext';
1210
import { DeploymentProvider } from './context/DeploymentContext';
1311
import { AuthProvider } from './auth/AuthProvider';
@@ -46,8 +44,6 @@ const AppContent: React.FC = () => {
4644
<Route path="/rollback" element={<RollbackPage />} />
4745
<Route path="/deployment-history" element={<DeploymentHistory />} />
4846
<Route path="/analytics" element={<AnalyticsDashboard />} />
49-
<Route path="/search" element={<EnhancedSearch />} />
50-
<Route path="/templates" element={<TemplateManagement />} />
5147
{/* Redirect old routes */}
5248
<Route path="/home" element={<Navigate to="/" replace />} />
5349
<Route path="/menu" element={<Navigate to="/" replace />} />

0 commit comments

Comments
 (0)