fix(native): useUserPlan derive from useMe (was a stale module cache)

useUserPlan had its own module-level cache + fetch-once-on-mount, separate
from useMe's invalidateMe(). So the __DEV__ tier-override toggle (which calls
invalidateMe()) never reached useUserPlan consumers → the app didn't react to
a plan switch. Now useUserPlan just reads me.plan from useMe → inherits its
live-invalidation, the toggle propagates everywhere.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-05-11 15:18:59 +02:00
parent 790b5e5c24
commit f6852be760

View File

@ -1,43 +1,18 @@
import { useEffect, useState } from "react"; import { useMe } from "./useMe";
import { apiFetch } from "../lib/api"; import type { Plan } from "./useMe";
export type Plan = "free" | "pro" | "legend"; export type { Plan };
type MeResponse = {
id: string;
email: string;
username: string;
plan: Plan;
};
let cachedPlan: Plan | null = null;
/** /**
* Holt den User-Plan vom Backend (/api/auth/me). * Plan des eingeloggten Users abgeleitet aus useMe() (single source of truth,
* Plan wird in DB gespeichert (nicht in user_metadata) daher BFF-Call nötig. * inkl. Live-Invalidierung via invalidateMe()).
*
* Vorher hatte useUserPlan einen eigenen Modul-Cache + fetch-once-on-mount
* das war ein Bug: der __DEV__-Tier-Toggle (ruft invalidateMe() auf) erreichte
* die useUserPlan-Consumer NICHT, also reagierte die App nicht auf den Plan-Wechsel.
* Jetzt erbt useUserPlan die Invalidierung von useMe Toggle propagiert überall.
*/ */
export function useUserPlan(): { plan: Plan; loading: boolean } { export function useUserPlan(): { plan: Plan; loading: boolean } {
const [plan, setPlan] = useState<Plan>(cachedPlan ?? "free"); const { me, loading } = useMe();
const [loading, setLoading] = useState(cachedPlan === null); return { plan: me?.plan ?? "free", loading };
useEffect(() => {
let cancelled = false;
(async () => {
try {
const res = await apiFetch<MeResponse>("/api/auth/me");
if (cancelled) return;
cachedPlan = res.plan ?? "free";
setPlan(cachedPlan);
} catch (e) {
console.warn("[useUserPlan] failed:", e);
} finally {
if (!cancelled) setLoading(false);
}
})();
return () => {
cancelled = true;
};
}, []);
return { plan, loading };
} }