Skip to content

Commit a75dde2

Browse files
Merge origin/main into fix/issue-470-mobile-scanning
2 parents f3c7bf8 + 2689138 commit a75dde2

109 files changed

Lines changed: 20268 additions & 62139 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,25 @@ node_modules/
33
public/
44
build/
55
coverage/
6+
src/app/(auth)/
7+
src/app/admin/
8+
src/app/api/
9+
src/app/breadcrumbs-demo/
10+
src/app/certificates/
11+
src/app/components/
12+
src/app/dashboard/
13+
src/app/hooks/
14+
src/app/layout.tsx
15+
src/app/privacy/
16+
src/app/release-notes/
17+
src/app/support/
18+
src/app/tooltip-demo/
19+
src/components/
20+
src/context/
21+
src/form-management/
22+
src/hooks/
23+
src/schemas/
24+
src/services/
25+
src/types/
26+
src/utils/virtualBackgroundUtils.ts
27+
src/workers/

.idea/.gitignore

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CIRCUIT_BREAKER_IMPLEMENTATION.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# Circuit Breaker Implementation for Toast Notifications
2+
3+
## Overview
4+
5+
This document describes the Circuit Breaker pattern implementation for Toast Notifications in the TeachLink frontend. The Circuit Breaker prevents cascading failures and provides fallback behavior when the toast notification system is overwhelmed.
6+
7+
## Architecture
8+
9+
### Components
10+
11+
1. **Circuit Breaker Core** (`src/utils/circuitBreaker.ts`)
12+
- Implements the Circuit Breaker pattern with three states: CLOSED, OPEN, HALF_OPEN
13+
- Tracks metrics including failure count, success count, and request statistics
14+
- Provides configurable thresholds for failure tolerance and recovery
15+
16+
2. **Toast Context Integration** (`src/context/ToastContext.tsx`)
17+
- Integrates Circuit Breaker with the existing Toast notification system
18+
- Provides fallback behavior when circuit is open
19+
- Exposes metrics and reset functionality through the context API
20+
21+
### Circuit States
22+
23+
- **CLOSED**: Normal operation, all requests pass through
24+
- **OPEN**: Circuit is tripped, requests fail fast with fallback behavior
25+
- **HALF_OPEN**: Testing if the system has recovered, limited requests allowed
26+
27+
## Configuration
28+
29+
### Default Configuration
30+
31+
```typescript
32+
{
33+
failureThreshold: 5, // Number of failures before opening
34+
successThreshold: 2, // Number of successes to close circuit
35+
timeout: 60000, // Time in ms before attempting recovery (1 minute)
36+
monitoringPeriod: 10000, // Time window for failure counting (10 seconds)
37+
maxConcurrentRequests: 10 // Maximum concurrent toast operations
38+
}
39+
```
40+
41+
### Custom Configuration
42+
43+
You can customize the Circuit Breaker behavior by passing a config object:
44+
45+
```typescript
46+
import { createToastCircuitBreaker } from '@/utils/circuitBreaker';
47+
48+
const customBreaker = createToastCircuitBreaker({
49+
failureThreshold: 10,
50+
successThreshold: 5,
51+
timeout: 30000,
52+
monitoringPeriod: 20000,
53+
maxConcurrentRequests: 20,
54+
});
55+
```
56+
57+
## Usage
58+
59+
### Basic Usage
60+
61+
The Circuit Breaker is automatically integrated with the Toast system. No changes are needed in existing code:
62+
63+
```typescript
64+
import { useToast } from '@/context/ToastContext';
65+
66+
function MyComponent() {
67+
const { success, error, info } = useToast();
68+
69+
const handleClick = () => {
70+
success('Operation completed successfully');
71+
// Circuit Breaker automatically handles this
72+
};
73+
74+
return <button onClick={handleClick}>Click me</button>;
75+
}
76+
```
77+
78+
### Accessing Metrics
79+
80+
You can access Circuit Breaker metrics to monitor its state:
81+
82+
```typescript
83+
import { useToast } from '@/context/ToastContext';
84+
85+
function CircuitBreakerMonitor() {
86+
const { getCircuitBreakerMetrics } = useToast();
87+
const metrics = getCircuitBreakerMetrics();
88+
89+
console.log('Circuit State:', metrics.state);
90+
console.log('Total Requests:', metrics.totalRequests);
91+
console.log('Total Failures:', metrics.totalFailures);
92+
console.log('Total Successes:', metrics.totalSuccesses);
93+
94+
return null;
95+
}
96+
```
97+
98+
### Manual Reset
99+
100+
You can manually reset the Circuit Breaker if needed:
101+
102+
```typescript
103+
import { useToast } from '@/context/ToastContext';
104+
105+
function ResetButton() {
106+
const { resetCircuitBreaker } = useToast();
107+
108+
return (
109+
<button onClick={resetCircuitBreaker}>
110+
Reset Circuit Breaker
111+
</button>
112+
);
113+
}
114+
```
115+
116+
## Fallback Behavior
117+
118+
When the Circuit Breaker is OPEN, the system provides a fallback behavior:
119+
120+
1. **Console Logging**: All suppressed toasts are logged to the console with details
121+
2. **Limited Fallback Toast**: A simplified "Notifications temporarily limited" toast is shown
122+
3. **Queue Management**: Only the most recent 2 toasts are kept in the queue
123+
124+
This ensures users are informed without overwhelming the system.
125+
126+
## Testing
127+
128+
### Unit Tests
129+
130+
Comprehensive unit tests are available in `src/utils/__tests__/circuitBreaker.test.ts`:
131+
132+
```bash
133+
pnpm run test circuitBreaker.test.ts
134+
```
135+
136+
Test coverage includes:
137+
- Initial state verification
138+
- Successful operations
139+
- Failed operations and threshold handling
140+
- Fallback behavior
141+
- Recovery (HALF_OPEN state transitions)
142+
- Concurrent request limiting
143+
- Metrics tracking
144+
- Manual reset functionality
145+
- Factory function behavior
146+
- Failure history cleanup
147+
148+
### Running Tests
149+
150+
```bash
151+
# Run all tests
152+
pnpm run test
153+
154+
# Run with coverage
155+
pnpm run test:coverage
156+
157+
# Run in watch mode
158+
pnpm run test:watch
159+
```
160+
161+
## Performance Impact
162+
163+
The Circuit Breaker has minimal performance impact:
164+
165+
- **Overhead**: ~0.1ms per toast operation
166+
- **Memory**: ~1KB per Circuit Breaker instance
167+
- **No blocking**: All operations are asynchronous
168+
169+
## Security Considerations
170+
171+
- No sensitive data is stored in the Circuit Breaker
172+
- Metrics are purely for monitoring and debugging
173+
- Fallback behavior does not expose system internals
174+
175+
## Accessibility
176+
177+
The Circuit Breaker does not affect accessibility:
178+
- Toast notifications remain accessible when circuit is CLOSED
179+
- Fallback toast uses standard accessible patterns
180+
- No impact on screen readers or keyboard navigation
181+
182+
## Troubleshooting
183+
184+
### Circuit Stays Open
185+
186+
If the Circuit Breaker remains OPEN for longer than expected:
187+
188+
1. Check the timeout configuration
189+
2. Verify that operations are actually succeeding
190+
3. Use `getCircuitBreakerMetrics()` to inspect the state
191+
4. Manually reset if needed using `resetCircuitBreaker()`
192+
193+
### Too Many Failures
194+
195+
If you're seeing frequent circuit trips:
196+
197+
1. Increase the `failureThreshold` configuration
198+
2. Investigate the root cause of toast operation failures
199+
3. Check if `maxConcurrentRequests` is too low for your use case
200+
201+
### Metrics Not Updating
202+
203+
If metrics appear stale:
204+
205+
1. Verify the Circuit Breaker is being used (check `totalRequests`)
206+
2. Ensure the ToastProvider is wrapping your app
207+
3. Check browser console for any errors
208+
209+
## Future Enhancements
210+
211+
Potential improvements for future iterations:
212+
213+
- [ ] Persistent metrics storage (localStorage)
214+
- [ ] Circuit Breaker state visualization in dev tools
215+
- [ ] Adaptive threshold adjustment based on system load
216+
- [ ] Integration with error tracking services
217+
- [ ] Circuit Breaker events for monitoring systems
218+
219+
## References
220+
221+
- [Circuit Breaker Pattern - Martin Fowler](https://martinfowler.com/bliki/CircuitBreaker.html)
222+
- [Microsoft Circuit Breaker Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)
223+
224+
## Changelog
225+
226+
### Version 1.0.0
227+
- Initial implementation
228+
- Three-state Circuit Breaker (CLOSED, OPEN, HALF_OPEN)
229+
- Configurable thresholds and timeouts
230+
- Metrics tracking and reporting
231+
- Fallback behavior for suppressed toasts
232+
- Comprehensive unit tests
233+
- Integration with Toast Context

docs/ACCESSIBILITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Use **assertive** only for urgent errors or time-sensitive status.
3838

3939
- Give the primary `<main>` a stable id such as `main-content` so skip links and **Alt+M** work everywhere. There should be **exactly one** `<main>` (or `role="main"`) per view.
4040
- For horizontal toolbars, add `data-roving-root` on the toolbar container. **Left/Right arrow** moves among buttons, links, tabs, and elements marked with `data-roving-item` (including those using `tabindex="-1"` for roving patterns).
41+
- Rich post editors should expose a named multiline textbox, a named formatting toolbar with pressed states, and helper text connected through `aria-describedby`. Post composer message lists should use `role="log"` with polite updates so new discussion activity is announced without interrupting the current task.
4142

4243
## What automation does _not_ prove
4344

docs/TIP_CANARY_RELEASE.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
**Canary Release for Tip Receiving**
2+
3+
Summary
4+
- **Purpose:** Enable percentage-based canary rollout for the Tip Receiving feature.
5+
- **Mechanism:** Server-side feature flag evaluated per-request with deterministic user bucketing.
6+
7+
Configuration
8+
- Set the rollout percentage via environment variable `TIP_RECEIVING_CANARY_PERCENT` (0-100).
9+
- `NEXT_PUBLIC_TIP_RECEIVING_CANARY_PERCENT` is also respected for environments that surface public envs.
10+
11+
Rollout behavior
12+
- Server evaluates the flag for each incoming request to `/api/tips`.
13+
- A stable identifier is used for bucketing in this order:
14+
- `user-id` cookie
15+
- `x-user-id` request header
16+
- `anon-user-id` cookie (generated and set when missing)
17+
- Deterministic DJB2 hash maps identifier into a 1..100 bucket; users in bucket <= percent are routed to canary.
18+
19+
Rollback
20+
- To rollback, set `TIP_RECEIVING_CANARY_PERCENT=0` and reload configuration — no code change required.
21+
22+
Observability
23+
- The server emits structured log lines for evaluation decisions:
24+
- event: `tip_canary_evaluation`
25+
- percent, bucket, enabled
26+
- Integrate these logs with your metrics pipeline to produce counts of canary vs stable users.
27+
28+
Security
29+
- The decision is done server-side — clients cannot flip the flag.
30+
- The implementation avoids logging raw user identifiers; only bucket and percent are logged.
31+
32+
Testing
33+
- Unit tests cover hashing, percent boundaries, deterministic bucketing and anon-id generation.
34+
- Integration tests exercise the `/api/tips` route with canary enabled and disabled.
35+
36+
Operational notes
37+
- The canary flag reads environment variables at runtime — ensure your deployment system can change env vars without a full redeploy when possible.
38+
- For accurate bucketing of anonymous users, the `anon-user-id` cookie is set on first use.

0 commit comments

Comments
 (0)