diff --git a/SLOP_CLEANUP_PLAN.md b/SLOP_CLEANUP_PLAN.md new file mode 100644 index 0000000..990aa7c --- /dev/null +++ b/SLOP_CLEANUP_PLAN.md @@ -0,0 +1,33 @@ +# Frontend Systematic Audit & Cleanup Plan + +## Goal +Perform a comprehensive audit and cleanup of the `frontend/` directory to remove shadowing, duplicates, corruption (appending), and dead code. + +## Phase 1: Discovery (READ-ONLY) +I will conduct a comprehensive scan of the `frontend/` directory to build an accurate inventory. +* **File Shadowing Audit**: Scan for files with overlapping names but different extensions (e.g., `.js` vs `.ts`, `.jsx` vs `.tsx`) that cause build-time shadowing. +* **Implementation Duplicate Audit**: Use content searching to find identical or near-identical function/class definitions across different files. +* **Corruption Check**: Scan files for duplicate symbol declarations (identifying where code was incorrectly appended rather than replaced). +* **Dependency/Import Audit**: Cross-reference `package.json` with actual imports to identify unused packages and orphaned imports in code. +* **Slop Identification**: Locate commented-out blocks, unused variables, and dead functions. + +## Phase 2: Categorization (PLANNING) +I will create a structured todo list (`FRONTEND_CLEANUP_TODO.md`) with the following categories: +* **`[DELETE]`**: Conflicting or redundant files (e.g., `client.js`). +* **`[REPAIR]`**: Corrupted files that must be completely overwritten to remove duplicates. +* **`[CLEAN]`**: Files requiring removal of unused imports, variables, or dead code. +* **`[REFACTOR]`**: Files requiring naming or pattern consistency fixes. + +## Phase 3: Systematic Execution (IMPLEMENTATION) +I will execute the cleanup in this order to maintain stability: +1. **File Purge**: Remove all files in the `[DELETE]` category first to resolve shadowing. +2. **File Repair**: Use full-file rewrites for files in the `[REPAIR]` category. +3. **Slop Removal**: Systematic pass through files in the `[CLEAN]` category. +4. **Verification**: + - Run `npm install` to ensure dependency integrity. + - Run all existing tests (`npm test`) and the reproduction test to confirm functionality. + - Check for build errors/linting issues. + +## Notes +- This plan will be updated and tracked via `FRONTEND_CLEANUP_TODO.md`. +- No changes will be made until the Phase 2 Todo list is reviewed and approved. diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js deleted file mode 100644 index abb643d..0000000 --- a/frontend/src/api/client.js +++ /dev/null @@ -1,72 +0,0 @@ -const BASE_URL = import.meta.env.VITE_API_BASE_URL || ''; -export function localToUTC(localValue) { - return new Date(localValue).toISOString(); -} -async function fetchStats(endpoint, from_date, to_date, extraParams = {}) { - const fromDT = new Date(`${from_date}T00:00:00`).toISOString(); - const toDT = new Date(`${to_date}T23:59:59`).toISOString(); - const params = new URLSearchParams({ from_date: fromDT, to_date: toDT, ...extraParams }); - const response = await fetch(`${BASE_URL}/api/stats/${endpoint}?${params.toString()}`); - if (!response.ok) - throw new Error(`Failed to fetch ${endpoint}`); - return response.json(); -} -export async function fetchDailySummary(from_date, to_date, day_start, day_end) { - return fetchStats('daily-summary', from_date, to_date, { day_start, day_end }); -} -export async function fetchTimetable(from_date, to_date, day_start, day_end) { - return fetchStats('timetable', from_date, to_date, { day_start, day_end }); -} -export async function fetchWakeSleepTimes(from_date, to_date, wakeup_ref, bedtime_ref) { - return fetchStats('wake-sleep-times', from_date, to_date, { wakeup_ref, bedtime_ref }); -} -// Session API functions -export async function fetchActiveSession() { - const response = await fetch(`${BASE_URL}/api/sessions/active`); - if (!response.ok) - return null; - return response.json(); -} -export async function fetchSessions() { - const response = await fetch(`${BASE_URL}/api/sessions`); - if (!response.ok) - throw new Error('Failed to fetch sessions'); - return response.json(); -} -export async function createSession(payload) { - const response = await fetch(`${BASE_URL}/api/sessions`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) - throw new Error('Failed to create session'); - return response.json(); -} -export async function endSession(sessionId, payload) { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}/end`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) - throw new Error('Failed to end session'); - return response.json(); -} -export async function deleteSession(sessionId) { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}`, { - method: 'DELETE', - }); - if (!response.ok) - throw new Error('Failed to delete session'); -} -export async function updateSession(sessionId, payload) { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) - throw new Error('Failed to update session'); - return response.json(); -} diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index de2f95b..742eea1 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -95,82 +95,3 @@ export async function updateSession(sessionId: number, payload: SleepSessionUpda if (!response.ok) throw new Error('Failed to update session'); return response.json(); } - - -export function localToUTC(localValue: string): string { - return new Date(localValue).toISOString(); -} - -async function fetchStats(endpoint: string, from_date: string, to_date: string, extraParams: Record = {}): Promise { - const fromDT = new Date(`${from_date}T00:00:00`).toISOString(); - const toDT = new Date(`${to_date}T23:59:59`).toISOString(); - const params = new URLSearchParams({ from_date: fromDT, to_date: toDT, ...extraParams }); - const response = await fetch(`${BASE_URL}/api/stats/${endpoint}?${params.toString()}`); - if (!response.ok) throw new Error(`Failed to fetch ${endpoint}`); - return response.json(); -} - -export async function fetchDailySummary(from_date: string, to_date: string, day_start: string, day_end: string): Promise { - return fetchStats('daily-summary', from_date, to_date, { day_start, day_end }); -} - -export async function fetchTimetable(from_date: string, to_date: string, day_start: string, day_end: string): Promise { - return fetchStats('timetable', from_date, to_date, { day_start, day_end }); -} - -export async function fetchWakeSleepTimes(from_date: string, to_date: string, wakeup_ref: string, bedtime_ref: string): Promise { - return fetchStats('wake-sleep-times', from_date, to_date, { - wakeup_ref: localHHMMToUTCHHMM(wakeup_ref), - bedtime_ref: localHHMMToUTCHHMM(bedtime_ref) - }); -} - -// Session API functions -export async function fetchActiveSession(): Promise { - const response = await fetch(`${BASE_URL}/api/sessions/active`); - if (!response.ok) return null; - return response.json(); -} - -export async function fetchSessions(): Promise { - const response = await fetch(`${BASE_URL}/api/sessions`); - if (!response.ok) throw new Error('Failed to fetch sessions'); - return response.json(); -} - -export async function createSession(payload: SleepSessionCreate): Promise { - const response = await fetch(`${BASE_URL}/api/sessions`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) throw new Error('Failed to create session'); - return response.json(); -} - -export async function endSession(sessionId: number, payload: SleepSessionUpdate): Promise { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}/end`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) throw new Error('Failed to end session'); - return response.json(); -} - -export async function deleteSession(sessionId: number): Promise { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}`, { - method: 'DELETE', - }); - if (!response.ok) throw new Error('Failed to delete session'); -} - -export async function updateSession(sessionId: number, payload: SleepSessionUpdate): Promise { - const response = await fetch(`${BASE_URL}/api/sessions/${sessionId}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), - }); - if (!response.ok) throw new Error('Failed to update session'); - return response.json(); -} diff --git a/verify_real_wakeup.py b/verify_real_wakeup.py deleted file mode 100644 index 4db5a01..0000000 --- a/verify_real_wakeup.py +++ /dev/null @@ -1,89 +0,0 @@ -import datetime - -def solve(): - # --- CONSTANTS FROM DATABASE/USER --- - # Actual wakeup time (UTC) from DB for session 1 - wakeup_utc_str = "2026-05-27 03:17:00" - wakeup_utc = datetime.datetime.strptime(wakeup_utc_str, "%Y-%m-%d %H:%M:%S") - wakeup_utc_mins = wakeup_utc.hour * 60 + wakeup_utc.minute - - # User's local reference time (Stockholm, UTC+2) - local_ref_str = "04:00" - local_ref_mins = 4 * 60 - - # Stockholm offset (UTC+2) -> getTimezoneOffset() returns -120 - offset_in_minutes = -120 - - print(f"DATABASE WAKEUP (UTC): {wakeup_utc_str} ({wakeup_utc_mins} mins from midnight)") - print(f"LOCAL REFERENCE: {local_ref_str} ({local_ref_mins} mins from midnight)") - print(f"STOCKHOLM OFFSET: {offset_in_minutes} (getTimezoneOffset style)") - - # --- SCENARIO 1: THE BUGGY WAY (Current implementation) --- - # Backend receives local "04:00" but treats it as UTC. - # Backend calculates delta = (UTC_wakeup - Ref_as_if_UTC) - ref_as_utc = local_ref_mins # 240 - buggy_delta = wakeup_utc_mins - ref_as_utc # 197 - 240 = -43 - print(f"\n[BUGGY SCENARIO]") - print(f"Backend returns (wrong) delta: {buggy_delta}") - - # Frontend receives -43 and tries to adjust it. - # offsetFromRef = (received_delta - offset) - ref_mins_local - # wait, the logic was: localMins = (received + abs(offset)). - # Let's follow the code exactly: - # adjustForTimezone(delta) = delta - offset_in_minutes - # (Wait, if the component thinks 'delta' is absolute minutes from midnight?) - # The user said: "Render the Wakeup Times given -43 as value ... results to 01:17" - # Let's see how to get 01:17 from -43 and ref 04:00. - # 240 (ref) - 163 = 77? No. - # If offsetFromRef is -163: formatMinutesAfter(-163, "04:00") -> 240 - 163 = 77 (01:17). - # How do we get -163 from -43? - # -43 - 120 = -163. (Ah! It's subtracting the absolute offset instead of handling sign). - # Or: -43 + (-120) = -163. - # This happens if the code does: delta + offset_in_minutes (where offset is -120). - # Wait, if offset is -120: -43 + (-120) = -163. - # So the component is doing: localMins = delta + offset_in_minutes. - # Then offsetFromRef = localMins - ref_mins = (-163) - 240 = -403? No. - # Let's check component: - # offsetFromRef = getLocalOffsetFromReference(day.wakeup_minutes, wakeup_ref); - # which is: (wakeup_minutes - offsetInMinutes) - ref_mins. - # If wakeup_minutes = -43 and offsetInMinutes = 120 (if sign is flipped): - # (-43 - 120) - 240 = -163 - 240 = -403. - # If offsetInMinutes = -120: - # (-43 - (-120)) - 240 = (77) - 240 = -163. - # YES! That's exactly it. - # (-43 - (-120)) - 240 = -163. - # formatMinutesAfter(-163, "04:00") -> 240 + (-163) = 77. - # 77 minutes is 01:17. Correct! - - def buggy_frontend(delta, ref_mins, offset): - local_m = delta - offset - return local_m - ref_mins - - buggy_offset_from_ref = buggy_frontend(buggy_delta, local_ref_mins, offset_in_minutes) - print(f"BUGGY Frontend offsetFromRef: {buggy_offset_from_ref}") - print(f"BUGGY Frontend Display: {local_ref_mins + buggy_offset_from_ref} (Minutes from midnight)") - - # --- SCENARIO 2: THE FIXED WAY (My proposed plan) --- - # 1. Frontend converts local ref "04:00" to UTC "02:00". - # 2. Backend receives ref=120. Calculates delta = 197 - 120 = 77. - # 3. Frontend receives delta=77 and uses it DIRECTLY as offsetFromRef. - - correct_delta = wakeup_utc_mins - (local_ref_mins + offset_in_minutes) - print(f"\n[FIXED SCENARIO]") - print(f"Backend returns (correct) delta: {correct_delta}") - - # Frontend uses it directly. - fixed_offset_from_ref = correct_delta - print(f"FIXED Frontend offsetFromRef: {fixed_offset_from_ref}") - print(f"FIXED Frontend Display: {local_ref_mins + fixed_offset_from_ref} (Minutes from midnight)") - - # ASSERT - expected_mins = 5 * 60 + 17 # 317 - actual_mins = local_ref_mins + fixed_offset_from_ref - print(f"\nASSERTION: Expected {expected_mins}, Actual {actual_mins}") - if actual_mins == expected_mins: - print("SUCCESS!") - else: - print("FAILURE!") - -solve()