Architecture - HoseaCodes/PropFlow-UI GitHub Wiki

** Architecture (OpenAI-based MCP System)**

Frontend (Angular - Vercel)
β”‚
β”œβ”€β”€ Dashboard (view + request weekly reports)
β”œβ”€β”€ Email Trigger Button (calls /api/email-report)
β”œβ”€β”€ View Weekly Suggestions & Insights
β”‚
└────API Calls───► Backend (Node.js + Express - EC2)
                     β”‚
                     β”œβ”€β”€ MongoDB (EC2 or Atlas)
                     β”œβ”€β”€ Node Cron (generates report weekly)
                     β”œβ”€β”€ OpenAI API (analyzes guest reviews)
                     └── Nodemailer (sends weekly report email)

1. Backend Folder Structure

backend/
β”œβ”€β”€ models/
β”‚   └── WeeklyReport.js
β”œβ”€β”€ routes/
β”‚   └── reports.js
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ openaiService.js
β”‚   β”œβ”€β”€ reportService.js
β”‚   └── emailService.js
β”œβ”€β”€ schedulers/
β”‚   └── weeklyReport.js
β”œβ”€β”€ server.js
β”œβ”€β”€ .env
└── package.json

2. Sample Code Snippets

models/WeeklyReport.js

const mongoose = require('mongoose');

const WeeklyReportSchema = new mongoose.Schema({
  createdAt: { type: Date, default: Date.now },
  avgOccupancy: Number,
  avgRate: Number,
  guestReviewSummary: String,
  recommendations: [String],
});

module.exports = mongoose.model("WeeklyReport", WeeklyReportSchema);

services/openaiService.js

const { OpenAI } = require("openai");

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function analyzeReviews(reviews) {
  const combinedReviews = reviews.join(" ");
  const prompt = `
Analyze these Airbnb guest reviews and summarize:
1. Overall sentiment (positive, neutral, negative)
2. Common themes
3. Three specific improvement suggestions

Reviews:
${combinedReviews}`;

  const res = await openai.chat.completions.create({
    model: "gpt-4",
    messages: [{ role: "user", content: prompt }],
  });

  return res.choices[0].message.content;
}

module.exports = { analyzeReviews };

services/reportService.js

const WeeklyReport = require('../models/WeeklyReport');
const { analyzeReviews } = require('./openaiService');

async function generateWeeklyReport() {
  const dummyReviews = [
    "The place was clean but the check-in was confusing.",
    "Great location but the WiFi was slow.",
    "Host was very helpful!"
  ];

  const summary = await analyzeReviews(dummyReviews);
  
  const newReport = new WeeklyReport({
    avgOccupancy: 72,
    avgRate: 145,
    guestReviewSummary: summary,
    recommendations: [
      "Clarify check-in instructions",
      "Improve WiFi router placement",
      "Keep up excellent communication"
    ]
  });

  await newReport.save();
}

module.exports = { generateWeeklyReport };

services/emailService.js

const nodemailer = require("nodemailer");

const transporter = nodemailer.createTransport({
  service: "Gmail",
  auth: {
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASS,
  },
});

async function sendReportEmail(email, report) {
  await transporter.sendMail({
    from: process.env.EMAIL_USER,
    to: email,
    subject: "Your Weekly Airbnb Report",
    html: `<h2>Summary</h2><p>${report.guestReviewSummary}</p><h3>Suggestions</h3><ul>${report.recommendations.map(r => `<li>${r}</li>`).join("")}</ul>`,
  });
}

module.exports = { sendReportEmail };

routes/reports.js

const express = require("express");
const router = express.Router();
const WeeklyReport = require("../models/WeeklyReport");
const { sendReportEmail } = require("../services/emailService");

router.get("/latest", async (req, res) => {
  const report = await WeeklyReport.findOne().sort({ createdAt: -1 });
  res.json(report);
});

router.post("/:id/email", async (req, res) => {
  const report = await WeeklyReport.findById(req.params.id);
  await sendReportEmail(req.body.email, report);
  res.json({ message: "Email sent" });
});

module.exports = router;

schedulers/weeklyReport.js

const cron = require("node-cron");
const { generateWeeklyReport } = require("../services/reportService");

cron.schedule("0 9 * * MON", async () => {
  console.log("Generating weekly report...");
  await generateWeeklyReport();
});

server.js

const express = require("express");
const mongoose = require("mongoose");
require("dotenv").config();
const reportRoutes = require("./routes/reports");

const app = express();
app.use(express.json());
app.use("/api/reports", reportRoutes);

mongoose.connect(process.env.MONGO_URI, () => {
  console.log("Connected to MongoDB");
});

require("./schedulers/weeklyReport");

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

3. .env Example

OPENAI_API_KEY=your-openai-key
MONGO_URI=your-mongodb-uri
[email protected]
EMAIL_PASS=your-email-password

⚠️ **GitHub.com Fallback** ⚠️