From 2889b562e64993482bd13fd806af8ed0865bab8b Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Sat, 14 Feb 2026 11:52:56 +0900
Subject: refactor: migrate API from GraphQL to REST (TypeSpec/OpenAPI)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Replace the entire GraphQL stack (gqlgen, urql, graphql-codegen) with a
TypeSpec → OpenAPI 3.x pipeline using oapi-codegen for Go server stubs
and openapi-fetch + openapi-typescript for the frontend client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
 frontend/src/contexts/AuthContext.tsx | 75 +++++++++++++++--------------------
 1 file changed, 32 insertions(+), 43 deletions(-)

(limited to 'frontend/src/contexts/AuthContext.tsx')

diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx
index 7e38786..9b157cb 100644
--- a/frontend/src/contexts/AuthContext.tsx
+++ b/frontend/src/contexts/AuthContext.tsx
@@ -1,10 +1,12 @@
-import { createContext, type ReactNode, useContext } from "react";
-import { useMutation, useQuery } from "urql";
 import {
-	GetCurrentUserDocument,
-	LoginDocument,
-	LogoutDocument,
-} from "../graphql/generated/graphql";
+	createContext,
+	type ReactNode,
+	useCallback,
+	useContext,
+	useEffect,
+	useState,
+} from "react";
+import { api } from "../services/api-client";
 
 type LoginResult = { success: true } | { success: false; error: string };
 
@@ -17,56 +19,43 @@ interface AuthContextType {
 
 const AuthContext = createContext<AuthContextType | undefined>(undefined);
 
-const urqlContextUser = { additionalTypenames: ["User"] };
-
 export function AuthProvider({ children }: { children: ReactNode }) {
-	const [, executeLogin] = useMutation(LoginDocument);
-	const [, executeLogout] = useMutation(LogoutDocument);
-	const [currentUserResult, reexecuteGetCurrentUser] = useQuery({
-		query: GetCurrentUserDocument,
-		context: urqlContextUser,
-	});
+	const [isLoggedIn, setIsLoggedIn] = useState(false);
+	const [isLoading, setIsLoading] = useState(true);
+
+	const checkAuth = useCallback(async () => {
+		const { data } = await api.GET("/api/auth/me");
+		setIsLoggedIn(!!data);
+		setIsLoading(false);
+	}, []);
 
-	const isLoggedIn = !!currentUserResult.data?.currentUser;
-	const isLoading = currentUserResult.fetching || currentUserResult.stale;
+	useEffect(() => {
+		checkAuth();
+	}, [checkAuth]);
 
 	const login = async (
 		username: string,
 		password: string,
 	): Promise<LoginResult> => {
-		try {
-			const result = await executeLogin(
-				{ username, password },
-				urqlContextUser,
-			);
-
-			if (result.error) {
-				const errorMessage =
-					result.error.graphQLErrors[0]?.message || result.error.message;
-				return { success: false, error: errorMessage };
-			}
+		const { data, error } = await api.POST("/api/auth/login", {
+			body: { username, password },
+		});
 
-			if (result.data?.login?.user) {
-				reexecuteGetCurrentUser({ requestPolicy: "network-only" });
-				return { success: true };
-			}
+		if (error) {
+			return { success: false, error: error.message };
+		}
 
-			const errorMessage = "Invalid username or password";
-			return { success: false, error: errorMessage };
-		} catch (error) {
-			const errorMessage =
-				error instanceof Error ? error.message : "An unknown error occurred";
-			console.error("Login failed:", error);
-			return { success: false, error: errorMessage };
+		if (data?.user) {
+			setIsLoggedIn(true);
+			return { success: true };
 		}
+
+		return { success: false, error: "Invalid username or password" };
 	};
 
 	const logout = async () => {
-		try {
-			await executeLogout({}, urqlContextUser);
-		} catch (error) {
-			console.error("Logout failed:", error);
-		}
+		await api.POST("/api/auth/logout");
+		setIsLoggedIn(false);
 	};
 
 	return (
-- 
cgit v1.3-1-g0d28

