Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/napkin.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@
| 2026-02-17 | self | Ran `sed` on bracketed Next route paths without quoting, causing zsh `no matches found` | Always single-quote paths containing `[id]` before `sed`/`cat`/`rg` |
| 2026-02-17 | self | Queried prod with `queries/users:getByEmailPublic` and failed because deployed function name was `queries/users:getByEmail` | When checking prod Convex, list available functions from error output and call the deployed name instead of assuming local function names |
| 2026-02-17 | self | Missed a closing quote in a `sed` command for a bracketed path and got `unmatched '` | Double-check shell quoting when commands include `[id]` paths before execution |
| 2026-02-17 | self | Switched server admin checks to `fetchAuthQuery` but forgot generic type args, causing TS `unknown` on response shape | When using `fetchAuthQuery`, provide explicit generic result typing at call sites |
3 changes: 2 additions & 1 deletion apps/web/app/challenges/[id]/admin/activity-types/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Id } from "@repo/backend/_generated/dataModel";
import { getChallengeOrThrow } from "@/lib/challenge-helpers";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { AdminActivityTypesTable } from "@/components/admin/admin-activity-types-table";
import { fetchAuthQuery } from "@/lib/server-auth";

interface ActivityTypesAdminPageProps {
params: Promise<{ id: string }>;
Expand All @@ -17,7 +18,7 @@ export default async function ActivityTypesAdminPage({
const { id } = await params;
const challenge = await getChallengeOrThrow(id);

const adminStatus = await convex.query(api.queries.participations.isUserChallengeAdmin, {
const adminStatus = await fetchAuthQuery<{ isAdmin: boolean; reason: "global_admin" | "creator" | "challenge_admin" | null }>(api.queries.participations.isUserChallengeAdmin, {
challengeId: challenge.id as Id<"challenges">,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { Id } from "@repo/backend/_generated/dataModel";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { FlaggedActivityActions } from "@/components/admin/flagged-activity-actions";
import { fetchAuthQuery } from "@/lib/server-auth";

interface FlaggedActivityDetailPageProps {
params: Promise<{ id: string; activityId: string }>;
Expand Down Expand Up @@ -42,7 +43,7 @@ export default async function FlaggedActivityDetailPage({
notFound();
}

const adminStatus = await convex.query(api.queries.participations.isUserChallengeAdmin, {
const adminStatus = await fetchAuthQuery<{ isAdmin: boolean; reason: "global_admin" | "creator" | "challenge_admin" | null }>(api.queries.participations.isUserChallengeAdmin, {
challengeId: detail.activity.challengeId as Id<"challenges">,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { FlaggingHelpDialog } from "@/components/admin/flagging-help-dialog";
import { fetchAuthQuery } from "@/lib/server-auth";

interface FlaggedActivitiesPageProps {
params: Promise<{ id: string }>;
Expand Down Expand Up @@ -42,7 +43,7 @@ export default async function FlaggedActivitiesPage({
const searchParamsResolved = await searchParams;
const challenge = await getChallengeOrThrow(id);

const adminStatus = await convex.query(api.queries.participations.isUserChallengeAdmin, {
const adminStatus = await fetchAuthQuery<{ isAdmin: boolean; reason: "global_admin" | "creator" | "challenge_admin" | null }>(api.queries.participations.isUserChallengeAdmin, {
challengeId: challenge.id as Id<"challenges">,
});

Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/challenges/[id]/admin/integrations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Id } from "@repo/backend/_generated/dataModel";

import { getChallengeOrThrow } from "@/lib/challenge-helpers";
import { IntegrationsTabs } from "./integrations-tabs";
import { fetchAuthQuery } from "@/lib/server-auth";

interface IntegrationsAdminPageProps {
params: Promise<{ id: string }>;
Expand All @@ -16,7 +17,7 @@ export default async function IntegrationsAdminPage({
const { id } = await params;
const challenge = await getChallengeOrThrow(id);

const adminStatus = await convex.query(api.queries.participations.isUserChallengeAdmin, {
const adminStatus = await fetchAuthQuery<{ isAdmin: boolean; reason: "global_admin" | "creator" | "challenge_admin" | null }>(api.queries.participations.isUserChallengeAdmin, {
challengeId: challenge.id as Id<"challenges">,
});

Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/challenges/[id]/admin/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ArrowLeft } from "lucide-react";

import { requireAuth } from "@/lib/auth";
import { AdminNavigation, type AdminNavigationGroup } from "@/components/admin/admin-navigation";
import { fetchAuthQuery } from "@/lib/server-auth";

interface ChallengeAdminLayoutProps {
children: ReactNode;
Expand All @@ -32,7 +33,7 @@ export default async function ChallengeAdminLayout({
}

// Check if user can manage this challenge
const adminStatus = await convex.query(api.queries.participations.isUserChallengeAdmin, {
const adminStatus = await fetchAuthQuery<{ isAdmin: boolean; reason: "global_admin" | "creator" | "challenge_admin" | null }>(api.queries.participations.isUserChallengeAdmin, {
challengeId: id as Id<"challenges">,
});

Expand Down
4 changes: 4 additions & 0 deletions packages/backend/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type * as actions_createChallengeFromConfig from "../actions/createChalle
import type * as actions_fix2025ActivityTypes from "../actions/fix2025ActivityTypes.js";
import type * as actions_fixContributesToStreak from "../actions/fixContributesToStreak.js";
import type * as actions_payments from "../actions/payments.js";
import type * as actions_rescoreStravaActivities from "../actions/rescoreStravaActivities.js";
import type * as actions_seed from "../actions/seed.js";
import type * as actions_setup2026ActivityTypes from "../actions/setup2026ActivityTypes.js";
import type * as actions_setup2026Challenges from "../actions/setup2026Challenges.js";
Expand Down Expand Up @@ -57,6 +58,7 @@ import type * as mutations_miniGames from "../mutations/miniGames.js";
import type * as mutations_participations from "../mutations/participations.js";
import type * as mutations_paymentConfig from "../mutations/paymentConfig.js";
import type * as mutations_payments from "../mutations/payments.js";
import type * as mutations_rescoreStrava from "../mutations/rescoreStrava.js";
import type * as mutations_stravaWebhook from "../mutations/stravaWebhook.js";
import type * as mutations_templates from "../mutations/templates.js";
import type * as mutations_users from "../mutations/users.js";
Expand Down Expand Up @@ -105,6 +107,7 @@ declare const fullApi: ApiFromModules<{
"actions/fix2025ActivityTypes": typeof actions_fix2025ActivityTypes;
"actions/fixContributesToStreak": typeof actions_fixContributesToStreak;
"actions/payments": typeof actions_payments;
"actions/rescoreStravaActivities": typeof actions_rescoreStravaActivities;
"actions/seed": typeof actions_seed;
"actions/setup2026ActivityTypes": typeof actions_setup2026ActivityTypes;
"actions/setup2026Challenges": typeof actions_setup2026Challenges;
Expand Down Expand Up @@ -148,6 +151,7 @@ declare const fullApi: ApiFromModules<{
"mutations/participations": typeof mutations_participations;
"mutations/paymentConfig": typeof mutations_paymentConfig;
"mutations/payments": typeof mutations_payments;
"mutations/rescoreStrava": typeof mutations_rescoreStrava;
"mutations/stravaWebhook": typeof mutations_stravaWebhook;
"mutations/templates": typeof mutations_templates;
"mutations/users": typeof mutations_users;
Expand Down