Commit graph

8 commits

Author SHA1 Message Date
693e458e07 feat: photo gallery on article detail with upload, sort and set-main
- Add secured GET /admin/photos/{filename} to serve files from var/uploads/
- Add POST /api/articles/{id}/photos/sort for drag-and-drop reordering
- Add PhotoService::reorder() to persist new sort positions
- Add photo gallery field (onlyOnDetail) using custom Twig template:
  - Drag-and-drop reorder via SortableJS CDN
  - Click or drop to upload new photos
  - Set main (★) and delete per photo
  - Main photo highlighted with blue border + badge
- Add field.photos translation key (EN/DE)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 09:10:59 +00:00
cfb5cc4ad0 feat: replace Mistral web_search with Tavily for specs research
- Add WebSearchInterface + TavilyWebSearch (POST /search, max 5 results)
- SpecsResearchAgent now fetches search results first, injects them as
  {{searchResults}} context into the prompt, then calls plain generate()
  — no dependency on model-specific web_search tool support
- Update specs_research prompt template (PHP default + DB migration) to
  use the new {{searchResults}} variable
- Wire TAVILY_API_KEY env var; register TavilyWebSearch in services.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 08:35:52 +00:00
ec159d7b3a feat: DB-backed translations editable in admin
- Add Translation entity (locale/domain/key/value, unique on all three)
- Add TranslationRepositoryInterface + DoctrineTranslationRepository
- Add DatabaseTranslator decorator (#[AsDecorator]) that checks DB first
  and falls back to YAML files; clears per-request cache on setLocale()
- Add TranslationCrudController with locale/domain filters and read-only
  key/locale/domain on edit to prevent accidental renames
- Add "Übersetzungen / Translations" menu entry in DashboardController
- Migration 20260520000000: create app.translations table
- Migration 20260520010000: seed from admin.en.yaml + admin.de.yaml (204 rows)
- Flatten admin.de.yaml to dot-notation; add new keys for translation CRUD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 07:53:52 +00:00
49e36a0a06 feat: editable AI prompt templates and articleType context in specs research
All agent prompts are now stored in app.prompt_templates (migration 20260519000000)
and editable by admins via the new AI Prompts CRUD page. If no DB entry exists
for a key the hardcoded default is used automatically as fallback.

PromptTemplateService renders templates with {{variable}} substitution.
All four agents (SpecsResearch, JsonCoding, EbayText, OllamaVision) use the service.

SpecsResearchAgent now receives the articleType name (e.g. "Laptop") so the
specs prompt is scoped to the correct device category instead of being generic.
SpecsResearchHandler loads the ArticleType from the repository for this purpose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 07:19:02 +00:00
d51efa057b feat: add MistralClient as switchable alternative to OllamaClient
Implements OllamaClientInterface against the Mistral Cloud API
(/v1/chat/completions). Switch by toggling the alias in services.yaml
and pointing AI_TEXT_MODEL / AI_VISION_MODEL env vars at the MISTRAL_*
or OLLAMA_* counterparts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 16:03:16 +00:00
6bf001b0c0 feat: implement Plan 2 — Article Management API
- 6 new domain repository interfaces (StoragePath, ArticlePhoto, AttributeValue, ChannelField, ArticleTypePlatformConfig, AttributeMapping)
- 6 Doctrine repository implementations
- StorageManager with multi-path quota-aware file storage (LocalStorageManager)
- Application services: ArticleTypeService, ArticleService, ArticleValidator, PhotoService, PlatformService, MappingService
- REST controllers: ArticleType, Article, Photo, Platform, Mapping (all under /api prefix)
- inventory_number sequence migration
- 22 unit tests passing, PHPStan level 9 clean, CS Fixer clean
- Fixed phpdoc_to_comment CS Fixer rule (disabled) to preserve @var type annotations
- Fixed PHPStan: User::getUserIdentifier non-empty-string, AIPipelineJob nullable missingFields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:19:20 +00:00
a9c377789e feat: add Doctrine repository implementations and wire interfaces in services.yaml 2026-05-14 04:31:33 +00:00
e249c3d80f feat: install Symfony 7 skeleton with Doctrine, Messenger, UID, Security 2026-05-14 04:21:34 +00:00