From 172a8b95fad06ae69a2fc7fae137b40adb8f7b8c Mon Sep 17 00:00:00 2001 From: debb-major Date: Tue, 16 Sep 2025 18:19:10 +0100 Subject: [PATCH] added AI layer for summarization and report generation --- backend/.env.sample | 10 ------- backend/app/db/database.py | 23 ++++++++++++++- backend/app/db/seeds/volunteers.py | 2 +- backend/main.py | 23 +++++++++++++-- backend/summarizer.py | 45 ++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 15 deletions(-) delete mode 100644 backend/.env.sample create mode 100644 backend/summarizer.py diff --git a/backend/.env.sample b/backend/.env.sample deleted file mode 100644 index a65862b..0000000 --- a/backend/.env.sample +++ /dev/null @@ -1,10 +0,0 @@ -# .env.example -# ✅ PostgreSQL connection string -# Format: postgresql+asyncpg://:@:/ -DATABASE_URL=example_url - -# ✅ Gemini API key -GEMINI_API_KEY=example_key - -# Deployed frontend url -FRONTEND_URL=url \ No newline at end of file diff --git a/backend/app/db/database.py b/backend/app/db/database.py index 9483eeb..15ed397 100644 --- a/backend/app/db/database.py +++ b/backend/app/db/database.py @@ -17,4 +17,25 @@ def get_db(): try: yield db finally: - db.close() \ No newline at end of file + db.close() + +# am I supposed to use 'db' or 'base' or what so as to connect with supabase here? +# backend/db.py +from supabase import create_client + +SUPABASE_URL = os.getenv("SUPABASE_URL") +SUPABASE_KEY = os.getenv("SUPABASE_KEY") + +supabase = create_client(SUPABASE_URL, SUPABASE_KEY) + +def get_impact_stats(): + """ + Fetch NGO impact stats from Supabase. + Expected table: 'impact_stats' + Example row: { totalLearners, supportPartners, volunteerHours, activeVolunteers } + """ + response = supabase.table("impact_stats").select("*").execute() # so i can know what to use here .................. + + if response.data and len(response.data) > 0: + return response.data[0] # take first row for demo + return {"learners_reached": 0, "volunteer_hours": 0, "events_hosted": 0} diff --git a/backend/app/db/seeds/volunteers.py b/backend/app/db/seeds/volunteers.py index fc8b2ce..c34f28d 100644 --- a/backend/app/db/seeds/volunteers.py +++ b/backend/app/db/seeds/volunteers.py @@ -43,6 +43,6 @@ def seed_volunteers(): print(f"Adding Volunteer: {data['name']}") db.commit() - print("✅ Volunteers table seeded successfully.") + print("Volunteers table seeded successfully.") finally: db.close() diff --git a/backend/main.py b/backend/main.py index 83a6572..b93a73f 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,4 +1,3 @@ -# main.py from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware @@ -6,7 +5,11 @@ from app.api.routes.metrics import router as metrics_router from app.api.routes.impact import router as impact_router -import app.api.models +import app.api.models + +from summarizer import summarize_impact +from db import get_impact_stats # added this in database.py + # Base.metadata.drop_all(bind=engine) @@ -31,5 +34,19 @@ def health_check(): return {"message": f"Server is running and healthy"} +# check here ..................... +@app.get("/report") +def generate_report(): + # Fetch stats from Supabase + stats = get_impact_stats() + + # Pass stats to Gemini summarizer + summary = summarize_impact(stats) + + return { + "stats": stats, + "summary": summary + } + app.include_router(metrics_router, prefix="/api", tags=["metrics"]) -app.include_router(impact_router, prefix="/api", tags=["impact"]) \ No newline at end of file +app.include_router(impact_router, prefix="/api", tags=["impact"]) diff --git a/backend/summarizer.py b/backend/summarizer.py new file mode 100644 index 0000000..f231114 --- /dev/null +++ b/backend/summarizer.py @@ -0,0 +1,45 @@ +import os +import google.generativeai as genai +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +# Configure Gemini client +genai.configure(api_key=os.getenv("GEMINI_API_KEY")) + +# The summarizer function +def summarize_impact(data: dict) -> str: + """ + Summarize NGO impact stats into a donor-friendly narrative. + + Args: + data (dict): Example: + { + "total_learners": 120, + "support_partners": 19, + "volunteer_hours": 85, + "active_volunteers": 30 + } + + Returns: + str: AI-generated summary text. + """ + model = genai.GenerativeModel("gemini-1.5-flash") + + prompt = f""" + You are helping an NGO write a donor-friendly impact report. + + Stats provided: + - Total learners: {data.get('total_learners', 0)} + - Support partners: {data.get('support_partners', 0)} + - Volunteer hours: {data.get('volunteer_hours', 0)} + - Active volunteers: {data.get('active_volunteers', 0)} + + Write a short, positive summary (3–4 sentences) highlighting achievements. + Make it clear, inspiring, and professional. + """ + + response = model.generate_content(prompt) + + return response.text if response and response.text else "No summary generated."