From 3a1154ef039b728d718a5d18f757651dad764fba Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Sun, 16 Aug 2026 00:35:49 +0200 Subject: [PATCH] feat(web): add private company and portfolio presence --- .dockerignore | 7 ++ Dockerfile | 48 +++++++++++ PRESENCE-STRATEGY.md | 151 +++++++++++++++++++++++++++++++++++ docker-compose.yml | 27 +++++++ next.config.ts | 2 +- src/app/globals.css | 43 +++++++--- src/app/layout.tsx | 11 ++- src/app/page.tsx | 184 ++++++++++++++++++++++++++++--------------- 8 files changed, 390 insertions(+), 83 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 PRESENCE-STRATEGY.md create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c550055 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9b37c3f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +FROM node:22-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json package-lock.json* ./ +RUN npm ci + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js telemetry is disabled +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN npm run build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Copy the standalone output folder and the public folder +COPY --from=builder /app/public ./public + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/PRESENCE-STRATEGY.md b/PRESENCE-STRATEGY.md new file mode 100644 index 0000000..f5e228e --- /dev/null +++ b/PRESENCE-STRATEGY.md @@ -0,0 +1,151 @@ +# Präsenzstrategie für Jan Wagner / w-make + +Stand: 2026-08-15 + +## 1. Ziel + +Die Präsenz soll drei Zielgruppen in weniger als einer Minute verstehen lassen: + +1. **Industrie- und Mittelstandskunden:** Jan löst reale Prozessprobleme mit belastbarer Software. +2. **Technische Entscheider und Partner:** Jan kann Domäne, Architektur und Betrieb zusammen denken. +3. **Zukünftige Arbeitgeber:** Jan ist ein Senior Engineer mit Ownership, nicht nur ein Implementierer. + +Primäre Conversion: qualifizierter Erstkontakt. Nicht: möglichst viele Projekte oder Technologien zeigen. + +## 2. Empfohlene Positionierung + +> Ich entwickle robuste digitale Systeme für industrielle und anspruchsvolle Geschäftsprozesse — mit Domänenverständnis, klarer Architektur und Verantwortung für den Betrieb. + +Die Positionierung ist stärker als „innovative Lösungen“ oder „Full-Stack-Entwicklung“, weil sie ein Problem, eine Zielgruppe und einen Qualitätsanspruch benennt. + +## 3. Was bewusst nicht auf die öffentliche Startseite gehört + +- Casino-Automation und Echtgeld-Workflows +- Trading-/Prediction-Market-Projekte +- Interne Hermes-Infrastruktur, Bot-Namen und Serverdetails +- Unbelegte Zahlen wie Testanzahl, Verfügbarkeit oder Effizienzgewinne +- „Enterprise-Niveau“, „24/7 verfügbar“ oder ähnliche Behauptungen ohne veröffentlichbare Nachweise + +Diese Themen können privat als technische Lernprojekte oder auf Anfrage erscheinen. Öffentlich verwässern sie die B2B-Positionierung und können bei Kunden bzw. Arbeitgebern unnötige Risiko- und Vertrauensfragen auslösen. + +## 4. Inhaltliche Säulen + +### A. Industrie-Software und Domäne + +Der stärkste Beleg ist W-Make Batch. Daraus entstehen: + +- Case Study: „Wie aus einem Produktionsprozess ein belastbares Softwaresystem wird“ +- Architekturartikel: „Warum fachliche Buchungen nicht einfach gelöscht werden dürfen“ +- Prozessartikel: „Vom Satzzettel zum Tagesprotokoll: ein durchgängiges Produktionsmodell“ +- Produktseite: Problem → Lösung → Arbeitsweise → Demo/Kontakt + +### B. Engineering-Entscheidungen + +- Datenintegrität statt schneller CRUD-Logik +- Fachliche Regeln als explizite Invarianten +- Kleine, testbare Module statt verteilte Business-Logik +- Migrationen, Backups, Auditierbarkeit und sichere Fehlerpfade + +### C. Persönliche Perspektive + +- Übergang von Glass Technology zu Software Engineering +- Was Domänenwissen in der Produktentwicklung verändert +- Entscheidungen, die im Betrieb wichtiger sind als im Demo-Video +- Ehrliche technische Rückblicke mit Problem, Entscheidung, Ergebnis und offenem Rest + +## 5. Seitenstruktur für den öffentlichen Auftritt + +1. **Startseite:** Positionierung, 1–2 Belege, Arbeitsweise, Kontakt +2. **Über mich:** Glas-/Industrie-Hintergrund, Senior-Engineering-Profil, Arbeitsprinzipien +3. **W-Make Batch:** eigenständige Case Study mit Screenshots/Diagramm und klarer Abgrenzung zu vertraulichen Kundendaten +4. **Engineering Notes:** 4–6 substanzielle Artikel statt Newsfeed +5. **Kontakt:** E-Mail, LinkedIn/Git-Profil, Einsatzformen, Standort/remote +6. **Impressum/Datenschutz:** vor öffentlichem Launch rechtlich vervollständigen + +## 6. Case-Study-Template + +Jede Referenz folgt demselben Muster: + +- **Ausgangslage:** Welcher Prozess war schwierig oder fehleranfällig? +- **Verantwortung:** Welche Rolle und welchen Anteil hatte Jan? +- **Entscheidungen:** Welche Architektur-/Domänenentscheidungen waren entscheidend? +- **Ergebnis:** Nur belegbare Resultate; vertrauliche Werte anonymisieren. +- **Beweis:** Screenshot, vereinfachtes Modell, Teststrategie oder öffentliche Demo. +- **Lernpunkt:** Was kann ein anderer technischer Entscheider daraus übernehmen? +- **CTA:** Gespräch über einen ähnlichen Prozess. + +## 7. Priorisierte 30-Tage-Roadmap + +### Woche 1 — Vertrauen und Basis + +- Eigene Domain-/Unternehmensbezeichnung festlegen. +- Professionelle Kontaktadresse und LinkedIn-Profil verknüpfen. +- W-Make Batch als Referenz auf Freigabe und Vertraulichkeit prüfen. +- Impressum-/Datenschutz-Anforderungen vor Launch mit fachkundiger Stelle klären. + +### Woche 2 — Belege + +- Case Study zu W-Make Batch schreiben. +- 3–5 aussagekräftige Screenshots oder ein anonymisiertes Prozessdiagramm erstellen. +- Rolle, Zeitraum, Verantwortung und veröffentlichbare Ergebnisse sauber dokumentieren. + +### Woche 3 — Auffindbarkeit + +- LinkedIn-Headline an die Positionierung anpassen. +- Eine Engineering Note veröffentlichen. +- Profile konsistent verlinken: Website, LinkedIn, GitHub/Gitea nur wenn öffentlich geeignet. +- Title, Description, Open Graph, Sitemap und Search Console ergänzen. + +### Woche 4 — Conversion + +- Kontaktformular oder klare E-Mail ergänzen. +- Angebot in 2–3 konkrete Einstiege übersetzen: Prozessanalyse, technische Due Diligence, Produkt-/Backend-Entwicklung. +- Jede Seite mit genau einem nächsten Schritt versehen. +- Mobile, Tastaturbedienung, Ladezeit und externe Links prüfen. + +## 8. Konkrete Angebotsformulierungen + +### Prozessanalyse + +> Ich analysiere einen bestehenden digitalen Prozess, identifiziere fachliche Bruchstellen und übersetze die Ergebnisse in eine priorisierte technische Roadmap. + +### Produkt- und Backend-Entwicklung + +> Ich entwickle oder stabilisiere Anwendungen, bei denen Datenmodell, Geschäftslogik und Betrieb wichtiger sind als ein schneller Prototyp. + +### Technische Zusammenarbeit + +> Ich unterstütze Teams bei Architekturentscheidungen, schwierigen Integrationen und der Überführung von gewachsenem Code in ein wartbares System. + +## 9. Noch offen vor dem Launch + +- Öffentlich verwendbare Kontaktadresse +- Vollständiger Name/Firmierung nach UG-Gründung +- Impressums- und Datenschutzhinweise +- Freigabe zur Darstellung von W-Make Batch und verwendbaren Screenshots +- Tatsächliche öffentliche Profile/Links +- Messbare Ergebnisse, sofern sie veröffentlicht werden dürfen + +## 10. Erfolgskriterien + +Nach dem ersten Ausbau muss ein fremder Besucher beantworten können: + +- Was macht Jan konkret? +- Für wen ist das relevant? +- Woran ist die Qualität erkennbar? +- Wie kann ich Kontakt aufnehmen? + +Wenn eine Information nicht auf eine dieser vier Fragen einzahlt, gehört sie nicht auf die Startseite. + +## Quellen aus dem Workspace + +- `/home/eldov-ryzen5/workspace/Coding/Batchmaker/README.md` +- `/home/eldov-ryzen5/workspace/Coding/Batchmaker/AGENTS.md` +- `/home/eldov-ryzen5/workspace/Server/README.md` +- `/home/eldov-ryzen5/workspace/Coding/hermes-tools/README.md` +- `/home/eldov-ryzen5/workspace/w-make-com/src/app/page.tsx` +- `/home/eldov-ryzen5/workspace/w-make-com/src/app/layout.tsx` + +Die Quellen belegen technische Substanz. Kundennamen, Resultate und Rollen dürfen nur nach Freigabe öffentlich behauptet werden. + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..52e18de --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.8" + +services: + # Das Portfolio (Next.js) + w-make-portfolio: + build: . + image: w-make-portfolio:latest + container_name: w-make-portfolio + restart: always + expose: + - "3000" + labels: + - "traefik.enable=true" + - "traefik.docker.network=proxy" + - "traefik.http.routers.w-make.rule=Host(`w-make.com`) || Host(`www.w-make.com`)" + - "traefik.http.routers.w-make.priority=100" + - "traefik.http.routers.w-make.entrypoints=websecure" + - "traefik.http.routers.w-make.tls=true" + - "traefik.http.routers.w-make.tls.certresolver=http_resolver" + - "traefik.http.routers.w-make.middlewares=default@file,crowdsec-bouncer-plugin@file" + - "traefik.http.services.w-make.loadbalancer.server.port=3000" + networks: + - proxy + +networks: + proxy: + external: true diff --git a/next.config.ts b/next.config.ts index e9ffa30..68a6c64 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: "standalone", }; export default nextConfig; diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..91e527f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,26 +1,45 @@ @import "tailwindcss"; :root { - --background: #ffffff; - --foreground: #171717; + /* Tech Style Dark Theme by Default */ + --background: #020617; /* Slate 950 */ + --foreground: #f8fafc; /* Slate 50 */ + + /* Primary Action Colors (Electric Blue / Cyan) */ + --primary: #0ea5e9; + --primary-foreground: #ffffff; + + /* Metallic / Professional Accents */ + --accent: #334155; /* Slate 700 */ + --accent-foreground: #f8fafc; + + --border: #1e293b; /* Slate 800 */ } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-border: var(--border); -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } + --font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; + --font-mono: var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace; } body { - background: var(--background); + background-color: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-sans); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Subtle Grid Background for that "Tech" feel */ +.bg-grid-pattern { + background-image: linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px), + linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px); + background-size: 40px 40px; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9852c15..bfe4b97 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,17 +13,16 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Jan Wagner — Software für Prozesse, auf die man sich verlassen muss", + description: "Jan Wagner entwickelt robuste digitale Systeme für industrielle und anspruchsvolle Geschäftsprozesse.", }; export default function RootLayout({ children }: LayoutProps<"/">) { return ( - + {children} ); } + +// ponytail: Open Graph, structured data and canonical URL follow after the public domain is final. diff --git a/src/app/page.tsx b/src/app/page.tsx index c887311..330db0b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,69 +1,125 @@ -import Image from "next/image"; +const projects = [ + { + label: "Industrie-Software", + title: "W-Make Batch", + text: "Eine durchgängige Batchmanagement-Lösung für die Behälterglas-Produktion — von Satzzettel und Gemengebuch bis Silo-Management, Schichtprotokoll und Berechnung.", + facts: "Node.js · SQLite · Web Components · E2E-Tests", + href: "https://batch.w-make.com", + cta: "Produkt-Showroom öffnen", + }, + { + label: "Produktentwicklung", + title: "Digitale Prozesse, die den Betrieb verstehen", + text: "Ich verbinde Domänenwissen aus der Glasindustrie mit sauberer Softwarearchitektur. Das Ergebnis sind Systeme, die fachlich belastbar und im Alltag nutzbar sind.", + facts: "Fachlichkeit · Datenintegrität · Wartbarkeit", + href: "#arbeitsweise", + cta: "Arbeitsweise ansehen", + }, + { + label: "Technische Systeme", + title: "Automatisierung mit klaren Grenzen", + text: "Von APIs und Datenmodellen bis zu Infrastruktur und Observability: Automatisierung wird dort eingesetzt, wo sie Risiken reduziert — nicht um Komplexität zu verstecken.", + facts: "Backend · Tooling · Betrieb", + href: "#kontakt", + cta: "Projekt besprechen", + }, +]; + +const principles = [ + ["Fachlichkeit zuerst", "Ich beginne beim realen Prozess, nicht beim Framework. Fachliche Regeln werden sichtbar, prüfbar und nachvollziehbar umgesetzt."], + ["Verlässliche Systeme", "Datenintegrität, sichere Zustände und verständliche Fehlerbehandlung sind keine Extras — sie sind die Grundlage."], + ["Kleine, tragfähige Lösungen", "Keine Architektur um ihrer selbst willen. Erst die kleinste Lösung, die den Prozess dauerhaft besser macht."], +]; export default function Home() { return ( -
-
- Next.js logo -
-

