chore: remove legacy workspace and restructure API + modular admin UI
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const base = path.resolve(__dirname, '../src/modules');
|
||||
const mods = ['gifts', 'guests', 'todos'];
|
||||
for (const mod of mods) {
|
||||
const folder = path.join(base, mod, 'model');
|
||||
if (fs.existsSync(folder)) {
|
||||
try {
|
||||
fs.rmSync(folder, { recursive: true, force: true });
|
||||
console.log(`Removed folder ${folder}`);
|
||||
} catch (err) {
|
||||
console.warn(`Could not remove ${folder}:`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const base = path.resolve(__dirname, '../src/modules');
|
||||
const mapping = {
|
||||
guests: 'guest.model.ts',
|
||||
gifts: 'gift.model.ts',
|
||||
todos: 'todo.model.ts',
|
||||
};
|
||||
|
||||
for (const mod of Object.keys(mapping)) {
|
||||
const modDir = path.join(base, mod);
|
||||
const modelDir = path.join(modDir, 'model');
|
||||
const src = path.join(modelDir, mapping[mod]);
|
||||
const dst = path.join(modDir, 'model.ts');
|
||||
|
||||
if (fs.existsSync(src)) {
|
||||
console.log(`Moving ${src} -> ${dst}`);
|
||||
fs.renameSync(src, dst);
|
||||
}
|
||||
|
||||
if (fs.existsSync(modelDir)) {
|
||||
try {
|
||||
const files = fs.readdirSync(modelDir);
|
||||
if (files.length === 0) {
|
||||
console.log(`Removing empty directory ${modelDir}`);
|
||||
fs.rmdirSync(modelDir);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`Failed to clean model directory ${modelDir}:`, e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const loginSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6),
|
||||
});
|
||||
|
||||
export type LoginDto = z.infer<typeof loginSchema>;
|
||||
@@ -1,9 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const registerSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6),
|
||||
name: z.string().optional(),
|
||||
});
|
||||
|
||||
export type RegisterDto = z.infer<typeof registerSchema>;
|
||||
@@ -1,11 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const createContributionSchema = z.object({
|
||||
giftId: z.string().uuid(),
|
||||
contributorName: z.string().min(1),
|
||||
contributorEmail: z.string().email().optional(),
|
||||
amount: z.number().min(0),
|
||||
type: z.enum(["individual", "group"]).optional(),
|
||||
});
|
||||
|
||||
export type CreateContributionDto = z.infer<typeof createContributionSchema>;
|
||||
@@ -1,11 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const createGiftSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
imageUrl: z.string().optional(),
|
||||
price: z.number().optional(),
|
||||
experience: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type CreateGiftDto = z.infer<typeof createGiftSchema>;
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Router } from "express";
|
||||
import { GiftService } from "../../modules/gifts/service";
|
||||
import { validateBody } from "../../core/middleware/validate";
|
||||
import { createGiftSchema, createContributionSchema } from "../../modules/gifts/types";
|
||||
import { requireAuth } from "../../core/middleware/auth";
|
||||
|
||||
const service = new GiftService();
|
||||
|
||||
export function registerGiftRoutes(router: Router) {
|
||||
const r = Router();
|
||||
|
||||
// Protected routes
|
||||
r.use(requireAuth);
|
||||
|
||||
r.post("/gift", validateBody(createGiftSchema), async (req, res) => {
|
||||
const ownerId = (req as any).user?.id;
|
||||
const gift = await service.createGift({ ...req.body, ownerId });
|
||||
res.json(gift);
|
||||
});
|
||||
|
||||
r.get("/gift", async (_req, res) => {
|
||||
const gifts = await service.listGifts();
|
||||
res.json(gifts);
|
||||
});
|
||||
|
||||
r.get("/gift/:id", async (req, res) => {
|
||||
const requesterId = (req as any).user?.id;
|
||||
const gift = await service.getGiftById(req.params.id, requesterId);
|
||||
if (!gift) {
|
||||
return res.status(404).json({ error: "Gift not found" });
|
||||
}
|
||||
res.json(gift);
|
||||
});
|
||||
|
||||
r.post(
|
||||
"/gift/contribution",
|
||||
validateBody(createContributionSchema),
|
||||
async (req, res) => {
|
||||
const contribution = await service.createContribution(req.body);
|
||||
res.json(contribution);
|
||||
},
|
||||
);
|
||||
|
||||
r.get("/gift/:id/contributions", async (req, res) => {
|
||||
const requesterId = (req as any).user?.id;
|
||||
const contributions = await service.listContributions(req.params.id, requesterId);
|
||||
res.json(contributions);
|
||||
});
|
||||
|
||||
router.use(r);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const createGuestSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email().optional(),
|
||||
phone: z.string().optional(),
|
||||
rsvp: z.boolean().optional(),
|
||||
tableId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
export type CreateGuestDto = z.infer<typeof createGuestSchema>;
|
||||
@@ -1,8 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const updateRsvpSchema = z.object({
|
||||
rsvp: z.boolean(),
|
||||
tableId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
export type UpdateRsvpDto = z.infer<typeof updateRsvpSchema>;
|
||||
@@ -1,34 +0,0 @@
|
||||
import { Router } from "express";
|
||||
import { GuestService } from "../../modules/guests/service";
|
||||
import { validateBody } from "../../core/middleware/validate";
|
||||
import { createGuestSchema, updateRsvpSchema } from "../../modules/guests/types";
|
||||
|
||||
const service = new GuestService();
|
||||
|
||||
export function registerGuestRoutes(router: Router) {
|
||||
const r = Router();
|
||||
|
||||
r.post("/guest", validateBody(createGuestSchema), async (req, res) => {
|
||||
const guest = await service.createGuest(req.body);
|
||||
res.json(guest);
|
||||
});
|
||||
|
||||
r.get("/guest", async (_req, res) => {
|
||||
const guests = await service.listGuests();
|
||||
res.json(guests);
|
||||
});
|
||||
|
||||
r.patch(
|
||||
"/guest/:id/rsvp",
|
||||
validateBody(updateRsvpSchema),
|
||||
async (req, res) => {
|
||||
const updated = await service.updateRsvp(req.params.id, req.body);
|
||||
if (!updated) {
|
||||
return res.status(404).json({ error: "Guest not found" });
|
||||
}
|
||||
res.json(updated);
|
||||
},
|
||||
);
|
||||
|
||||
router.use(r);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Express } from "express";
|
||||
|
||||
export function registerHealthRoutes(app: Express) {
|
||||
app.get("/api/health", (_req, res) => {
|
||||
res.json({ ok: true, timestamp: new Date().toISOString() });
|
||||
});
|
||||
}
|
||||
@@ -1,18 +1,15 @@
|
||||
import type { Express } from "express";
|
||||
import { registerHealthRoutes } from "./health/health.routes";
|
||||
import { registerAdminRoutes } from "./admin/routes";
|
||||
import { registerAuthRoutes } from "./auth/routes";
|
||||
import { registerOrganizadorRoutes } from "./organizador/routes";
|
||||
import { registerInvitadosRoutes } from "./invitados/routes";
|
||||
import { registerAuthRoutes } from "./organizador/auth/routes";
|
||||
import { requireRole, requireInvitadoAccess } from "./middleware";
|
||||
|
||||
export function registerApiRoutes(app: Express) {
|
||||
// shared middleware could be added here (logging, tenant resolution, etc.)
|
||||
|
||||
registerHealthRoutes(app);
|
||||
|
||||
// Auth routes (register / login) are global and shared by all clients.
|
||||
app.use("/api/auth", registerAuthRoutes());
|
||||
// Public auth endpoints for organizer/admin users
|
||||
app.use("/api/organizador/auth", registerAuthRoutes());
|
||||
|
||||
// Admin-only routes
|
||||
app.use("/api/admin", requireRole("admin"), registerAdminRoutes());
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Router } from "express";
|
||||
import { AuthService } from "../../modules/auth/auth.service";
|
||||
import { UserService } from "../../modules/auth/user.service";
|
||||
import { validateBody } from "../../core/middleware/validate";
|
||||
import { loginSchema, registerSchema } from "../../modules/auth/types";
|
||||
import { AuthService } from "../../../modules/auth/auth.service";
|
||||
import { UserService } from "../../../modules/auth/user.service";
|
||||
import { validateBody } from "../../../core/middleware/validate";
|
||||
import { loginSchema, registerSchema } from "../../../modules/auth/types";
|
||||
|
||||
const authService = new AuthService();
|
||||
const userService = new UserService();
|
||||
7
packages/server/src/api/organizador/health/routes.ts
Normal file
7
packages/server/src/api/organizador/health/routes.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { Router } from "express";
|
||||
|
||||
export function registerHealthRoutes(router: Router) {
|
||||
router.get("/health", (_req, res) => {
|
||||
res.json({ ok: true, timestamp: new Date().toISOString() });
|
||||
});
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { Router } from "express";
|
||||
import { requireRole } from "../middleware";
|
||||
import { registerGuestRoutes } from "./guests/routes";
|
||||
import { registerGiftRoutes } from "./gifts/routes";
|
||||
import { registerHealthRoutes } from "./health/routes";
|
||||
import { registerTodoRoutes } from "./todos/routes";
|
||||
|
||||
export function registerOrganizadorRoutes() {
|
||||
@@ -10,6 +11,7 @@ export function registerOrganizadorRoutes() {
|
||||
// Organizador routes are for organizers (and admins).
|
||||
// Authentication and role enforcement is handled in api/index.ts.
|
||||
|
||||
registerHealthRoutes(router);
|
||||
registerGuestRoutes(router, requireRole("admin", "organizer"));
|
||||
registerGiftRoutes(router, requireRole("admin", "organizer"));
|
||||
registerTodoRoutes(router, requireRole("admin", "organizer"));
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const createTodoSchema = z.object({
|
||||
title: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
dueDate: z.string().optional(),
|
||||
});
|
||||
|
||||
export type CreateTodoDto = z.infer<typeof createTodoSchema>;
|
||||
@@ -1,33 +0,0 @@
|
||||
import { Router } from "express";
|
||||
import { TodoService } from "../../modules/todos/service";
|
||||
import { validateBody } from "../../core/middleware/validate";
|
||||
import { createTodoSchema } from "../../modules/todos/types";
|
||||
import { requireAuth } from "../../core/middleware/auth";
|
||||
|
||||
const service = new TodoService();
|
||||
|
||||
export function registerTodoRoutes(router: Router) {
|
||||
const r = Router();
|
||||
|
||||
r.use(requireAuth);
|
||||
|
||||
r.post("/todo", validateBody(createTodoSchema), async (req, res) => {
|
||||
const todo = await service.createTodo(req.body);
|
||||
res.json(todo);
|
||||
});
|
||||
|
||||
r.get("/todo", async (_req, res) => {
|
||||
const todos = await service.listTodos();
|
||||
res.json(todos);
|
||||
});
|
||||
|
||||
r.patch("/todo/:id/complete", async (req, res) => {
|
||||
const updated = await service.markComplete(req.params.id);
|
||||
if (!updated) {
|
||||
return res.status(404).json({ error: "Todo not found" });
|
||||
}
|
||||
res.json(updated);
|
||||
});
|
||||
|
||||
router.use(r);
|
||||
}
|
||||
Reference in New Issue
Block a user