Skip to content

loremipsumpy/RedFoxInterviewTest

 
 

Repository files navigation

RedFox Technical Test

Table of Contents

  1. Introduction & Overview
  2. Quick Start Guide
  3. Understanding the Requirements
  4. Technical Implementation Guide
  5. Testing & Verification
  6. Submission & Evaluation
  7. Reference & Troubleshooting

1. Introduction & Overview

This solution is a skeleton for managing user data from a remote API endpoint. Your task is to complete the implementation to fully support the data structure returned by the external API.

⏰ Time Allocation: 10-12 hours of focused development time

Data Source

This project fetches user data from JSONPlaceholder API: https://jsonplaceholder.typicode.com/users

The external API returns rich user data including address and geographic coordinates, but the skeleton currently only processes basic user and company data - address/geo data is ignored.

Project Architecture

RedFoxInterviewTest/
├── RedFox.Api          # Web API & Controllers
├── RedFox.Application  # CQRS, DTOs, MediatR
├── RedFox.Domain       # Entities, Value Objects
└── RedFox.Infrastructure # DbContext, Services

Architecture: Clean Architecture with CQRS pattern using MediatR, Entity Framework Core with SQLite, and AutoMapper.


2. Quick Start Guide

Prerequisites

  • .NET 8.0 SDK
  • Your preferred IDE (Visual Studio, VS Code, Rider)
  • Internet connection (required for external API calls)

Setup & Run

# 1. Clone and navigate to project
git clone [repository-url]
cd RedFoxInterviewTest

# 2. Restore dependencies and build
dotnet restore
dotnet build

# 3. Run the API
dotnet run --project RedFox.Api

# 4. Verify setup
# Navigate to: http://localhost:5105/swagger
# Or test directly: GET http://localhost:5105/users

Database Setup

  • Database: SQLite with automatic creation (ExtendedYankee2.db)
  • Seeding: Initial data fetched from JSONPlaceholder API on startup
  • Migrations: EF Core handles schema updates

Verification Checklist

✅ API starts successfully on http://localhost:5105
✅ Database file ExtendedYankee2.db is created automatically
✅ Initial data seeding fetches 10 users from external API
/users endpoint returns partial user data (missing address information)
✅ Swagger UI accessible at http://localhost:5105/swagger


3. Understanding the Requirements

Current vs Expected Implementation

Currently Working:

  • ✅ Basic User/Company entities with proper relationship
  • ✅ EF Core DbContext configuration with SQLite
  • ✅ Background service (DbInitWorker) for initial data seeding
  • ✅ Base CQRS pattern with MediatR
  • ✅ API endpoint returning partial user data
  • ✅ AutoMapper configuration for basic mappings

What You Need to Implement:

  • Missing entities: Address and Geo
  • Missing relationships: User → Address (1:1), Address → Geo (1:1)
  • Incomplete data extraction: DbInitWorker ignores address/geo from API
  • Missing DTOs: AddressDto, GeoDto
  • Incomplete mappings: AutoMapper missing address/geo mappings
  • Missing query includes: Handlers don't load address/geo relationships
  • Missing CRUD operations: Only GET /users implemented
  • Missing CORS: No cross-origin configuration

API Endpoints to Implement

Endpoint Method Status Description
/users GET ✅ Partial Get all users (missing address data)
/users/{id} GET ❌ Missing Get single user by ID
/users POST ❌ Missing Create new user
/users/{id} PUT ❌ Missing Update existing user
/users/{id} DELETE ❌ Missing Delete user

4. Technical Implementation Guide

Step 1: Complete Domain Model

Required Entity Relationships:

  • User (1) ↔ (1) Address (one-to-one)
  • Address (1) ↔ (1) Geo (one-to-one)
  • User (*) ↔ (1) Company (many-to-one, already implemented)

Entity Design Considerations:

  • Address and Geo can be implemented as entities or value objects
  • Consider which approach fits best with EF Core and your design
  • Ensure proper foreign key relationships

Step 2: Database Configuration

Tasks:

  1. Create EF Core entity configurations for Address and Geo
  2. Configure one-to-one relationships with proper foreign keys
  3. Create and apply EF Core migration:
    dotnet ef migrations add AddAddressAndGeo -p RedFox.Infrastructure -s RedFox.Api
    dotnet ef database update -p RedFox.Infrastructure -s RedFox.Api
  4. Update DbInitWorker to extract and save address/geo data from API

Step 3: CQRS & Data Layer Updates

