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/components/FeedItem.tsx | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

(limited to 'frontend/src/components/FeedItem.tsx')

diff --git a/frontend/src/components/FeedItem.tsx b/frontend/src/components/FeedItem.tsx
index 8333f75..1fb9001 100644
--- a/frontend/src/components/FeedItem.tsx
+++ b/frontend/src/components/FeedItem.tsx
@@ -1,33 +1,29 @@
 import { faCheck, faCircle, faTrash } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { useMutation } from "urql";
-import type { GetFeedsQuery } from "../graphql/generated/graphql";
-import {
-	MarkFeedReadDocument,
-	MarkFeedUnreadDocument,
-	UnsubscribeFeedDocument,
-} from "../graphql/generated/graphql";
+import type { components } from "../api/generated";
+import { api } from "../services/api-client";
 
-type Feed = NonNullable<GetFeedsQuery["feeds"]>[0];
+type Feed = components["schemas"]["Feed"];
 
 interface Props {
 	feed: Feed;
 	onFeedUnsubscribed?: () => void;
+	onFeedChanged?: () => void;
 }
 
-const urqlContextFeed = { additionalTypenames: ["Feed"] };
-
-export function FeedItem({ feed, onFeedUnsubscribed }: Props) {
-	const [, markFeedRead] = useMutation(MarkFeedReadDocument);
-	const [, markFeedUnread] = useMutation(MarkFeedUnreadDocument);
-	const [, unsubscribeFeed] = useMutation(UnsubscribeFeedDocument);
-
+export function FeedItem({ feed, onFeedUnsubscribed, onFeedChanged }: Props) {
 	const handleMarkAllRead = async (feedId: string) => {
-		await markFeedRead({ id: feedId }, urqlContextFeed);
+		await api.POST("/api/feeds/{feedId}/read", {
+			params: { path: { feedId } },
+		});
+		onFeedChanged?.();
 	};
 
 	const handleMarkAllUnread = async (feedId: string) => {
-		await markFeedUnread({ id: feedId }, urqlContextFeed);
+		await api.POST("/api/feeds/{feedId}/unread", {
+			params: { path: { feedId } },
+		});
+		onFeedChanged?.();
 	};
 
 	const handleUnsubscribeFeed = async (feedId: string) => {
@@ -35,7 +31,9 @@ export function FeedItem({ feed, onFeedUnsubscribed }: Props) {
 			"Are you sure you want to unsubscribe from this feed?",
 		);
 		if (confirmed) {
-			await unsubscribeFeed({ id: feedId }, urqlContextFeed);
+			await api.DELETE("/api/feeds/{feedId}", {
+				params: { path: { feedId } },
+			});
 			onFeedUnsubscribed?.();
 		}
 	};
-- 
cgit v1.3-1-g0d28

