Skip to content

Commit b3e1c84

Browse files
committed
specs: migrate to ms graph
1 parent 6edc471 commit b3e1c84

File tree

3 files changed

+452
-0
lines changed

3 files changed

+452
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
# Design Document
2+
3+
## Overview
4+
5+
This design outlines the migration from direct REST API calls using superagent to the official Microsoft Graph SDK (@microsoft/microsoft-graph-client) for OneNote operations. The migration will maintain all existing functionality while leveraging the SDK's built-in features including automatic retries, better error handling, and improved authentication integration.
6+
7+
The current system uses direct HTTP calls to Microsoft Graph endpoints for OneNote operations including retrieving sections, pages, page content, and image downloads. The new implementation will use the Graph SDK's fluent API while preserving the exact same behavior and data flow.
8+
9+
## Architecture
10+
11+
### Current Architecture
12+
```
13+
MSAL Authentication → superagent HTTP calls → OneNote REST API
14+
```
15+
16+
### New Architecture
17+
```
18+
MSAL Authentication → Graph SDK Client → OneNote REST API
19+
```
20+
21+
### Authentication Integration
22+
23+
The Graph SDK will integrate with the existing MSAL authentication system through a custom authentication provider that bridges the current token management with the SDK's authentication interface.
24+
25+
```javascript
26+
class MSALAuthenticationProvider {
27+
async getAccessToken() {
28+
const onenoteData = localStorage.getItem('onenote');
29+
if (!onenoteData || !onenoteData.accessToken) {
30+
throw new Error('No access token available');
31+
}
32+
return onenoteData.accessToken;
33+
}
34+
}
35+
```
36+
37+
## Components and Interfaces
38+
39+
### 1. Authentication Provider Bridge
40+
41+
**Purpose**: Bridge existing MSAL token management with Graph SDK authentication requirements
42+
43+
**Implementation**:
44+
- Implements the Graph SDK's `AuthenticationProvider` interface
45+
- Retrieves tokens from existing localStorage cache
46+
- Handles token expiration by delegating to existing refresh mechanisms
47+
48+
### 2. Graph Client Factory
49+
50+
**Purpose**: Create and configure the Microsoft Graph client instance
51+
52+
**Implementation**:
53+
```javascript
54+
function createGraphClient() {
55+
const authProvider = new MSALAuthenticationProvider();
56+
57+
return Client.initWithMiddleware({
58+
authProvider,
59+
defaultVersion: 'v1.0',
60+
debugLogging: process.env.NODE_ENV === 'development'
61+
});
62+
}
63+
```
64+
65+
### 3. OneNote Service Layer
66+
67+
**Purpose**: Encapsulate all OneNote operations using the Graph SDK
68+
69+
**Key Methods**:
70+
- `getSections(notebookName, sectionName)` - Find section by notebook and name
71+
- `getPageCount(sectionId)` - Get total page count for a section
72+
- `getPages(sectionId, options)` - Get pages with pagination
73+
- `getPagePreview(pageId)` - Get page preview content
74+
- `getPageContent(pageId)` - Get full page HTML content
75+
- `downloadImage(imageUrl)` - Download images from Graph endpoints
76+
77+
### 4. Migration Wrapper
78+
79+
**Purpose**: Provide backward compatibility during migration
80+
81+
**Implementation**: Maintains the same function signatures as existing code while internally using the Graph SDK.
82+
83+
## Data Models
84+
85+
### Section Model
86+
```javascript
87+
{
88+
id: string,
89+
displayName: string,
90+
pagesUrl: string,
91+
parentNotebook: {
92+
displayName: string,
93+
sectionsUrl: string
94+
}
95+
}
96+
```
97+
98+
### Page Model
99+
```javascript
100+
{
101+
id: string,
102+
title: string,
103+
self: string,
104+
links: {
105+
oneNoteClientUrl: { href: string },
106+
oneNoteWebUrl: { href: string }
107+
}
108+
}
109+
```
110+
111+
### Page Preview Model
112+
```javascript
113+
{
114+
previewText: string,
115+
links: {
116+
previewImageUrl?: { href: string }
117+
}
118+
}
119+
```
120+
121+
## Error Handling
122+
123+
### SDK Error Mapping
124+
125+
The Graph SDK provides enhanced error handling that will be mapped to maintain compatibility with existing error handling patterns:
126+
127+
```javascript
128+
function mapGraphError(error) {
129+
// Map Graph SDK errors to existing error format
130+
if (error.code === 'InvalidAuthenticationToken') {
131+
throw new Error('Token refresh failed - device login required');
132+
}
133+
134+
if (error.code === 'TooManyRequests') {
135+
// SDK handles retries automatically, but we can add custom logic
136+
throw new Error('Rate limit exceeded');
137+
}
138+
139+
// Preserve original error structure for unknown errors
140+
throw error;
141+
}
142+
```
143+
144+
### Timeout Configuration
145+
146+
Configure SDK timeouts to match existing behavior:
147+
148+
```javascript
149+
const client = Client.initWithMiddleware({
150+
authProvider,
151+
middleware: [
152+
new TimeoutHandler({
153+
timeout: 120000 // 120 seconds to match existing TIMEOUTS.response
154+
})
155+
]
156+
});
157+
```
158+
159+
## Testing Strategy
160+
161+
### Unit Tests
162+
163+
1. **Authentication Provider Tests**
164+
- Test token retrieval from localStorage
165+
- Test error handling when tokens are missing/expired
166+
- Test integration with existing MSAL flow
167+
168+
2. **OneNote Service Tests**
169+
- Mock Graph SDK client responses
170+
- Test all OneNote operations (sections, pages, content, images)
171+
- Verify data transformation matches existing format
172+
- Test error scenarios and mapping
173+
174+
3. **Integration Tests**
175+
- Test complete flow from authentication to data retrieval
176+
- Verify backward compatibility with existing function signatures
177+
- Test timeout and retry behavior
178+
179+
### Migration Testing
180+
181+
1. **Parallel Testing**
182+
- Run both old and new implementations side-by-side
183+
- Compare outputs to ensure identical behavior
184+
- Measure performance differences
185+
186+
2. **Feature Parity Tests**
187+
- Random note selection produces same distribution
188+
- Sequential note tracking works identically
189+
- Image download maintains size limits and streaming
190+
- Recent note filtering behaves the same
191+
192+
## Implementation Plan
193+
194+
### Phase 1: Foundation
195+
- Install Graph SDK and fetch polyfill dependencies
196+
- Create authentication provider bridge
197+
- Set up Graph client factory with proper configuration
198+
199+
### Phase 2: Core Services
200+
- Implement OneNote service layer using Graph SDK
201+
- Create migration wrapper maintaining existing interfaces
202+
- Add comprehensive error handling and mapping
203+
204+
### Phase 3: Feature Migration
205+
- Replace section lookup functionality
206+
- Replace page counting and retrieval
207+
- Replace page preview and content operations
208+
- Replace image download functionality
209+
210+
### Phase 4: Testing & Validation
211+
- Implement comprehensive test suite
212+
- Run parallel testing to verify behavior
213+
- Performance testing and optimization
214+
- Remove superagent dependency if no longer needed
215+
216+
## Configuration Changes
217+
218+
### Package.json Updates
219+
```json
220+
{
221+
"dependencies": {
222+
"@microsoft/microsoft-graph-client": "^3.0.7",
223+
"isomorphic-fetch": "^3.0.0"
224+
}
225+
}
226+
```
227+
228+
### Environment Variables
229+
No new environment variables required - existing MS Graph configuration will be reused.
230+
231+
## Backward Compatibility
232+
233+
The migration maintains 100% backward compatibility by:
234+
235+
1. **Preserving Function Signatures**: All existing function calls work unchanged
236+
2. **Maintaining Data Structures**: Response objects have identical structure
237+
3. **Keeping Error Patterns**: Error messages and types remain consistent
238+
4. **Preserving Behavior**: Random selection, sequential tracking, and caching work identically
239+
240+
## Performance Considerations
241+
242+
### Expected Improvements
243+
- **Automatic Retries**: SDK handles transient failures automatically
244+
- **Connection Pooling**: Better HTTP connection management
245+
- **Request Optimization**: SDK optimizes Graph API calls
246+
247+
### Monitoring Points
248+
- Response times for OneNote operations
249+
- Memory usage during image downloads
250+
- Error rates and retry patterns
251+
- Token refresh frequency
252+
253+
## Security Considerations
254+
255+
### Token Handling
256+
- Graph SDK never stores tokens - relies on our authentication provider
257+
- Existing MSAL security model remains unchanged
258+
- Token refresh logic preserved exactly
259+
260+
### Image Downloads
261+
- Maintain existing 3MB size limits
262+
- Preserve streaming download behavior for large files
263+
- Keep existing timeout protections
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Requirements Document
2+
3+
## Introduction
4+
5+
This feature involves migrating the existing OneNote API integration from direct REST API calls using superagent to the official Microsoft Graph SDK (@microsoft/microsoft-graph-client). The current system retrieves random or sequential notes from OneNote sections and sends them via Telegram notifications. The migration should maintain all existing functionality while leveraging the benefits of the official SDK including better error handling, automatic retries, and improved type safety.
6+
7+
## Requirements
8+
9+
### Requirement 1
10+
11+
**User Story:** As a system administrator, I want the OneNote integration to use the official Microsoft Graph SDK, so that the system benefits from improved reliability, better error handling, and official Microsoft support.
12+
13+
#### Acceptance Criteria
14+
15+
1. WHEN the system initializes THEN it SHALL use @microsoft/microsoft-graph-client instead of direct superagent calls
16+
2. WHEN making Graph API requests THEN the system SHALL use the Graph SDK's built-in authentication handling
17+
3. WHEN API errors occur THEN the system SHALL leverage the SDK's enhanced error handling and retry mechanisms
18+
4. WHEN the migration is complete THEN all existing OneNote functionality SHALL work identically to the current implementation
19+
20+
### Requirement 2
21+
22+
**User Story:** As a developer, I want comprehensive tests for the migrated OneNote functionality, so that I can ensure the migration maintains all existing behavior and catches any regressions.
23+
24+
#### Acceptance Criteria
25+
26+
1. WHEN tests are written THEN they SHALL cover all OneNote API operations (getNote, getNoteCount, setNoteSection, getNotePreview, getNoteContents)
27+
2. WHEN tests run THEN they SHALL verify authentication token handling works correctly with the Graph SDK
28+
3. WHEN tests execute THEN they SHALL validate that random and sequential note retrieval functions identically to the current implementation
29+
4. WHEN tests complete THEN they SHALL confirm that image extraction and download functionality remains unchanged
30+
31+
### Requirement 3
32+
33+
**User Story:** As a system user, I want the note retrieval functionality to work exactly as before, so that my Telegram notifications continue to deliver the same OneNote content without interruption.
34+
35+
#### Acceptance Criteria
36+
37+
1. WHEN retrieving notes in random mode THEN the system SHALL return random notes from the specified section with the same distribution as before
38+
2. WHEN retrieving notes in sequential mode THEN the system SHALL return notes in the same order and track the last page identically
39+
3. WHEN getting note previews THEN the system SHALL return the same preview text and metadata as the current implementation
40+
4. WHEN extracting images THEN the system SHALL download and process images with the same size limits and error handling
41+
42+
### Requirement 4
43+
44+
**User Story:** As a system maintainer, I want the authentication flow to remain unchanged, so that existing token management and device login processes continue to work without modification.
45+
46+
#### Acceptance Criteria
47+
48+
1. WHEN using the Graph SDK THEN it SHALL integrate seamlessly with the existing MSAL authentication system
49+
2. WHEN tokens are refreshed THEN the Graph SDK SHALL use the same cached tokens from the current MSAL implementation
50+
3. WHEN authentication fails THEN the system SHALL trigger the same device login flow as currently implemented
51+
4. WHEN tokens expire THEN the Graph SDK SHALL handle token refresh transparently using existing mechanisms
52+
53+
### Requirement 5
54+
55+
**User Story:** As a developer, I want the migration to include proper dependency management, so that the new Graph SDK is correctly installed and configured while removing unused dependencies.
56+
57+
#### Acceptance Criteria
58+
59+
1. WHEN installing dependencies THEN the system SHALL add @microsoft/microsoft-graph-client and appropriate fetch polyfill
60+
2. WHEN the migration is complete THEN superagent dependency SHALL be removed if no longer needed elsewhere
61+
3. WHEN the application starts THEN it SHALL import and configure the Graph SDK with proper authentication middleware
62+
4. WHEN making API calls THEN the system SHALL use the Graph SDK's fluent API instead of manual URL construction
63+
64+
### Requirement 6
65+
66+
**User Story:** As a system operator, I want the migrated system to maintain the same performance characteristics, so that note retrieval times and resource usage remain consistent.
67+
68+
#### Acceptance Criteria
69+
70+
1. WHEN retrieving notes THEN response times SHALL be comparable to or better than the current implementation
71+
2. WHEN handling timeouts THEN the Graph SDK SHALL respect the same timeout values (120s response, 60s deadline)
72+
3. WHEN processing large images THEN the system SHALL maintain the same 3MB size limits and streaming download behavior
73+
4. WHEN caching data THEN the system SHALL continue to use the same localStorage and DynamoDB persistence patterns

0 commit comments

Comments
 (0)