Projektgeruest mit Workspaces fuer Server und Weboberflaeche

Fastify mit Prisma im Server-Workspace, React mit Vite im Web-Workspace.
Das Frontend baut direkt nach server/public, damit am Ende ein einzelnes
Image API und Oberflaeche ausliefert.
This commit is contained in:
2026-09-18 11:31:13 +02:00
parent 638a88f0de
commit d7e7a3b186
9 changed files with 5269 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
# Dependencies
node_modules/
.pnp
.pnp.js
# Build output
dist/
build/
*.tsbuildinfo
.vite/
# Frontend-Bundle, wird beim Build erzeugt
server/public/
# Environment
.env
.env.local
.env.*.local
!.env.example
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Runtime data
uploads/
tmp/
coverage/
# Editor / OS
.DS_Store
Thumbs.db
.idea/
*.swp
*~
# Local notes
notes/
+5059
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
{
"name": "cc-manager",
"version": "1.0.0",
"private": true,
"description": "Tracking von Custom Characters, Paketen und Redesigns",
"license": "GPL-3.0-or-later",
"workspaces": [
"server",
"web"
],
"engines": {
"node": ">=20"
},
"scripts": {
"dev": "concurrently -n api,web -c blue,magenta \"npm:dev:api\" \"npm:dev:web\"",
"dev:api": "npm run dev --workspace=server",
"dev:web": "npm run dev --workspace=web",
"build": "npm run build --workspace=web && npm run build --workspace=server",
"start": "npm run start --workspace=server",
"migrate": "npm run migrate --workspace=server",
"migrate:dev": "npm run migrate:dev --workspace=server",
"generate": "npm run generate --workspace=server",
"typecheck": "npm run typecheck --workspace=server && npm run typecheck --workspace=web",
"test": "npm run test --workspace=server"
},
"devDependencies": {
"concurrently": "^9.1.2"
}
}
+41
View File
@@ -0,0 +1,41 @@
{
"name": "@cc-manager/server",
"version": "1.0.0",
"private": true,
"type": "module",
"main": "dist/index.js",
"scripts": {
"dev": "tsx watch --env-file-if-exists=.env src/index.ts",
"build": "prisma generate && tsc -p tsconfig.json",
"start": "node dist/index.js",
"generate": "prisma generate",
"migrate": "prisma migrate deploy",
"migrate:dev": "prisma migrate dev",
"studio": "prisma studio",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"@fastify/cookie": "^11.0.2",
"@fastify/helmet": "^13.0.1",
"@fastify/multipart": "^9.0.3",
"@fastify/rate-limit": "^10.2.2",
"@fastify/static": "^8.1.1",
"@node-rs/argon2": "^2.0.2",
"@prisma/client": "^6.5.0",
"csv-parse": "^5.6.0",
"fastify": "^5.2.1",
"otplib": "^13.5.0",
"prisma": "^6.5.0",
"qrcode": "^1.5.4",
"zod": "^3.24.2"
},
"devDependencies": {
"@electric-sql/pglite": "^0.5.8",
"@electric-sql/pglite-socket": "^0.2.11",
"@types/node": "^22.13.10",
"@types/qrcode": "^1.5.5",
"tsx": "^4.19.3",
"typescript": "^5.8.2"
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2023",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2023"],
"outDir": "dist",
"rootDir": "src",
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"sourceMap": true,
"declaration": false
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist", "src/**/*.test.ts"]
}
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex, nofollow" />
<title>CC-Manager</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
{
"name": "@cc-manager/web",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"preview": "vite preview",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.3.0"
},
"devDependencies": {
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "^5.8.2",
"vite": "^6.2.1"
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"allowImportingTsExtensions": false,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"skipLibCheck": true,
"types": ["vite/client"]
},
"include": ["src", "vite.config.ts"]
}
+21
View File
@@ -0,0 +1,21 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
// Landet im Server-Image neben dem kompilierten Backend.
outDir: '../server/public',
emptyOutDir: true,
sourcemap: false,
},
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: false,
},
},
},
});