Deduplicate getAccountFull calls in profile page (generateMetadata + prefetch)

Problem

Profile pages (/@username) call getAccountFull() twice during SSR - once in generateMetadata() and once in the layout prefetch. This results in 2 API calls (condenser_api.get_accounts + condenser_api.get_follow_count) that could be deduplicated.

Root Cause

In apps/blog/app/[param]/(user-profile)/layout.tsx:

// generateMetadata() - Line ~45-60
export async function generateMetadata({ params }: ProfileLayoutProps): Promise<Metadata> {
  const username = (await params).param.slice(1);
  const accountData = await getAccountFull(username);  // FIRST CALL
  // ... uses accountData for OG metadata
}

// Layout component - Line ~80-96  
export default async function ProfileLayout({ children, params }: ProfileLayoutProps) {
  const username = resolveParam.param.slice(1);
  // ...
  await queryClient.prefetchQuery({
    queryKey: ['profileData', username],
    queryFn: () => getAccountFull(username)  // SECOND CALL (same data!)
  });
  // ...
}

Why React Query Doesn't Deduplicate This

  1. generateMetadata() runs before the component renders
  2. It calls getAccountFull() directly (not through React Query)
  3. The layout then calls prefetchQuery() with the same function
  4. Since generateMetadata() doesn't use React Query, the data isn't cached

Impact

  • 2 API calls instead of 1 per profile page visit:
    • condenser_api.get_accounts
    • condenser_api.get_follow_count
  • Increases API load unnecessarily
  • Adds latency to profile page SSR

Proposed Fix

Use Next.js cache() to deduplicate the function at the request level:

// In a shared utility or at top of layout.tsx
import { cache } from 'react';

const getAccountFullCached = cache(async (username: string) => {
  return getAccountFull(username);
});

// Then use getAccountFullCached in both generateMetadata() and prefetchQuery()

Alternative: Only fetch in one place and pass data down, but cache() is cleaner.

Implementation

  1. Create cached wrapper in apps/blog/lib/cached-api.ts:
import { cache } from 'react';
import { getAccountFull } from '@transaction/lib/hive-api';

export const getAccountFullCached = cache(getAccountFull);
  1. Update layout.tsx to use cached version in both places
  • #790 (closed) - Remove unnecessary SSR prefetch for user subscriptions
  • #793 (closed) - Remove duplicate community data prefetching
  • #764 - Current API calls are sub-optimal for denser needs
  • NOTES/05-api-call-comparison-results.md - Full API comparison analysis