From a9c8d16f052f22a6a6711b996d9ab34876c59c0b Mon Sep 17 00:00:00 2001 From: Deven Thiel Date: Thu, 5 Mar 2026 17:06:35 -0500 Subject: [PATCH] Old files removed --- client/index.html | 15 - client/package.json | 36 -- client/src/App.tsx | 58 --- client/src/__tests__/appStore.test.ts | 151 ------ client/src/__tests__/components.test.tsx | 287 ----------- client/src/__tests__/crypto.test.ts | 53 -- client/src/__tests__/format.test.ts | 54 -- client/src/__tests__/setup.ts | 37 -- client/src/__tests__/stats.test.ts | 256 ---------- client/src/__tests__/storage.test.ts | 100 ---- client/src/__tests__/tax.test.ts | 282 ----------- client/src/__tests__/timerStore.test.ts | 245 --------- client/src/components/auth/LoginScreen.tsx | 171 ------- client/src/components/charts/ChartPanel.tsx | 300 ----------- client/src/components/charts/ChartSidebar.tsx | 30 -- client/src/components/common/Modal.tsx | 72 --- .../src/components/spreadsheet/EntryForm.tsx | 234 --------- .../spreadsheet/HierSpreadsheet.tsx | 179 ------- client/src/lib/crypto/encryption.ts | 121 ----- client/src/lib/format.ts | 60 --- client/src/lib/id.ts | 6 - client/src/lib/stats/aggregate.ts | 289 ----------- client/src/lib/storage/adapters.ts | 201 -------- client/src/lib/storage/vault.ts | 79 --- client/src/lib/tax/brackets.ts | 206 -------- client/src/lib/tax/calculate.ts | 280 ----------- client/src/main.tsx | 14 - client/src/pages/DashboardPage.tsx | 156 ------ client/src/pages/LedgerPage.tsx | 320 ------------ client/src/pages/SettingsPage.tsx | 240 --------- client/src/pages/TaxPage.tsx | 249 --------- client/src/pages/TimerPage.tsx | 373 -------------- client/src/store/appStore.ts | 404 --------------- client/src/store/timerStore.ts | 241 --------- client/src/themes/ThemeProvider.tsx | 34 -- client/src/themes/global.css | 475 ------------------ client/src/themes/themes.css | 361 ------------- client/src/types/index.ts | 344 ------------- client/tsconfig.json | 24 - client/tsconfig.tsbuildinfo | 1 - client/vite.config.ts | 27 - server/.env.example | 14 - server/package.json | 38 -- server/src/__tests__/server.test.ts | 192 ------- server/src/app.ts | 24 - server/src/db/mongo.ts | 51 -- server/src/index.ts | 21 - server/src/middleware/auth.ts | 39 -- server/src/routes/auth.ts | 135 ----- server/src/routes/data.ts | 39 -- server/tsconfig.json | 14 - server/vitest.config.ts | 9 - 52 files changed, 7641 deletions(-) delete mode 100644 client/index.html delete mode 100644 client/package.json delete mode 100644 client/src/App.tsx delete mode 100644 client/src/__tests__/appStore.test.ts delete mode 100644 client/src/__tests__/components.test.tsx delete mode 100644 client/src/__tests__/crypto.test.ts delete mode 100644 client/src/__tests__/format.test.ts delete mode 100644 client/src/__tests__/setup.ts delete mode 100644 client/src/__tests__/stats.test.ts delete mode 100644 client/src/__tests__/storage.test.ts delete mode 100644 client/src/__tests__/tax.test.ts delete mode 100644 client/src/__tests__/timerStore.test.ts delete mode 100644 client/src/components/auth/LoginScreen.tsx delete mode 100644 client/src/components/charts/ChartPanel.tsx delete mode 100644 client/src/components/charts/ChartSidebar.tsx delete mode 100644 client/src/components/common/Modal.tsx delete mode 100644 client/src/components/spreadsheet/EntryForm.tsx delete mode 100644 client/src/components/spreadsheet/HierSpreadsheet.tsx delete mode 100644 client/src/lib/crypto/encryption.ts delete mode 100644 client/src/lib/format.ts delete mode 100644 client/src/lib/id.ts delete mode 100644 client/src/lib/stats/aggregate.ts delete mode 100644 client/src/lib/storage/adapters.ts delete mode 100644 client/src/lib/storage/vault.ts delete mode 100644 client/src/lib/tax/brackets.ts delete mode 100644 client/src/lib/tax/calculate.ts delete mode 100644 client/src/main.tsx delete mode 100644 client/src/pages/DashboardPage.tsx delete mode 100644 client/src/pages/LedgerPage.tsx delete mode 100644 client/src/pages/SettingsPage.tsx delete mode 100644 client/src/pages/TaxPage.tsx delete mode 100644 client/src/pages/TimerPage.tsx delete mode 100644 client/src/store/appStore.ts delete mode 100644 client/src/store/timerStore.ts delete mode 100644 client/src/themes/ThemeProvider.tsx delete mode 100644 client/src/themes/global.css delete mode 100644 client/src/themes/themes.css delete mode 100644 client/src/types/index.ts delete mode 100644 client/tsconfig.json delete mode 100644 client/tsconfig.tsbuildinfo delete mode 100644 client/vite.config.ts delete mode 100644 server/.env.example delete mode 100644 server/package.json delete mode 100644 server/src/__tests__/server.test.ts delete mode 100644 server/src/app.ts delete mode 100644 server/src/db/mongo.ts delete mode 100644 server/src/index.ts delete mode 100644 server/src/middleware/auth.ts delete mode 100644 server/src/routes/auth.ts delete mode 100644 server/src/routes/data.ts delete mode 100644 server/tsconfig.json delete mode 100644 server/vitest.config.ts diff --git a/client/index.html b/client/index.html deleted file mode 100644 index c285952..0000000 --- a/client/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - ten99timecard — 1099 Income & Tax Tracker - - - - - -
- - - diff --git a/client/package.json b/client/package.json deleted file mode 100644 index 5c74e6b..0000000 --- a/client/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "ten99timecard-client", - "version": "1.0.0", - "private": true, - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "preview": "vite preview", - "test": "vitest run", - "test:watch": "vitest", - "test:coverage": "vitest run --coverage" - }, - "dependencies": { - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-router-dom": "^6.26.2", - "zustand": "^4.5.5", - "recharts": "^2.12.7", - "date-fns": "^3.6.0", - "clsx": "^2.1.1" - }, - "devDependencies": { - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", - "@vitejs/plugin-react": "^4.3.4", - "typescript": "^5.6.3", - "vite": "^5.4.10", - "vitest": "^2.1.4", - "@vitest/coverage-v8": "^2.1.4", - "@testing-library/react": "^16.0.1", - "@testing-library/jest-dom": "^6.6.3", - "@testing-library/user-event": "^14.5.2", - "jsdom": "^25.0.1" - } -} diff --git a/client/src/App.tsx b/client/src/App.tsx deleted file mode 100644 index dd43b8c..0000000 --- a/client/src/App.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { BrowserRouter, Routes, Route, NavLink, Navigate } from 'react-router-dom'; -import { useAppStore } from '@/store/appStore'; -import { ThemeProvider } from '@/themes/ThemeProvider'; -import { LoginScreen } from '@/components/auth/LoginScreen'; -import { DashboardPage } from '@/pages/DashboardPage'; -import { LedgerPage } from '@/pages/LedgerPage'; -import { TaxPage } from '@/pages/TaxPage'; -import { TimerPage } from '@/pages/TimerPage'; -import { SettingsPage } from '@/pages/SettingsPage'; - -export function App() { - const unlocked = useAppStore((s) => s.localAuth.unlocked); - const username = useAppStore((s) => s.localAuth.username); - const saving = useAppStore((s) => s.saving); - const saveError = useAppStore((s) => s.lastSaveError); - - return ( - - {!unlocked ? ( - - ) : ( - -
-
- ten99timecard - -
- {saving && Saving…} - {saveError && ⚠ Save failed} - {username} -
-
-
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - -
-
-
- )} -
- ); -} diff --git a/client/src/__tests__/appStore.test.ts b/client/src/__tests__/appStore.test.ts deleted file mode 100644 index 7fedcff..0000000 --- a/client/src/__tests__/appStore.test.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { describe, it, expect, beforeEach } from 'vitest'; -import { useAppStore } from '@/store/appStore'; - -describe('appStore — CRUD', () => { - beforeEach(async () => { - // Reset to logged-in fresh state - useAppStore.setState({ - data: { - workEntries: [], - payments: [], - expenses: [], - taxInputs: {}, - dashboard: { charts: [], widgets: [] }, - settings: { theme: 'standard', mode: 'dark', storageMode: 'cookie', defaultRate: 50 }, - version: 1, - }, - localAuth: { unlocked: true, username: 'test' }, - cloudAuth: { token: null, email: null, provider: null }, - vault: null, // no persistence in tests - }); - }); - - it('addWorkEntry assigns id and timestamps', () => { - const e = useAppStore.getState().addWorkEntry({ - date: '2024-01-01', description: 'code review', amount: 150, - }); - expect(e.id).toBeTruthy(); - expect(e.createdAt).toBeGreaterThan(0); - expect(useAppStore.getState().data.workEntries).toHaveLength(1); - }); - - it('updateWorkEntry patches fields', () => { - const e = useAppStore.getState().addWorkEntry({ - date: '2024-01-01', description: 'old', amount: 100, - }); - useAppStore.getState().updateWorkEntry(e.id, { description: 'new' }); - const updated = useAppStore.getState().data.workEntries[0]; - expect(updated.description).toBe('new'); - expect(updated.amount).toBe(100); // unchanged - expect(updated.updatedAt).toBeGreaterThanOrEqual(e.createdAt); - }); - - it('deleteWorkEntry removes it', () => { - const e = useAppStore.getState().addWorkEntry({ - date: '2024-01-01', description: 'x', amount: 1, - }); - useAppStore.getState().deleteWorkEntry(e.id); - expect(useAppStore.getState().data.workEntries).toHaveLength(0); - }); - - it('addPayment / addExpense follow same pattern', () => { - const p = useAppStore.getState().addPayment({ - date: '2024-01-01', amount: 5000, payer: 'Acme', - }); - const ex = useAppStore.getState().addExpense({ - date: '2024-01-01', amount: 200, description: 'laptop', deductible: true, - }); - expect(p.id).toBeTruthy(); - expect(ex.id).toBeTruthy(); - expect(useAppStore.getState().data.payments).toHaveLength(1); - expect(useAppStore.getState().data.expenses).toHaveLength(1); - }); - - it('mutations bump version counter', () => { - const v0 = useAppStore.getState().data.version; - useAppStore.getState().addWorkEntry({ date: '2024-01-01', description: 'x' }); - const v1 = useAppStore.getState().data.version; - expect(v1).toBe(v0 + 1); - }); - - it('setTaxInputs merges per-year', () => { - useAppStore.getState().setTaxInputs(2024, { priorYearAGI: 50000 }); - useAppStore.getState().setTaxInputs(2024, { priorYearTax: 6000 }); - const ti = useAppStore.getState().data.taxInputs[2024]; - expect(ti.priorYearAGI).toBe(50000); - expect(ti.priorYearTax).toBe(6000); - expect(ti.filingStatus).toBe('single'); - }); - - it('chart add/update/remove', () => { - useAppStore.getState().addChart({ title: 'test chart' }); - const charts = useAppStore.getState().data.dashboard.charts; - expect(charts).toHaveLength(1); - const id = charts[0].id; - - useAppStore.getState().updateChart(id, { type: 'bar' }); - expect(useAppStore.getState().data.dashboard.charts[0].type).toBe('bar'); - - useAppStore.getState().removeChart(id); - expect(useAppStore.getState().data.dashboard.charts).toHaveLength(0); - }); - - it('setTheme updates both theme and mode', () => { - useAppStore.getState().setTheme('cyberpunk', 'light'); - expect(useAppStore.getState().data.settings.theme).toBe('cyberpunk'); - expect(useAppStore.getState().data.settings.mode).toBe('light'); - }); - - it('setDefaultRate updates settings', () => { - useAppStore.getState().setDefaultRate(85); - expect(useAppStore.getState().data.settings.defaultRate).toBe(85); - }); -}); - -describe('appStore — auth', () => { - beforeEach(() => { - useAppStore.getState().logout(); - }); - - it('register creates encrypted vault and unlocks', async () => { - await useAppStore.getState().register('alice', 'my-strong-password'); - expect(useAppStore.getState().localAuth.unlocked).toBe(true); - expect(useAppStore.getState().localAuth.username).toBe('alice'); - expect(document.cookie).toContain('t99_alice'); - }); - - it('register fails if user exists', async () => { - await useAppStore.getState().register('bob', 'password123'); - useAppStore.getState().logout(); - await expect( - useAppStore.getState().register('bob', 'different') - ).rejects.toThrow(); - }); - - it('login succeeds with correct password', async () => { - await useAppStore.getState().register('carol', 'secret-pass-123'); - useAppStore.getState().addWorkEntry({ date: '2024-01-01', description: 'marker', amount: 999 }); - await useAppStore.getState().persist(); - useAppStore.getState().logout(); - - await useAppStore.getState().login('carol', 'secret-pass-123'); - expect(useAppStore.getState().localAuth.unlocked).toBe(true); - expect(useAppStore.getState().data.workEntries[0].description).toBe('marker'); - }); - - it('login fails with wrong password', async () => { - await useAppStore.getState().register('dave', 'correct-pass'); - useAppStore.getState().logout(); - await expect( - useAppStore.getState().login('dave', 'wrong-pass') - ).rejects.toThrow(/Wrong password/); - }); - - it('logout locks and clears data', async () => { - await useAppStore.getState().register('eve', 'password123'); - useAppStore.getState().addWorkEntry({ date: '2024-01-01', description: 'secret' }); - useAppStore.getState().logout(); - expect(useAppStore.getState().localAuth.unlocked).toBe(false); - expect(useAppStore.getState().data.workEntries).toHaveLength(0); - }); -}); diff --git a/client/src/__tests__/components.test.tsx b/client/src/__tests__/components.test.tsx deleted file mode 100644 index a1cca2e..0000000 --- a/client/src/__tests__/components.test.tsx +++ /dev/null @@ -1,287 +0,0 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { render, screen, fireEvent } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { HierSpreadsheet } from '@/components/spreadsheet/HierSpreadsheet'; -import { WorkEntryForm, ExpenseForm } from '@/components/spreadsheet/EntryForm'; -import { Modal, ConfirmDialog } from '@/components/common/Modal'; -import { LoginScreen } from '@/components/auth/LoginScreen'; -import { useAppStore } from '@/store/appStore'; -import type { HierNode } from '@/types'; - -// ─── HierSpreadsheet ───────────────────────────────────────────────────────── - -describe('HierSpreadsheet', () => { - const tree: HierNode[] = [ - { - key: '2024', level: 'year', label: '2024', value: 1500, - children: [ - { - key: '2024-03', level: 'month', label: 'March 2024', value: 1500, - children: [ - { - key: '2024-03-15', level: 'day', label: 'Mar 15', value: 1500, - children: [ - { key: 'i1', level: 'item', label: 'Task A', value: 1000, children: [] }, - { key: 'i2', level: 'item', label: 'Task B', value: 500, children: [] }, - ], - }, - ], - }, - ], - }, - ]; - - it('shows only top-level rows by default', () => { - render(); - expect(screen.getByText('2024')).toBeInTheDocument(); - expect(screen.queryByText('March 2024')).not.toBeInTheDocument(); - }); - - it('expands row on click', async () => { - render(); - await userEvent.click(screen.getByText('2024')); - expect(screen.getByText('March 2024')).toBeInTheDocument(); - }); - - it('collapses expanded row on second click', async () => { - render(); - await userEvent.click(screen.getByText('2024')); - expect(screen.getByText('March 2024')).toBeInTheDocument(); - await userEvent.click(screen.getByText('2024')); - expect(screen.queryByText('March 2024')).not.toBeInTheDocument(); - }); - - it('Item-level button expands entire tree', async () => { - render(); - await userEvent.click(screen.getByRole('button', { name: 'Item' })); - expect(screen.getByText('Task A')).toBeInTheDocument(); - expect(screen.getByText('Task B')).toBeInTheDocument(); - }); - - it('Year button collapses everything', async () => { - render(); - await userEvent.click(screen.getByRole('button', { name: 'Item' })); - await userEvent.click(screen.getByRole('button', { name: 'Year' })); - expect(screen.queryByText('Task A')).not.toBeInTheDocument(); - }); - - it('Month button expands years but not days', async () => { - render(); - await userEvent.click(screen.getByRole('button', { name: 'Month' })); - expect(screen.getByText('March 2024')).toBeInTheDocument(); - expect(screen.queryByText('Mar 15')).not.toBeInTheDocument(); - }); - - it('displays grand total', () => { - render(); - expect(screen.getByText('Grand Total')).toBeInTheDocument(); - // $1,500.00 appears in both year row and grand total - expect(screen.getAllByText('$1,500.00').length).toBeGreaterThanOrEqual(1); - }); - - it('calls onEdit for item rows', async () => { - const onEdit = vi.fn(); - render(); - await userEvent.click(screen.getByRole('button', { name: 'Item' })); - const editBtns = screen.getAllByTitle('Edit'); - await userEvent.click(editBtns[0]); - expect(onEdit).toHaveBeenCalledTimes(1); - }); - - it('shows empty state', () => { - render(); - expect(screen.getByText(/No entries yet/)).toBeInTheDocument(); - }); -}); - -// ─── WorkEntryForm ─────────────────────────────────────────────────────────── - -describe('WorkEntryForm', () => { - // Helper: inputs are wrapped in .field divs with sibling