Skip to content

Commit 05a2c00

Browse files
CopilotMWG-Logan
andauthored
Update documentation for SWA authentication and implemented frontend (MWG-Logan#30)
* Initial plan * Update documentation to reflect SWA authentication and implemented Blazor frontend Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com>
1 parent 3aed3b7 commit 05a2c00

File tree

5 files changed

+103
-30
lines changed

5 files changed

+103
-30
lines changed

Bezalu.ProjectReporting.API/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,13 @@ Required App Settings:
9595

9696
## Security
9797

98-
- Function auth level currently `Function`; set keys or add front-end auth (e.g., Entra ID) before production.
99-
- Do not send sensitive data inside report payload for PDF endpoint; only project analysis data.
98+
- **Authentication**: Azure Static Web Apps (SWA) with Azure AD integration
99+
- Function endpoints use `AuthorizationLevel.Anonymous` - authentication enforced at SWA layer
100+
- SWA configuration requires `authenticated` role for all `/api/*` routes
101+
- Unauthenticated requests blocked by SWA with 401 redirect to Azure AD login
102+
- Azure Functions trust SWA authentication; no additional function keys required
103+
- **Configuration**: Sensitive data (API keys, credentials) stored in Azure App Settings; use Azure Key Vault references in production
104+
- **Data Handling**: Report payloads contain project analysis data only; no raw credentials transmitted
100105

101106
## Extensibility
102107

README.md

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ A comprehensive project reporting solution that integrates with ConnectWise Mana
44

55
## Overview
66

7-
This solution consists of two main projects:
7+
This solution consists of three main projects:
88

99
1. **Bezalu.ProjectReporting.API** - Azure Functions backend API that generates project completion reports
10-
2. **Bezalu.ProjectReporting.Web** - Blazor WebAssembly frontend (not yet implemented)
10+
2. **Bezalu.ProjectReporting.Web** - Blazor WebAssembly frontend for interactive report viewing and PDF export
11+
3. **Bezalu.ProjectReporting.Shared** - Shared DTOs for consistent contracts between API and frontend
1112

1213
## Features
1314

@@ -90,8 +91,11 @@ Generates a comprehensive project completion report for the specified project ID
9091

9192
### Frontend (Web)
9293

93-
- **Blazor WebAssembly** (to be implemented)
94-
- Will consume the API to display and generate PDF reports
94+
- **Blazor WebAssembly** with Fluent UI components
95+
- Interactive report visualization with tabs for phases and tickets
96+
- AI-generated summary rendered as Markdown using Markdig
97+
- PDF export functionality (posts existing report to API to avoid regeneration)
98+
- Integrated with Azure Static Web Apps for deployment and authentication
9599

96100
## Project Structure
97101

@@ -106,16 +110,34 @@ CW-ProjectReporting/
106110
│ ├── host.json # Azure Functions host configuration
107111
│ ├── local.settings.json # Local development settings (not in git)
108112
│ └── README.md # Detailed API documentation
109-
└── Bezalu.ProjectReporting.Web/
110-
└── (Blazor WebAssembly project - to be implemented)
113+
├── Bezalu.ProjectReporting.Web/
114+
│ ├── Pages/ # Blazor pages (Home.razor)
115+
│ ├── Layout/ # Layout components
116+
│ ├── wwwroot/ # Static assets and JS helpers
117+
│ ├── staticwebapp.config.json # Azure Static Web Apps configuration
118+
│ └── Program.cs # Blazor WebAssembly startup
119+
└── Bezalu.ProjectReporting.Shared/
120+
└── DTOs/ # Shared data transfer objects
111121
```
112122

113123
## Security
114124

115-
- API keys and credentials stored in configuration (use Azure Key Vault in production)
116-
- `local.settings.json` excluded from source control
117-
- Function-level authorization required for API endpoints
118-
- No vulnerabilities detected by CodeQL security scanning
125+
- **Authentication**: Azure Static Web Apps with Azure AD (Entra ID) integration
126+
- API endpoints use `AuthorizationLevel.Anonymous` at the Function level
127+
- Authentication enforced by Static Web Apps configuration - requires `authenticated` role for `/api/*` routes
128+
- Unauthenticated requests receive 401 and redirect to Azure AD login
129+
- **Configuration**: API keys and credentials stored in Azure App Settings (use Azure Key Vault in production)
130+
- **Source Control**: `local.settings.json` excluded from source control
131+
- **Scanning**: No vulnerabilities detected by CodeQL security scanning
132+
133+
### Authentication Flow
134+
135+
1. User accesses the Blazor WebAssembly app hosted on Azure Static Web Apps
136+
2. Static Web Apps enforces authentication via Azure AD (configured in `staticwebapp.config.json`)
137+
3. Authenticated users receive session cookies from SWA
138+
4. API requests include SWA authentication cookies automatically
139+
5. SWA validates authentication before forwarding requests to Azure Functions
140+
6. Azure Functions trust the SWA authentication layer (no additional function-level auth required)
119141

120142
## Development Notes
121143

@@ -126,12 +148,13 @@ CW-ProjectReporting/
126148

127149
## Future Enhancements
128150

129-
- Implement Blazor frontend for report visualization
130-
- Add PDF generation capability
131-
- Implement additional report types
132-
- Add caching for improved performance
151+
- Add visual charts for timeline and budget variance trends
152+
- Implement additional report types (financial analysis, resource utilization)
153+
- Add caching layer for ConnectWise API responses
133154
- Add unit and integration tests
134155
- Implement batch report generation
156+
- Add Excel export capability
157+
- Implement browser-side caching (localStorage) for recent reports
135158

136159
## Documentation
137160

docs/architecture.md

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ The solution consists of three projects:
77
- Bezalu.ProjectReporting.Shared (DTO contracts shared by both)
88

99
## Data Flow
10-
1. User enters Project ID in Web UI.
11-
2. Front end POSTs projectId to `/api/reports/project-completion`.
12-
3. API fetches project, phases, tickets, notes from ConnectWise.
13-
4. API builds `ProjectCompletionReportResponse` and invokes Azure OpenAI to produce `AiGeneratedSummary`.
14-
5. JSON returned to client; client renders summary markdown using Markdig.
15-
6. User initiates PDF download; front end POSTs the full report JSON to `/api/reports/project-completion/pdf`.
16-
7. API composes PDF using QuestPDF with supplied data (skip re-fetch & AI).
17-
8. Client receives PDF bytes and triggers browser download via JS interop.
10+
1. User accesses Blazor WebAssembly app via Azure Static Web Apps.
11+
2. Static Web Apps enforces authentication via Azure AD (Entra ID).
12+
3. User enters Project ID in Web UI.
13+
4. Front end POSTs projectId to `/api/reports/project-completion` (with SWA auth cookies).
14+
5. SWA validates authentication and forwards request to Azure Functions.
15+
6. API fetches project, phases, tickets, notes from ConnectWise.
16+
7. API builds `ProjectCompletionReportResponse` and invokes Azure OpenAI to produce `AiGeneratedSummary`.
17+
8. JSON returned to client; client renders summary markdown using Markdig.
18+
9. User initiates PDF download; front end POSTs the full report JSON to `/api/reports/project-completion/pdf`.
19+
10. API composes PDF using QuestPDF with supplied data (skip re-fetch & AI).
20+
11. Client receives PDF bytes and triggers browser download via JS interop.
1821

1922
## Key Services
2023
- `IConnectWiseApiClient`: wraps HTTP calls to ConnectWise endpoints.
@@ -26,8 +29,18 @@ The solution consists of three projects:
2629
- POST for PDF avoids second expensive aggregation call.
2730
- Markdown + Markdig chosen for flexibility in AI summary formatting.
2831
- QuestPDF chosen for deterministic server-side PDF rendering.
32+
- **Azure Static Web Apps** provides integrated hosting, authentication, and API routing.
33+
- **Function AuthorizationLevel.Anonymous** used because authentication is enforced upstream by SWA.
34+
35+
## Authentication Architecture
36+
- **Static Web Apps** handles authentication via Azure AD (Entra ID)
37+
- `staticwebapp.config.json` enforces `authenticated` role for `/api/*` routes
38+
- Unauthenticated users redirected to `/.auth/login/aad`
39+
- SWA session cookies automatically included in API requests
40+
- Azure Functions trust SWA authentication layer - no function keys needed
2941

3042
## Future Enhancements
3143
- Caching of raw ConnectWise responses.
3244
- Additional export formats (Excel, HTML full report).
33-
- Authentication (OIDC) integration for user-level access.
45+
- User-level access control based on ConnectWise permissions.
46+
- Visual charts for variance trends and project analytics.

docs/deployment.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,38 @@
22

33
## Azure Static Web Apps + Azure Functions
44
- Front end (Blazor WASM) deployed to Static Web Apps.
5-
- API (Azure Functions) either integrated (api folder) or separate Functions App.
5+
- API (Azure Functions) integrated via SWA's managed Functions (api folder) or linked to separate Functions App.
6+
- **Authentication** handled by Static Web Apps with Azure AD integration.
7+
8+
## Steps (Integrated Deployment)
9+
1. Create Azure Static Web App resource in Azure Portal.
10+
2. Configure Azure AD authentication provider in SWA settings.
11+
3. Set `api_location` to point to Azure Functions project folder during SWA build.
12+
4. Configure Application Settings for ConnectWise + Azure OpenAI in SWA or linked Functions App.
13+
5. Deploy via GitHub Actions (auto-configured by SWA) or manual deployment:
14+
- Front-end: `dotnet publish -c Release Bezalu.ProjectReporting.Web`
15+
- API: Functions automatically deployed with SWA or via `func azure functionapp publish <name>`
616

717
## Steps (Separate Functions App)
818
1. Create Azure Functions App (Isolated .NET runtime) and configure Application Settings for ConnectWise + Azure OpenAI.
919
2. Deploy API project via `func azure functionapp publish <name>` or CI.
10-
3. Create Static Web App and set `api_location` to Functions App if integrated, else configure front end to call external API base URL.
11-
4. Upload front-end build (`dotnet publish -c Release Bezalu.ProjectReporting.Web`).
20+
3. Create Static Web App and link to external Functions App or configure front end to call external API base URL.
21+
4. Configure Azure AD authentication in Static Web Apps settings.
22+
5. Upload front-end build output to SWA.
1223

1324
## Configuration Keys
1425
- `ConnectWise:*`
1526
- `AzureOpenAI:Endpoint`
1627
- `AzureOpenAI:DeploymentName`
1728

1829
## Authentication
19-
- Add Entra ID or other auth on Static Web Apps; issue front-end access token; secure Functions with Easy Auth or custom.
30+
- **Azure Static Web Apps** integrated with **Azure AD (Entra ID)** for authentication
31+
- Configure authentication provider in Azure Portal under SWA > Settings > Authentication
32+
- `staticwebapp.config.json` enforces authentication:
33+
- `/api/*` routes require `authenticated` role
34+
- Unauthenticated users redirected to `/.auth/login/aad`
35+
- No function keys needed - Azure Functions use `AuthorizationLevel.Anonymous` and trust SWA authentication
36+
- Session managed by SWA; cookies automatically included in API requests
2037

2138
## Environment Segregation
2239
- Use separate resource groups for dev/stage/prod.

docs/frontend.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
# Front-End (Blazor WebAssembly)
22

3+
## Overview
4+
The front-end is a Blazor WebAssembly application using Microsoft Fluent UI components, deployed on Azure Static Web Apps with integrated Azure AD authentication.
5+
36
## Key Behaviors
7+
- User must authenticate via Azure AD before accessing the application.
48
- User enters Project ID; triggers report fetch.
59
- Displays metrics in Fluent UI components (cards, tabs, data grids, accordion).
610
- AI summary rendered as markdown using Markdig.
711
- PDF download posts existing report JSON to API; no recomputation.
812

13+
## Authentication
14+
- **Azure Static Web Apps** handles authentication via Azure AD (Entra ID)
15+
- Configured in `staticwebapp.config.json`:
16+
- `/api/*` routes require `authenticated` role
17+
- Unauthenticated users redirected to `/.auth/login/aad`
18+
- SWA session cookies automatically included in API requests
19+
- No additional token management needed in Blazor code
20+
921
## State Management
1022
- Local component state only (no global store yet).
1123
- `IsLoading` for initial report, `IsPdfLoading` for PDF call.
1224

1325
## HTTP
14-
- `HttpClient` base address from host environment; assumes reverse proxy or relative `/api` route.
26+
- `HttpClient` base address from host environment.
27+
- Assumes SWA reverse proxy routing for `/api` routes.
28+
- SWA authentication cookies automatically included in requests.
29+
- No manual authorization headers needed.
1530

1631
## File Download
1732
- `saveFile` JS helper converts Base64 to Blob and triggers `<a download>`.

0 commit comments

Comments
 (0)