Skip to content

npjd/htn-backend-take-home-2025

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Endpoints

Root Endpoint

GET /
Returns a simple welcome message.
Response:

{
  "Hello": "World"
}

User Management

GET /users

Fetches a list of all users in the database.
Response:

  • Returns a list of users, each with the following attributes:
    • id: User ID
    • name: Name of the user
    • email: Email address
    • phone: Phone number (if provided)
    • badge_code: Badge code (if provided)
    • updated_at: Timestamp of the last update

Example Response:

[
  {
    "id": "1",
    "name": "Alice",
    "email": "alice@example.com",
    "phone": "+1 (555) 123 4567",
    "badge_code": "ABC123",
    "updated_at": "2025-01-01 12:34:56"
  }
]

PUT /users/{user_id}

Updates a user's information.
Request: Provide the user ID and any fields to update (name, phone, email, badge_code).

Example Request Body:

{
  "name": "Updated Name",
  "phone": "+1 (555) 765 4321"
}

Response:
Returns the updated user information.


Scan Management

POST /scan/{user_id}

Records a new scan for a user.

Request: Provide the user ID and activity details.

Example Request Body:

{
  "activity_name": "Visited Booth",
  "activity_category": "Event"
}

Response:
Returns the scan details.

{
  "message": "Scan added successfully",
  "user_id": "1",
  "activity": "Visited Booth",
  "scanned_at": "2025-02-08T12:00:00Z"
}

GET /scans

Fetches the frequency of activity scans, with optional filtering by activity category or frequency range.

Query Parameters:

  • min_frequency (default = 0): Minimum scan frequency to include
  • max_frequency: Maximum scan frequency to include
  • activity_category: Filter by a specific activity category

Response:
Returns a list of activities and their corresponding scan frequencies.

[
  {
    "activity_name": "Visited Booth",
    "activity_category": "Event",
    "frequency": 15
  }
]

GET /scans/clusters

Clusters scans by activity name and time periods (hourly or per minute).

Query Parameters:

  • activity_name (required)
  • time_unit (default = "hour"; options: "hour" or "minute")
  • start_time (optional): ISO 8601 format (e.g., "2025-02-01T10:00:00")
  • end_time (optional): ISO 8601 format

Response:
Returns the activity clusters grouped by time period.

[
  {
    "activity_name": "Visited Booth",
    "time_period": "2025-02-01 12",
    "scan_count": 5
  }
]

Database Initialization

The SQLite database is initialized through the init_db() function, and it is accessed via the get_db_connection() utility. Ensure that the database is created and initialized before running the API.


Running the Application

Docker Compose Setup

The application can be run using Docker Compose. The provided docker-compose.yml file defines two services:

  1. api: The main FastAPI application running on port 3000.
  2. tests: A container for running the test suite using pytest.

Steps to Run

  1. Build and start the services:

    docker-compose up --build
  2. Access the API:

  3. Run tests:

    docker-compose run tests

Environment Variables

The application uses the following environment variables in the docker-compose.yml file:

  • DB_FILE: Path to the SQLite database file
  • REMOTE_USER_DATA: Remote JSON user data for initialization (if needed)

You can customize these values based on your environment.


Directory Structure

.
├── Dockerfile
├── docker-compose.yml
├── main.py        # FastAPI application code
├── db.py          # Database connection and initialization
├── models.py      # Pydantic models
├── test.py        # Test cases
├── data/
│   └── hackathon.db   # SQLite database (created at runtime)

Sample cURL Commands

  1. Get all users:

    curl -X GET http://localhost:3000/users
  2. Update a user:

    curl -X PUT http://localhost:3000/users/1 \
      -H "Content-Type: application/json" \
      -d '{"name": "New Name", "phone": "+1 (555) 999 9999"}'
  3. Add a new scan:

    curl -X POST http://localhost:3000/scan/1 \
      -H "Content-Type: application/json" \
      -d '{"activity_name": "Visited Booth", "activity_category": "Event"}'

Design Choices

  1. Normalized Database Design: The API uses a relational SQLite database with well-structured tables for users and scans, ensuring efficient data retrieval and minimizing redundancy. The users table includes constraints like UUID as the primary key and email/badge_code uniqueness to maintain data integrity.

  2. Dynamic Query Building: Many endpoints (e.g., /scans and /scans/clusters) allow dynamic filtering based on optional query parameters like frequency, time periods, and categories, promoting flexibility for different use cases without overloading the database.

  3. Safety and Validation: All user inputs are validated using Pydantic models (e.g., custom phone number validation) and SQL parameterized queries to prevent SQL injection and ensure data consistency.

  4. Idempotent Initialization: The database initialization (init_db) ensures that tables are created only if they do not already exist, and partial failures result in clean rollbacks, preventing data corruption.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published