Back to projects

kds werkzeugbau

Corporate website for a tool & mould manufacturer

PublishedJune 2026
Private repository
TypeScript
React
Next.js
NestJS
Prisma
PostgreSQL
UI/UX Design
BullMQ
Redis
SeaweedFS
Docker
next-intl

Project Introduction & Development Overview

KDS Werkzeugbau is a corporate website built for KDS Werkzeugbau GmbH, a German tool and mould manufacturer. The project covers a public-facing multilingual company website — including core competencies, news, job listings, and contact — as well as a staff admin portal for content management. The architecture is identical to the Marienmühle project, sharing the same monorepo stack, so this page focuses on what is different.

System Specifications & Feature Overview

The system is focused on corporate content management rather than transactional workflows. There are no reservations or menus — instead the key public-facing features are the news feed, job board, core competency pages, and a contact/inquiry form.

Database Architecture & Schema

The database is PostgreSQL with Prisma ORM, following the same migration workflow as Marienmühle. The schema is simpler — there are no reservations or tables. The core models are:

  • Post — News and event articles with optional image, PDF, date range, and tags ()
  • Job — Open positions with tasks, profile requirements, benefits, and a start/end date range
  • Customer — Inquiry senders (name, optional email, optional phone, newsletter opt-in)
  • ContactRequest — Linked to a Customer; carries a one-time process token for staff acknowledgement
  • Media — Images and PDFs stored in SeaweedFS, referenced by Posts
  • Email / EmailTemplate — Job queue records and MJML template references
  • Staff / RefreshToken — Admin users and session management
  • ClosedDay — Date ranges when the company is closed
  • Settings — Company name and contact email used across the site

Project Structure & Turborepo Monorepo Setup

Identical monorepo layout to Marienmühle — three apps under and six shared packages under , built with Turborepo.

    • api
    • email-worker
    • web
    • common
    • database
    • eslint-config
    • logger
    • typescript-config
    • ui
  • docs
  • bruno

REST API Endpoints & NestJS Backend

The API is a NestJS application. Modules cover: auth, analytics, posts, jobs, contact-requests, customers, media, email, email-template, settings, staff, closed-days, health, storage, and BullMQ. Most write endpoints require staff authentication; public endpoints are limited to reading posts/jobs and submitting contact requests.

Posts
GET

Get all news posts with optional tag filtering and pagination

Query Parameters:

1
10
createdAt
DESC
NEWS
POST

Create a new post (staff only)

Request Body (json):

Jobs
GET

Get all active job listings

Query Parameters:

1
10
Contact
POST

Submit a public contact/inquiry request

Request Body (json):

Media
POST

Upload image or PDF to SeaweedFS (staff only)

Request Body (form):

Authentication & Security

Authentication is the same CSRF + JWT dual-cookie scheme used in Marienmühle — short-lived access token (HS512, 15 min), long-lived refresh token (7 days), and a 48-character hex CSRF token. All three arrive as cookies on login; write endpoints check the CSRF token in addition to the access JWT.

Authentication
POST

Staff authentication with email and password

Request Body (json):

POST

Staff logout and deletion of session cookies

POST

Refresh access token using refresh token cookie

Incoming request bodies are validated with Zod via a custom NestJS before any business logic runs, rejecting malformed input with a 400 response.

Next.js Web Application

The web app uses the same Next.js 16 / Tailwind v4 / setup as Marienmühle with one notable addition: next-intl for German/English internationalisation. Translation JSON files live in and .

The app is split into three route groups:

  • — public-facing company site (home, core competencies, news, jobs, contact, directions)
  • — staff portal (dashboard, posts, jobs, customers, contact requests, emails, settings, closed days)
  • — login and preview-login flows

Email Worker Service

The email worker is a separate NestJS application that consumes the BullMQ queue backed by Redis. It handles two email types:

  • Contact Request Confirmation — sent to the customer immediately after they submit an inquiry
  • Contact Request Notification — sent to staff to alert them of a new inquiry

Templates are written in MJML and rendered via Handlebars for dynamic content. Nodemailer handles dispatch; failed jobs are retried with exponential backoff.

Docker Deployment & CI/CD Pipeline

Deployment follows the same pattern as Marienmühle — Docker Compose, Coolify, and GitHub Actions. Four application images are built and pushed to GitHub Container Registry: , , , and . Each has its own build workflow triggered by path-filtered pushes to .

A single workflow watches for the successful completion of all four build workflows, then triggers a Coolify webhook to pull and restart the updated containers.