fix: @ts-nocheck aus allen drei Dateien entfernen
Some checks are pending
Playwright Tests / test (push) Waiting to run
Test and SonarQube / quality (push) Waiting to run

Die Dateien schalteten die Typpruefung komplett ab und blieben deshalb auch
von ignoreBuildErrors: false unberuehrt -- eine Luecke im gerade erst
geschlossenen Netz.

- calendar-cache.ts brauchte die Ausnahme gar nicht: ohne sie null Fehler.
- microsoft-todo.ts hatte vier Faelle zirkulaerer Typinferenz
  (url -> data -> response -> url), aufgeloest durch explizite Annotationen.
- outlook-calendar.ts verbarg einen moeglichen Laufzeitfehler: Der Code
  streute response!-Assertions, eine Stelle war vergessen. Statt noch einer
  Assertion prueft er jetzt echt, ob nach drei Wiederholversuchen ueberhaupt
  eine Antwort vorliegt.

Ausserdem Block I in TODO.md: Hervorhebung des aktuellen Tages im
Spaltenkopf und die Symbole in Kalenderterminen nach oben rechts, beide mit
Fundstelle in globals.css.

Verifiziert: Typecheck 0 Fehler, npm run build Exit 0.

v1.118.2

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mARTin-B78 2026-09-07 13:59:57 +02:00
parent db99b486c7
commit 53de4017e5
7 changed files with 73 additions and 16 deletions

View File

@ -2,6 +2,24 @@
All notable changes to this project are documented in this file. All notable changes to this project are documented in this file.
## [1.118.2] - 2026-09-07
### Fixed
- **Kein `@ts-nocheck` mehr im Projekt.** Drei Dateien hatten die Typprüfung komplett
abgeschaltet und blieben deshalb auch von `ignoreBuildErrors: false` unberührt:
- `calendar-cache.ts` brauchte die Ausnahme überhaupt nicht — ohne sie: null Fehler.
- `microsoft-todo.ts`: vier Fälle zirkulärer Typinferenz (`url` → `data` → `response`
→ `url`), aufgelöst durch explizite Annotationen.
- `outlook-calendar.ts`: Hinter der Ausnahme steckte ein möglicher Laufzeitfehler. Der
Code streute `response!`-Assertions, eine Stelle war vergessen. Statt einer weiteren
Assertion prüft der Code jetzt echt, ob nach den drei Wiederholversuchen überhaupt
eine Antwort vorliegt.
### Added
- `TODO.md`: Block I mit zwei UI-Wünschen — Hervorhebung des aktuellen Tages auch im
Spaltenkopf, und die Symbole in Kalenderterminen nach oben rechts. Beide mit den
konkreten Fundstellen in `globals.css`.
## [1.118.1] - 2026-09-07 ## [1.118.1] - 2026-09-07
### Fixed ### Fixed

40
TODO.md
View File

