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
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 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.
This assessment evaluates how you use modern code generation tools 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.
Expand Down Expand Up @@ -41,3 +41,58 @@ Your solution should include at least one real workflow, for example:
- 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.

---

# Task Management API

This is a simple REST API for managing tasks. You can create, read, update, and delete tasks. It's built with Python and Flask.

## Setup

Make sure you have Python installed, then run:

```bash
pip install -r requirements.txt
```

## Running the App

Start the server:

```bash
python app.py
```

The API runs on `http://localhost:5000`

## API Endpoints

- `GET /` - Check if API is running
- `POST /api/tasks` - Create a new task
- `GET /api/tasks` - Get all tasks
- `GET /api/tasks/{id}` - Get one task
- `PUT /api/tasks/{id}` - Update a task
- `DELETE /api/tasks/{id}` - Delete a task

## Example

Create a task:
```bash
curl -X POST http://localhost:5000/api/tasks \
-H "Content-Type: application/json" \
-d '{"title": "My task", "description": "Do something"}'
```

## Running Tests

Run all tests:

```bash
pytest
```

## Notes

- Tasks are stored in memory and will be lost when you restart the server
- All responses are in JSON format
40 changes: 40 additions & 0 deletions SPECS/task-management-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Feature Spec: Task Management API

## Goal
- Build a RESTful backend API for managing tasks
- Provide CRUD operations (Create, Read, Update, Delete) for tasks
- Include data persistence (in-memory storage)
- Create a comprehensive test suite

## Scope
- In:
- REST API endpoints for task management
- Task model with id, title, description, status, and created_at fields
- In-memory data storage
- Test suite with unit and integration tests
- API documentation
- Out:
- Frontend UI
- Database persistence (using in-memory storage instead)
- Authentication/Authorization
- Advanced features like filtering, pagination

## Requirements
- API must be built using Python and Flask framework
- All endpoints must return JSON responses
- Tasks should have: id (auto-generated), title (required), description (optional), status (default: "pending"), created_at (timestamp)
- API should handle errors gracefully with appropriate HTTP status codes
- Tests must cover all endpoints and edge cases
- Application must run locally with simple setup

## Acceptance Criteria
- [ ] POST /api/tasks - Create a new task
- [ ] GET /api/tasks - List all tasks
- [ ] GET /api/tasks/{id} - Get a specific task by ID
- [ ] PUT /api/tasks/{id} - Update a task by ID
- [ ] DELETE /api/tasks/{id} - Delete a task by ID
- [ ] All endpoints return appropriate HTTP status codes (200, 201, 404, 400)
- [ ] Test suite covers all endpoints with success and error cases
- [ ] Application can be run with simple command (e.g., `python app.py` or `flask run`)
- [ ] README includes setup and run instructions
- [ ] Tests can be run with a simple command (e.g., `pytest`)
119 changes: 119 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from flask import Flask, request, jsonify
from flask_cors import CORS
from datetime import datetime
import uuid

app = Flask(__name__)
CORS(app)

tasks = []


class Task:
# Initialize task with title, optional description and status
def __init__(self, title, description=None, status="pending"):
self.id = str(uuid.uuid4())
self.title = title
self.description = description or ""
self.status = status
self.created_at = datetime.utcnow().isoformat()

# Convert task object to dictionary
def to_dict(self):
return {
"id": self.id,
"title": self.title,
"description": self.description,
"status": self.status,
"created_at": self.created_at
}

# Update task fields from provided data
def update(self, data):
if "title" in data:
self.title = data["title"]
if "description" in data:
self.description = data["description"]
if "status" in data:
self.status = data["status"]


# Find and return task by ID
def find_task_by_id(task_id):
for task in tasks:
if task.id == task_id:
return task
return None


# Create a new task
@app.route("/api/tasks", methods=["POST"])
def create_task():
data = request.get_json()

if not data or "title" not in data:
return jsonify({"error": "Title is required"}), 400

task = Task(
title=data["title"],
description=data.get("description"),
status=data.get("status", "pending")
)
tasks.append(task)

return jsonify(task.to_dict()), 201


# Get all tasks
@app.route("/api/tasks", methods=["GET"])
def list_tasks():
return jsonify([task.to_dict() for task in tasks]), 200


# Get a specific task by ID
@app.route("/api/tasks/<task_id>", methods=["GET"])
def get_task(task_id):
task = find_task_by_id(task_id)

if not task:
return jsonify({"error": "Task not found"}), 404

return jsonify(task.to_dict()), 200


# Update a task by ID
@app.route("/api/tasks/<task_id>", methods=["PUT"])
def update_task(task_id):
task = find_task_by_id(task_id)

if not task:
return jsonify({"error": "Task not found"}), 404

data = request.get_json()
if not data:
return jsonify({"error": "No data provided"}), 400

task.update(data)
return jsonify(task.to_dict()), 200


# Delete a task by ID
@app.route("/api/tasks/<task_id>", methods=["DELETE"])
def delete_task(task_id):
task = find_task_by_id(task_id)

if not task:
return jsonify({"error": "Task not found"}), 404

tasks.remove(task)
return jsonify({"message": "Task deleted successfully"}), 200


# Health check endpoint
@app.route("/", methods=["GET"])
def health_check():
return jsonify({"status": "ok", "message": "Task Management API is running"}), 200


if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Flask==3.0.0
pytest==7.4.3
pytest-flask==1.3.0
flask-cors==4.0.0
Loading