- To get started, edit the{" "} - - page.tsx - {" "} - file. -

-

- Looking for a starting point or more instructions? Head over to{" "} - - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -

-
-
- - Vercel logomark - Deploy Now - - - Documentation - -
-
-
+
+
+
+ + +
+
+

Jan Wagner · Software Engineering

+

+ Software für Prozesse, auf die man sich verlassen muss. +

+

+ Ich entwickle robuste digitale Systeme für industrielle und anspruchsvolle Geschäftsprozesse — mit Domänenverständnis, klarer Architektur und Verantwortung für den Betrieb. +

+ +
+ +
+ +
+
+
+

Ausgewählte Arbeit

+

Nicht nur Features. Systeme.

+
+

Die stärkste Referenz ist ein nachvollziehbares System mit echtem fachlichem Kontext — nicht eine lange Liste von Buzzwords.

+
+
+ {projects.map((project) => ( +
+

{project.label}

+

{project.title}

+

{project.text}

+

{project.facts}

+ {project.cta} +
+ ))} +
+
+ +
+
+
+

Arbeitsweise

+

Senior heißt: Entscheidungen verantworten.

+
+
+ {principles.map(([title, text], index) => ( +
+ 0{index + 1} +

{title}

{text}

+
+ ))} +
+
+
+ +
+
+

Kontakt

+

Sie haben einen Prozess, der bessere Software verdient?

+

Lassen Sie uns klären, wo der größte Hebel liegt — in einem neuen Produkt, einer bestehenden Anwendung oder einer technischen Entscheidung.

+

Kontaktkanal und Impressum werden vor dem öffentlichen Launch ergänzt.

+
+
+ + +
+
); } + +// ponytail: Kontaktadresse und rechtliche Angaben erst ergänzen, wenn die UG-/Domain-Daten feststehen.