103 lines
4.6 KiB
Markdown
103 lines
4.6 KiB
Markdown
# Tasks: enterprise-network-quality
|
||
|
||
**Change ID**: enterprise-network-quality
|
||
**Package**: `@suaveplan/network-quality`
|
||
**Target path**: `universal/network/network-quality`
|
||
**Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger`, `@suaveplan/timing`
|
||
|
||
---
|
||
|
||
## 1. Scaffold
|
||
|
||
- [x] Create `universal/network/network-quality/` with `src/`, `tests/`, `src/__benchmarks__/`, and all feature subdirectories.
|
||
- [x] Write `package.json` at version `0.1.0`: `"sideEffects": false`, exports map, deps per `proposal.md`.
|
||
- [x] Write `tsconfig.json`, `vitest.config.ts`, scripts (including `bench`).
|
||
|
||
---
|
||
|
||
## 2. Types and error codes
|
||
|
||
- [x] Define all public types in `src/types/common.ts`: `QualityMeasurement`, `QualityReport`, `QualityWindowStats`, `QualityTrend`, `QualityGrade`, `ThresholdViolation`, `QualityMonitorOptions`, `QualityThresholds`, `QualityProbe`, `QualityEvent`.
|
||
- [x] Write `src/types/common.md` (≥200 words, simple + advanced examples).
|
||
- [x] Define error codes in `src/error-codes.ts`.
|
||
- [x] Write Zod schemas in `src/types/schemas.ts` + `src/types/schemas.md`.
|
||
|
||
---
|
||
|
||
## 3. Window statistics (`src/stats/`)
|
||
|
||
- [x] Implement `computeWindowStats(measurements: QualityMeasurement[], windowMs: number): QualityWindowStats`:
|
||
- Filter measurements within the last `windowMs`.
|
||
- Compute avg RTT, avg jitter, avg packet loss, p95 RTT.
|
||
- Uses insertion-sort for p95 on small sample sets (≤100).
|
||
- [x] Implement `exponentialSmooth(values: number[], alpha: number): number[]`: EWMA.
|
||
- [x] Write `window-stats.test.ts` + `window-stats.md`.
|
||
|
||
---
|
||
|
||
## 4. Scorer (`src/scoring/`)
|
||
|
||
- [x] Implement `computeQualityScore(measurement: QualityMeasurement, thresholds?: QualityThresholds): number`:
|
||
- RTT factor (40%): 100 when rtt ≤ 50ms; 0 when rtt ≥ thresholds.maxRttMs (default 500ms); linear between.
|
||
- Jitter factor (20%): 100 when jitter ≤ 10ms; 0 when jitter ≥ 100ms.
|
||
- Packet loss factor (30%): 100 when 0%; 0 when ≥ thresholds.maxPacketLoss (default 0.1).
|
||
- Throughput factor (10%): 0 if below threshold; 100 if above.
|
||
- Return weighted sum (0–100).
|
||
- [x] Implement `gradeScore(score: number): QualityGrade`.
|
||
- [x] Implement `detectTrend(recent: number[], older: number[]): QualityTrend`:
|
||
- Compare averages; `improving` if delta > +5, `degrading` if delta < -5, else `stable`.
|
||
- [x] Write `scorer.test.ts` (≤500 lines): boundary cases, all four factors.
|
||
- [x] Write `scorer.md` (≥200 words).
|
||
|
||
---
|
||
|
||
## 5. Probe factories (`src/probes/`)
|
||
|
||
- [x] Implement `createRttProbe(url, options?)`: HTTP HEAD probe with clock-measured RTT.
|
||
- [x] Implement `createBandwidthProbe(url, options?)`: fetch known-size payload, compute bytes/elapsed.
|
||
- [x] Write `rtt-probe.test.ts` + `rtt-probe.md`.
|
||
- [x] Write `bandwidth-probe.test.ts` + `bandwidth-probe.md`.
|
||
|
||
---
|
||
|
||
## 6. Quality monitor (`src/core/monitor/`)
|
||
|
||
- [x] Implement `createQualityMonitor(options?)`:
|
||
- Validates options with Zod.
|
||
- `start(signal?)` — runs measurement loop via `@suaveplan/timing` interval.
|
||
- Each tick: call `options.probe ?? createRttProbe(options.rttUrl)`.
|
||
- Store in sliding window `measurements[]` (capped at `windowSize`, default 20).
|
||
- Apply exponential smoothing before scoring.
|
||
- Detect trend comparing newest half vs oldest half of window.
|
||
- Compute threshold violations.
|
||
- Emit `measurement` event. On grade transition, emit `degradation` or `recovery`.
|
||
- OTel: gauge `net.quality.rtt_ms`, gauge `net.quality.score`, gauge `net.quality.packet_loss`.
|
||
- [x] Implement `selectBestPeer(peers, monitor)` — returns peer with lowest `score` gauge if custom probe; otherwise highest `score` field.
|
||
- [x] Write `monitor.test.ts` (≤500 lines): start/stop, degradation event fired, recovery event, threshold violation.
|
||
- [x] Write `monitor.md` (≥200 words).
|
||
|
||
---
|
||
|
||
## 7. Benchmarks (`src/__benchmarks__/quality.bench.ts`)
|
||
|
||
- [x] `computeWindowStats_20`, `computeWindowStats_100`: 20 and 100 measurement samples.
|
||
- [x] `scorer_hot`: 10k `computeQualityScore` calls.
|
||
|
||
---
|
||
|
||
## 8. Property-based tests (`tests/property.test.ts`)
|
||
|
||
- [x] Score monotonicity: increasing RTT (all else equal) never increases the score.
|
||
- [x] Grade boundary consistency: score ≥ 80 → grade is `excellent`.
|
||
- [x] Trend stability: stable measurements produce `stable` trend.
|
||
|
||
---
|
||
|
||
## 9. Docs and verify
|
||
|
||
- [x] All per-file `.md` files per layout in `proposal.md`.
|
||
- [x] `universal/network/network-quality/README.md`.
|
||
- [x] `bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-quality` — all green, 100%.
|
||
- [x] `bun scripts/publish.ts --package @suaveplan/network-quality`.
|
||
- [x] Update `CLAUDE.md`. Archive change folder.
|