Despliegue en VPS

This commit is contained in:
2026-06-07 21:25:45 +02:00
parent c06300833b
commit e08d959cf9
11 changed files with 3609 additions and 90 deletions
+38
View File
@@ -0,0 +1,38 @@
import Database from "better-sqlite3";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
const __dirname = dirname(fileURLToPath(import.meta.url));
const db = new Database(join(__dirname, "..", "localesp.db"));
db.exec(`
CREATE TABLE IF NOT EXISTS businesses (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
category TEXT NOT NULL,
address TEXT NOT NULL,
description TEXT NOT NULL,
contact TEXT NOT NULL DEFAULT '',
lat REAL NOT NULL,
lng REAL NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
createdAt TEXT NOT NULL
)
`);
const empty = db.prepare("SELECT COUNT(*) AS n FROM businesses").get().n === 0;
if (empty) {
const ins = db.prepare(`
INSERT INTO businesses
(id, name, category, address, description, contact, lat, lng, status, createdAt)
VALUES
(@id, @name, @category, @address, @description, @contact, @lat, @lng, @status, @createdAt)
`);
for (const b of [
{ id: "1", name: "Café del Mercado", category: "Cafetería", address: "Plaza Mayor 3, Madrid", description: "Café de especialidad y bollería artesana.", contact: "hola@cafedelmercado.example", lat: 40.4155, lng: -3.7074, status: "approved", createdAt: "2025-01-10T10:00:00Z" },
{ id: "2", name: "Librería El Faro", category: "Librería", address: "Calle Luna 12, Madrid", description: "Librería independiente con sección infantil.", contact: "", lat: 40.4221, lng: -3.7059, status: "approved", createdAt: "2025-01-12T10:00:00Z" },
{ id: "3", name: "Taller Bicicletas Rueda", category: "Servicios", address: "Calle Embajadores 45, Madrid", description: "Reparación y venta de segunda mano.", contact: "+34 600 000 000", lat: 40.4078, lng: -3.7053, status: "approved", createdAt: "2025-01-15T10:00:00Z" },
]) ins.run(b);
}
export default db;
+51
View File
@@ -0,0 +1,51 @@
import express from "express";
import { randomUUID } from "crypto";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import db from "./db.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
app.use(express.json());
app.use(express.static(join(__dirname, "../dist")));
app.get("/api/businesses", (_req, res) => {
res.json(db.prepare("SELECT * FROM businesses WHERE status = 'approved' ORDER BY createdAt DESC").all());
});
app.post("/api/businesses", (req, res) => {
const { name, category, address, description, contact, lat, lng } = req.body;
const business = {
id: randomUUID(),
name, category, address, description,
contact: contact || "",
lat, lng,
status: "pending",
createdAt: new Date().toISOString(),
};
db.prepare(`
INSERT INTO businesses (id, name, category, address, description, contact, lat, lng, status, createdAt)
VALUES (@id, @name, @category, @address, @description, @contact, @lat, @lng, @status, @createdAt)
`).run(business);
res.status(201).json(business);
});
app.get("/api/admin/pending", (_req, res) => {
res.json(db.prepare("SELECT * FROM businesses WHERE status = 'pending' ORDER BY createdAt ASC").all());
});
app.patch("/api/admin/businesses/:id", (req, res) => {
const { status } = req.body;
if (!["approved", "rejected"].includes(status))
return res.status(400).json({ error: "status must be 'approved' or 'rejected'" });
const info = db.prepare("UPDATE businesses SET status = ? WHERE id = ?").run(status, req.params.id);
if (info.changes === 0) return res.status(404).json({ error: "not found" });
res.json({ ok: true });
});
app.get(/^\/(?!api\/).*/, (_req, res) => {
res.sendFile(join(__dirname, "../dist/index.html"));
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`API listening on http://localhost:${PORT}`));