Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 34 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
# Candidate Assessment: Spec-Driven Development With Codegen Tools

This assessment evaluates how you use modern code generation tools (for example `5.2-Codex`, `Claude`, `Copilot`, and similar) to design, build, and test a software application using a spec-driven development pattern. You may build a frontend, a backend, or both.

## Goals
- Build a working application with at least one meaningful feature.
- Create a testing framework to validate the application.
- Demonstrate effective use of code generation tools to accelerate delivery.
- Show clear, maintainable engineering practices.

## Deliverables
- Application source code in this repository.
- A test suite and test harness that can be run locally.
- Documentation that explains how to run the app and the tests.

## Scope Options
Pick one:
- Frontend-only application.
- Backend-only application.
- Full-stack application.

Your solution should include at least one real workflow, for example:
- Create and view a resource.
- Search or filter data.
- Persist data in memory or storage.

## Rules
- You must use a code generation tool (for example `5.2-Codex`, `Claude`, or similar). You can use multiple tools.
- You must build the application and a testing framework for it.
- The application and tests must run locally.
- Do not include secrets or credentials in this repository.

## Evaluation Criteria
- Working product: Does the app do what it claims?
- Test coverage: Do tests cover key workflows and edge cases?
- Engineering quality: Clarity, structure, and maintainability.
- Use of codegen: How effectively you used tools to accelerate work.
- Documentation: Clear setup and run instructions.

## What to Submit
- When you are complete, put up a Pull Request against this repository with your changes.
- A short summary of your approach and tools used in your PR submission
- Any additional information or approach that helped you.
# Candidate Assessment – Tasks Board

A spec-driven frontend application built using Next.js App Router.

This project demonstrates structured development using a spec-first workflow, clean architecture, workflow validation, and local persistence.

---

## 🚀 Features

- Create tasks with title and optional notes
- Toggle task status (Todo / Done)
- Delete tasks
- Search by title or notes
- Filter by status (All / Todo / Done)
- LocalStorage persistence (data survives refresh)
- Smooth UI animations (Framer Motion)
- Light & Dark mode support (system-based)
- Full workflow test coverage (Vitest + Testing Library)

---

## 🏗 Tech Stack

- Next.js (App Router)
- React
- Tailwind CSS
- Framer Motion
- Vitest + Testing Library
- LocalStorage (browser persistence)

---

## 📁 Project Structure
41 changes: 41 additions & 0 deletions SPECS/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
34 changes: 34 additions & 0 deletions SPECS/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Candidate Assessment – Tasks Board

A spec-driven frontend application built using Next.js App Router.

This project demonstrates structured development using a spec-first workflow, clean architecture, workflow validation, and local persistence.

---

## 🚀 Features

- Create tasks with title and optional notes
- Toggle task status (Todo / Done)
- Delete tasks
- Search by title or notes
- Filter by status (All / Todo / Done)
- LocalStorage persistence (data survives refresh)
- Smooth UI animations (Framer Motion)
- Light & Dark mode support (system-based)
- Full workflow test coverage (Vitest + Testing Library)

---

## 🏗 Tech Stack

- Next.js (App Router)
- React
- Tailwind CSS
- Framer Motion
- Vitest + Testing Library
- LocalStorage (browser persistence)

---

## 📁 Project Structure
56 changes: 56 additions & 0 deletions SPECS/SPECS/000-app-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Spec 000 — App Overview (Frontend-only)

## Goal
Build a frontend-only web app that demonstrates a real workflow, local persistence, and a working test harness.

## Scope
Frontend-only (no backend). Data will persist using browser storage.

## Tech Stack
- Next.js (App Router)
- React
- Tailwind CSS
- shadcn/ui (UI components)
- Framer Motion (animations)
- Vitest + React Testing Library (tests)

## Core Workflow
A "Tasks Board" app that allows a user to:
1) Create a task
2) View tasks in a list
3) Filter/search tasks
4) Toggle completion status
5) Delete tasks
6) Persist tasks locally (localStorage)

