From d855e5b3752656ab7749732022a4b754ca20fa5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=ABshira=20Randobrava?=
<121398589+d3shira@users.noreply.github.com>
Date: Thu, 2 Jul 2026 16:18:39 +0200
Subject: [PATCH 1/4] GET employee records endpoint and simple html to show
table on website
---
backend/app/main.py | 26 +++++++++++++++++
backend/app/schemas/employee.py | 11 ++++++++
backend/app/templates/index.html | 48 ++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+)
create mode 100644 backend/app/schemas/employee.py
create mode 100644 backend/app/templates/index.html
diff --git a/backend/app/main.py b/backend/app/main.py
index e69de29..ac7ed48 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -0,0 +1,26 @@
+from fastapi import FastAPI, Request, Depends
+from fastapi.responses import HTMLResponse
+from fastapi.templating import Jinja2Templates
+from sqlalchemy.orm import Session
+
+from app.database.connection import SessionLocal
+from app.database.models import EmployeeRecord
+from app.schemas.employee import EmployeeRecordSchema
+
+app = FastAPI()
+templates = Jinja2Templates(directory="app/templates")
+
+def get_db():
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
+
+@app.get("/", response_class=HTMLResponse)
+def show_records(request: Request, db: Session = Depends(get_db)):
+ db_records = db.query(EmployeeRecord).all()
+ serialized_records = [EmployeeRecordSchema.model_validate(rec) for rec in db_records]
+
+ return templates.TemplateResponse(request = request, name = "index.html", context = {"records": serialized_records})
+
\ No newline at end of file
diff --git a/backend/app/schemas/employee.py b/backend/app/schemas/employee.py
new file mode 100644
index 0000000..95b1156
--- /dev/null
+++ b/backend/app/schemas/employee.py
@@ -0,0 +1,11 @@
+from pydantic import BaseModel, ConfigDict
+
+class EmployeeRecordSchema(BaseModel):
+ model_config = ConfigDict(from_attributes=True)
+
+ id: int
+ employee_id: int
+ exam_score: int
+ years_exp: int
+ salary: float
+
diff --git a/backend/app/templates/index.html b/backend/app/templates/index.html
new file mode 100644
index 0000000..be9993f
--- /dev/null
+++ b/backend/app/templates/index.html
@@ -0,0 +1,48 @@
+
+
+
+
+ ML Project Records
+
+
+
+
+ Database Records View
+ Reading directly from your PostgreSQL employee_records table:
+
+
+
+
+ | Record ID |
+ Employee ID |
+ Exam Score |
+ Years of Experience |
+ Salary |
+
+
+
+ {% for record in records %}
+
+ | {{ record.id }} |
+ {{ record.employee_id }} |
+ {{ record.exam_score }} |
+ {{ record.years_exp }} |
+ ${{ "%.2f"|format(record.salary) }} |
+
+ {% else %}
+
+ |
+ No records found in the database yet.
+ |
+
+ {% endfor %}
+
+
+
+
+
\ No newline at end of file
From 1977f36b0041b9419bc6b4f2a495bf70f76bfcb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=ABshira=20Randobrava?=
<121398589+d3shira@users.noreply.github.com>
Date: Thu, 2 Jul 2026 18:20:33 +0200
Subject: [PATCH 2/4] GET/CREATE schemas for each database model(table)
---
backend/app/schemas/employee.py | 34 +++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/backend/app/schemas/employee.py b/backend/app/schemas/employee.py
index 95b1156..f5ca780 100644
--- a/backend/app/schemas/employee.py
+++ b/backend/app/schemas/employee.py
@@ -1,5 +1,24 @@
+from typing import Optional
+
from pydantic import BaseModel, ConfigDict
+class DepartmentSchema(BaseModel):
+ model_config = ConfigDict(from_attributes=True)
+
+ id: int
+ name: str
+
+
+class EmployeeSchema(BaseModel):
+ model_config = ConfigDict(from_attributes=True)
+
+ id: int
+ first_name: str
+ last_name: str
+ email: Optional[str] = None
+ department_id: int
+
+
class EmployeeRecordSchema(BaseModel):
model_config = ConfigDict(from_attributes=True)
@@ -9,3 +28,18 @@ class EmployeeRecordSchema(BaseModel):
years_exp: int
salary: float
+class DepartmentCreate(BaseModel):
+ name: str
+
+class EmployeeCreate(BaseModel):
+ first_name: str
+ last_name: str
+ email: Optional[str] = None
+ department_id: Optional[int] = None
+
+class EmployeeRecordCreate(BaseModel):
+ employee_id: int
+ exam_score: int
+ years_exp: int
+ salary: float
+
From fd7bafc002e7132209b54224827338fe4b9f1ca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=ABshira=20Randobrava?=
<121398589+d3shira@users.noreply.github.com>
Date: Thu, 2 Jul 2026 19:02:45 +0200
Subject: [PATCH 3/4] separate html pages for each table
---
backend/app/main.py | 112 +++++++++++++++++++++--
backend/app/templates/departments.html | 71 +++++++++++++++
backend/app/templates/employees.html | 86 ++++++++++++++++++
backend/app/templates/index.html | 51 ++++-------
backend/app/templates/records.html | 118 +++++++++++++++++++++++++
5 files changed, 400 insertions(+), 38 deletions(-)
create mode 100644 backend/app/templates/departments.html
create mode 100644 backend/app/templates/employees.html
create mode 100644 backend/app/templates/records.html
diff --git a/backend/app/main.py b/backend/app/main.py
index ac7ed48..7254a2f 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -1,11 +1,18 @@
-from fastapi import FastAPI, Request, Depends
+from fastapi import FastAPI, Request, Depends, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from app.database.connection import SessionLocal
-from app.database.models import EmployeeRecord
-from app.schemas.employee import EmployeeRecordSchema
+from app.database.models import Department, Employee, EmployeeRecord
+from app.schemas.employee import (
+ DepartmentCreate,
+ DepartmentSchema,
+ EmployeeCreate,
+ EmployeeSchema,
+ EmployeeRecordSchema,
+ EmployeeRecordCreate,
+)
app = FastAPI()
templates = Jinja2Templates(directory="app/templates")
@@ -17,10 +24,103 @@ def get_db():
finally:
db.close()
+
@app.get("/", response_class=HTMLResponse)
-def show_records(request: Request, db: Session = Depends(get_db)):
+def home(request: Request):
+ return templates.TemplateResponse(
+ request=request,
+ name="index.html",
+ context={"title": "ML App Home"},
+ )
+
+
+@app.get("/departments", response_class=HTMLResponse)
+def department_page(request: Request, db: Session = Depends(get_db)):
+ db_departments = db.query(Department).all()
+ return templates.TemplateResponse(
+ request=request,
+ name="departments.html",
+ context={"departments": db_departments},
+ )
+
+
+@app.get("/employees", response_class=HTMLResponse)
+def employee_page(request: Request, db: Session = Depends(get_db)):
+ db_departments = db.query(Department).all()
+ db_employees = db.query(Employee).all()
+ return templates.TemplateResponse(
+ request=request,
+ name="employees.html",
+ context={
+ "departments": db_departments,
+ "employees": db_employees,
+ },
+ )
+
+
+@app.get("/records", response_class=HTMLResponse)
+def records_page(request: Request, db: Session = Depends(get_db)):
+ db_employees = db.query(Employee).all()
db_records = db.query(EmployeeRecord).all()
- serialized_records = [EmployeeRecordSchema.model_validate(rec) for rec in db_records]
+ return templates.TemplateResponse(
+ request=request,
+ name="records.html",
+ context={
+ "employees": db_employees,
+ "records": db_records,
+ },
+ )
+
+
+@app.post("/departments", response_model=DepartmentSchema)
+def create_department(department_in: DepartmentCreate, db: Session = Depends(get_db)):
+ department = Department(name=department_in.name)
+ db.add(department)
+ db.commit()
+ db.refresh(department)
+ return department
+
+
+@app.post("/employees", response_model=EmployeeSchema)
+def create_employee(employee_in: EmployeeCreate, db: Session = Depends(get_db)):
+ department = None
+ if employee_in.department_id is not None:
+ department = db.get(Department, employee_in.department_id)
+ if department is None:
+ raise HTTPException(status_code=400, detail="department_id does not exist")
+ else:
+ department = db.query(Department).filter_by(name="General").first()
+ if department is None:
+ department = Department(name="General")
+ db.add(department)
+ db.flush()
+
+ employee = Employee(
+ first_name=employee_in.first_name,
+ last_name=employee_in.last_name,
+ email=employee_in.email,
+ department_id=department.id,
+ )
+ db.add(employee)
+ db.commit()
+ db.refresh(employee)
+ return employee
+
+
+@app.post("/records", response_model=EmployeeRecordSchema)
+def create_record(record_in: EmployeeRecordCreate, db: Session = Depends(get_db)):
+ employee = db.get(Employee, record_in.employee_id)
+ if employee is None:
+ raise HTTPException(status_code=400, detail="employee_id does not exist")
- return templates.TemplateResponse(request = request, name = "index.html", context = {"records": serialized_records})
+ db_record = EmployeeRecord(
+ employee_id=record_in.employee_id,
+ exam_score=record_in.exam_score,
+ years_exp=record_in.years_exp,
+ salary=record_in.salary,
+ )
+ db.add(db_record)
+ db.commit()
+ db.refresh(db_record)
+ return db_record
\ No newline at end of file
diff --git a/backend/app/templates/departments.html b/backend/app/templates/departments.html
new file mode 100644
index 0000000..010acdd
--- /dev/null
+++ b/backend/app/templates/departments.html
@@ -0,0 +1,71 @@
+
+
+
+
+ Departments
+
+
+
+
+
+ Departments
+
+
+ Existing departments
+
+ {% for department in departments %}
+ - {{ department.id }} — {{ department.name }}
+ {% else %}
+ - No departments yet.
+ {% endfor %}
+
+
+
+
+
+
diff --git a/backend/app/templates/employees.html b/backend/app/templates/employees.html
new file mode 100644
index 0000000..a090d36
--- /dev/null
+++ b/backend/app/templates/employees.html
@@ -0,0 +1,86 @@
+
+
+
+
+ Employees
+
+
+
+
+
+ Employees
+
+
+ Existing employees
+
+ {% for employee in employees %}
+ - {{ employee.id }} — {{ employee.first_name }} {{ employee.last_name }} (dept {{ employee.department_id }})
+ {% else %}
+ - No employees yet.
+ {% endfor %}
+
+
+
+
+
+
diff --git a/backend/app/templates/index.html b/backend/app/templates/index.html
index be9993f..ee07a2e 100644
--- a/backend/app/templates/index.html
+++ b/backend/app/templates/index.html
@@ -11,38 +11,25 @@
+
+
+
- Database Records View
- Reading directly from your PostgreSQL employee_records table:
-
-
-
-
- | Record ID |
- Employee ID |
- Exam Score |
- Years of Experience |
- Salary |
-
-
-
- {% for record in records %}
-
- | {{ record.id }} |
- {{ record.employee_id }} |
- {{ record.exam_score }} |
- {{ record.years_exp }} |
- ${{ "%.2f"|format(record.salary) }} |
-
- {% else %}
-
- |
- No records found in the database yet.
- |
-
- {% endfor %}
-
-
-
+
+ ML App Home
+ Use the pages below to manage your data.
+
+