---
title: "Project Setup"
description: "Deploy the starter project, review the Feedback type and seed data, and implement the data utility functions that the API routes will use."
canonical_url: "https://vercel.com/academy/agent-friendly-apis/setup-project"
md_url: "https://vercel.com/academy/agent-friendly-apis/setup-project.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-04-11T03:44:18.000Z"
content_type: "lesson"
course: "agent-friendly-apis"
course_title: "Agent-Friendly APIs"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Project Setup

# Set Up the Project

Every cooking school has opinions. The knife skills instructor thinks the claw grip lesson is flawless. The bread baking teacher is convinced nobody reads the hydration guide. And the students? They have their own opinions, scattered across emails, sticky notes, and hallway conversations.

We're going to collect those opinions in one place. A feedback API backed by a JSON file, with real course names, real comments, and enough structure that we can query it, filter it, and summarize it. Nothing fancy on the frontend. We're building an API, so the terminal is our kitchen.

## Outcome

Scaffold a Next.js project with a `Feedback` type and a JSON file of seed data.

## Fast Track

1. Deploy the starter repo to Vercel, then clone it locally
2. Review the `Feedback` interface in `lib/types.ts` and the seed data in `data/feedback.json`
3. Implement the three functions in `lib/data.ts`

## Hands-on exercise

Start by deploying the starter repo. This gets you a live URL right away, which we'll need when we add agent-friendly docs later in the course.

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel-labs%2Fcooking-school-feedback\&repository-name=cooking-school-feedback)

Once Vercel creates your project, clone it locally and install dependencies:

```bash
git clone <your-repo-url>
cd cooking-school-feedback
pnpm install
```

The starter gives you a Next.js app with the App Router and TypeScript already configured. No styling libraries needed for this course since we're building an API, not a UI.

The starter includes the type definition and seed data already. Your job is to implement the data utility. Here's what's in the box:

**`lib/types.ts`** already has the `Feedback` interface. Open it and confirm it has these fields:

- `id` (string), unique identifier like `"fb-001"`
- `courseSlug` (string), which course the feedback belongs to
- `lessonSlug` (string), which lesson within the course
- `rating` (number), integer from 1 to 5
- `comment` (string), the feedback text
- `author` (string), who submitted it
- `createdAt` (string), ISO 8601 timestamp

**`data/feedback.json`** already contains 10 seed feedback entries across three courses at our cooking school: `knife-skills`, `bread-baking`, and `pasta-from-scratch`. Real names, real comments, and a range of ratings. A mix of glowing reviews and constructive criticism that will make the summary endpoint more interesting later.

The real work is in **`lib/data.ts`**. Open it up. The function signatures are there, but the implementations are stubs. You'll need to fill in three functions:

- `getAllFeedback()`, reads the file and returns the parsed array
- `getFeedbackById(id)`, finds a single entry by its `id`
- `addFeedback(entry)`, generates an `id` and `createdAt`, appends to the file, returns the new entry

Use `fs/promises` for file operations and `path.join(process.cwd(), "data", "feedback.json")` for the file path.

\*\*Note: ID generation\*\*

A simple pattern: count the existing entries and pad the number. If there are 10 entries, the next id is `fb-011`. Not production-grade, but perfect for a course project.

## Try It

After implementing the functions, verify the setup by running the dev server and checking that the project compiles:

```bash
pnpm dev
```

You should see:

```
▲ Next.js 16.2.1 (Turbopack)
- Local: http://localhost:3000
```

No errors. The data utility won't be reachable from the browser yet (we'll wire up the API routes in the next lesson), but the project should compile cleanly.

You can also verify the types work by opening `lib/data.ts` in your editor and confirming there are no TypeScript errors on the `Feedback` import.

\*\*Warning: JSON file path\*\*

The `process.cwd()` approach works in development and in `next build`. If you see a "file not found" error, make sure the `data/` folder is at the project root, not inside `app/`.

\*\*Warning: If you see 'fs is not defined'\*\*

Make sure you're importing from `fs/promises`, not `fs`. And double-check the import is `import fs from "fs/promises"`, not a named import like `import { readFile } from "fs"`. The data utility runs on the server, so Node built-ins are available, but the import path matters.

\*\*Warning: If TypeScript complains about your function signatures\*\*

Each function needs to be `async` since `fs.readFile` and `fs.writeFile` return Promises. If your editor shows a type error on the return value, check that you have `async` before the function keyword and that the return type matches (`Promise<Feedback[]>`, `Promise<Feedback | undefined>`, `Promise<Feedback>`).

## Commit

```bash
git add -A && git commit -m "feat(api): scaffold project with feedback types and seed data"
```

## Done-When

- [ ] `lib/types.ts` exports a `Feedback` interface with all 7 fields (provided by starter)
- [ ] `data/feedback.json` contains 10 seed feedback entries across three courses (provided by starter)
- [ ] `lib/data.ts` has working implementations of `getAllFeedback`, `getFeedbackById`, and `addFeedback`
- [ ] `pnpm dev` starts without errors

