← back to kbarnoski__melody-memo

Function bodies 245 total

All specs Real LLM only Function bodies
middleware function · typescript · L4-L55 (52 LOC)
middleware.ts
export async function middleware(request: NextRequest) {
  let supabaseResponse = NextResponse.next({
    request,
  });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value }) =>
            request.cookies.set(name, value)
          );
          supabaseResponse = NextResponse.next({
            request,
          });
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          );
        },
      },
    }
  );

  const {
    data: { user },
  } = await supabase.auth.getUser();

  // Redirect unauthenticated users to login (except for auth pages)
  const isAuthPage =
    request.nextUrl.pathname === "/login" ||
    request.nextUrl.pathname === "/signup";

  if (!use
POST function · typescript · L19-L86 (68 LOC)
src/app/api/analysis/summarize/route.ts
export async function POST(request: Request) {
  try {
    const { analysisId, analysis, title } = await request.json();

    if (!analysis || !analysisId) {
      return Response.json({ error: "Missing analysis data" }, { status: 400 });
    }

    const NOTE_NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
    function midiToNote(midi: number): string {
      return `${NOTE_NAMES[midi % 12]}${Math.floor(midi / 12) - 1}`;
    }

    // Build chord progression string
    const chordProgression = (analysis.chords ?? [])
      .map((c: { chord: string; time: number; duration: number }) =>
        `${c.chord} (${formatTime(c.time)}, ${c.duration.toFixed(1)}s)`
      )
      .join(" | ");

    // Note range
    const notes = analysis.notes ?? [];
    const midiValues = notes.map((n: { midi: number }) => n.midi);
    const minNote = midiValues.length > 0 ? midiToNote(Math.min(...midiValues)) : "N/A";
    const maxNote = midiValues.length > 0 ? midiToNote(Math.max(.
midiToNote function · typescript · L28-L30 (3 LOC)
src/app/api/analysis/summarize/route.ts
    function midiToNote(midi: number): string {
      return `${NOTE_NAMES[midi % 12]}${Math.floor(midi / 12) - 1}`;
    }
formatTime function · typescript · L88-L92 (5 LOC)
src/app/api/analysis/summarize/route.ts
function formatTime(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
resolveFfmpegPath function · typescript · L9-L17 (9 LOC)
src/app/api/audio/[id]/route.ts
function resolveFfmpegPath(): string {
  if (process.env.FFMPEG_PATH) return process.env.FFMPEG_PATH;
  try {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const p = require("ffmpeg-static");
    if (p) return p;
  } catch { /* ignore */ }
  return "ffmpeg";
}
isALAC function · typescript · L21-L29 (9 LOC)
src/app/api/audio/[id]/route.ts
function isALAC(bytes: Uint8Array): boolean {
  const searchLen = Math.min(bytes.length, 500000);
  for (let i = 0; i < searchLen - 3; i++) {
    if (bytes[i] === 0x61 && bytes[i+1] === 0x6c && bytes[i+2] === 0x61 && bytes[i+3] === 0x63) {
      return true;
    }
  }
  return false;
}
transcodeToAAC function · typescript · L31-L63 (33 LOC)
src/app/api/audio/[id]/route.ts
async function transcodeToAAC(inputBuffer: ArrayBuffer): Promise<Buffer> {
  const dir = await mkdtemp(join(tmpdir(), "audio-"));
  const inputPath = join(dir, "input.m4a");
  const outputPath = join(dir, "output.m4a");

  try {
    await writeFile(inputPath, Buffer.from(inputBuffer));
    await access(ffmpegPath).catch(() => {
      throw new Error(`ffmpeg not found at: ${ffmpegPath}`);
    });

    await new Promise<void>((resolve, reject) => {
      execFile(
        ffmpegPath,
        ["-i", inputPath, "-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart", "-y", outputPath],
        { timeout: 120000 },
        (error, _stdout, stderr) => {
          if (error) {
            console.error("[TRANSCODE] ffmpeg error:", error.message, stderr);
            reject(error);
          } else {
            resolve();
          }
        }
      );
    });

    return await readFile(outputPath);
  } finally {
    await unlink(inputPath).catch(() => {});
    await unlink(outputPath).catch
Powered by Repobility — scan your code at https://repobility.com
resolveRecording function · typescript · L74-L98 (25 LOC)
src/app/api/audio/[id]/route.ts
async function resolveRecording(id: string) {
  const supabase = await createClient();
  const { data } = await supabase
    .from("recordings")
    .select(RECORDING_COLUMNS)
    .eq("id", id)
    .single();

  if (data) return { recording: data as RecordingRow, client: supabase, owned: true };

  // Fallback for shared recordings
  const anonClient = createAnonClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  );
  const { data: shared } = await anonClient
    .from("recordings")
    .select(RECORDING_COLUMNS)
    .eq("id", id)
    .not("share_token", "is", null)
    .single();

  if (shared) return { recording: shared as RecordingRow, client: anonClient, owned: false };
  return null;
}
GET function · typescript · L102-L211 (110 LOC)
src/app/api/audio/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const result = await resolveRecording(id);

  if (!result) {
    return NextResponse.json({ error: "Recording not found" }, { status: 404 });
  }

  const { recording, client } = result;

  // Check query param to know if client needs transcoded version
  const needsTranscode = request.nextUrl.searchParams.get("transcode") === "1";

  if (!needsTranscode) {
    // If a persisted AAC transcode exists, serve that instead of the original
    const fileToSign = recording.aac_file_name ?? recording.file_name;

    const { data: signedData } = await client.storage
      .from("recordings")
      .createSignedUrl(fileToSign, 3600);

    if (signedData?.signedUrl) {
      return NextResponse.json({
        url: signedData.signedUrl,
        codec: recording.aac_file_name ? "aac" : (recording.audio_codec ?? null),
        hasAac: !!recording.aac_file_name,
  
PATCH function · typescript · L213-L252 (40 LOC)
src/app/api/audio/[id]/route.ts
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const supabase = await createClient();

  // Verify the user owns this recording
  const { data: recording } = await supabase
    .from("recordings")
    .select("id")
    .eq("id", id)
    .single();

  if (!recording) {
    return NextResponse.json({ error: "Recording not found" }, { status: 404 });
  }

  const body = await request.json();

  // Save waveform peaks (and optionally duration)
  if (body.waveform_peaks) {
    const updates: Record<string, unknown> = { waveform_peaks: body.waveform_peaks };
    if (typeof body.duration === "number" && body.duration > 0) {
      updates.duration = body.duration;
    }

    const { error } = await supabase
      .from("recordings")
      .update(updates)
      .eq("id", id);

    if (error) {
      return NextResponse.json({ error: error.message }, { status: 500 });
    }
    return NextResponse.json(
POST function · typescript · L5-L22 (18 LOC)
src/app/api/chat/compare/route.ts
export async function POST(request: Request) {
  const { messages, analysisA, analysisB, titleA, titleB } = await request.json();

  const systemPrompt = buildCompareSystemPrompt(
    titleA,
    analysisA,
    titleB,
    analysisB
  );

  const result = streamText({
    model: defaultModel,
    system: systemPrompt,
    messages,
  });

  return result.toDataStreamResponse();
}
POST function · typescript · L5-L24 (20 LOC)
src/app/api/chat/insights/route.ts
export async function POST(request: Request) {
  const { messages, analyses } = await request.json();

  const systemPrompt = buildInsightsSystemPrompt(
    analyses.map((a: { title: string; key_signature: string | null; tempo: number | null; chords: { chord: string }[] }) => ({
      recording_title: a.title,
      key_signature: a.key_signature,
      tempo: a.tempo,
      chords: a.chords,
    }))
  );

  const result = streamText({
    model: defaultModel,
    system: systemPrompt,
    messages,
  });

  return result.toDataStreamResponse();
}
POST function · typescript · L6-L49 (44 LOC)
src/app/api/chat/route.ts
export async function POST(request: Request) {
  try {
    const { messages, recordingId, analysis } = await request.json();

    if (!messages || !Array.isArray(messages)) {
      return new Response("Invalid messages format", { status: 400 });
    }

    const systemPrompt = buildRecordingSystemPrompt(analysis);

    const result = streamText({
      model: defaultModel,
      system: systemPrompt,
      messages: messages.map((m: { role: string; content: string }) => ({
        role: m.role as "user" | "assistant",
        content: m.content,
      })),
    });

    // Fire-and-forget: save user message without blocking the stream
    const lastUserMessage = messages[messages.length - 1];
    if (lastUserMessage?.role === "user") {
      createClient().then(async (supabase) => {
        const { data: { user } } = await supabase.auth.getUser();
        if (user) {
          await supabase.from("chat_messages").insert({
            recording_id: recordingId,
            user_id: user.
POST function · typescript · L19-L58 (40 LOC)
src/app/api/insights/summarize/route.ts
export async function POST(request: Request) {
  try {
    const { analyses } = await request.json();

    if (!analyses || !Array.isArray(analyses) || analyses.length === 0) {
      return Response.json({ error: "No analyses provided" }, { status: 400 });
    }

    const recordingSummaries = analyses.map((a: {
      title: string;
      key_signature: string | null;
      tempo: number | null;
      chords: { chord: string }[];
    }) => {
      const uniqueChords = [...new Set(a.chords.map((c) => c.chord))];
      return `- "${a.title}" — Key: ${a.key_signature ?? "?"}, Tempo: ${a.tempo ? `~${a.tempo} BPM` : "?"}, Chords: ${uniqueChords.slice(0, 10).join(", ")}`;
    }).join("\n");

    const prompt = `Analyze this library of ${analyses.length} piano voice memo recordings and generate insights.

## Recordings
${recordingSummaries}

Group similar recordings into clusters based on shared musical characteristics (key, chord vocabulary, tempo, style). Identify any standout recordings th
getCreationDate function · typescript · L6-L58 (53 LOC)
src/app/api/recordings/fix-dates/route.ts
function getCreationDate(buf: ArrayBuffer): Date | null {
  const view = new DataView(buf);

  // Scan top-level atoms to find moov
  let offset = 0;
  while (offset + 8 <= view.byteLength) {
    let size = view.getUint32(offset);
    const type = String.fromCharCode(
      view.getUint8(offset + 4), view.getUint8(offset + 5),
      view.getUint8(offset + 6), view.getUint8(offset + 7)
    );

    // Handle 64-bit extended size (size field = 1)
    let headerSize = 8;
    if (size === 1 && offset + 16 <= view.byteLength) {
      const hi = view.getUint32(offset + 8);
      const lo = view.getUint32(offset + 12);
      size = hi * 4294967296 + lo;
      headerSize = 16;
    }

    if (size < 8) break;

    if (type === "moov") {
      const end = Math.min(offset + size, view.byteLength);
      let inner = offset + headerSize;
      while (inner + 20 <= end) {
        const atomSize = view.getUint32(inner);
        const atomType = String.fromCharCode(
          view.getUint8(inner + 4), 
All rows above produced by Repobility · https://repobility.com
POST function · typescript · L60-L108 (49 LOC)
src/app/api/recordings/fix-dates/route.ts
export async function POST() {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { data: recordings, error } = await supabase
    .from("recordings")
    .select("id, file_name, recorded_at")
    .eq("user_id", user.id);

  if (error || !recordings) {
    return NextResponse.json({ error: "Failed to fetch recordings" }, { status: 500 });
  }

  const results = [];

  for (const rec of recordings) {
    const { data: fileData, error: dlError } = await supabase.storage
      .from("recordings")
      .download(rec.file_name);

    if (dlError || !fileData) {
      results.push({ id: rec.id, file: rec.file_name, oldDate: rec.recorded_at, newDate: null, error: dlError?.message });
      continue;
    }

    const buf = await fileData.arrayBuffer();
    const creationDate = getCreationDate(buf);

    if (creationDate) {
      const newDate 
GET function · typescript · L4-L22 (19 LOC)
src/app/api/recordings/[id]/analysis/route.ts
export async function GET(
  _request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const supabase = await createClient();

  const { data, error } = await supabase
    .from("analyses")
    .select("*")
    .eq("recording_id", id)
    .single();

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 404 });
  }

  return NextResponse.json(data);
}
POST function · typescript · L24-L49 (26 LOC)
src/app/api/recordings/[id]/analysis/route.ts
export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const supabase = await createClient();
  const body = await request.json();

  const { data, error } = await supabase
    .from("analyses")
    .upsert(
      {
        recording_id: id,
        ...body,
      },
      { onConflict: "recording_id" }
    )
    .select()
    .single();

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json(data);
}
CollectionDetailLoading function · typescript · L1-L25 (25 LOC)
src/app/(app)/collections/[id]/loading.tsx
export default function CollectionDetailLoading() {
  return (
    <div className="space-y-6 animate-pulse">
      <div>
        <div className="h-8 w-48 rounded bg-muted" />
        <div className="mt-2 h-4 w-32 rounded bg-muted" />
      </div>

      <div className="space-y-3">
        {Array.from({ length: 4 }).map((_, i) => (
          <div
            key={i}
            className="flex items-center gap-4 rounded-xl border bg-card px-6 py-4"
          >
            <div className="h-10 w-10 shrink-0 rounded-lg bg-muted" />
            <div className="flex-1 space-y-2">
              <div className="h-4 w-48 rounded bg-muted" />
              <div className="h-3 w-32 rounded bg-muted" />
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
CollectionPage function · typescript · L5-L57 (53 LOC)
src/app/(app)/collections/[id]/page.tsx
export default async function CollectionPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const supabase = await createClient();

  const { data: collection } = await supabase
    .from("collections")
    .select("*")
    .eq("id", id)
    .single();

  if (!collection) notFound();

  // Get recordings in this collection
  const { data: items } = await supabase
    .from("collection_recordings")
    .select("position, recording:recordings(id, title, duration, created_at)")
    .eq("collection_id", id)
    .order("position");

  const recordings = (items ?? [])
    .map((item) => ({
      position: item.position,
      ...(item.recording as unknown as { id: string; title: string; duration: number | null; created_at: string }),
    }))
    .filter((r) => r.id);

  // Get ALL user recordings to power the "add recording" picker
  const { data: allRecordings } = await supabase
    .from("recordings")
    .select("id, title, duration, created_at")
CollectionsLoading function · typescript · L1-L19 (19 LOC)
src/app/(app)/collections/loading.tsx
export default function CollectionsLoading() {
  return (
    <div className="space-y-6 animate-pulse">
      <div className="flex items-center justify-between">
        <div className="h-8 w-40 rounded bg-muted" />
        <div className="h-9 w-32 rounded bg-muted" />
      </div>

      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        {Array.from({ length: 6 }).map((_, i) => (
          <div key={i} className="rounded-xl border bg-card p-6 space-y-3">
            <div className="h-5 w-32 rounded bg-muted" />
            <div className="h-3 w-20 rounded bg-muted" />
          </div>
        ))}
      </div>
    </div>
  );
}
CollectionsPage function · typescript · L7-L59 (53 LOC)
src/app/(app)/collections/page.tsx
export default async function CollectionsPage() {
  const supabase = await createClient();

  const { data: collections } = await supabase
    .from("collections")
    .select("*, collection_recordings(count)")
    .order("created_at", { ascending: false });

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Collections</h1>
          <p className="text-muted-foreground">
            Organize recordings into themed collections
          </p>
        </div>
        <CreateCollectionDialog />
      </div>

      {collections && collections.length > 0 ? (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {collections.map((collection) => (
            <Link key={collection.id} href={`/collections/${collection.id}`}>
              <Card className="cursor-pointer transition-colors hover:bg-accent/50">
                <CardHeader className="pb-2">
          
formatDuration function · typescript · L32-L36 (5 LOC)
src/app/(app)/compare/page.tsx
function formatDuration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
noteRange function · typescript · L38-L47 (10 LOC)
src/app/(app)/compare/page.tsx
function noteRange(notes: { midi: number }[] | null): string {
  if (!notes || notes.length === 0) return "--";
  const NOTE_NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
  const sorted = [...notes].sort((a, b) => a.midi - b.midi);
  const lo = sorted[0].midi;
  const hi = sorted[sorted.length - 1].midi;
  const loName = `${NOTE_NAMES[lo % 12]}${Math.floor(lo / 12) - 1}`;
  const hiName = `${NOTE_NAMES[hi % 12]}${Math.floor(hi / 12) - 1}`;
  return `${loName} -- ${hiName}`;
}
ComparisonRow function · typescript · L49-L82 (34 LOC)
src/app/(app)/compare/page.tsx
function ComparisonRow({
  label,
  valueA,
  valueB,
}: {
  label: string;
  valueA: string;
  valueB: string;
}) {
  const match = valueA === valueB && valueA !== "--";
  return (
    <div className="grid grid-cols-[1fr_auto_1fr] items-center gap-4 border-b border-border py-3 last:border-0">
      <span className="text-right font-mono text-sm">{valueA}</span>
      <div className="flex flex-col items-center gap-1">
        <span className="text-xs uppercase tracking-widest text-muted-foreground">
          {label}
        </span>
        {valueA !== "--" && valueB !== "--" && (
          <Badge
            variant={match ? "default" : "outline"}
            className={
              match
                ? "bg-neutral-800 text-neutral-100 dark:bg-neutral-200 dark:text-neutral-900"
                : ""
            }
          >
            {match ? "Match" : "Differs"}
          </Badge>
        )}
      </div>
      <span className="font-mono text-sm">{valueB}</span>
    </div>
  );
CompareChat function · typescript · L90-L185 (96 LOC)
src/app/(app)/compare/page.tsx
function CompareChat({
  titleA,
  titleB,
  analysisA,
  analysisB,
}: {
  titleA: string;
  titleB: string;
  analysisA: FullAnalysis;
  analysisB: FullAnalysis;
}) {
  const scrollRef = useRef<HTMLDivElement>(null);
  const chatKey = `${titleA}-${titleB}`;

  const { messages, input, handleInputChange, handleSubmit, isLoading, append } =
    useChat({
      api: "/api/chat/compare",
      body: { analysisA, analysisB, titleA, titleB },
      id: chatKey,
    });

  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages]);

  return (
    <Card>
      <CardHeader className="pb-2">
        <CardTitle className="text-base font-medium tracking-tight">
          AI Comparison Chat
        </CardTitle>
        <p className="text-xs text-muted-foreground">
          Ask about the relationship between these two recordings
        </p>
      </CardHeader>
      <CardContent>
        <div className="flex h-[300px
ComparePage function · typescript · L187-L447 (261 LOC)
src/app/(app)/compare/page.tsx
export default function ComparePage() {
  const [recordings, setRecordings] = useState<Recording[]>([]);
  const [loading, setLoading] = useState(true);
  const [idA, setIdA] = useState<string>("");
  const [idB, setIdB] = useState<string>("");

  useEffect(() => {
    async function fetchRecordings() {
      const supabase = createClient();
      const { data } = await supabase
        .from("recordings")
        .select(
          "id, title, duration, analyses(key_signature, tempo, time_signature, chords, notes, summary, status)"
        )
        .order("created_at", { ascending: false });

      if (data) {
        const mapped: Recording[] = data.map((r) => ({
          id: r.id,
          title: r.title,
          duration: r.duration,
          analyses: Array.isArray(r.analyses)
            ? r.analyses[0] ?? null
            : r.analyses,
        }));
        setRecordings(mapped);
      }
      setLoading(false);
    }
    fetchRecordings();
  }, []);

  const recA = recordi
fetchRecordings function · typescript · L194-L215 (22 LOC)
src/app/(app)/compare/page.tsx
    async function fetchRecordings() {
      const supabase = createClient();
      const { data } = await supabase
        .from("recordings")
        .select(
          "id, title, duration, analyses(key_signature, tempo, time_signature, chords, notes, summary, status)"
        )
        .order("created_at", { ascending: false });

      if (data) {
        const mapped: Recording[] = data.map((r) => ({
          id: r.id,
          title: r.title,
          duration: r.duration,
          analyses: Array.isArray(r.analyses)
            ? r.analyses[0] ?? null
            : r.analyses,
        }));
        setRecordings(mapped);
      }
      setLoading(false);
    }
InsightsLoading function · typescript · L1-L24 (24 LOC)
src/app/(app)/insights/loading.tsx
export default function InsightsLoading() {
  return (
    <div className="space-y-6 animate-pulse">
      <div className="h-8 w-40 rounded bg-muted" />

      {/* Stats cards */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {Array.from({ length: 4 }).map((_, i) => (
          <div key={i} className="rounded-xl border bg-card p-6 space-y-2">
            <div className="h-3 w-20 rounded bg-muted" />
            <div className="h-7 w-16 rounded bg-muted" />
          </div>
        ))}
      </div>

      {/* Content area */}
      <div className="space-y-3">
        {Array.from({ length: 4 }).map((_, i) => (
          <div key={i} className="h-16 rounded-xl border bg-card" />
        ))}
      </div>
    </div>
  );
}
InsightsPage function · typescript · L6-L105 (100 LOC)
src/app/(app)/insights/page.tsx
export default async function InsightsPage() {
  const supabase = await createClient();

  const { data: recordings, error } = await supabase
    .from("recordings")
    .select(
      "id, title, duration, created_at, analyses(key_signature, tempo, time_signature, chords)"
    );

  if (error) {
    console.error("Insights query error:", error);
  }

  const allRecordings = recordings ?? [];
  const totalRecordings = allRecordings.length;

  const analysesData = allRecordings
    .filter((r) => {
      if (!r.analyses) return false;
      if (Array.isArray(r.analyses)) return r.analyses.length > 0;
      return true; // single object means analysis exists
    })
    .map((r) => {
      const analysis = Array.isArray(r.analyses) ? r.analyses[0] : r.analyses;
      const a = analysis as {
        key_signature: string | null;
        tempo: number | null;
        time_signature: string | null;
        chords: { chord: string; time: number; duration: number }[];
      };
      return {
 
AppLayout function · typescript · L3-L12 (10 LOC)
src/app/(app)/layout.tsx
export default function AppLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex h-screen overflow-hidden">
      <Sidebar />
      <main className="flex-1 overflow-y-auto pt-14 md:pt-0">
        <div className="mx-auto max-w-5xl px-4 py-6 sm:px-6 sm:py-8">{children}</div>
      </main>
    </div>
  );
}
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
LibraryLoading function · typescript · L1-L28 (28 LOC)
src/app/(app)/library/loading.tsx
export default function LibraryLoading() {
  return (
    <div className="space-y-6 animate-pulse">
      {/* Header with search */}
      <div className="flex items-center justify-between">
        <div className="h-8 w-32 rounded bg-muted" />
        <div className="h-9 w-24 rounded bg-muted" />
      </div>
      <div className="h-10 w-full rounded-md bg-muted" />

      {/* Recording cards */}
      <div className="space-y-3">
        {Array.from({ length: 5 }).map((_, i) => (
          <div
            key={i}
            className="flex items-center gap-4 rounded-xl border bg-card px-6 py-4"
          >
            <div className="h-10 w-10 shrink-0 rounded-lg bg-muted" />
            <div className="flex-1 space-y-2">
              <div className="h-4 w-48 rounded bg-muted" />
              <div className="h-3 w-32 rounded bg-muted" />
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
LibraryPage function · typescript · L4-L56 (53 LOC)
src/app/(app)/library/page.tsx
export default async function LibraryPage() {
  const supabase = await createClient();

  const [{ data: recordings }, { data: tags }] = await Promise.all([
    supabase
      .from("recordings")
      .select(
        "id, title, duration, created_at, recorded_at, file_name, description, analyses(id, status, key_signature, tempo), recording_tags(tag_id, tags(id, name))"
      )
      .order("created_at", { ascending: false }),
    supabase
      .from("tags")
      .select("id, name")
      .order("name", { ascending: true }),
  ]);

  const normalized = (recordings ?? []).map((rec) => {
    // analyses can be an array or a single object depending on the relationship
    const analysesList = Array.isArray(rec.analyses)
      ? rec.analyses
      : rec.analyses
        ? [rec.analyses]
        : [];
    const completed = analysesList.find((a: { status?: string }) => a.status === "completed") as
      | { key_signature?: string | null; tempo?: number | null }
      | undefined;

    ret
RecordingLoading function · typescript · L1-L38 (38 LOC)
src/app/(app)/recording/[id]/loading.tsx
export default function RecordingLoading() {
  return (
    <div className="space-y-6 animate-pulse">
      {/* Title area */}
      <div>
        <div className="h-8 w-64 rounded bg-muted" />
        <div className="mt-2 h-4 w-48 rounded bg-muted" />
      </div>

      {/* Waveform player area */}
      <div className="space-y-3">
        <div className="h-[104px] rounded-lg border bg-card" />
        <div className="flex items-center justify-between">
          <div className="h-4 w-10 rounded bg-muted" />
          <div className="flex gap-2">
            <div className="h-9 w-9 rounded bg-muted" />
            <div className="h-9 w-9 rounded bg-muted" />
            <div className="h-9 w-9 rounded bg-muted" />
          </div>
          <div className="h-4 w-10 rounded bg-muted" />
        </div>
      </div>

      {/* Tabs area */}
      <div className="space-y-4">
        <div className="flex gap-4 border-b pb-2">
          <div className="h-5 w-20 rounded bg-muted" />
        
formatDuration function · typescript · L7-L11 (5 LOC)
src/app/(app)/recording/[id]/page.tsx
function formatDuration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
RecordingPage function · typescript · L13-L83 (71 LOC)
src/app/(app)/recording/[id]/page.tsx
export default async function RecordingPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const supabase = await createClient();

  // Run all queries in parallel to eliminate waterfall
  const [recordingResult, analysisResult, messagesResult] = await Promise.all([
    supabase.from("recordings").select("*").eq("id", id).single(),
    supabase.from("analyses").select("*").eq("recording_id", id).single(),
    supabase
      .from("chat_messages")
      .select("*")
      .eq("recording_id", id)
      .order("created_at", { ascending: true }),
  ]);

  const recording = recordingResult.data;
  if (!recording) notFound();

  // Use proxy API route — it detects ALAC and transcodes to AAC for Chrome
  const audioUrl = `/api/audio/${id}`;

  const analysis = analysisResult.data;
  const messages = messagesResult.data;

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold">{recording.title}</h1>
        {r
UploadPage function · typescript · L23-L293 (271 LOC)
src/app/(app)/upload/page.tsx
export default function UploadPage() {
  const [files, setFiles] = useState<UploadingFile[]>([]);
  const [isDragging, setIsDragging] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const router = useRouter();

  const addFiles = useCallback((newFiles: FileList | File[]) => {
    const audioFiles = Array.from(newFiles).filter((f) =>
      f.type.startsWith("audio/") || f.name.endsWith(".m4a") || f.name.endsWith(".mp3") || f.name.endsWith(".wav")
    );
    if (audioFiles.length === 0) {
      toast.error("Please select audio files (M4A, MP3, WAV)");
      return;
    }
    setFiles((prev) => {
      const remaining = 100 - prev.length;
      if (remaining <= 0) {
        toast.error("Maximum 100 files per batch");
        return prev;
      }
      const toAdd = audioFiles.slice(0, remaining);
      if (toAdd.length < audioFiles.length) {
        toast.warning(`Added ${toAdd.length} of ${audioFiles.length} files (100 file limit)`);
      }
      return [
   
handleDrop function · typescript · L54-L58 (5 LOC)
src/app/(app)/upload/page.tsx
  function handleDrop(e: React.DragEvent) {
    e.preventDefault();
    setIsDragging(false);
    addFiles(e.dataTransfer.files);
  }
removeFile function · typescript · L60-L62 (3 LOC)
src/app/(app)/upload/page.tsx
  function removeFile(index: number) {
    setFiles((prev) => prev.filter((_, i) => i !== index));
  }
Powered by Repobility — scan your code at https://repobility.com
uploadAll function · typescript · L64-L183 (120 LOC)
src/app/(app)/upload/page.tsx
  async function uploadAll() {
    const supabase = createClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    if (!user) {
      toast.error(authError?.message ?? "Not logged in. Please sign in first.");
      return;
    }

    let successCount = 0;
    let failCount = 0;

    for (let i = 0; i < files.length; i++) {
      if (files[i].status === "done") continue;

      setFiles((prev) =>
        prev.map((f, idx) => (idx === i ? { ...f, status: "uploading", progress: 10 } : f))
      );

      const file = files[i].file;
      const fileName = `${user.id}/${Date.now()}-${file.name}`;

      setFiles((prev) =>
        prev.map((f, idx) => (idx === i ? { ...f, progress: 30 } : f))
      );

      const { error: uploadError } = await supabase.storage
        .from("recordings")
        .upload(fileName, file, {
          contentType: file.type || "audio/mp4",
          upsert: false,
        });

      if (uploadError) {
        const msg = upl
RootLayout function · typescript · L22-L39 (18 LOC)
src/app/layout.tsx
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <Providers>
          {children}
          <Toaster />
        </Providers>
      </body>
    </html>
  );
}
LoginPage function · typescript · L11-L102 (92 LOC)
src/app/login/page.tsx
export default function LoginPage() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const router = useRouter();

  async function handleLogin(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    const supabase = createClient();
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      setError(error.message);
      setLoading(false);
    } else {
      router.push("/library");
      router.refresh();
    }
  }

  return (
    <div className="relative flex min-h-screen items-center justify-center bg-background p-4">
      <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
        <div className="h-[500px] w-[500px] rounded-full bg-primary/5 blur-3xl" />
      </div>
      <div className="relativ
handleLogin function · typescript · L18-L36 (19 LOC)
src/app/login/page.tsx
  async function handleLogin(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    const supabase = createClient();
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      setError(error.message);
      setLoading(false);
    } else {
      router.push("/library");
      router.refresh();
    }
  }
Home function · typescript · L3-L5 (3 LOC)
src/app/page.tsx
export default function Home() {
  redirect("/library");
}
createAnonClient function · typescript · L9-L14 (6 LOC)
src/app/share/[token]/page.tsx
function createAnonClient() {
  return createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  );
}
formatDuration function · typescript · L16-L20 (5 LOC)
src/app/share/[token]/page.tsx
function formatDuration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
generateMetadata function · typescript · L22-L43 (22 LOC)
src/app/share/[token]/page.tsx
export async function generateMetadata({
  params,
}: {
  params: Promise<{ token: string }>;
}) {
  const { token } = await params;
  const supabase = createAnonClient();
  const { data: recording } = await supabase
    .from("recordings")
    .select("title, description")
    .eq("share_token", token)
    .single();

  if (!recording) {
    return { title: "Recording Not Found" };
  }

  return {
    title: `${recording.title} — Resonance`,
    description: recording.description || "Shared recording on Resonance",
  };
}
All rows above produced by Repobility · https://repobility.com
SharedRecordingPage function · typescript · L45-L221 (177 LOC)
src/app/share/[token]/page.tsx
export default async function SharedRecordingPage({
  params,
}: {
  params: Promise<{ token: string }>;
}) {
  const { token } = await params;
  const supabase = createAnonClient();

  const { data: recording } = await supabase
    .from("recordings")
    .select("*, analyses(*)")
    .eq("share_token", token)
    .single();

  if (!recording) notFound();

  const analysis =
    recording.analyses && recording.analyses.length > 0
      ? recording.analyses[0]
      : null;

  const audioUrl = `/api/audio/${recording.id}`;

  const uniqueChords = analysis?.chords
    ? [...new Set((analysis.chords as { chord: string }[]).map((c) => c.chord))]
    : [];

  return (
    <div className="min-h-screen bg-background text-foreground">
      <div className="mx-auto max-w-2xl px-4 py-10 sm:px-6 sm:py-16">
        {/* Header */}
        <header className="mb-12">
          <p className="text-xs font-mono uppercase tracking-widest text-muted-foreground mb-6">
            Shared Recording
        
SignupPage function · typescript · L11-L104 (94 LOC)
src/app/signup/page.tsx
export default function SignupPage() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const router = useRouter();

  async function handleSignup(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    const supabase = createClient();
    const { error } = await supabase.auth.signUp({
      email,
      password,
    });

    if (error) {
      setError(error.message);
      setLoading(false);
    } else {
      router.push("/library");
      router.refresh();
    }
  }

  return (
    <div className="relative flex min-h-screen items-center justify-center bg-background p-4">
      <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
        <div className="h-[500px] w-[500px] rounded-full bg-primary/5 blur-3xl" />
      </div>
      <div className="relative w-full m
handleSignup function · typescript · L18-L36 (19 LOC)
src/app/signup/page.tsx
  async function handleSignup(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);

    const supabase = createClient();
    const { error } = await supabase.auth.signUp({
      email,
      password,
    });

    if (error) {
      setError(error.message);
      setLoading(false);
    } else {
      router.push("/library");
      router.refresh();
    }
  }
page 1 / 5next ›