Well and Good

This commit is contained in:
Bryson Mmari 2025-09-01 16:38:32 +03:00
commit f777c6d2cc
13 changed files with 2413 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
node_modules
# Keep environment variables out of version control
.env
/src/generated/prisma

0
API/api Normal file
View File

2092
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "express",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "tsx src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@prisma/client": "^6.15.0",
"dotenv": "^17.2.1",
"express": "^5.1.0",
"morgan": "^1.10.1"
},
"devDependencies": {
"@types/node": "^24.3.0",
"prisma": "^6.15.0",
"ts-node": "^10.9.2",
"tsx": "^4.20.5",
"typescript": "^5.9.2"
}
}

View File

@ -0,0 +1,96 @@
-- CreateEnum
CREATE TYPE "public"."UPDATE_STATUS" AS ENUM ('IN_PROGRESS', 'LIVE', 'DEPRECATED', 'ARCHIVED');
-- CreateTable
CREATE TABLE "public"."Post" (
"id" SERIAL NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"title" VARCHAR(255) NOT NULL,
"content" TEXT,
"published" BOOLEAN NOT NULL DEFAULT false,
"authorId" TEXT NOT NULL,
CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "public"."User" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"username" TEXT NOT NULL,
"password" TEXT NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "public"."Product" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"name" TEXT NOT NULL,
"belongsToId" TEXT NOT NULL,
CONSTRAINT "Product_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "public"."Update" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"title" VARCHAR(255) NOT NULL,
"body" TEXT NOT NULL,
"status" "public"."UPDATE_STATUS" NOT NULL DEFAULT 'IN_PROGRESS',
"version" TEXT,
"asset" TEXT NOT NULL,
"productId" TEXT NOT NULL,
CONSTRAINT "Update_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "public"."UpdatePoint" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"name" VARCHAR(255) NOT NULL,
"description" TEXT NOT NULL,
"updateId" TEXT NOT NULL,
CONSTRAINT "UpdatePoint_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "public"."_UpdateToUser" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_UpdateToUser_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_username_key" ON "public"."User"("username");
-- CreateIndex
CREATE INDEX "_UpdateToUser_B_index" ON "public"."_UpdateToUser"("B");
-- AddForeignKey
ALTER TABLE "public"."Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "public"."User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."Product" ADD CONSTRAINT "Product_belongsToId_fkey" FOREIGN KEY ("belongsToId") REFERENCES "public"."User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."Update" ADD CONSTRAINT "Update_productId_fkey" FOREIGN KEY ("productId") REFERENCES "public"."Product"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."UpdatePoint" ADD CONSTRAINT "UpdatePoint_updateId_fkey" FOREIGN KEY ("updateId") REFERENCES "public"."Update"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."_UpdateToUser" ADD CONSTRAINT "_UpdateToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Update"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."_UpdateToUser" ADD CONSTRAINT "_UpdateToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

86
prisma/schema.prisma Normal file
View File

@ -0,0 +1,86 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
}
model User {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
username String @unique
password String
updates Update[]
Post Post[]
Product Product[]
}
model Product {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String
belongsToId String
belongsTo User @relation(fields: [belongsToId], references: [id])
updates Update[]
}
enum UPDATE_STATUS {
IN_PROGRESS
LIVE
DEPRECATED
ARCHIVED
}
model Update{
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
body String
status UPDATE_STATUS @default(IN_PROGRESS)
version String?
asset String
productId String
product Product @relation(fields: [productId], references: [id])
updatePoints UpdatePoint[]
User User[]
}
model UpdatePoint {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String @db.VarChar(255)
description String
updateId String
update Update @relation(fields: [updateId], references: [id])
}

1
src/api.request.http Normal file
View File

@ -0,0 +1 @@
GET http://localhost:3000

8
src/index.ts Normal file
View File

@ -0,0 +1,8 @@
import app from './server';
import dotenv from 'dotenv';
dotenv.config();
app.listen(process.env.PORT || 3000, () => {
console.log(`Server is running on port ${process.env.PORT || 3000}`);
});

62
src/router.ts Normal file
View File

@ -0,0 +1,62 @@
import { Router } from "express";
const router = Router();
/**
* Products Router
*/
router.get("/product", (req, res) => {
res.json({message: "List of products"});
});
router.get("/product/:id", (req, res) => {});
router.post("/product", (req, res) => {});
router.put("/product/:id", (req, res) => {});
router.delete("/product/:id", (req, res) => {});
/**
* Update
*/
router.get("/update", (req, res) => {});
router.get("/update/:id", (req, res) => {});
router.post("/update", (req, res) => {});
router.put("/update/:id", (req, res) => {});
router.delete("/update/:id", (req, res) => {});
/**
* UpdatePoint
*/
router.get("/updatepoint", (req, res) => {});
router.get("/updatepoint/:id", (req, res) => {});
router.post("/updatepoint", (req, res) => {});
router.put("/updatepoint/:id", (req, res) => {});
router.delete("/updatepoint/:id", (req, res) => {});
/**
* Users Router
*/
// router.get("/user", (req, res) => {});
// router.get("/user/:id", (req, res) => {});
// router.post("/user", (req, res) => {});
// router.put("/user/:id", (req, res) => {});
// router.delete("/user/:id", (req, res) => {});
export default router;

18
src/server.ts Normal file
View File

@ -0,0 +1,18 @@
import express from 'express';
import router from './router';
import morgan from 'morgan';
const app = express();
app.use(morgan('dev'));
app.use('/api', router);
app.get('/', (req, res) => {
console.log('Request received');
res.status(200);
res.json({'message': 'Hello Developer!'});
});
// Export the app
export default app;

View File

@ -0,0 +1,4 @@
Setting
install express
install prisma
install morgan

12
tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"strict": false,
"lib": ["ESNext"],
"esModuleInterop": true,
"module":"ESNext",
"moduleResolution": "Node",
"target": "ESNext"
}
}