[Analytics] Add Composite Daily Focus Score & Distraction Ratio Evaluator in src/lib/analytics/focus-score.ts
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- node.js, typescript
- Domain
- analytics
Research direction
Create src/lib/analytics/focus-score.ts and tests/focus-score.test.ts; start by checking the project's TypeScript configuration and existing test conventions. Implement the specified interface, scoring, tiers, and validation, then cover the listed edge cases with node:test and node:assert/strict. Done when strict TypeScript checking passes and the tests cover the acceptance criteria.
Written by the indexing model from the issue text.
Description
🎯 Feature Overview & Context
In PACT OS, end-of-day reflection debriefs provide users with a holistic view of their productivity. Rather than looking only at total raw hours, users benefit from a single weighted Focus Score (0–100) that balances deep work volume, shallow work volume, and context-switching interruption penalties.
🧩 Scope & Deliverables
- Module Implementation: Create
src/lib/analytics/focus-score.ts - Unit Test Suite: Create
tests/focus-score.test.tsusing nativenode:testandnode:assert/strict.
📐 Specification & Interface Contracts
export interface DailyFocusMetrics {
deepWorkMinutes: number;
shallowWorkMinutes: number;
interruptionCount: number;
targetDeepWorkMinutes?: number; // default: 240 (4 hours)
}
export type FocusTier = 'optimal' | 'productive' | 'fragmented' | 'unfocused';
export interface DailyFocusAssessment {
/** Composite score from 0 to 100 (integer) */
score: number;
/** Percentage of total work time spent in deep work (0.0 to 1.0, 2 decimals) */
deepWorkRatio: number;
/** Penalty points deducted due to interruptions */
interruptionPenalty: number;
/** Qualitative performance tier */
tier: FocusTier;
/** Brief takeaway summary */
summary: string;
}
export function calculateDailyFocusScore(
metrics: DailyFocusMetrics
): DailyFocusAssessment;
Scoring Rules & Formulas:
- Total Minutes & Deep Ratio:
$$\text{totalMinutes} = \text{deepWorkMinutes} + \text{shallowWorkMinutes}$$
$$\text{deepWorkRatio} = \text{totalMinutes} === 0 ? 0.0 : \text{roundTo2Decimals}(\text{deepWorkMinutes} / \text{totalMinutes})$$ - Component Weights:
- Volume Score (max 70 pts):
$$\text{volumeScore} = \min(70, (\text{deepWorkMinutes} / \text{targetDeepWorkMinutes}) \times 70)$$ - Quality Bonus (max 30 pts):
$$\text{qualityBonus} = \text{deepWorkRatio} \times 30$$ - Interruption Penalty (capped at 25 pts):
$$\text{interruptionPenalty} = \min(25, \text{interruptionCount} \times 3)$$
- Volume Score (max 70 pts):
- Composite Score:
$$\text{score} = \max(0, \min(100, \text{Math.round}(\text{volumeScore} + \text{qualityBonus} - \text{interruptionPenalty})))$$ - Tiers:
score >= 85:'optimal'70 <= score < 85:'productive'50 <= score < 70:'fragmented'score < 50:'unfocused'
- Validation: Throws
TypeErrorif any field is not a finite number, andRangeErrorif any metric is negative ortargetDeepWorkMinutes <= 0.
🧪 Acceptance Criteria
- TypeScript strict mode passes with 0 errors (
npx tsc --noEmit). - Uses extensionless import in test file (
import { calculateDailyFocusScore } from '../src/lib/analytics/focus-score'). - Unit tests cover 0 minutes, hitting exact target, excessive interruptions penalty clamp, all 4 performance tiers, and invalid parameters.
- Zero external dependencies added.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 7
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 79
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TheVicky1/Pact_OS
-
area:finance difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
[Text] Add Word-Boundary Preserving Smart Text Truncator in src/lib/text/smart-truncate.tsPossibly taken @rudraparmar76 claimed this today. Openarea:data difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
TheVicky1/Pact_OS#760 · 1 comment ·
Maintainers usually reply within 1 day
-
area:habits difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
area:data beginner-friendly difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
beginner-friendly difficulty:easy enhancement gamification good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
All issues in TheVicky1/Pact_OS
Similar issues
-
Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
getsentry/sentry-javascript#26203 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bytedance/flowgram.ai#1235 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
devswha/herdr-web-ui#3325 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100