Required Changes:

  • Update existing queries/handlers to include all relationships using .Include()
  • Create DTOs for Address and Geo entities
  • Update UserDto to include address property
  • Update AutoMapper profiles for complete object mapping
  • Ensure UserCreationDto handles nested address data from API

Step 4: Complete CRUD API Implementation

Required Endpoints:

  • GET /users - Get all users with nested data (✅ enhance existing)
  • GET /users/{id} - Get single user by ID with full nested structure
  • POST /users - Create new user with address and company information
  • PUT /users/{id} - Update existing user (full update)
  • DELETE /users/{id} - Delete user and associated address/geo data

CQRS Implementation Requirements:

  • Create individual commands: CreateUserCommand, UpdateUserCommand, DeleteUserCommand
  • Create corresponding handlers following existing pattern
  • Implement proper validation using FluentValidation or built-in validation
  • Create request/response DTOs for each operation
  • Handle cascade operations (address/geo relationships)

Implementation Guidelines:

  • Each endpoint should follow CQRS pattern with separate commands/queries
  • Use proper Entity Framework Include() statements for nested data
  • Implement validation at both DTO and entity level
  • Consider using FluentValidation for complex validation rules
  • Ensure proper transaction handling for create/update operations
  • Handle foreign key relationships correctly (User-Address-Geo cascade)

Step 5: API & Infrastructure

Required Updates:

  • Enhance /users endpoint to return complete nested structure
  • Add CORS configuration to allow localhost origins for development
  • Update query handlers to include address/geo relationships
  • Maintain Clean Architecture principles throughout

API Requirements:

  • Follow RESTful conventions with proper HTTP verbs
  • Return appropriate HTTP status codes (200, 201, 204, 404, 400, 500)
  • Implement proper error handling and validation responses
  • Ensure all endpoints return consistent JSON structure
  • Add request validation for required fields and business rules

Step 6: Documentation

Deliverables:

  • Brief documentation about your architectural decisions
  • Explanation of entity vs value object choice for Address/Geo
  • CRUD API design decisions and validation strategy
  • Any trade-offs or assumptions made
  • Instructions for running and testing your solution

5. Testing & Verification

Verification Steps

  1. Complete CRUD API Testing:

    # Test GET all users
    GET http://localhost:5105/users
    
    # Test GET single user
    GET http://localhost:5105/users/1
    
    # Test CREATE user
    POST http://localhost:5105/users
    Content-Type: application/json
    { /* User creation JSON */ }
    
    # Test UPDATE user
    PUT http://localhost:5105/users/1
    Content-Type: application/json
    { /* Updated user JSON */ }
    
    # Test DELETE user
    DELETE http://localhost:5105/users/1
  2. API Response Verification:

    • All endpoints return complete nested JSON with address and geo data
    • Proper HTTP status codes (200, 201, 204, 404, 400, 500)
    • Consistent JSON structure across all endpoints
    • Error responses include meaningful validation messages
  3. Database Verification:

    • Check SQLite database contains Address and Geo tables
    • Verify all 10 users have associated address and geo records
    • Confirm proper foreign key relationships
    • Test cascade operations (deleting user removes address/geo)
  4. Validation Testing:

    • Test required field validation (empty name, email, etc.)
    • Test email format validation
    • Test duplicate username/email handling
    • Test invalid ID handling (404 responses)
  5. Code Quality Check:

    • Solution builds without warnings
    • All layers maintain Clean Architecture separation
    • CQRS pattern consistently applied for all operations
    • Proper error handling and logging

Definition of "Complete"

  • ✅ All 10 users from JSONPlaceholder API stored with complete data
  • ✅ All 5 CRUD endpoints implemented and working correctly
  • ✅ API returns exact format shown in "Expected API Response" (see Reference section)
  • ✅ Database schema includes all required relationships
  • ✅ Proper validation and error handling implemented
  • ✅ CORS allows localhost requests
  • ✅ Code follows existing architectural patterns

6. Submission & Evaluation

Git Workflow Requirements

  1. Create Feature Branch:

    git checkout -b firstName_lastName

    Replace firstName_lastName with your actual name (e.g., john_doe)

  2. Development Process:

    • Make regular commits with clear, descriptive messages
    • Follow conventional commit format when possible
    • Commit frequently to show development progression
  3. Pull Request Submission:

    git push origin firstName_lastName
    • Create a Pull Request from your branch to main
    • Important: A well-described PR earns additional points

PR Description Requirements

