diff --git a/src/app/[locale]/dashboard/page.tsx b/src/app/[locale]/dashboard/page.tsx
index a416ba7..78ba33a 100644
--- a/src/app/[locale]/dashboard/page.tsx
+++ b/src/app/[locale]/dashboard/page.tsx
@@ -169,7 +169,6 @@ export default async function DashboardPage() {
}
const tenantName = myTenant.metadata.name;
- const teamId = myTenant.status?.litellmTeamId || tenantName;
return (
@@ -209,12 +208,12 @@ export default async function DashboardPage() {
- {/* Usage */}
+ {/* Usage — no teamId passed, backend resolves from session */}
{t("usage")}
-
+
{/* Link to tenant detail */}
diff --git a/src/app/[locale]/tenants/[name]/page.tsx b/src/app/[locale]/tenants/[name]/page.tsx
index 20a2b81..5b95409 100644
--- a/src/app/[locale]/tenants/[name]/page.tsx
+++ b/src/app/[locale]/tenants/[name]/page.tsx
@@ -39,6 +39,12 @@ export default async function TenantDetailPage({
);
const channelUsers = tenant.spec.channelUsers || {};
+ // Admins inspecting another tenant's usage: pass teamId explicitly.
+ // Customers viewing their own: no teamId, backend resolves from session.
+ const usageTeamId = user.isPlatform
+ ? tenant.status?.litellmTeamId || undefined
+ : undefined;
+
return (
{/* Header */}
@@ -61,7 +67,7 @@ export default async function TenantDetailPage({
{t("usage")}
-
+
{/* Packages */}
@@ -96,4 +102,4 @@ export default async function TenantDetailPage({
);
-}
\ No newline at end of file
+}
diff --git a/src/app/api/workspace-defaults/route.ts b/src/app/api/workspace-defaults/route.ts
index 58b8043..06778f7 100644
--- a/src/app/api/workspace-defaults/route.ts
+++ b/src/app/api/workspace-defaults/route.ts
@@ -1,5 +1,6 @@
import { NextRequest, NextResponse } from "next/server";
import { getSessionUser } from "@/lib/session";
+import { getPackageDef } from "@/lib/packages";
import {
getDefaultSoulMd,
getDefaultAgentsMd,
@@ -7,9 +8,12 @@ import {
} from "@/lib/workspace-defaults";
/**
- * GET /api/workspace-defaults?orgName=...&packages=telegram,web-search
+ * GET /api/workspace-defaults?packages=telegram,web-search
* Returns default content for SOUL.md, AGENTS.md, and TOOLS.md.
* Used by the onboarding wizard to pre-fill textareas.
+ *
+ * orgName is always resolved from the authenticated session — never
+ * accepted as a query parameter.
*/
export async function GET(req: NextRequest) {
const user = await getSessionUser();
@@ -17,10 +21,13 @@ export async function GET(req: NextRequest) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
- const orgName =
- req.nextUrl.searchParams.get("orgName") || user.orgName || "Your Company";
+ // Always use the session org name — not a client-supplied parameter
+ const orgName = user.orgName || "Your Company";
+
const packagesParam = req.nextUrl.searchParams.get("packages") || "";
- const packages = packagesParam ? packagesParam.split(",").filter(Boolean) : [];
+ const packages = packagesParam
+ ? packagesParam.split(",").filter((id) => id && getPackageDef(id))
+ : [];
const [soulMd, agentsMd, toolsMd] = await Promise.all([
getDefaultSoulMd(orgName),
diff --git a/src/components/dashboard/usage-display.tsx b/src/components/dashboard/usage-display.tsx
index 155035b..cd4fab2 100644
--- a/src/components/dashboard/usage-display.tsx
+++ b/src/components/dashboard/usage-display.tsx
@@ -91,7 +91,13 @@ function UsageChart({ data }: { data: DailyUsage[] }) {
);
}
-export function UsageDisplay({ teamId }: { teamId: string | null }) {
+/**
+ * Usage display widget.
+ *
+ * - Customers: don't pass teamId — the backend resolves it from the session.
+ * - Admins inspecting a specific tenant: pass teamId to override.
+ */
+export function UsageDisplay({ teamId }: { teamId?: string | null }) {
const t = useTranslations("usage");
const [month, setMonth] = useState(getCurrentMonth);
const [data, setData] = useState(null);
@@ -101,10 +107,15 @@ export function UsageDisplay({ teamId }: { teamId: string | null }) {
const isCurrentMonth = month === getCurrentMonth();
const fetchUsage = useCallback(() => {
- if (!teamId) { setLoading(false); return; }
setLoading(true);
setError(null);
- fetch(`/api/usage?teamId=${encodeURIComponent(teamId)}&month=${month}`)
+
+ const params = new URLSearchParams({ month });
+ if (teamId) {
+ params.set("teamId", teamId);
+ }
+
+ fetch(`/api/usage?${params}`)
.then((res) => { if (!res.ok) throw new Error(`${res.status}`); return res.json(); })
.then(setData)
.catch((e) => setError(e.message))
@@ -113,8 +124,6 @@ export function UsageDisplay({ teamId }: { teamId: string | null }) {
useEffect(() => { fetchUsage(); }, [fetchUsage]);
- if (!teamId) return null;
-
return (
{/* Month selector */}
@@ -182,4 +191,4 @@ function StatCard({ label, value, accent }: { label: string; value: string; acce
{value}
);
-}
\ No newline at end of file
+}
diff --git a/src/components/onboarding/wizard.tsx b/src/components/onboarding/wizard.tsx
index fc2a181..6b02988 100644
--- a/src/components/onboarding/wizard.tsx
+++ b/src/components/onboarding/wizard.tsx
@@ -90,7 +90,7 @@ export function OnboardingWizard({ orgName, onComplete }: WizardProps) {
// Fetch DB-stored defaults on mount
useEffect(() => {
- fetch(`/api/workspace-defaults?orgName=${encodeURIComponent(orgName)}`)
+ fetch("/api/workspace-defaults")
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (data) {
@@ -106,7 +106,8 @@ export function OnboardingWizard({ orgName, onComplete }: WizardProps) {
.catch(() => {
/* use inline fallbacks */
});
- }, [orgName]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
// Re-fetch TOOLS.md preview when packages change
const packagesKey = config.packages.sort().join(",");
@@ -115,14 +116,14 @@ export function OnboardingWizard({ orgName, onComplete }: WizardProps) {
if (prevPackagesKey.current === packagesKey && defaultsLoaded) return;
prevPackagesKey.current = packagesKey;
fetch(
- `/api/workspace-defaults?orgName=${encodeURIComponent(orgName)}&packages=${encodeURIComponent(packagesKey)}`
+ `/api/workspace-defaults?packages=${encodeURIComponent(packagesKey)}`
)
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (data?.toolsMd) setToolsMdPreview(data.toolsMd);
})
.catch(() => {});
- }, [packagesKey, orgName, defaultsLoaded]);
+ }, [packagesKey, defaultsLoaded]);
const stepIndex = STEPS.indexOf(step);