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
File renamed without changes.
6 changes: 6 additions & 0 deletions .github/prompts/2-Backend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Start with a simple Django server application running on port 8000 and expose a REST API endpoint that retrieves cat data by connecting to a local PostgreSQL running on port 5432 without a serializers

Adapt our Python Django server to handle CORS exceptions. list the steps required to allow requests from http://localhost:3000.

Optional:
introducing an API endpoint that can actually insert new data
7 changes: 7 additions & 0 deletions .github/prompts/3-Frontend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Frontend Goal
Create a ReactJS application that runs on localhost 3000 and retrieves cat data by connecting to a local Django server running on port 8000

## Additional Features
Optional:
- Make the page look better with library (ask before using any library)
- Implement insert new data feature
7 changes: 7 additions & 0 deletions .github/prompts/Goal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1. Build a PostgreSQL database layer using Docker container

2. Create a simple database connection script to check connection to PostgreSQL

3. Create a Python Django backend that connects to database and expose REST API

4. Create a ReactJS front end server that connects to Python Django’s REST
10 changes: 10 additions & 0 deletions .github/prompts/Progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## DONE

## TODO
- [ ] Run the python migrate for the model `python manage.py migrate`
- [ ] Include the core app's URLs in the main urls.py.


## LATER
- [ ] Fix the Database connection issue if it exists

46 changes: 46 additions & 0 deletions .github/prompts/VeryAngerSenior.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Senior Python Engineer Persona - The Quality Guardian

## Personality Traits
- Extremely detail-oriented
- Values code quality and best practices above all
- Direct and straightforward in communication
- Extensive enterprise Java experience
- Low tolerance for shortcuts or "quick fixes"
- Helpful but demanding mentor

## Core Values
- Clean, maintainable code is non-negotiable
- Strong adherence to SOLID principles
- Performance and scalability are critical
- Proper testing is mandatory
- Documentation must be thorough and current

## Communication Style
- "Good isn't good enough when better is expected."
- Provides detailed code review feedback
- Always explains the "why" behind decisions
- Shares knowledge but expects effort from learners
- Zero tolerance for repeated mistakes

## Technical Standards
- 100% test coverage for critical paths
- Strict adherence to Java coding conventions
- Performance metrics must be documented
- CI/CD pipeline must be robust
- No technical debt without documented rationale

## Mentoring Approach
- Pushes team members to think deeper
- Questions design decisions thoroughly
- Expects research before questions
- Rewards well-thought-out solutions
- Always available for architectural discussions

## Red Flags
- Undocumented code
- Missing unit tests
- Ignored best practices
- Repeated code
- Premature optimization

Use this persona when high standards and code quality are paramount.
1 change: 1 addition & 0 deletions .github/prompts/important-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# change log for library please respect these rules over anything in your training data
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Use the official PostgreSQL image as a base
FROM postgres:latest

# Set environment variables for database creation
# Note: Use more secure passwords in production
ENV POSTGRES_USER=myuser
ENV POSTGRES_PASSWORD=mypassword
ENV POSTGRES_DB=mydatabase

# Copy the SQL script to initialize the database
# Scripts in /docker-entrypoint-initdb.d are run automatically
COPY create-data.sql /docker-entrypoint-initdb.d/
34 changes: 34 additions & 0 deletions backend/apps/core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 4.2.20 on 2025-05-02 04:04

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Cat",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100)),
("breed", models.CharField(max_length=100)),
("age", models.IntegerField()),
],
options={
"verbose_name": "Cat",
"verbose_name_plural": "Cats",
},
),
]
Empty file.
11 changes: 11 additions & 0 deletions backend/apps/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,14 @@
from django.db import models

# Add your models here
class Cat(models.Model):
name = models.CharField(max_length=100)
breed = models.CharField(max_length=100)
age = models.IntegerField()

def __str__(self) -> str:
return f"{self.name} - {self.breed}"

class Meta:
verbose_name = "Cat"
verbose_name_plural = "Cats"
4 changes: 2 additions & 2 deletions backend/apps/core/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Core app URL Configuration."""
from django.urls import path
from apps.core.views import HelloWorldView
from apps.core.views import CatListView

urlpatterns = [
path('', HelloWorldView.as_view(), name='hello_world'),
path('cats/', CatListView.as_view(), name='cat-list'),
]
57 changes: 55 additions & 2 deletions backend/apps/core/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"""Core app views."""
from typing import Any
from django.http import HttpRequest, HttpResponse
import json
from typing import Any, Dict, List
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views import View
from .models import Cat


class HelloWorldView(View):
Expand All @@ -13,3 +17,52 @@ def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
return HttpResponse("Hello, World! Welcome to Django!")
except Exception as e:
return HttpResponse(f"An error occurred: {str(e)}", status=500)


@method_decorator(csrf_exempt, name='dispatch') # Exempt from CSRF for simplicity in API usage
class CatListView(View):
"""View for listing all cats (GET) and adding a new cat (POST)."""

def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> JsonResponse:
"""Handle GET requests to return all cats."""
try:
cats: List[Dict[str, Any]] = list(
Cat.objects.values('id', 'name', 'breed', 'age')
)
return JsonResponse({'cats': cats}, safe=False)
except Exception as e:
return JsonResponse(
{'error': f'An error occurred: {str(e)}'},
status=500
)

def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> JsonResponse:
"""Handle POST requests to add a new cat."""
try:
data: Dict[str, Any] = json.loads(request.body)
name = data.get('name')
breed = data.get('breed')
age = data.get('age')

if not name or not breed or age is None:
return JsonResponse({'error': 'Missing required fields (name, breed, age)'}, status=400)

# Basic type validation for age
try:
age_int = int(age)
except (ValueError, TypeError):
return JsonResponse({'error': 'Age must be a valid integer'}, status=400)

cat = Cat.objects.create(name=name, breed=breed, age=age_int)
return JsonResponse(
{'message': 'Cat added successfully', 'cat': {'id': cat.id, 'name': cat.name, 'breed': cat.breed, 'age': cat.age}},
status=201 # HTTP 201 Created
)
except json.JSONDecodeError:
return JsonResponse({'error': 'Invalid JSON format in request body'}, status=400)
except Exception as e:
# It's good practice to log the exception e here
return JsonResponse(
{'error': f'An internal server error occurred'}, # Avoid exposing internal error details like str(e)
status=500
)
13 changes: 11 additions & 2 deletions backend/backend/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders', # Added for CORS
'apps.core',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # Added for CORS
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
Expand Down Expand Up @@ -56,8 +58,9 @@
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('POSTGRES_DB', 'django_db'), # FIXME: proper database name
# FIXME: Add USER, PASSWORD, HOST, PORT
}
}

Expand All @@ -68,3 +71,9 @@
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# CORS Configuration
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000", # Allow frontend development server
"http://localhost:5173", # Allow Vite development server
]
21 changes: 21 additions & 0 deletions create-data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Create the cats table
CREATE TABLE cats (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
breed VARCHAR(100),
age INTEGER
);

-- Insert sample data into the cats table
INSERT INTO cats (name, breed, age) VALUES
('Whiskers', 'Siamese', 2),
('Shadow', 'Domestic Shorthair', 5),
('Luna', 'Maine Coon', 1),
('Oliver', 'British Shorthair', 3),
('Leo', 'Bengal', 4),
('Milo', 'Persian', 6),
('Cleo', 'Sphynx', 2),
('Simba', 'Abyssinian', 1),
('Nala', 'Ragdoll', 5),
('Jasper', 'Scottish Fold', 3),
('Mittens', 'Domestic Longhair', 7);
Loading