Your Pull Request description should include:

  • Summary: Brief overview of what you implemented
  • Architecture Decisions: Explain your entity design choices (entities vs value objects)
  • CRUD Implementation: Describe your API design and validation strategy
  • Trade-offs: Document any assumptions or compromises made
  • Testing Instructions: How to verify your implementation works
  • Time Breakdown: Actual time spent on each major component

Evaluation Criteria (Total: 100 Points)

Category Points Focus Areas
Architecture Compliance 25 pts Clean Architecture separation, dependency direction, CQRS adherence
Data Modeling & EF Core 25 pts Entity relationships, EF Core configuration, efficient queries
CRUD API Implementation 30 pts Complete operations, JSON format, HTTP codes, validation
Code Quality & Patterns 10 pts Clean code, proper patterns, existing conventions
Documentation & Testing 10 pts Design explanations, verification ability, commit history

Evaluation Bonus (Maximum +10 points)

  • Clear PR description: +5 points
  • Comprehensive documentation: +3 points
  • Clean commit history: +2 points

Final Score: Base score (0-100) + Bonus points (0-10) = Total score (0-110)

Time Allocation Guidance

Recommended breakdown for 10-12 hour challenge:

  • Domain modeling (Address/Geo entities): 1-2 hours
  • EF Core configuration and migrations: 1-2 hours
  • Data extraction (DbInitWorker updates): 1-2 hours
  • DTOs and AutoMapper updates: 1-2 hours
  • CRUD API implementation (POST, PUT, DELETE): 3-4 hours
  • Query handler updates and testing: 1-2 hours
  • CORS, documentation, final testing: 1 hour

Important: Document any incomplete parts with explanations if you run out of time.


7. Reference & Troubleshooting

Expected API Response Examples

Current API Response (Incomplete)

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret", 
    "email": "Sincere@april.biz",
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  }
]

GET /users - Expected Complete Response

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556", 
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  }
]

GET /users/{id} - Expected Single User Response

{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough", 
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}

POST /users - Create User Request/Response

Request Body:

{
  "name": "John Doe",
  "username": "johndoe",
  "email": "john.doe@example.com", 
  "address": {
    "street": "123 Main St",
    "suite": "Apt 1",
    "city": "Anytown",
    "zipcode": "12345",
    "geo": {
      "lat": "40.7128",
      "lng": "-74.0060"
    }
  },
  "phone": "555-0123",
  "website": "johndoe.com",
  "company": {
    "name": "ACME Corp",
    "catchPhrase": "Innovation at its finest",
    "bs": "synergize cutting-edge solutions"
  }
}

Response (201 Created):

{
  "id": 11,
  "name": "John Doe",
  "username": "johndoe",
  "email": "john.doe@example.com",
  "address": {
    "street": "123 Main St",
    "suite": "Apt 1", 
    "city": "Anytown",
    "zipcode": "12345",
    "geo": {
      "lat": "40.7128",
      "lng": "-74.0060"
    }
  },
  "phone": "555-0123",
  "website": "johndoe.com",
  "company": {
    "name": "ACME Corp",
    "catchPhrase": "Innovation at its finest",
    "bs": "synergize cutting-edge solutions"
  }
}

PUT /users/{id} - Update User

Request Body: Same format as POST
Response (200 OK): Updated user object with same structure

DELETE /users/{id} - Delete User

Response (204 No Content): Empty response body

EF Core Migration Commands

# Create migration for new entities
dotnet ef migrations add MigrationName -p RedFox.Infrastructure -s RedFox.Api

# Apply migrations to database  
dotnet ef database update -p RedFox.Infrastructure -s RedFox.Api

# Remove database to start fresh (if needed)
rm ExtendedYankee2.db*

Common Issues & Solutions

Port Already in Use:

dotnet run --project RedFox.Api --urls="http://localhost:5106"

Database Lock Issues:

  • Stop the application completely
  • Delete ExtendedYankee2.db* files to reset database

External API Connection:

  • Ensure internet connectivity
  • Check if JSONPlaceholder API is accessible: https://jsonplaceholder.typicode.com/users

Migration Issues:

  • Ensure you're in the solution root directory
  • Use the full project paths as shown in commands above

Getting Help

  • Check Swagger UI for API documentation: http://localhost:5105/swagger
  • Review existing working code patterns (User/Company implementation)
  • Ensure all NuGet packages are restored: dotnet restore

Good luck! Remember that communication through your PR description is as important as the code itself.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages