feat: Initial commit of backend services and AGENTS.md
This commit is contained in:
23
backend/routes/ai.js
Normal file
23
backend/routes/ai.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const express = require("express");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get AI task suggestions
|
||||
router.get("/task-suggestions", auth, async (req, res) => {
|
||||
try {
|
||||
// In a real application, you would use a more sophisticated AI model to generate task suggestions.
|
||||
// For this example, we'll just return some mock data.
|
||||
const suggestions = [
|
||||
{ street: "Main St", description: "Clean up litter" },
|
||||
{ street: "Elm St", description: "Remove graffiti" },
|
||||
{ street: "Oak Ave", description: "Mow the lawn" },
|
||||
];
|
||||
res.json(suggestions);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
98
backend/routes/auth.js
Normal file
98
backend/routes/auth.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const express = require("express");
|
||||
const bcrypt = require("bcryptjs");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const User = require("../models/User");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get user
|
||||
router.get("/", auth, async (req, res) => {
|
||||
try {
|
||||
const user = await User.findById(req.user.id).select("-password");
|
||||
res.json(user);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Register
|
||||
router.post("/register", async (req, res) => {
|
||||
const { name, email, password } = req.body;
|
||||
|
||||
try {
|
||||
let user = await User.findOne({ email });
|
||||
if (user) {
|
||||
return res.status(400).json({ msg: "User already exists" });
|
||||
}
|
||||
|
||||
user = new User({
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
});
|
||||
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
user.password = await bcrypt.hash(password, salt);
|
||||
|
||||
await user.save();
|
||||
|
||||
const payload = {
|
||||
user: {
|
||||
id: user.id,
|
||||
},
|
||||
};
|
||||
|
||||
jwt.sign(
|
||||
payload,
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: 3600 },
|
||||
(err, token) => {
|
||||
if (err) throw err;
|
||||
res.json({ token });
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Login
|
||||
router.post("/login", async (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
try {
|
||||
let user = await User.findOne({ email });
|
||||
if (!user) {
|
||||
return res.status(400).json({ msg: "Invalid credentials" });
|
||||
}
|
||||
|
||||
const isMatch = await bcrypt.compare(password, user.password);
|
||||
if (!isMatch) {
|
||||
return res.status(400).json({ msg: "Invalid credentials" });
|
||||
}
|
||||
|
||||
const payload = {
|
||||
user: {
|
||||
id: user.id,
|
||||
},
|
||||
};
|
||||
|
||||
jwt.sign(
|
||||
payload,
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: 3600 },
|
||||
(err, token) => {
|
||||
if (err) throw err;
|
||||
res.json({ token });
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
66
backend/routes/events.js
Normal file
66
backend/routes/events.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const express = require("express");
|
||||
const Event = require("../models/Event");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all events
|
||||
router.get("/", async (req, res) => {
|
||||
try {
|
||||
const events = await Event.find();
|
||||
res.json(events);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create an event
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { title, description, date, location } = req.body;
|
||||
|
||||
try {
|
||||
const newEvent = new Event({
|
||||
title,
|
||||
description,
|
||||
date,
|
||||
location,
|
||||
});
|
||||
|
||||
const event = await newEvent.save();
|
||||
res.json(event);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// RSVP to an event
|
||||
router.put("/rsvp/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const event = await Event.findById(req.params.id);
|
||||
if (!event) {
|
||||
return res.status(404).json({ msg: "Event not found" });
|
||||
}
|
||||
|
||||
// Check if the user has already RSVPed
|
||||
if (
|
||||
event.participants.filter(
|
||||
(participant) => participant.toString() === req.user.id,
|
||||
).length > 0
|
||||
) {
|
||||
return res.status(400).json({ msg: "Already RSVPed" });
|
||||
}
|
||||
|
||||
event.participants.unshift(req.user.id);
|
||||
|
||||
await event.save();
|
||||
|
||||
res.json(event.participants);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
27
backend/routes/payments.js
Normal file
27
backend/routes/payments.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const express = require("express");
|
||||
const auth = require("../middleware/auth");
|
||||
const User = require("../models/User");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Handle premium subscription
|
||||
router.post("/subscribe", auth, async (req, res) => {
|
||||
try {
|
||||
// In a real application, you would integrate with a payment gateway like Stripe.
|
||||
// For this example, we'll just mock a successful payment.
|
||||
const user = await User.findById(req.user.id);
|
||||
if (!user) {
|
||||
return res.status(404).json({ msg: "User not found" });
|
||||
}
|
||||
|
||||
user.isPremium = true;
|
||||
await user.save();
|
||||
|
||||
res.json({ msg: "Subscription successful" });
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
63
backend/routes/posts.js
Normal file
63
backend/routes/posts.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const express = require("express");
|
||||
const Post = require("../models/Post");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all posts
|
||||
router.get("/", async (req, res) => {
|
||||
try {
|
||||
const posts = await Post.find().populate("user", ["name"]);
|
||||
res.json(posts);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create a post
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { content, imageUrl } = req.body;
|
||||
|
||||
try {
|
||||
const newPost = new Post({
|
||||
user: req.user.id,
|
||||
content,
|
||||
imageUrl,
|
||||
});
|
||||
|
||||
const post = await newPost.save();
|
||||
res.json(post);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Like a post
|
||||
router.put("/like/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const post = await Post.findById(req.params.id);
|
||||
if (!post) {
|
||||
return res.status(404).json({ msg: "Post not found" });
|
||||
}
|
||||
|
||||
// Check if the post has already been liked by this user
|
||||
if (
|
||||
post.likes.filter((like) => like.toString() === req.user.id).length > 0
|
||||
) {
|
||||
return res.status(400).json({ msg: "Post already liked" });
|
||||
}
|
||||
|
||||
post.likes.unshift(req.user.id);
|
||||
|
||||
await post.save();
|
||||
|
||||
res.json(post.likes);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
58
backend/routes/reports.js
Normal file
58
backend/routes/reports.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const express = require("express");
|
||||
const Report = require("../models/Report");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all reports
|
||||
router.get("/", async (req, res) => {
|
||||
try {
|
||||
const reports = await Report.find()
|
||||
.populate("street", ["name"])
|
||||
.populate("user", ["name"]);
|
||||
res.json(reports);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create a report
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { street, issue } = req.body;
|
||||
|
||||
try {
|
||||
const newReport = new Report({
|
||||
street,
|
||||
user: req.user.id,
|
||||
issue,
|
||||
});
|
||||
|
||||
const report = await newReport.save();
|
||||
res.json(report);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Resolve a report
|
||||
router.put("/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const report = await Report.findById(req.params.id);
|
||||
if (!report) {
|
||||
return res.status(404).json({ msg: "Report not found" });
|
||||
}
|
||||
|
||||
report.status = "resolved";
|
||||
|
||||
await report.save();
|
||||
|
||||
res.json(report);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
70
backend/routes/rewards.js
Normal file
70
backend/routes/rewards.js
Normal file
@@ -0,0 +1,70 @@
|
||||
const express = require("express");
|
||||
const Reward = require("../models/Reward");
|
||||
const User = require("../models/User");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all rewards
|
||||
router.get("/", async (req, res) => {
|
||||
try {
|
||||
const rewards = await Reward.find();
|
||||
res.json(rewards);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create a reward
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { name, description, cost, isPremium } = req.body;
|
||||
|
||||
try {
|
||||
const newReward = new Reward({
|
||||
name,
|
||||
description,
|
||||
cost,
|
||||
isPremium,
|
||||
});
|
||||
|
||||
const reward = await newReward.save();
|
||||
res.json(reward);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Redeem a reward
|
||||
router.post("/redeem/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const reward = await Reward.findById(req.params.id);
|
||||
if (!reward) {
|
||||
return res.status(404).json({ msg: "Reward not found" });
|
||||
}
|
||||
|
||||
const user = await User.findById(req.user.id);
|
||||
if (!user) {
|
||||
return res.status(404).json({ msg: "User not found" });
|
||||
}
|
||||
|
||||
if (user.points < reward.cost) {
|
||||
return res.status(400).json({ msg: "Not enough points" });
|
||||
}
|
||||
|
||||
if (reward.isPremium && !user.isPremium) {
|
||||
return res.status(403).json({ msg: "Premium reward not available" });
|
||||
}
|
||||
|
||||
user.points -= reward.cost;
|
||||
await user.save();
|
||||
|
||||
res.json({ msg: "Reward redeemed successfully" });
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
74
backend/routes/streets.js
Normal file
74
backend/routes/streets.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const express = require("express");
|
||||
const Street = require("../models/Street");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all streets
|
||||
router.get("/", async (req, res) => {
|
||||
try {
|
||||
const streets = await Street.find();
|
||||
res.json(streets);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Get single street
|
||||
router.get("/:id", async (req, res) => {
|
||||
try {
|
||||
const street = await Street.findById(req.params.id);
|
||||
if (!street) {
|
||||
return res.status(404).json({ msg: "Street not found" });
|
||||
}
|
||||
res.json(street);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create a street
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { name, location } = req.body;
|
||||
|
||||
try {
|
||||
const newStreet = new Street({
|
||||
name,
|
||||
location,
|
||||
});
|
||||
|
||||
const street = await newStreet.save();
|
||||
res.json(street);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Adopt a street
|
||||
router.put("/adopt/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const street = await Street.findById(req.params.id);
|
||||
if (!street) {
|
||||
return res.status(404).json({ msg: "Street not found" });
|
||||
}
|
||||
|
||||
if (street.status === "adopted") {
|
||||
return res.status(400).json({ msg: "Street already adopted" });
|
||||
}
|
||||
|
||||
street.adoptedBy = req.user.id;
|
||||
street.status = "adopted";
|
||||
|
||||
await street.save();
|
||||
|
||||
res.json(street);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
56
backend/routes/tasks.js
Normal file
56
backend/routes/tasks.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const express = require("express");
|
||||
const Task = require("../models/Task");
|
||||
const auth = require("../middleware/auth");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get all tasks for user
|
||||
router.get("/", auth, async (req, res) => {
|
||||
try {
|
||||
const tasks = await Task.find({ completedBy: req.user.id });
|
||||
res.json(tasks);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Create a task
|
||||
router.post("/", auth, async (req, res) => {
|
||||
const { street, description } = req.body;
|
||||
|
||||
try {
|
||||
const newTask = new Task({
|
||||
street,
|
||||
description,
|
||||
});
|
||||
|
||||
const task = await newTask.save();
|
||||
res.json(task);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
// Complete a task
|
||||
router.put("/:id", auth, async (req, res) => {
|
||||
try {
|
||||
const task = await Task.findById(req.params.id);
|
||||
if (!task) {
|
||||
return res.status(404).json({ msg: "Task not found" });
|
||||
}
|
||||
|
||||
task.completedBy = req.user.id;
|
||||
task.status = "completed";
|
||||
|
||||
await task.save();
|
||||
|
||||
res.json(task);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send("Server error");
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
21
backend/routes/users.js
Normal file
21
backend/routes/users.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const express = require('express');
|
||||
const User = require('../models/User');
|
||||
const auth = require('../middleware/auth');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Get user by ID
|
||||
router.get('/:id', auth, async (req, res) => {
|
||||
try {
|
||||
const user = await User.findById(req.params.id).populate('adoptedStreets');
|
||||
if (!user) {
|
||||
return res.status(404).json({ msg: 'User not found' });
|
||||
}
|
||||
res.json(user);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
res.status(500).send('Server error');
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user