docuscan-ai / start.py
pramodmisra's picture
Add email forwarding β€” SendGrid Inbound Parse with multi-tenant routing
db992a6
"""
DocuScan AI β€” Startup Script
1. Initialize database tables
2. Seed default org + super admin if none exist
3. Launch uvicorn
"""
import os
import hashlib
from pathlib import Path
# Ensure data directories exist
for d in ["/data", "/data/uploads", "/data/outputs"]:
Path(d).mkdir(parents=True, exist_ok=True)
from database import init_db, SessionLocal, engine
from models import Base, Organization, User, CloudConnection, CloudImport, EmailImport
def hash_password(pw: str) -> str:
return hashlib.sha256(pw.encode()).hexdigest()
def seed_data():
db = SessionLocal()
try:
# Seed default org if none
org_count = db.query(Organization).count()
if org_count == 0:
default_org = Organization(name="DocuScan", slug="docuscan")
db.add(default_org)
db.flush()
print(f"Created default organization: DocuScan (id={default_org.id})")
# Seed super admins
admins = [
User(
email="admin@docuscan.ai",
hashed_password=hash_password("Admin@123"),
full_name="System Admin",
role="super_admin",
org_id=default_org.id,
),
User(
email="neha@5gvector.com",
hashed_password=hash_password("Admin@123"),
full_name="Neha Misra",
role="super_admin",
org_id=default_org.id,
),
]
db.add_all(admins)
db.commit()
print("Seeded super admins: admin@docuscan.ai, neha@5gvector.com")
else:
user_count = db.query(User).count()
org_names = [o.name for o in db.query(Organization).all()]
print(f"Database has {org_count} org(s) ({', '.join(org_names)}), {user_count} user(s) β€” skipping seed")
# Always ensure neha@5gvector.com exists as super_admin
neha = db.query(User).filter_by(email="neha@5gvector.com").first()
if not neha:
default_org = db.query(Organization).first()
if default_org:
neha = User(
email="neha@5gvector.com",
hashed_password=hash_password("Admin@123"),
full_name="Neha Misra",
role="super_admin",
org_id=default_org.id,
)
db.add(neha)
db.commit()
print("Added super admin: neha@5gvector.com")
finally:
db.close()
def check_schema():
"""If old schema is detected (missing organizations table), recreate all tables."""
from sqlalchemy import inspect, text
inspector = inspect(engine)
tables = inspector.get_table_names()
if "users" in tables and "organizations" not in tables:
print("Old schema detected β€” recreating all tables for multi-org support...")
Base.metadata.drop_all(bind=engine)
print("Old tables dropped")
# Additive migration: add suggestions_json column if missing
if "documents" in inspector.get_table_names():
columns = [c["name"] for c in inspector.get_columns("documents")]
if "suggestions_json" not in columns:
with engine.connect() as conn:
conn.execute(text("ALTER TABLE documents ADD COLUMN suggestions_json TEXT"))
conn.commit()
print("Added suggestions_json column to documents table")
if __name__ == "__main__":
print("Checking schema...")
check_schema()
print("Initializing database...")
init_db()
print("Seeding data...")
seed_data()
print("Starting DocuScan AI on port 7860...")
import uvicorn
uvicorn.run("backend:app", host="0.0.0.0", port=7860)