Welcome: What This Lesson Is Really About

Welcome to the first lesson of the Task Manager API backend course.
This entire course is about building a backend-first Task Manager using Next.js + TypeScript, but we’re not starting with API routes or UI. We’re starting with the core of the domain: what a “task” is, how we store it in memory, and how our backend code should operate on it.

In this lesson, you’ll use Codex as your coding partner to:

  • Define a shared Task model and in-memory tasks store
  • Implement a service layer that knows how to create, read, update, delete, and filter tasks
  • Expose that service through a first /api/tasks HTTP endpoint

By the end of the lesson, you won’t just have some helper functions—you’ll have the core task engine of your API, built with clear layers and Codex-powered implementation.

What We’re Building and Why It Matters

Before you ever touch a route, it’s important to answer three questions:

  • What is the “thing” my API manages?
    For us, that “thing” is a task: it has an id, a title, some content, whether it’s completed, and optionally a due date.

  • Where does that data live?
    In this unit, it lives in a simple in-memory array (tasks), so you can focus on logic and structure without worrying about databases or files.

  • Who is allowed to touch that data?
    That’s the service layer: a small set of functions that are responsible for all reads and writes. Routes don’t manipulate arrays directly; they call service functions.

This layered design gives you:

  • A single, shared Task type used everywhere in the backend
  • A clear place to put business rules (for example, how IDs are generated or what “completed” means)
  • Thin, predictable API route handlers that just translate HTTP into service calls

Later lessons and units will add validation, security, logging, and persistence, but all of that will depend on the foundations you’re building here.

How We’ll Use Codex in This Lesson

You are not expected to hand-code every function from scratch. Instead, this lesson is about learning to direct Codex like a senior engineer directing a junior:

  • You decide the shape of the Task type and how the service functions should behave.
  • You tell Codex exactly which file it’s allowed to touch.
  • You describe the required behavior in natural language.
  • You ask Codex to show the full file so you can review its work.

A typical Codex prompt in this lesson will include:

  • A clear file scope

    "Modify only src/lib/tasks.ts."

  • The required types or functions and their fields/return types
  • Any important rules (e.g., auto-increment IDs, default completed to false)
  • A safety note

    "Do not change any other files."

  • A request for the final content

    "Show the full updated contents of src/lib/tasks.ts."

Everything you build in this lesson is done through these kinds of carefully constructed prompts.

Step 1: Shaping the Task Model and In-Memory Store

Your first practice is all about designing the Task domain and giving the backend a single source of truth.

Conceptually, you are answering:

  • What properties does every task have?
  • What types should those properties be?
  • Where do all tasks live in this application right now?

You’ll collaborate with Codex to fill in src/lib/tasks.ts so it contains:

  • A Task type with:

    • id: number
    • title: string
    • content: string
    • completed: boolean
    • dueDate?: string (optional ISO date string)
  • An exported, in-memory tasks: Task[] array, initially empty

At this point, you’re not worrying about how tasks get created or updated yet. You’re just defining “what a task is” and where the collection of tasks lives.

A typical high-quality prompt for this practice might look like:

Codex, modify only src/lib/tasks.ts.

Define a Task type with fields id: number, title: string, , , and optional (ISO date string).

Step 2: Turning Data into Behavior with a Task Service

Once you have a defined Task type and tasks store, the next question is: who manipulates it?

That’s the job of the service layer, implemented in src/lib/services/taskService.ts.

The service layer will be responsible for:

  • getAllTasks() — listing everything
  • createTask(...) — generating a new task with a new id
  • getTaskById(id) — finding a single task
  • updateTaskById(id, data, partial) — editing an existing task
  • deleteTaskById(id) — removing a task
  • filterTaskByStatus(completed) — filtering tasks by completion status

All of these functions operate on the shared tasks array. The routes won’t need to know how IDs are generated, how tasks are stored, or how updates are applied—they just call the service.

In this practice, you’ll ask Codex to:

  • Import Task and tasks from @/lib/tasks
  • Implement each service function with the correct types and behavior
  • Keep everything in-memory for now (no databases, no files)

A strong Codex prompt for this might be:

Codex, modify only src/lib/services/taskService.ts. Use and from and implement:

Step 3: Exposing the Task Service via /api/tasks

Once your Task model and service functions are in place, you’re ready to let HTTP clients talk to them through a route: src/app/api/tasks/route.ts.

The purpose of this route file is to:

  • Map HTTP methods to service-layer calls
  • Handle basic validation of incoming data
  • Return structured JSON responses with appropriate HTTP status codes

For this first collection-level route, you’ll support:

  • GET /api/tasks — return all tasks as JSON
  • POST /api/tasks — validate the body and create a new task

Conceptually, the handlers will:

  • For GET:

    • Call getAllTasks()
    • Return the list with status 200
  • For POST:

    • Parse the JSON body
    • Check that title and content are non-empty strings
    • If dueDate is provided, confirm it’s a valid date string
    • On validation failure, return a 400 JSON error
    • On success, call createTask(...) and return the created task with status 201

You’ll still use NextResponse.json in this unit; more advanced response helpers will come later.

An example Codex prompt might be:

How This Lesson Sets Up the Rest of the Course

In this first lesson, you:

  • Defined a shared Task model and in-memory tasks store
  • Implemented a focused taskService that centralizes all task operations
  • Exposed the service through a /api/tasks route that speaks HTTP and JSON

Everything else in the course builds on this layered foundation. In later units, you will:

  • Add stronger validation flows
  • Introduce more robust response helpers
  • Expand the API with additional routes and behaviors
  • Evolve from a simple in-memory store toward more realistic persistence strategies

But all of that depends on today’s work: a clear domain model, a clean service layer, and a thin route that uses them—built with precise, high-quality prompts to Codex.

You’re now ready to dive into the practices and start guiding Codex through implementing each piece of the Task core.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal