feat: wire mobile app to real Timmy backend via JSON REST API (#73)

Add /api/chat, /api/upload, and /api/chat/history endpoints to the
FastAPI dashboard so the Expo mobile app talks directly to Timmy's
brain (Ollama) instead of a non-existent Node.js server.

Backend:
- New src/dashboard/routes/chat_api.py with 4 endpoints
- Mount /uploads/ for serving chat attachments
- Same context injection and session management as HTMX chat

Mobile app fixes:
- Point API base URL at port 8000 (FastAPI) instead of 3000
- Create lib/_core/theme.ts (was referenced but never created)
- Fix shared/types.ts (remove broken drizzle/errors re-exports)
- Remove broken server/chat.ts and 1,235-line template README
- Clean package.json (remove express, mysql2, drizzle, tRPC deps)
- Remove debug console.log from theme-provider

Tests: 13 new tests covering all API endpoints (all passing).

https://claude.ai/code/session_01XqErDoh2rVsPY8oTj21Lz2

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Alexander Whitestone
2026-02-26 23:58:53 -05:00
committed by GitHub
parent 18ed6232f9
commit 5e60a6453b
11 changed files with 453 additions and 1475 deletions

View File

@@ -0,0 +1,56 @@
/**
* Core theme definitions — dark arcane palette matching the Timmy Time dashboard.
*
* All color tokens are defined here; constants/theme.ts re-exports them.
*/
export type ColorScheme = "light" | "dark";
export interface ThemeColorPalette {
primary: string;
background: string;
surface: string;
foreground: string;
muted: string;
border: string;
success: string;
warning: string;
error: string;
}
/** Per-scheme flat color maps (used by NativeWind vars & ThemeProvider). */
export const SchemeColors: Record<ColorScheme, ThemeColorPalette> = {
light: {
primary: "#a855f7",
background: "#080412",
surface: "#110820",
foreground: "#ede0ff",
muted: "#6b4a8a",
border: "#3b1a5c",
success: "#00e87a",
warning: "#ffb800",
error: "#ff4455",
},
dark: {
primary: "#a855f7",
background: "#080412",
surface: "#110820",
foreground: "#ede0ff",
muted: "#6b4a8a",
border: "#3b1a5c",
success: "#00e87a",
warning: "#ffb800",
error: "#ff4455",
},
};
/** Alias used by useColors() hook — keyed by scheme. */
export const Colors = SchemeColors;
export const ThemeColors = SchemeColors;
export const Fonts = {
regular: { fontFamily: "System", fontWeight: "400" as const },
medium: { fontFamily: "System", fontWeight: "500" as const },
bold: { fontFamily: "System", fontWeight: "700" as const },
};

View File

@@ -71,16 +71,16 @@ const ChatContext = createContext<ChatContextValue | null>(null);
// ── API call ────────────────────────────────────────────────────────────────
function getApiBase(): string {
// Set EXPO_PUBLIC_API_BASE_URL in your .env to point to your Timmy backend
// e.g. EXPO_PUBLIC_API_BASE_URL=http://192.168.1.100:3000
// Set EXPO_PUBLIC_API_BASE_URL in your .env to point to your Timmy dashboard
// e.g. EXPO_PUBLIC_API_BASE_URL=http://192.168.1.100:8000
const envBase = process.env.EXPO_PUBLIC_API_BASE_URL;
if (envBase) return envBase.replace(/\/+$/, "");
// Fallback for web: derive from window location
// Fallback for web: derive from window location (same host, port 8000)
if (typeof window !== "undefined" && window.location) {
return `${window.location.protocol}//${window.location.hostname}:3000`;
return `${window.location.protocol}//${window.location.hostname}:8000`;
}
// Default: local machine
return "http://127.0.0.1:3000";
// Default: Timmy dashboard on localhost
return "http://127.0.0.1:8000";
}
const API_BASE = getApiBase();

View File

@@ -61,8 +61,6 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
}),
[colorScheme, setColorScheme],
);
console.log(value, themeVariables)
return (
<ThemeContext.Provider value={value}>
<View style={[{ flex: 1 }, themeVariables]}>{children}</View>