diff --git a/backend/app/main.py b/backend/app/main.py index e69de29..0507979 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -0,0 +1,128 @@ +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 Department, Employee, EmployeeRecord +from app.schemas.employee import ( + DepartmentCreate, + DepartmentSchema, + EmployeeCreate, + EmployeeSchema, + EmployeeRecordSchema, + EmployeeRecordCreate, +) + +# ENDPOINTS IN MAIN.PY BUT USUALLY WHEN THE PROJECT IS BIGGER WE SEPARATE THEM IN ROUTER + +app = FastAPI() +templates = Jinja2Templates(directory="app/templates") + +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +@app.get("/", response_class=HTMLResponse) +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() + 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") + + 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/schemas/employee.py b/backend/app/schemas/employee.py new file mode 100644 index 0000000..14bf9fc --- /dev/null +++ b/backend/app/schemas/employee.py @@ -0,0 +1,49 @@ +from typing import Optional + +from pydantic import BaseModel, ConfigDict + +# GET SCHEMAS + +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) + + id: int + employee_id: int + exam_score: int + years_exp: int + salary: float + +# POST SCHEMAS - note that we don't have id fields here because they are created automatically + +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 + 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

+ +
+ + + + 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

+ +
+ + + + diff --git a/backend/app/templates/index.html b/backend/app/templates/index.html new file mode 100644 index 0000000..ee07a2e --- /dev/null +++ b/backend/app/templates/index.html @@ -0,0 +1,35 @@ + + + + + ML Project Records + + + + + +
+ +
+ +
+

ML App Home

+

Use the pages below to manage your data.

+ +
+ + \ No newline at end of file diff --git a/backend/app/templates/records.html b/backend/app/templates/records.html new file mode 100644 index 0000000..cea096f --- /dev/null +++ b/backend/app/templates/records.html @@ -0,0 +1,118 @@ + + + + + Records + + + +
+ +
+
+

Records

+
+

+

+

+

+ + +
+ +

Employee records

+ + + + + + + + + + + + {% for record in records %} + + + + + + + + {% else %} + + + + {% endfor %} + +
Record IDEmployee IDExam ScoreYears of ExperienceSalary
{{ record.id }}{{ record.employee_id }}{{ record.exam_score }}{{ record.years_exp }}${{ "%.2f"|format(record.salary) }}
No records found in the database yet.
+
+ + + +