A typed interface, structured seed data, and a data utility that reads and writes actual JSON. The foundation is in place for an API that agents can understand without guessing.

## Solution

```ts title="lib/types.ts"
export interface Feedback {
  id: string;
  courseSlug: string;
  lessonSlug: string;
  rating: number;
  comment: string;
  author: string;
  createdAt: string;
}
```

```ts title="lib/data.ts"
import fs from "fs/promises";
import path from "path";
import type { Feedback } from "./types";

const DATA_PATH = path.join(process.cwd(), "data", "feedback.json");

export async function getAllFeedback(): Promise<Feedback[]> {
  const raw = await fs.readFile(DATA_PATH, "utf-8");
  return JSON.parse(raw);
}

export async function getFeedbackById(
  id: string
): Promise<Feedback | undefined> {
  const all = await getAllFeedback();
  return all.find((fb) => fb.id === id);
}

export async function addFeedback(
  entry: Omit<Feedback, "id" | "createdAt">
): Promise<Feedback> {
  const all = await getAllFeedback();
  const newEntry: Feedback = {
    ...entry,
    id: `fb-${String(all.length + 1).padStart(3, "0")}`,
    createdAt: new Date().toISOString(),
  };
  all.push(newEntry);
  await fs.writeFile(DATA_PATH, JSON.stringify(all, null, 2));
  return newEntry;
}
```

```json title="data/feedback.json"
[
  {
    "id": "fb-001",
    "courseSlug": "knife-skills",
    "lessonSlug": "the-claw-grip",
    "rating": 5,
    "comment": "Finally understand why my onion cuts were uneven. The claw grip changed everything.",
    "author": "Priya Sharma",
    "createdAt": "2026-03-01T10:30:00Z"
  },
  {
    "id": "fb-002",
    "courseSlug": "knife-skills",
    "lessonSlug": "dicing-onions",
    "rating": 4,
    "comment": "Great technique breakdown but I wish there was a slow-motion video. Hard to follow the horizontal cut at full speed.",
    "author": "Marcus Chen",
    "createdAt": "2026-03-01T14:15:00Z"
  },
  {
    "id": "fb-003",
    "courseSlug": "bread-baking",
    "lessonSlug": "hydration-basics",
    "rating": 5,
    "comment": "I had no idea that flour-to-water ratio mattered this much. My loaves have been bricks for months. Not anymore.",
    "author": "Aisha Johnson",
    "createdAt": "2026-03-02T09:00:00Z"
  },
  {
    "id": "fb-004",
    "courseSlug": "knife-skills",
    "lessonSlug": "the-claw-grip",
    "rating": 3,
    "comment": "Felt a bit rushed. Would have liked more time on finger positioning before jumping to speed drills.",
    "author": "Tom Kowalski",
    "createdAt": "2026-03-02T11:45:00Z"
  },
  {
    "id": "fb-005",
    "courseSlug": "bread-baking",
    "lessonSlug": "shaping-boules",
    "rating": 5,
    "comment": "The surface tension explanation finally clicked. My dough used to spread flat every time.",
    "author": "Sofia Reyes",
    "createdAt": "2026-03-03T08:20:00Z"
  },
  {
    "id": "fb-006",
    "courseSlug": "bread-baking",
    "lessonSlug": "sourdough-starter",
    "rating": 4,
    "comment": "Good lesson, but the difference between a stiff starter and a liquid starter took me a second read.",
    "author": "James Okafor",
    "createdAt": "2026-03-03T16:00:00Z"
  },
  {
    "id": "fb-007",
    "courseSlug": "knife-skills",
    "lessonSlug": "julienne-cuts",
    "rating": 5,
    "comment": "Matchstick carrots used to take me forever. The guide-hand technique cut my prep time in half.",
    "author": "Lin Wei",
    "createdAt": "2026-03-04T10:10:00Z"
  },
  {
    "id": "fb-008",
    "courseSlug": "bread-baking",
    "lessonSlug": "hydration-basics",
    "rating": 2,
    "comment": "I already knew this from other baking courses. Wish there was a fast-track for people who have the fundamentals.",
    "author": "Derek Miles",
    "createdAt": "2026-03-04T13:30:00Z"
  },
  {
    "id": "fb-009",
    "courseSlug": "knife-skills",
    "lessonSlug": "dicing-onions",
    "rating": 5,
    "comment": "Best lesson in the course. No more crying over mangled onion pieces.",
    "author": "Nora Eriksson",
    "createdAt": "2026-03-05T09:45:00Z"
  },
  {
    "id": "fb-010",
    "courseSlug": "pasta-from-scratch",
    "lessonSlug": "egg-dough",
    "rating": 4,
    "comment": "The well method is so satisfying. Dough came together on the first try, which never happens to me.",
    "author": "Priya Sharma",
    "createdAt": "2026-03-05T15:20:00Z"
  }
]
```


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
