From 3047c8f7f28aae141917da033fbd9a5b68687389 Mon Sep 17 00:00:00 2001 From: Damjan Savic Date: Sun, 25 Jan 2026 06:29:02 +0100 Subject: [PATCH 01/17] auto-claude: subtask-1-1 - Create schemas directory and extract PersonJsonLd --- .auto-claude-security.json | 227 ++++++++++++++++++++ .auto-claude-status | 25 +++ .claude_settings.json | 39 ++++ .gitignore | 5 +- context.json | 74 +++++++ project_index.json | 27 +++ src/components/seo/schemas/PersonJsonLd.tsx | 80 +++++++ 7 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 .auto-claude-security.json create mode 100644 .auto-claude-status create mode 100644 .claude_settings.json create mode 100644 context.json create mode 100644 project_index.json create mode 100644 src/components/seo/schemas/PersonJsonLd.tsx diff --git a/.auto-claude-security.json b/.auto-claude-security.json new file mode 100644 index 0000000..eed60a2 --- /dev/null +++ b/.auto-claude-security.json @@ -0,0 +1,227 @@ +{ + "base_commands": [ + ".", + "[", + "[[", + "ag", + "awk", + "basename", + "bash", + "bc", + "break", + "cat", + "cd", + "chmod", + "clear", + "cmp", + "column", + "comm", + "command", + "continue", + "cp", + "curl", + "cut", + "date", + "df", + "diff", + "dig", + "dirname", + "du", + "echo", + "egrep", + "env", + "eval", + "exec", + "exit", + "expand", + "export", + "expr", + "false", + "fd", + "fgrep", + "file", + "find", + "fmt", + "fold", + "gawk", + "gh", + "git", + "grep", + "gunzip", + "gzip", + "head", + "help", + "host", + "iconv", + "id", + "jobs", + "join", + "jq", + "kill", + "killall", + "less", + "let", + "ln", + "ls", + "lsof", + "man", + "mkdir", + "mktemp", + "more", + "mv", + "nl", + "paste", + "pgrep", + "ping", + "pkill", + "popd", + "printenv", + "printf", + "ps", + "pushd", + "pwd", + "read", + "readlink", + "realpath", + "reset", + "return", + "rev", + "rg", + "rm", + "rmdir", + "sed", + "seq", + "set", + "sh", + "shuf", + "sleep", + "sort", + "source", + "split", + "stat", + "tail", + "tar", + "tee", + "test", + "time", + "timeout", + "touch", + "tr", + "tree", + "true", + "type", + "uname", + "unexpand", + "uniq", + "unset", + "unzip", + "watch", + "wc", + "wget", + "whereis", + "which", + "whoami", + "xargs", + "yes", + "yq", + "zip", + "zsh" + ], + "stack_commands": [ + "ar", + "clang", + "clang++", + "cmake", + "composer", + "dive", + "docker", + "docker-buildx", + "docker-compose", + "dockerfile", + "eslint", + "g++", + "gcc", + "ipython", + "jupyter", + "ld", + "make", + "meson", + "next", + "ninja", + "nm", + "node", + "notebook", + "npm", + "npx", + "objdump", + "pdb", + "php", + "pip", + "pip3", + "pipx", + "pnpm", + "pnpx", + "pudb", + "python", + "python3", + "react-scripts", + "strip", + "ts-node", + "tsc", + "tsx", + "vitest" + ], + "script_commands": [ + "bun", + "npm", + "pnpm", + "yarn" + ], + "custom_commands": [], + "detected_stack": { + "languages": [ + "python", + "javascript", + "typescript", + "php", + "c" + ], + "package_managers": [ + "pnpm" + ], + "frameworks": [ + "nextjs", + "react", + "vitest", + "eslint" + ], + "databases": [], + "infrastructure": [ + "docker" + ], + "cloud_providers": [], + "code_quality_tools": [], + "version_managers": [] + }, + "custom_scripts": { + "npm_scripts": [ + "dev", + "build", + "start", + "lint", + "build:images", + "generate:images", + "generate:images:dry", + "test", + "test:coverage" + ], + "make_targets": [], + "poetry_scripts": [], + "cargo_aliases": [], + "shell_scripts": [] + }, + "project_dir": "C:\\Users\\damja\\WebstormProjects\\Portfolio", + "created_at": "2026-01-22T15:28:38.237190", + "project_hash": "c4ad399e16be367eb4e6b076fe1d9ee3", + "inherited_from": "C:\\Users\\damja\\WebstormProjects\\Portfolio" +} \ No newline at end of file diff --git a/.auto-claude-status b/.auto-claude-status new file mode 100644 index 0000000..d3c20c7 --- /dev/null +++ b/.auto-claude-status @@ -0,0 +1,25 @@ +{ + "active": true, + "spec": "032-split-large-jsonld-tsx-component-759-lines-into-se", + "state": "planning", + "subtasks": { + "completed": 0, + "total": 0, + "in_progress": 1, + "failed": 0 + }, + "phase": { + "current": "Add New Schema Files", + "id": null, + "total": 14 + }, + "workers": { + "active": 0, + "max": 1 + }, + "session": { + "number": 2, + "started_at": "2026-01-25T06:23:19.101802" + }, + "last_update": "2026-01-25T06:28:11.697923" +} \ No newline at end of file diff --git a/.claude_settings.json b/.claude_settings.json new file mode 100644 index 0000000..a6f4d43 --- /dev/null +++ b/.claude_settings.json @@ -0,0 +1,39 @@ +{ + "sandbox": { + "enabled": true, + "autoAllowBashIfSandboxed": true + }, + "permissions": { + "defaultMode": "acceptEdits", + "allow": [ + "Read(./**)", + "Write(./**)", + "Edit(./**)", + "Glob(./**)", + "Grep(./**)", + "Read(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Write(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Edit(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Glob(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Grep(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Read(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se\\.auto-claude\\specs\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Write(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se\\.auto-claude\\specs\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Edit(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude\\worktrees\\tasks\\032-split-large-jsonld-tsx-component-759-lines-into-se\\.auto-claude\\specs\\032-split-large-jsonld-tsx-component-759-lines-into-se/**)", + "Read(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude/**)", + "Write(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude/**)", + "Edit(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude/**)", + "Glob(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude/**)", + "Grep(C:\\Users\\damja\\WebstormProjects\\Portfolio\\.auto-claude/**)", + "Bash(*)", + "WebFetch(*)", + "WebSearch(*)", + "mcp__context7__resolve-library-id(*)", + "mcp__context7__get-library-docs(*)", + "mcp__graphiti-memory__search_nodes(*)", + "mcp__graphiti-memory__search_facts(*)", + "mcp__graphiti-memory__add_episode(*)", + "mcp__graphiti-memory__get_episodes(*)", + "mcp__graphiti-memory__get_entity_edge(*)" + ] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index a484ab2..fa65296 100644 --- a/.gitignore +++ b/.gitignore @@ -81,4 +81,7 @@ supabase/.temp/ .history/ # Source images (originals before optimization) -source-images/ \ No newline at end of file +source-images/ + +# Auto Claude data directory +.auto-claude/ diff --git a/context.json b/context.json new file mode 100644 index 0000000..a4607ec --- /dev/null +++ b/context.json @@ -0,0 +1,74 @@ +{ + "files_to_modify": { + "frontend": [ + "src/components/seo/JsonLd.tsx", + "src/components/seo/index.ts" + ] + }, + "files_to_create": { + "frontend": [ + "src/components/seo/schemas/PersonJsonLd.tsx", + "src/components/seo/schemas/ProfessionalServiceJsonLd.tsx", + "src/components/seo/schemas/BreadcrumbJsonLd.tsx", + "src/components/seo/schemas/WebPageJsonLd.tsx", + "src/components/seo/schemas/FAQJsonLd.tsx", + "src/components/seo/schemas/ServiceJsonLd.tsx", + "src/components/seo/schemas/OrganizationJsonLd.tsx", + "src/components/seo/schemas/ArticleJsonLd.tsx", + "src/components/seo/schemas/HowToJsonLd.tsx", + "src/components/seo/schemas/ProfilePageJsonLd.tsx", + "src/components/seo/schemas/VideoJsonLd.tsx", + "src/components/seo/schemas/SoftwareAppJsonLd.tsx", + "src/components/seo/schemas/WebSiteJsonLd.tsx", + "src/components/seo/schemas/index.ts" + ] + }, + "files_to_reference": [ + "src/components/about/index.ts", + "src/components/layout/index.ts", + "src/components/portfolio/index.ts" + ], + "patterns": { + "component_organization": "Each component type gets its own directory with multiple component files and a barrel export index.ts", + "barrel_export": "index.ts re-exports all components from the directory using named exports", + "import_paths": "Imports use path alias @/components/... for cleaner imports", + "typescript": "All components use TypeScript with proper interface definitions" + }, + "existing_implementations": { + "description": "Found 14 JSON-LD schema components in a single 758-line file at src/components/seo/JsonLd.tsx", + "relevant_files": [ + "src/components/seo/JsonLd.tsx", + "src/components/seo/index.ts", + "src/app/[locale]/layout.tsx (imports PersonJsonLd, ProfessionalServiceJsonLd, OrganizationJsonLd, WebSiteJsonLd)", + "src/app/[locale]/about/page.tsx (imports ProfilePageJsonLd, BreadcrumbJsonLd)", + "src/app/[locale]/blog/[slug]/page.tsx (imports BreadcrumbJsonLd, ArticleJsonLd)", + "src/app/[locale]/leistungen/page.tsx (imports BreadcrumbJsonLd, FAQJsonLd)" + ], + "components_to_split": [ + "PersonJsonLd", + "ProfessionalServiceJsonLd", + "BreadcrumbJsonLd", + "WebPageJsonLd", + "FAQJsonLd", + "ServiceJsonLd", + "OrganizationJsonLd", + "ArticleJsonLd", + "HowToJsonLd", + "ProfilePageJsonLd", + "VideoJsonLd", + "SoftwareAppJsonLd", + "WebSiteJsonLd" + ], + "usage_locations": [ + "src/app/[locale]/layout.tsx", + "src/app/[locale]/about/page.tsx", + "src/app/[locale]/blog/page.tsx", + "src/app/[locale]/blog/[slug]/page.tsx", + "src/app/[locale]/contact/page.tsx", + "src/app/[locale]/leistungen/page.tsx", + "src/app/[locale]/leistungen/[slug]/page.tsx", + "src/app/[locale]/leistungen/standort/[city]/page.tsx", + "src/app/[locale]/portfolio/[slug]/page.tsx" + ] + } +} diff --git a/project_index.json b/project_index.json new file mode 100644 index 0000000..fe6dec7 --- /dev/null +++ b/project_index.json @@ -0,0 +1,27 @@ +{ + "project_type": "single", + "services": { + "frontend": { + "path": ".", + "tech_stack": ["typescript", "react", "nextjs", "tailwindcss"], + "framework": "Next.js 15 (App Router)", + "port": 3000, + "dev_command": "npm run dev", + "build_command": "npm run build", + "test_command": "npm test" + } + }, + "infrastructure": { + "docker": false, + "database": null, + "ci_cd": false + }, + "conventions": { + "linter": "eslint", + "formatter": "prettier", + "testing": "vitest", + "component_pattern": "Each component directory contains multiple .tsx files with a barrel export index.ts", + "import_pattern": "Path aliases using @/ for src directory", + "export_pattern": "index.ts re-exports components using export { ComponentName } or export { default as ComponentName }" + } +} diff --git a/src/components/seo/schemas/PersonJsonLd.tsx b/src/components/seo/schemas/PersonJsonLd.tsx new file mode 100644 index 0000000..9cd9aba --- /dev/null +++ b/src/components/seo/schemas/PersonJsonLd.tsx @@ -0,0 +1,80 @@ +import { type Locale } from '@/i18n/config'; + +interface JsonLdProps { + locale: Locale; +} + +export function PersonJsonLd({ locale }: JsonLdProps) { + const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com'; + + const schema = { + '@context': 'https://schema.org', + '@type': 'Person', + '@id': `${baseUrl}/#person`, + name: 'Damjan Savić', + givenName: 'Damjan', + familyName: 'Savić', + jobTitle: locale === 'de' + ? 'AI & Automation Specialist | Fullstack Entwickler' + : locale === 'sr' + ? 'AI & Automation Specialist | Fullstack Developer' + : 'AI & Automation Specialist | Fullstack Developer', + description: locale === 'de' + ? 'Entwicklung von KI-Agenten und Automatisierungslösungen. Von Voice-AI-Plattformen bis zu autonomen Web-Agenten.' + : locale === 'sr' + ? 'Razvoj AI agenata i rešenja za automatizaciju. Od voice AI platformi do autonomnih web agenata.' + : 'Remote AI developer building AI agents and automation solutions for clients in USA, UK and Europe. From voice AI platforms to autonomous web agents.', + url: baseUrl, + image: `${baseUrl}/images/og-image.jpg`, + email: 'info@damjan-savic.com', + telephone: '+491756950979', + address: { + '@type': 'PostalAddress', + addressLocality: locale === 'sr' ? 'Keln' : locale === 'en' ? 'Cologne' : 'Köln', + addressRegion: 'NRW', + addressCountry: 'DE', + }, + sameAs: [ + 'https://www.linkedin.com/in/damjansavic/', + 'https://github.com/damjansavic', + ], + knowsAbout: [ + 'Artificial Intelligence', + 'Machine Learning', + 'Process Automation', + 'Voice AI', + 'Web Development', + 'Python', + 'TypeScript', + 'React', + 'Next.js', + 'n8n', + 'SaaS Development', + ], + alumniOf: [ + { + '@type': 'EducationalOrganization', + name: 'FOM Hochschule für Ökonomie & Management', + }, + ], + hasCredential: [ + { + '@type': 'EducationalOccupationalCredential', + name: 'M.A. Software Development', + credentialCategory: 'degree', + }, + { + '@type': 'EducationalOccupationalCredential', + name: 'B.Sc. Wirtschaftsinformatik', + credentialCategory: 'degree', + }, + ], + }; + + return ( +