Initial project scaffold: FastAPI backend + Svelte 5 frontend

Backend (uv): FastAPI app with routers (foods, log, targets, OFF proxy),
SQLAlchemy models, Pydantic schemas, migration runner + 0001 initial schema,
example pytest suite (7 tests).
Frontend (npm): Vite 7 + Svelte 5 runes, lib/ (api, stores, scanner, format)
per spec §7, placeholder components, example vitest suite (4 tests).
SPEC.md §1: registered uvicorn and Vitest (rule §8.3.3).
This commit is contained in:
Craig
2026-07-26 10:25:59 +01:00
commit e047d884b6
47 changed files with 3994 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
<script>
import { onMount } from 'svelte'
import { api } from './lib/api.js'
import { currentDate } from './lib/stores.js'
import Dashboard from './components/Dashboard.svelte'
// Every async view handles loading / error / empty states (spec §8.2 rule 4)
let backend = $state({ loading: true, ok: false, error: null })
onMount(async () => {
try {
await api.health()
backend = { loading: false, ok: true, error: null }
} catch (e) {
backend = { loading: false, ok: false, error: e.message }
}
})
</script>
<main>
<h1>CalCount</h1>
{#if backend.loading}
<p>Connecting to backend…</p>
{:else if backend.error}
<p role="alert">Backend unreachable: {backend.error}</p>
{:else}
<Dashboard date={currentDate.value} />
{/if}
</main>
<style>
main {
max-width: 32rem;
margin: 0 auto;
padding: 1rem;
font-family: system-ui, sans-serif;
}
</style>