Validating Task Data with a Shared Helper

Welcome: From “It Works” to “It’s Safe to Use”

Welcome back. In the previous lesson, you used Codex to design the Task core: a shared Task model, an in-memory tasks array, and a service layer that knows how to create, read, update, and delete tasks. Your API can now do real work—but so far it mostly assumes that incoming JSON is correct.

In this lesson, you’ll upgrade your Task Manager API from “accept anything and hope” to “trust but verify.” You’ll:

  • Build a central task payload validator in src/lib/validateTaskPayload.ts
  • Plug that validator into updateTaskById in src/lib/services/taskService.ts
  • Wire validation into PUT and PATCH for src/app/api/tasks/[id]/route.ts, returning proper HTTP status codes

You’ll continue to rely on Codex for implementation, but now your prompts will describe more nuanced rules: allowed fields, required fields, strict types, and how to propagate errors back to the client.

What We’re Building and Why It Matters

So far, your API can:

  • Store tasks in memory
  • Expose /api/tasks and /api/tasks/[id] routes
  • Perform basic CRUD via the service layer

What it does not do yet is enforce the rules of your domain. Examples:

  • A client could send "completed": "yes" instead of a boolean.
  • A task update could include random fields like "hack": "oops".
  • A PUT could omit required fields entirely.

Without validation, bad data sneaks into your in-memory store and everything built on top becomes fragile.

This lesson introduces a clear separation of concerns:

  • validateTaskPayload checks if incoming data is shaped correctly.
  • taskService.updateTaskById decides whether to mutate state based on validator results.
  • The /api/tasks/[id] route translates service results into HTTP responses: 200, 400, 404, 204.

Once this pipeline is in place, every future feature you add (logging, persistence, UI) can assume the data is clean.

How We’ll Use Codex in This Lesson

You’ll use Codex in three focused ways:

  • To implement the reusable validator

    • One file: src/lib/validateTaskPayload.ts
    • Well-defined function: validateTaskPayload(payload: any, partial = false): string[]
    • Return array of human-readable error messages
  • To integrate validation into the service layer

    • One function: updateTaskById in src/lib/services/taskService.ts
    • Call validateTaskPayload and decide whether to update or return an error object
  • To enforce validation in PUT/PATCH routes

    • File: src/app/api/tasks/[id]/route.ts
    • Handlers use updateTaskById and map { error } / { task } to HTTP status codes

Across all three, your prompts should:

  • Restrict Codex to one file at a time
  • Describe allowed fields, required fields, and type expectations clearly
  • Explain how to treat partial updates vs full replacements
  • Ask Codex to show the full updated file content
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