## Data Model
Task:
- id: string (uuid or crypto.randomUUID)
- title: string (required)
- notes: string (optional)
- status: "todo" | "done"
- createdAt: ISO string

## Local Persistence
- Store tasks in localStorage under key: `ca_tasks_v1`
- On app load: read localStorage and hydrate UI
- On change: write updated tasks back to localStorage

## Accessibility + UX
- Inputs have labels
- Buttons have clear text
- Keyboard navigable
- Basic empty states (no tasks, no results)

## Non-Goals
- No authentication
- No server/API routes
- No database
- No external services

## Testing Strategy (High Level)
- Unit/UI tests for:
- Creating a task
- Filtering tasks
- Toggling done
- Persistence write/read behavior (mock localStorage)
74 changes: 74 additions & 0 deletions SPECS/SPECS/001-tasks-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Spec 001 — Tasks Workflow (CRUD + Search + Local Persistence)

## Summary
Implement a Tasks Board that supports create, list, filter/search, toggle done, delete, and persists tasks in localStorage.

## User Stories
1. As a user, I can add a task with a title so I can track work.
2. As a user, I can see all tasks in a list so I can review them.
3. As a user, I can search tasks by title/notes so I can find items quickly.
4. As a user, I can toggle a task as done so I can track progress.
5. As a user, I can delete a task so I can remove completed/irrelevant items.
6. As a user, my tasks persist after refresh so I don’t lose my work.

## Acceptance Criteria
### Create
- A form exists with:
- Title (required, min 2 chars)
- Notes (optional)
- Add button
- If title is missing/too short, show an inline error and do not add.

### List
- Tasks display in a clean card/list layout:
- Title
- Notes (if present)
- Created date (simple format)
- Status indicator (Todo/Done)
- Toggle Done button
- Delete button

### Search/Filter
- A search input filters tasks by:
- title OR notes (case-insensitive)
- A filter option exists:
- All / Todo / Done
- When no results match, show “No matching tasks”.

### Toggle Done
- Clicking Toggle Done updates the task status and UI immediately.

### Delete
- Clicking Delete removes the task from UI immediately.

### Persistence
- On first load:
- If localStorage has tasks, load them into state.
- If not, start empty.
- After any change (create/toggle/delete):
- Save the full tasks array to localStorage key `ca_tasks_v1`.

## UI/UX Requirements
- Use shadcn/ui for form controls and buttons where appropriate.
- Use Framer Motion for a subtle animation when tasks appear/remove.
- Responsive layout (works on mobile widths).

## Test Plan (Must Pass Locally)
Write tests that cover:
1) Add task success
2) Add task validation error
3) Search filters results
4) Toggle done changes UI/state
5) Delete removes task
6) Persistence:
- Reads from localStorage on load
- Writes to localStorage on change

## Files to Implement (Expected)
- `src/app/page.tsx` (main page)
- `src/components/tasks/TaskForm.tsx`
- `src/components/tasks/TaskList.tsx`
- `src/components/tasks/TaskItem.tsx`
- `src/lib/storage.ts` (localStorage helpers)
- `src/lib/tasks.ts` (task types + pure helpers)
- `src/test/tasks.spec.tsx` (workflow tests)
16 changes: 16 additions & 0 deletions SPECS/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TODO

## Spec Phase (no code changes without specs)
- [x] Create app overview spec (scope + architecture + workflows)
- [x] Create feature spec: Tasks workflow (CRUD + search/filter + persistence)
- [x] Create testing spec: key workflows + edge cases (covered inside Spec 001)

## Implementation Phase (only after matching specs exist)
- [x] Implement Tasks Board (create/list/search/filter/toggle/delete)
- [x] Implement persistence using localStorage (`ca_tasks_v1`)
- [x] Add Framer Motion animations
- [x] Add tests for workflows + persistence

## Optional polish
- [ ] Replace basic HTML controls with shadcn/ui components (optional)
- [ ] Add small UI empty-state illustration or nicer styling (optional)
Binary file added SPECS/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions SPECS/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import "tailwindcss";

:root {
--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
34 changes: 34 additions & 0 deletions SPECS/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}
Loading