11from fastapi import FastAPI , UploadFile , File , Depends , HTTPException
22from fastapi .middleware .cors import CORSMiddleware
3- from sqlalchemy import create_engine , Column , Integer , String , Date , Text
4- from sqlalchemy .orm import sessionmaker , declarative_base , Session
3+ from sqlalchemy import Column , Integer , String , Date , Text
4+ from sqlalchemy .orm import Session
55from datetime import date
66from dotenv import load_dotenv
7- from pydantic import BaseModel
8- import os , shutil
7+ import os
8+ import shutil
99
1010# ================================================
11- # 1️⃣ Load Environment Variables & Database Setup
11+ # 1️⃣ Load Environment Variables + Shared Database
1212# ================================================
1313load_dotenv ()
1414
15- DATABASE_URL = os .getenv ("DATABASE_URL" , "sqlite:///./app.db" )
16- engine = create_engine (DATABASE_URL , pool_pre_ping = True )
17- SessionLocal = sessionmaker (autocommit = False , autoflush = False , bind = engine )
18- Base = declarative_base ()
15+ # ❗ IMPORT SHARED BASE + ENGINE (do NOT create Base here)
16+ from app .database import Base , engine , SessionLocal
1917
2018# ================================================
21- # 2️⃣ Local Models for Internal Tables (Task + Audit Log)
19+ # 2️⃣ Models (Task + AuditLog) using shared Base
2220# ================================================
2321class Task (Base ):
2422 __tablename__ = "tasks"
23+
2524 id = Column (Integer , primary_key = True , index = True )
2625 title = Column (String (255 ), nullable = False )
2726 department = Column (String (100 ), nullable = True )
@@ -35,26 +34,29 @@ class Task(Base):
3534
3635class AuditLog (Base ):
3736 __tablename__ = "audit_logs"
37+
3838 id = Column (Integer , primary_key = True )
3939 action = Column (String (50 ))
4040 detail = Column (Text )
4141
4242
4343# ================================================
44- # 3️⃣ FastAPI App Initialization
44+ # 3️⃣ FastAPI App Init
4545# ================================================
4646app = FastAPI (title = "FAT-EIBL (Edme) – API" )
4747
48- # Enable CORS for the frontend
49- allow = os .getenv ("ALLOW_ORIGINS" , "*" ).split ("," )
48+ # CORS setup
49+ allowed_origins = os .getenv ("ALLOW_ORIGINS" , "*" ).split ("," )
50+
5051app .add_middleware (
5152 CORSMiddleware ,
52- allow_origins = allow ,
53+ allow_origins = allowed_origins ,
5354 allow_credentials = True ,
5455 allow_methods = ["*" ],
5556 allow_headers = ["*" ],
5657)
5758
59+
5860# ================================================
5961# 4️⃣ Database Dependency
6062# ================================================
@@ -65,63 +67,60 @@ def get_db():
6567 finally :
6668 db .close ()
6769
70+
6871# ================================================
69- # 5️⃣ Import Routers (Users, Forgot Password)
72+ # 5️⃣ Routers
7073# ================================================
7174from app .routers import users , forgot_password
7275
7376app .include_router (users .router , prefix = "/users" , tags = ["Users" ])
74- app .include_router (forgot_password .router , prefix = "/users" , tags = ["Forgot Password" ])
77+ app .include_router (forgot_password .router , prefix = "/auth" , tags = ["Forgot Password" ])
78+
7579
7680# ================================================
77- # 6️⃣ Health Check Endpoint
81+ # 6️⃣ Health Check
7882# ================================================
7983@app .get ("/health" )
8084def health_check ():
81- """Simple endpoint to verify backend health"""
82- return { "status" : "ok" , "message" : "Backend is running properly" }
85+ return { "status" : "ok" , "message" : "Backend running" }
86+
8387
8488# ================================================
85- # 7️⃣ File Upload Handler (Optional)
89+ # 7️⃣ File Upload
8690# ================================================
8791UPLOAD_DIR = os .path .join (os .getcwd (), "uploads" )
8892os .makedirs (UPLOAD_DIR , exist_ok = True )
8993
94+
9095@app .post ("/upload/{task_id}" )
9196async def upload_file (task_id : int , file : UploadFile = File (...), db : Session = Depends (get_db )):
92- """Attach a file to a specific task"""
93- obj = db .get (Task , task_id )
94- if not obj :
97+ task = db .get (Task , task_id )
98+ if not task :
9599 raise HTTPException (status_code = 404 , detail = "Task not found" )
96100
97- safe_name = f"task_{ task_id } _" + os .path .basename (file .filename )
98- dest = os .path .join (UPLOAD_DIR , safe_name )
101+ filename = f"task_{ task_id } _" + os .path .basename (file .filename )
102+ path = os .path .join (UPLOAD_DIR , filename )
99103
100- with open (dest , "wb" ) as buffer :
104+ with open (path , "wb" ) as buffer :
101105 shutil .copyfileobj (file .file , buffer )
102106
103- obj .attachment = safe_name
104- db .add (AuditLog (action = "upload" , detail = f"Task ID { task_id } uploaded file { safe_name } " ))
107+ task .attachment = filename
108+ db .add (AuditLog (action = "upload" , detail = f"File uploaded for task { task_id } " ))
105109 db .commit ()
106110
107- return {"task_id" : task_id , "filename" : safe_name }
111+ return {"ok" : True , "filename" : filename }
112+
108113
109114# ================================================
110- # 8️⃣ Database Initialization Endpoint (/create-db)
115+ # 8️⃣ Create All Tables
111116# ================================================
112117from app .models .user import User
113118from app .models .otp import OtpModel
114- from app .database import Base as DBBase , engine as DBEngine
115119
116120@app .get ("/create-db" )
117- def create_database ():
118- """
119- 🔧 Create all database tables if they don't exist.
120- Run this once on Render or local after migrations.
121- """
121+ def create_db ():
122122 try :
123- DBBase .metadata .create_all (bind = DBEngine )
124123 Base .metadata .create_all (bind = engine )
125- return {"ok" : True , "message" : "✅ All database tables created successfully " }
124+ return {"ok" : True , "message" : "Tables created" }
126125 except Exception as e :
127126 return {"ok" : False , "error" : str (e )}
0 commit comments