feat: Backend REST API Grundstruktur

🔐 Auth Routes:
- POST /register, /login, /refresh, /logout
- GET /me

👥 Contacts Routes:
- CRUD + /activities, /deals
- /import, /export (DSGVO Art. 20)

💰 Deals Routes:
- CRUD + /pipeline (Kanban View)
- /move, /won, /lost
- /forecast

📝 Activities Routes:
- CRUD + /upcoming
- /complete

📊 Pipelines Routes:
- CRUD + /stages

 Features:
- CORS Middleware
- Error Handler
- Request Logger
- API Documentation Endpoint
This commit is contained in:
2026-02-11 10:05:51 +00:00
parent 4b7297c199
commit cc74d66fad
6 changed files with 1010 additions and 19 deletions

109
src/routes/pipelines.ts Normal file
View File

@@ -0,0 +1,109 @@
import { Router } from "@oak/oak";
const router = new Router({ prefix: "/api/v1/pipelines" });
// GET /api/v1/pipelines - List pipelines
router.get("/", async (ctx) => {
ctx.response.body = {
success: true,
data: [
{
id: "pipeline-1",
name: "Sales Pipeline",
isDefault: true,
stages: [
{ id: "lead", name: "Lead", order: 1, probability: 10 },
{ id: "qualified", name: "Qualifiziert", order: 2, probability: 25 },
{ id: "proposal", name: "Angebot", order: 3, probability: 50 },
{ id: "negotiation", name: "Verhandlung", order: 4, probability: 75 },
{ id: "closed_won", name: "Gewonnen", order: 5, probability: 100 },
{ id: "closed_lost", name: "Verloren", order: 6, probability: 0 },
],
dealsCount: 15,
totalValue: 250000,
},
],
};
});
// GET /api/v1/pipelines/:id
router.get("/:id", async (ctx) => {
const { id } = ctx.params;
ctx.response.body = {
success: true,
data: {
id,
name: "Sales Pipeline",
isDefault: true,
stages: [
{ id: "lead", name: "Lead", order: 1, probability: 10 },
{ id: "qualified", name: "Qualifiziert", order: 2, probability: 25 },
{ id: "proposal", name: "Angebot", order: 3, probability: 50 },
{ id: "negotiation", name: "Verhandlung", order: 4, probability: 75 },
{ id: "closed_won", name: "Gewonnen", order: 5, probability: 100 },
{ id: "closed_lost", name: "Verloren", order: 6, probability: 0 },
],
},
};
});
// POST /api/v1/pipelines - Create pipeline
router.post("/", async (ctx) => {
const body = await ctx.request.body.json();
ctx.response.status = 201;
ctx.response.body = {
success: true,
message: "Pipeline created",
data: {
id: "new-pipeline-uuid",
...body,
},
};
});
// PUT /api/v1/pipelines/:id - Update pipeline
router.put("/:id", async (ctx) => {
const { id } = ctx.params;
const body = await ctx.request.body.json();
ctx.response.body = {
success: true,
message: "Pipeline updated",
data: {
id,
...body,
},
};
});
// PUT /api/v1/pipelines/:id/stages - Update stages (reorder, add, remove)
router.put("/:id/stages", async (ctx) => {
const { id } = ctx.params;
const body = await ctx.request.body.json();
const { stages } = body;
ctx.response.body = {
success: true,
message: "Stages updated",
data: {
id,
stages,
},
};
});
// DELETE /api/v1/pipelines/:id
router.delete("/:id", async (ctx) => {
const { id } = ctx.params;
// TODO: Check if pipeline has deals
ctx.response.body = {
success: true,
message: "Pipeline deleted",
};
});
export { router as pipelinesRouter };