feat: Add DevSecOps tools, Woodpecker proxy, Vault persistent storage, pitch-deck annex slides
All checks were successful
CI / test-bqas (push) Successful in 32s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 46s
CI / test-python-voice (push) Successful in 38s

- Install Gitleaks, Trivy, Grype, Syft, Semgrep, Bandit in backend-core Dockerfile
- Add Woodpecker SQLite proxy API (fallback without API token)
- Mount woodpecker_data volume read-only to backend-core
- Add backend proxy fallback in admin-core Woodpecker route
- Add Vault file-based persistent storage (config.hcl, init-vault.sh)
- Auto-init, unseal and root-token persistence for Vault
- Add 6 pitch-deck annex slides (Assumptions, Architecture, GTM, Regulatory, Engineering, AI Pipeline)
- Dynamic margin/amortization KPIs in BusinessModelSlide
- Market sources modal with citations in MarketSlide
- Redesign nginx landing page to 3-column layout (Lehrer/Compliance/Core)
- Extend MkDocs nav with Services and SDK documentation sections
- Add SDK Protection architecture doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-17 15:42:43 +01:00
parent eb43b40dd0
commit b7d21daa24
31 changed files with 3323 additions and 299 deletions

View File

@@ -3,9 +3,10 @@
import { motion } from 'framer-motion'
import { Language, PitchTeamMember } from '@/lib/types'
import { t } from '@/lib/i18n'
import { User } from 'lucide-react'
import { User, Linkedin } from 'lucide-react'
import GradientText from '../ui/GradientText'
import FadeInView from '../ui/FadeInView'
import Image from 'next/image'
interface TeamSlideProps {
lang: Language
@@ -34,14 +35,39 @@ export default function TeamSlide({ lang, team }: TeamSlideProps) {
className="bg-white/[0.08] backdrop-blur-xl border border-white/10 rounded-3xl p-8"
>
<div className="flex items-start gap-5">
{/* Avatar */}
<div className="w-20 h-20 rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600
flex items-center justify-center shrink-0 shadow-lg">
<User className="w-10 h-10 text-white" />
</div>
{/* Avatar — Foto oder Fallback */}
{member.photo_url ? (
<div className="w-20 h-20 rounded-2xl overflow-hidden shrink-0 shadow-lg">
<Image
src={member.photo_url}
alt={member.name}
width={80}
height={80}
className="w-full h-full object-cover"
/>
</div>
) : (
<div className="w-20 h-20 rounded-2xl bg-gradient-to-br from-indigo-500 to-purple-600
flex items-center justify-center shrink-0 shadow-lg">
<User className="w-10 h-10 text-white" />
</div>
)}
<div className="flex-1">
<h3 className="text-xl font-bold text-white mb-1">{member.name}</h3>
<div className="flex items-center gap-2 mb-1">
<h3 className="text-xl font-bold text-white">{member.name}</h3>
{member.linkedin_url && (
<a
href={member.linkedin_url}
target="_blank"
rel="noopener noreferrer"
className="p-1 text-white/30 hover:text-[#0A66C2] transition-colors"
title="LinkedIn"
>
<Linkedin className="w-4 h-4" />
</a>
)}
</div>
<p className="text-indigo-400 text-sm font-medium mb-3">
{lang === 'de' ? member.role_de : member.role_en}
</p>