---
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-08-26T21:03:36.381Z"
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 collects opinions. Instructors hear them through emails, sticky notes, and hallway conversations.

We'll collect that feedback in a JSON-backed API with enough structure to query, filter, and summarize it. This course stays in the terminal because the API is the project.

## 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. The deployed GET routes can read the bundled seed file, but the JSON-writing exercise in this section is for local development only.

[![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 provides a Next.js app with App Router and TypeScript configured. This API project does not need a styling library.

The starter includes the type definition and seed data. You'll implement the data utility.

**`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`** contains 10 feedback entries for `knife-skills`, `bread-baking`, and `pasta-from-scratch`. The range of ratings will make the summary endpoint useful later.

Open **`lib/data.ts`**. The function signatures are present, but the implementations are stubs:

- `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\*\*

Count the existing entries and pad the number. If there are 10 entries, the next id is `fb-011`. This approach is sufficient for the 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.x (Turbopack)
- Local: http://localhost:3000
```

The project should compile cleanly. The data utility will become reachable after you add API routes in the next lesson.

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: Local writes are not production storage\*\*

`fs.writeFile` updates the JSON file while you work locally. On Vercel, function filesystems are not durable or shared storage, so a POST may disappear on a later invocation. Use Vercel Blob or a database for production writes.

\*\*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

You now have a typed interface, structured seed data, and a utility that reads and writes JSON. The next lesson exposes that data through an API route.

## 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)
