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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
notepad .gitignore
91 changes: 78 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,108 @@
# 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.

- Build a working application with at least one 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:

Pick one of the following:

- 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 use a code generation tool (for example 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
## Submission Criteria

- 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.
- Include a short summary of your approach and tools used in your PR submission.
- Include any additional information or approach that helped you.

---

# Task Management API

REST API for managing tasks: create, read, update, and delete. Implemented in Python with Flask.

## Setup

Requires Python 3. Install dependencies:

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

## Running the App

Start the server:

```bash
python app.py
```

The API is available at `http://localhost:5000`.

## API Endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | `/` | Health check; returns status and message. |
| POST | `/api/tasks` | Create a task. Body must include `title`; `description` and `status` are optional. |
| GET | `/api/tasks` | List all tasks. |
| GET | `/api/tasks/{id}` | Get a single task by ID. |
| PUT | `/api/tasks/{id}` | Update a task. Body may include `title`, `description`, `status`. |
| DELETE | `/api/tasks/{id}` | Delete a task by ID. |

## Example Request

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 the full test suite:

```bash
pytest
```

For verbose output:

```bash
pytest -v
```

## Notes

- Tasks are stored in memory only; data is lost when the server stops.
- All request and response bodies are JSON.
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`)
Binary file added __pycache__/app.cpython-311.pyc
Binary file not shown.
Binary file added __pycache__/test_app.cpython-311-pytest-8.2.1.pyc
Binary file not shown.
140 changes: 140 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
from flask import Flask, request, jsonify
from flask_cors import CORS
from datetime import datetime
import uuid

app = Flask(__name__)
CORS(app)


# Holds items in a map by id and a list for ordered listing; supports clear() for tests
class TaskRepo:
def __init__(self):
self._by_id = {}
self._order = []

def clear(self):
self._by_id.clear()
self._order.clear()

def add(self, item):
uid = item["id"]
self._by_id[uid] = item
self._order.append(uid)

def get(self, tid):
return self._by_id.get(tid)

def drop(self, item):
uid = item["id"]
del self._by_id[uid]
self._order.remove(uid)

def list_all(self):
return [self._by_id[uid] for uid in self._order]


tasks = TaskRepo()


# Build one new item dict
def _build_item(title, description=None, status="pending"):
uid = str(uuid.uuid4())
return {
"id": uid,
"title": title,
"description": description if description is not None else "",
"status": status,
"created_at": datetime.utcnow().isoformat(),
}


# Mutate item with payload keys
def _patch(item, payload):
for key in ("title", "description", "status"):
if key in payload:
item[key] = payload[key]


# Public Task type for code that imports it
class Task:
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()

def to_dict(self):
return {
"id": self.id,
"title": self.title,
"description": self.description,
"status": self.status,
"created_at": self.created_at,
}

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"]


@app.route("/api/tasks", methods=["POST"])
def create_task():
body = request.get_json()
if not body or "title" not in body:
return jsonify({"error": "Title is required"}), 400
entry = _build_item(
title=body["title"],
description=body.get("description"),
status=body.get("status", "pending"),
)
tasks.add(entry)
return jsonify(entry), 201


@app.route("/api/tasks", methods=["GET"])
def list_tasks():
return jsonify(tasks.list_all()), 200


@app.route("/api/tasks/<task_id>", methods=["GET"])
def get_task(task_id):
entry = tasks.get(task_id)
if entry is None:
return jsonify({"error": "Task not found"}), 404
return jsonify(entry), 200


@app.route("/api/tasks/<task_id>", methods=["PUT"])
def update_task(task_id):
entry = tasks.get(task_id)
if entry is None:
return jsonify({"error": "Task not found"}), 404
body = request.get_json()
if not body:
return jsonify({"error": "No data provided"}), 400
_patch(entry, body)
return jsonify(entry), 200


@app.route("/api/tasks/<task_id>", methods=["DELETE"])
def delete_task(task_id):
entry = tasks.get(task_id)
if entry is None:
return jsonify({"error": "Task not found"}), 404
tasks.drop(entry)
return jsonify({"message": "Task deleted successfully"}), 200


@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)
Empty file added cd
Empty file.
Empty file added git
Empty file.
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