@ -109,8 +109,10 @@ Anleitung siehe [`docs/secret-rotation.md`](docs/secret-rotation.md).
- [x] `tsconfig.json`: `include` von `**/*` auf `src/**/*` eingegrenzt. **Das war die - [x] `tsconfig.json`: `include` von `**/*` auf `src/**/*` eingegrenzt. **Das war die
Ursache der Langsamkeit**, nicht die Dateigröße: Der Lauf dauert jetzt **19 Sekunden** Ursache der Langsamkeit**, nicht die Dateigröße: Der Lauf dauert jetzt **19 Sekunden**
statt über 30 Minuten. Meine gegenteilige Vermutung war falsch. statt über 30 Minuten. Meine gegenteilige Vermutung war falsch.
- [ ] **3 Dateien mit `@ts-nocheck`** aufspüren und entschärfen — die überspringen den - [x] **3 Dateien mit `@ts-nocheck`** entschärft — im Projekt gibt es jetzt **kein einziges
Typecheck vollständig, auch mit `ignoreBuildErrors: false` `@ts-nocheck` mehr**. `calendar-cache.ts` brauchte es gar nicht (0 Fehler), in
`microsoft-todo.ts` fehlten Typannotationen, und in `outlook-calendar.ts` steckte
ein möglicher Laufzeitfehler dahinter.
- [ ] `any`-Stellen reduzieren — ESLint zählt **470** `no-explicit-any` — fortlaufend, kein Blocker - [ ] `any`-Stellen reduzieren — ESLint zählt **470** `no-explicit-any` — fortlaufend, kein Blocker
- [ ] **209** ungenutzte Variablen (`no-unused-vars`) aufräumen — fortlaufend - [ ] **209** ungenutzte Variablen (`no-unused-vars`) aufräumen — fortlaufend
- [ ] **11** unvollständige Hook-Abhängigkeiten (`react-hooks/exhaustive-deps`) prüfen — - [ ] **11** unvollständige Hook-Abhängigkeiten (`react-hooks/exhaustive-deps`) prüfen —
@ -149,6 +151,8 @@ Blindflug. Ebenso hilfreich: A2, damit es überhaupt Tests gibt.
- [ ] `getWeekNumber` existiert **dreimal** im Projekt (WeeklyView, `WeekPrintModal.tsx`, - [ ] `getWeekNumber` existiert **dreimal** im Projekt (WeeklyView, `WeekPrintModal.tsx`,
`api/user/export-week-view/route.ts`) — Duplikate gegen `date-utils.ts` ersetzen, `api/user/export-week-view/route.ts`) — Duplikate gegen `date-utils.ts` ersetzen,
vorher die drei Implementierungen auf Gleichheit prüfen vorher die drei Implementierungen auf Gleichheit prüfen
- [ ] `calendar-cache.ts` hat mit `getWeekStart` eine **vierte** eigene Wochenlogik —
ebenfalls gegen `date-utils.ts` ersetzen
- [ ] Drag & Drop in einen Hook `useTaskDragDrop.ts` - [ ] Drag & Drop in einen Hook `useTaskDragDrop.ts`
- [ ] Someday-Listen in `SomedayLists.tsx` - [ ] Someday-Listen in `SomedayLists.tsx`
- [ ] All-Day-Leiste in `AllDayBar.tsx` - [ ] All-Day-Leiste in `AllDayBar.tsx`
@ -275,6 +279,38 @@ Umgestellt auf `dataSources.query()`; die Suche filtert jetzt auf `data_source`
--- ---
## Block I — UI-Wünsche
### I1. Aktuellen Tag auch im Spaltenkopf hervorheben
- [ ] Hervorhebungsfarbe zusätzlich hinter Wochentagsname und Datum legen
**Wunsch:** Der laufende Tag soll deutlicher auffallen. Aktuell ist nur der Spaltenkörper
eingefärbt, der Kopfbereich mit "SEP 7 / MONDAY" bleibt weiß.
**Wo:** `globals.css:666` färbt `.weekly-day-column.is-today` mit
`var(--weekly-today-highlight)`. Der Kopf ist ein eigenes `<header class="weekly-day-header">`
([WeeklyView.tsx:7089](src/components/WeeklyView.tsx#L7089)) und übermalt die Farbe
offenbar mit eigenem Hintergrund. Der Wochentagsname hat bereits eine eigene Regel
(`globals.css:708`, `.weekly-day-name.is-today` setzt nur die Schriftfarbe).
**Zu klären:** Der Kopf ist vermutlich `sticky` und braucht deshalb einen deckenden
Hintergrund — die Farbe muss also gesetzt, nicht nur geerbt werden.
### I2. Symbole in Kalenderterminen nach oben rechts
- [ ] `.event-icons-row` von unten rechts nach oben rechts verschieben
**Wunsch:** Die kleinen Symbole (Wiederholung, Anbieter) sitzen unten rechts im Termin und
sollen nach oben rechts.
**Wo:** `globals.css:3183` — `.event-icons-row` hat `bottom: 2px; right: 4px;`. Für oben
rechts wird daraus `top: 2px; right: 4px;`.
**Achtung:** Der Titel beginnt oben links; bei kurzen Terminen könnten sich Symbole und
Titel überlappen. Vermutlich braucht die Titelzeile rechts etwas Freiraum
(`padding-right`), damit nichts verdeckt wird.
---
## Block G — Infrastruktur (Supabase-LXC 201) ## Block G — Infrastruktur (Supabase-LXC 201)
### G1. Container läuft privilegiert *(Sicherheitsthema)* ### G1. Container läuft privilegiert *(Sicherheitsthema)*

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.118.1", "version": "1.118.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.118.1", "version": "1.118.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@auth/prisma-adapter": "^2.11.1", "@auth/prisma-adapter": "^2.11.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.118.1", "version": "1.118.2",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -1,4 +1,3 @@
// @ts-nocheck
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { prisma } from './prisma'; import { prisma } from './prisma';

View File

@ -1,4 +1,3 @@
// @ts-nocheck
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
const GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0'; const GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0';
@ -163,7 +162,7 @@ export const fetchMsTodoTasksForSync = async (
})(); })();
while (url) { while (url) {
const response = await fetch(url, { const response: Response = await fetch(url, {
headers: { headers: {
'Authorization': `Bearer ${accessToken}`, 'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -176,7 +175,7 @@ export const fetchMsTodoTasksForSync = async (
throw new Error(`Failed to fetch To-Do tasks for sync: ${response.status} ${response.statusText}`); throw new Error(`Failed to fetch To-Do tasks for sync: ${response.status} ${response.statusText}`);
} }
const data = await response.json(); const data: any = await response.json();
allTasks.push(...((data.value || []) as MicrosoftTodoTask[])); allTasks.push(...((data.value || []) as MicrosoftTodoTask[]));
url = data['@odata.nextLink'] || null; url = data['@odata.nextLink'] || null;
} }
@ -212,7 +211,7 @@ export const fetchMsTodoTasksDelta = async (
let deltaToken: string | null = null; let deltaToken: string | null = null;
while (url) { while (url) {
const response = await fetch(url, { const response: Response = await fetch(url, {
headers: { headers: {
'Authorization': `Bearer ${accessToken}`, 'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -229,7 +228,7 @@ export const fetchMsTodoTasksDelta = async (
throw new Error(`Failed to fetch To-Do delta: ${response.status} ${response.statusText}`); throw new Error(`Failed to fetch To-Do delta: ${response.status} ${response.statusText}`);
} }
const data = await response.json(); const data: any = await response.json();
for (const item of (data.value || [])) { for (const item of (data.value || [])) {
if (item['@removed']) { if (item['@removed']) {
tasks.push({ ...item, _deleted: true } as any); tasks.push({ ...item, _deleted: true } as any);

View File

@ -1,4 +1,3 @@
// @ts-nocheck
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
// import { GoogleCalendarEvent as CalendarEvent } from './google-calendar'; // import { GoogleCalendarEvent as CalendarEvent } from './google-calendar';
@ -194,10 +193,16 @@ export const getUpcomingEvents = async (
break; break;
} }
if (!response!.ok) { // Nach der Retry-Schleife kann response fehlen, wenn jeder Versuch abbrach. Eine echte
const errorText = await response!.text(); // Pruefung statt weiterer "!"-Assertions: die verschieben das Problem nur zur Laufzeit.
console.error(`[OUTLOOK] Failed to fetch events for calendar ${calendarId}:`, response!.status, response!.statusText, errorText); if (!response) {
throw new Error(`Failed to fetch events: ${response!.status} ${response!.statusText}`); throw new Error(`[OUTLOOK] Keine Antwort fuer Kalender ${calendarId} nach 3 Versuchen`);
}
if (!response.ok) {
const errorText = await response.text();
console.error(`[OUTLOOK] Failed to fetch events for calendar ${calendarId}:`, response.status, response.statusText, errorText);
throw new Error(`Failed to fetch events: ${response.status} ${response.statusText}`);
} }
const data = await response.json(); const data = await response.json();