require("dotenv").config(); const express = require("express"); const bodyParser = require("body-parser"); const { User, Post, sequelize } = require("./models"); const app = express(); app.use(bodyParser.json()); // Helper to get model by resource name const models = { users: User, posts: Post }; // Sync DB sequelize.sync(); // TreeQL-style dynamic GET app.get("/:resource/:id?/:subresource?", async (req, res) => { const { resource, id, subresource } = req.params; const Model = models[resource]; if (!Model) return res.status(404).json({ error: "Resource not found" }); try { if (id) { const instance = await Model.findByPk( id, subresource ? { include: subresource } : {} ); if (!instance) return res.status(404).json({ error: "Not found" }); if (subresource && instance[subresource]) { return res.json(instance[subresource]); } return res.json(instance); } else { const all = await Model.findAll(); return res.json(all); } } catch (e) { return res.status(500).json({ error: e.message }); } }); // TreeQL-style POST (create resource or subresource) app.post("/:resource/:id?/:subresource?", async (req, res) => { const { resource, id, subresource } = req.params; const Model = models[resource]; if (!Model) return res.status(404).json({ error: "Resource not found" }); try { if (id && subresource) { // e.g. POST /users/1/posts const parent = await models[resource].findByPk(id); if (!parent) return res.status(404).json({ error: "Parent not found" }); const childModel = models[subresource]; if (!childModel) return res.status(404).json({ error: "Subresource not found" }); const child = await childModel.create({ ...req.body, UserId: id }); return res.status(201).json(child); } else { // e.g. POST /users const instance = await Model.create(req.body); return res.status(201).json(instance); } } catch (e) { return res.status(500).json({ error: e.message }); } }); // TreeQL-style PUT (update resource) app.put("/:resource/:id", async (req, res) => { const { resource, id } = req.params; const Model = models[resource]; if (!Model) return res.status(404).json({ error: "Resource not found" }); try { const instance = await Model.findByPk(id); if (!instance) return res.status(404).json({ error: "Not found" }); await instance.update(req.body); return res.json(instance); } catch (e) { return res.status(500).json({ error: e.message }); } }); // TreeQL-style DELETE (delete resource) app.delete("/:resource/:id", async (req, res) => { const { resource, id } = req.params; const Model = models[resource]; if (!Model) return res.status(404).json({ error: "Resource not found" }); try { const instance = await Model.findByPk(id); if (!instance) return res.status(404).json({ error: "Not found" }); await instance.destroy(); return res.json({ success: true }); } catch (e) { return res.status(500).json({ error: e.message }); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`TreeQL API running on port ${PORT}`));