← Back to Kontasks
Fix: ISO Year Boundary in Quota Period ID Generation
Fixed the year boundary quirk where Dec 31 generated wrong ISO year
Output
š§ Fixed: ISO Year Boundary in Quota Period IDs
The Problem
The 7-day quota period ID generation used timestamp.getUTCFullYear() for the year, but ISO weeks can span calendar year boundaries.
| Date | Calendar Year | ISO Year | ISO Week |
| Dec 31, 2025 | 2025 | 2026 | W01 |
| Jan 1, 2026 | 2026 | 2026 | W01 |
Dec 31, 2025 (Wednesday) and Jan 1, 2026 (Thursday) are both in ISO week 1 of 2026.
The Fix
Replaced getISOWeek() with getISOWeekAndYear() which returns both values:
function getISOWeekAndYear(date: Date): { week: number; year: number } { // The ISO year is the year of the Thursday of the week const isoYear = d.getUTCFullYear(); return { week, year: isoYear }; }
Before vs After
| Date | Before (Wrong) | After (Correct) |
| Dec 31, 2025 | qp_7d_acct_2025W01 |
qp_7d_acct_2026W01 |
| Jan 1, 2026 | qp_7d_acct_2026W01 |
qp_7d_acct_2026W01 |
ā Both dates now correctly generate the same period ID
Files Changed
/konnectvol/konui/src/ āāā gv-quota-period-store.ts (+10 -7 lines) /konnectvol/konui/tests/ āāā gv-quota-period-store.test.ts (+9 -9 lines)
Test Results
ā 38 passed, 0 failed - gv-quota-period-store.test.ts
ā 42 passed, 0 failed - gv-topic-store.test.ts
Commit
20a4bd75 Fix: ISO year boundary in quota period ID generation
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
bugfixgraphquota-periods
Created
10 Jan 2026, 6:33 pm
Updated
10 Jan 2026, 6:33 pm
Timing
ā±ļø 109.1s
0 tools
ā TTFE 0%
ā Thinking 100%
ā Tools 0%
Created By
claude
š Claude's Context
Session
ses_7c4eba4a...
š Git Commit
20a4bd75
Raw Data
{
"id": "1b96b69c-6bd9-420c-aab1-8282096cba1e",
"type": "general",
"status": "completed",
"title": "Fix: ISO Year Boundary in Quota Period ID Generation",
"description": "Fixed the year boundary quirk where Dec 31 generated wrong ISO year",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\">\n<h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">š§ Fixed: ISO Year Boundary in Quota Period IDs</h2>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#f43f5e;margin:0 0 12px 0;\">The Problem</h3>\n<p style=\"margin:0 0 12px 0;line-height:1.6;\">The 7-day quota period ID generation used <code style=\"color:#e5c07b;\">timestamp.getUTCFullYear()</code> for the year, but ISO weeks can span calendar year boundaries.</p>\n<table style=\"width:100%;border-collapse:collapse;color:#e0e0e0;\">\n<tr style=\"border-bottom:1px solid #444;\">\n<td style=\"padding:8px;\"><span style=\"color:#7f848e;\">Date</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#7f848e;\">Calendar Year</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#7f848e;\">ISO Year</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#7f848e;\">ISO Week</span></td>\n</tr>\n<tr>\n<td style=\"padding:8px;\"><span style=\"color:#61afef;\">Dec 31, 2025</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#f43f5e;\">2025</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#98c379;\">2026</span></td>\n<td style=\"padding:8px;\">W01</td>\n</tr>\n<tr>\n<td style=\"padding:8px;\"><span style=\"color:#61afef;\">Jan 1, 2026</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#98c379;\">2026</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#98c379;\">2026</span></td>\n<td style=\"padding:8px;\">W01</td>\n</tr>\n</table>\n<p style=\"margin:12px 0 0 0;color:#7f848e;\">Dec 31, 2025 (Wednesday) and Jan 1, 2026 (Thursday) are both in ISO week 1 of 2026.</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#98c379;margin:0 0 12px 0;\">The Fix</h3>\n<p style=\"margin:0 0 12px 0;\">Replaced <code style=\"color:#e5c07b;\">getISOWeek()</code> with <code style=\"color:#98c379;\">getISOWeekAndYear()</code> which returns both values:</p>\n<pre style=\"background:#1e1e1e;padding:12px;border-radius:4px;overflow-x:auto;margin:0;\"><span style=\"color:#c678dd;\">function</span> <span style=\"color:#61afef;\">getISOWeekAndYear</span>(<span style=\"color:#e5c07b;\">date</span>: Date): { <span style=\"color:#e06c75;\">week</span>: number; <span style=\"color:#e06c75;\">year</span>: number } {\n <span style=\"color:#7f848e;\">// The ISO year is the year of the Thursday of the week</span>\n <span style=\"color:#c678dd;\">const</span> isoYear = d.getUTCFullYear();\n <span style=\"color:#c678dd;\">return</span> { week, <span style=\"color:#e06c75;\">year</span>: isoYear };\n}</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#56b6c2;margin:0 0 12px 0;\">Before vs After</h3>\n<table style=\"width:100%;border-collapse:collapse;color:#e0e0e0;\">\n<tr style=\"border-bottom:1px solid #444;\">\n<td style=\"padding:8px;\"><span style=\"color:#7f848e;\">Date</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#f43f5e;\">Before (Wrong)</span></td>\n<td style=\"padding:8px;\"><span style=\"color:#98c379;\">After (Correct)</span></td>\n</tr>\n<tr>\n<td style=\"padding:8px;\">Dec 31, 2025</td>\n<td style=\"padding:8px;\"><code style=\"color:#f43f5e;\">qp_7d_acct_2025W01</code></td>\n<td style=\"padding:8px;\"><code style=\"color:#98c379;\">qp_7d_acct_2026W01</code></td>\n</tr>\n<tr>\n<td style=\"padding:8px;\">Jan 1, 2026</td>\n<td style=\"padding:8px;\"><code style=\"color:#e5c07b;\">qp_7d_acct_2026W01</code></td>\n<td style=\"padding:8px;\"><code style=\"color:#98c379;\">qp_7d_acct_2026W01</code></td>\n</tr>\n</table>\n<p style=\"margin:12px 0 0 0;color:#98c379;\">ā
Both dates now correctly generate the same period ID</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#e5c07b;margin:0 0 12px 0;\">Files Changed</h3>\n<pre style=\"margin:0;line-height:1.6;\"><span style=\"color:#56b6c2;\">/konnectvol/konui/src/</span>\nāāā <span style=\"color:#e5c07b;\">gv-quota-period-store.ts</span> <span style=\"color:#7f848e;\">(+10 -7 lines)</span>\n\n<span style=\"color:#56b6c2;\">/konnectvol/konui/tests/</span>\nāāā <span style=\"color:#e5c07b;\">gv-quota-period-store.test.ts</span> <span style=\"color:#7f848e;\">(+9 -9 lines)</span></pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#98c379;margin:0 0 12px 0;\">Test Results</h3>\n<p style=\"margin:0;\"><span style=\"color:#98c379;\">ā
</span> <strong>38 passed, 0 failed</strong> - gv-quota-period-store.test.ts</p>\n<p style=\"margin:8px 0 0 0;\"><span style=\"color:#98c379;\">ā
</span> <strong>42 passed, 0 failed</strong> - gv-topic-store.test.ts</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;\">\n<h3 style=\"color:#56b6c2;margin:0 0 8px 0;\">Commit</h3>\n<code style=\"color:#98c379;\">20a4bd75</code> <span style=\"color:#7f848e;\">Fix: ISO year boundary in quota period ID generation</span>\n</div>\n\n</div>",
"requestedAt": "2026-01-10T05:32:30.000Z",
"requestId": "714f7e90-2f00-4dea-8d11-7105b3efbc21",
"commitSha": "20a4bd75",
"choices": [
{
"label": "Run full test suite",
"value": "Run the full konui test suite to verify all tests pass",
"primary": true
},
{
"label": "Update VIBE.md",
"value": "Update VIBE.md to remove the 'NO TESTS' note from gvQuotaPeriod store"
},
{
"label": "View the diff",
"value": "Show me the full git diff for this commit"
}
],
"turnTiming": {
"totalMs": 109101,
"ttfeMs": 78,
"thinkingMs": 109023,
"toolExecutionMs": 0,
"toolCallCount": 0,
"thinkingPct": 100,
"toolsPct": 0,
"ttfePct": 0
}
},
"createdBy": "claude",
"createdAt": "2026-01-10T08:33:11.816Z",
"updatedAt": "2026-01-10T08:33:20.369Z",
"requestId": "714f7e90-2f00-4dea-8d11-7105b3efbc21",
"scope": "vibetools",
"tags": [
"bugfix",
"graph",
"quota-periods"
],
"sessionId": "ses_7c4eba4a-596",
"flowId": "flow_01KEHQ5A6Y7SHWCMHHZYGBC592",
"flowLinks": [
{
"flowId": "flow_01KEHQ5A6Y7SHWCMHHZYGBC592",
"edgeType": "evidence",
"createdAt": "2026-01-10T08:33:11.816Z"
}
]
}