add new guide service
This commit is contained in:
@@ -153,9 +153,6 @@ Sehr sauber:
|
||||
- reload steuerbar
|
||||
- PID-Handling robust
|
||||
|
||||
Empfehlung:
|
||||
Health-Check Endpoint ergänzen.
|
||||
|
||||
---
|
||||
|
||||
# 7. Tag-System
|
||||
@@ -280,9 +277,8 @@ Sehr gut umgesetzt.
|
||||
# 14. Identifizierte Schwachstellen
|
||||
|
||||
1. Vollständiger FAISS-Rebuild bei jedem Ingest
|
||||
2. Kein Vector-Service Health-Endpoint
|
||||
3. Keine automatische Index-Korruptionsprüfung
|
||||
4. Kein Backpressure bei mehreren Ingest-Jobs
|
||||
2. Keine automatische Index-Korruptionsprüfung
|
||||
3. Kein Backpressure bei mehreren Ingest-Jobs
|
||||
|
||||
Keine strukturelle Schwäche.
|
||||
|
||||
@@ -297,7 +293,6 @@ Keine strukturelle Schwäche.
|
||||
- ChunkWriteService
|
||||
- VectorRebuildService
|
||||
|
||||
- Health-Endpoint im Vector-Service
|
||||
- Timeout-Absicherung beim Reload
|
||||
|
||||
## Phase C
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"doctrine/doctrine-bundle": "^2.18",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.7",
|
||||
"doctrine/orm": "^3.6",
|
||||
"league/commonmark": "^2.8",
|
||||
"smalot/pdfparser": "^2.12",
|
||||
"symfony/asset": "7.4.*",
|
||||
"symfony/console": "^7.4",
|
||||
"symfony/dotenv": "^7.4",
|
||||
"symfony/flex": "^2",
|
||||
|
||||
581
composer.lock
generated
581
composer.lock
generated
@@ -4,8 +4,83 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ffc8b627f07f3eb413d757a4d80af3f2",
|
||||
"content-hash": "bf516574b65f7c2abdc053c964f769aa",
|
||||
"packages": [
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
|
||||
"reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f",
|
||||
"reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.42",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
|
||||
"scrutinizer/ocular": "1.6.0",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"vimeo/psalm": "^4.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dflydev\\DotAccessData\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dragonfly Development Inc.",
|
||||
"email": "info@dflydev.com",
|
||||
"homepage": "http://dflydev.com"
|
||||
},
|
||||
{
|
||||
"name": "Beau Simensen",
|
||||
"email": "beau@dflydev.com",
|
||||
"homepage": "http://beausimensen.com"
|
||||
},
|
||||
{
|
||||
"name": "Carlos Frutos",
|
||||
"email": "carlos@kiwing.it",
|
||||
"homepage": "https://github.com/cfrutos"
|
||||
},
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com"
|
||||
}
|
||||
],
|
||||
"description": "Given a deep data structure, access data by dot notation.",
|
||||
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
|
||||
"keywords": [
|
||||
"access",
|
||||
"data",
|
||||
"dot",
|
||||
"notation"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
|
||||
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3"
|
||||
},
|
||||
"time": "2024-07-08T12:26:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
"version": "2.6.0",
|
||||
@@ -1119,6 +1194,195 @@
|
||||
},
|
||||
"time": "2026-02-08T16:21:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
|
||||
"reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"league/config": "^1.1.1",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.1 || ^3.0",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"cebe/markdown": "^1.0",
|
||||
"commonmark/cmark": "0.31.1",
|
||||
"commonmark/commonmark.js": "0.31.1",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"embed/embed": "^4.4",
|
||||
"erusev/parsedown": "^1.0",
|
||||
"ext-json": "*",
|
||||
"github/gfm": "0.29.0",
|
||||
"michelf/php-markdown": "^1.4 || ^2.0",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"phpstan/phpstan": "^1.8.2",
|
||||
"phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
|
||||
"scrutinizer/ocular": "^1.8.1",
|
||||
"symfony/finder": "^5.3 | ^6.0 | ^7.0",
|
||||
"symfony/process": "^5.4 | ^6.0 | ^7.0",
|
||||
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0",
|
||||
"unleashedtech/php-coding-standard": "^3.1.1",
|
||||
"vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\CommonMark\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
|
||||
"homepage": "https://commonmark.thephpleague.com",
|
||||
"keywords": [
|
||||
"commonmark",
|
||||
"flavored",
|
||||
"gfm",
|
||||
"github",
|
||||
"github-flavored",
|
||||
"markdown",
|
||||
"md",
|
||||
"parser"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://commonmark.thephpleague.com/",
|
||||
"forum": "https://github.com/thephpleague/commonmark/discussions",
|
||||
"issues": "https://github.com/thephpleague/commonmark/issues",
|
||||
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
|
||||
"source": "https://github.com/thephpleague/commonmark"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.colinodell.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.paypal.me/colinpodell/10.00",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/colinodell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-26T21:48:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/config",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/config.git",
|
||||
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
|
||||
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dflydev/dot-access-data": "^3.0.1",
|
||||
"nette/schema": "^1.2",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.8.2",
|
||||
"phpunit/phpunit": "^9.5.5",
|
||||
"scrutinizer/ocular": "^1.8.1",
|
||||
"unleashedtech/php-coding-standard": "^3.1",
|
||||
"vimeo/psalm": "^4.7.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Config\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Define configuration arrays with strict schemas and access values with dot notation",
|
||||
"homepage": "https://config.thephpleague.com",
|
||||
"keywords": [
|
||||
"array",
|
||||
"config",
|
||||
"configuration",
|
||||
"dot",
|
||||
"dot-access",
|
||||
"nested",
|
||||
"schema"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://config.thephpleague.com/",
|
||||
"issues": "https://github.com/thephpleague/config/issues",
|
||||
"rss": "https://github.com/thephpleague/config/releases.atom",
|
||||
"source": "https://github.com/thephpleague/config"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.colinodell.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.paypal.me/colinpodell/10.00",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/colinodell",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-11T20:36:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.10.0",
|
||||
@@ -1222,6 +1486,164 @@
|
||||
],
|
||||
"time": "2026-01-02T08:56:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/schema.git",
|
||||
"reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002",
|
||||
"reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nette/utils": "^4.0",
|
||||
"php": "8.1 - 8.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/phpstan-rules": "^1.0",
|
||||
"nette/tester": "^2.6",
|
||||
"phpstan/extension-installer": "^1.4@stable",
|
||||
"phpstan/phpstan": "^2.1.39@stable",
|
||||
"tracy/tracy": "^2.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nette\\": "src"
|
||||
},
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause",
|
||||
"GPL-2.0-only",
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Grudl",
|
||||
"homepage": "https://davidgrudl.com"
|
||||
},
|
||||
{
|
||||
"name": "Nette Community",
|
||||
"homepage": "https://nette.org/contributors"
|
||||
}
|
||||
],
|
||||
"description": "📐 Nette Schema: validating data structures against a given Schema.",
|
||||
"homepage": "https://nette.org",
|
||||
"keywords": [
|
||||
"config",
|
||||
"nette"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/schema/issues",
|
||||
"source": "https://github.com/nette/schema/tree/v1.3.5"
|
||||
},
|
||||
"time": "2026-02-23T03:47:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
"version": "v4.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/utils.git",
|
||||
"reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe",
|
||||
"reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "8.2 - 8.5"
|
||||
},
|
||||
"conflict": {
|
||||
"nette/finder": "<3",
|
||||
"nette/schema": "<1.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"jetbrains/phpstorm-attributes": "^1.2",
|
||||
"nette/phpstan-rules": "^1.0",
|
||||
"nette/tester": "^2.5",
|
||||
"phpstan/extension-installer": "^1.4@stable",
|
||||
"phpstan/phpstan": "^2.1@stable",
|
||||
"tracy/tracy": "^2.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "to use Image",
|
||||
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
|
||||
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
|
||||
"ext-json": "to use Nette\\Utils\\Json",
|
||||
"ext-mbstring": "to use Strings::lower() etc...",
|
||||
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nette\\": "src"
|
||||
},
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause",
|
||||
"GPL-2.0-only",
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Grudl",
|
||||
"homepage": "https://davidgrudl.com"
|
||||
},
|
||||
{
|
||||
"name": "Nette Community",
|
||||
"homepage": "https://nette.org/contributors"
|
||||
}
|
||||
],
|
||||
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
|
||||
"homepage": "https://nette.org",
|
||||
"keywords": [
|
||||
"array",
|
||||
"core",
|
||||
"datetime",
|
||||
"images",
|
||||
"json",
|
||||
"nette",
|
||||
"paginator",
|
||||
"password",
|
||||
"slugify",
|
||||
"string",
|
||||
"unicode",
|
||||
"utf-8",
|
||||
"utility",
|
||||
"validation"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/utils/issues",
|
||||
"source": "https://github.com/nette/utils/tree/v4.1.3"
|
||||
},
|
||||
"time": "2026-02-13T03:05:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
"version": "3.0.0",
|
||||
@@ -1523,6 +1945,79 @@
|
||||
},
|
||||
"time": "2026-01-08T08:04:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/asset",
|
||||
"version": "v7.4.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/asset.git",
|
||||
"reference": "d944ae87e4697af05aadeacfc5e603c3c18ef4fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/asset/zipball/d944ae87e4697af05aadeacfc5e603c3c18ef4fb",
|
||||
"reference": "d944ae87e4697af05aadeacfc5e603c3c18ef4fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/http-foundation": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-client": "^6.4|^7.0|^8.0",
|
||||
"symfony/http-foundation": "^6.4|^7.0|^8.0",
|
||||
"symfony/http-kernel": "^6.4|^7.0|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Asset\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/asset/tree/v7.4.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-09T09:33:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v7.4.3",
|
||||
@@ -3959,6 +4454,90 @@
|
||||
],
|
||||
"time": "2024-12-23T08:48:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||
"reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-02T08:10:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.33.0",
|
||||
|
||||
@@ -264,7 +264,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* formats?: array<string, string|list<scalar|null|Param>>,
|
||||
* },
|
||||
* assets?: bool|array{ // Assets configuration
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* enabled?: bool|Param, // Default: true
|
||||
* strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false
|
||||
* version_strategy?: scalar|null|Param, // Default: null
|
||||
* version?: scalar|null|Param, // Default: null
|
||||
|
||||
162
public/assets/styles/admin-markdown.css
Normal file
162
public/assets/styles/admin-markdown.css
Normal file
@@ -0,0 +1,162 @@
|
||||
/* =========================================================
|
||||
Markdown Guide Styling (Admin Dark)
|
||||
========================================================= */
|
||||
|
||||
.markdown-content {
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Headings
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content h1,
|
||||
.markdown-content h2,
|
||||
.markdown-content h3,
|
||||
.markdown-content h4 {
|
||||
font-weight: 600;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.markdown-content h1 {
|
||||
font-size: 1.8rem;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.markdown-content h2 {
|
||||
font-size: 1.4rem;
|
||||
border-bottom: 1px solid #222;
|
||||
padding-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.markdown-content h3 {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Paragraphs
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Lists
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content ul,
|
||||
.markdown-content ol {
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.markdown-content li {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Links
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content a {
|
||||
color: #0dcaf0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-content a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Inline Code
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content code {
|
||||
background: #1e1e1e;
|
||||
color: #ffc107;
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Code Blocks
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content pre {
|
||||
background: #111;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
border: 1px solid #222;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.markdown-content pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Tables
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.markdown-content th {
|
||||
background: #1a1a1a;
|
||||
border: 1px solid #333;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-content td {
|
||||
border: 1px solid #333;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.markdown-content tr:nth-child(even) {
|
||||
background: #141414;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Blockquotes
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content blockquote {
|
||||
border-left: 4px solid #0dcaf0;
|
||||
padding-left: 1rem;
|
||||
margin: 1rem 0;
|
||||
color: #cfcfcf;
|
||||
background: #151515;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------
|
||||
Horizontal Rule
|
||||
--------------------------------------------------------- */
|
||||
|
||||
.markdown-content hr {
|
||||
border: none;
|
||||
border-top: 1px solid #333;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.guide-item:hover {
|
||||
background-color: #151515 !important;
|
||||
}
|
||||
|
||||
.guide-item .fw-semibold {
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
@@ -233,4 +233,44 @@ button:disabled {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Admin Dark Base Fix
|
||||
========================================================= */
|
||||
|
||||
body {
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
.card.bg-black,
|
||||
.card.bg-dark {
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
.list-group-item.bg-black,
|
||||
.list-group-item.bg-dark {
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
.list-group-item.bg-black a,
|
||||
.list-group-item.bg-dark a {
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #9aa0a6 !important;
|
||||
}
|
||||
|
||||
.guide-item {
|
||||
color: #e2e2e2 !important;
|
||||
}
|
||||
|
||||
.guide-item small {
|
||||
color: #9aa0a6 !important;
|
||||
}
|
||||
|
||||
.card.bg-black .card-body
|
||||
{
|
||||
color: #e2e2e2 !important;
|
||||
}
|
||||
109
src/Controller/Admin/GuideController.php
Normal file
109
src/Controller/Admin/GuideController.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Service\MarkdownRenderer;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
#[Route('/admin/guides')]
|
||||
final class GuideController extends AbstractController
|
||||
{
|
||||
private string $guidePath;
|
||||
|
||||
public function __construct(ParameterBagInterface $params)
|
||||
{
|
||||
$this->guidePath = rtrim(
|
||||
$params->get('kernel.project_dir'),
|
||||
'/'
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('', name: 'admin_guides_index')]
|
||||
public function index(): Response
|
||||
{
|
||||
if (!is_dir($this->guidePath)) {
|
||||
return $this->render('admin/guides/index.html.twig', [
|
||||
'guides' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
$files = glob($this->guidePath . '/*.md') ?: [];
|
||||
|
||||
$guides = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$slug = basename($file, '.md');
|
||||
|
||||
if (!$this->isValidSlug($slug)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$content = file_get_contents($file) ?: '';
|
||||
|
||||
$title = $this->extractTitleFromMarkdown($content)
|
||||
?? $this->humanizeSlug($slug);
|
||||
|
||||
$guides[] = [
|
||||
'slug' => $slug,
|
||||
'title' => $title,
|
||||
];
|
||||
}
|
||||
|
||||
usort($guides, fn ($a, $b) => strcasecmp($a['title'], $b['title']));
|
||||
|
||||
return $this->render('admin/guides/index.html.twig', [
|
||||
'guides' => $guides,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{slug}', name: 'admin_guides_view')]
|
||||
public function view(string $slug, MarkdownRenderer $renderer): Response
|
||||
{
|
||||
if (!$this->isValidSlug($slug)) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$file = $this->guidePath . '/' . $slug . '.md';
|
||||
|
||||
if (!is_file($file)) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$content = file_get_contents($file) ?: '';
|
||||
|
||||
return $this->render('admin/guides/view.html.twig', [
|
||||
'slug' => $slug,
|
||||
'title' => $this->extractTitleFromMarkdown($content)
|
||||
?? $this->humanizeSlug($slug),
|
||||
'html' => $renderer->render($content),
|
||||
]);
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Helper
|
||||
// =========================================================
|
||||
|
||||
private function extractTitleFromMarkdown(string $content): ?string
|
||||
{
|
||||
if (preg_match('/^#\s+(.+)$/m', $content, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function humanizeSlug(string $slug): string
|
||||
{
|
||||
return ucfirst(str_replace('-', ' ', $slug));
|
||||
}
|
||||
|
||||
private function isValidSlug(string $slug): bool
|
||||
{
|
||||
return (bool) preg_match('/^[a-zA-Z0-9\-_]+$/', $slug);
|
||||
}
|
||||
}
|
||||
38
src/Service/MarkdownRenderer.php
Normal file
38
src/Service/MarkdownRenderer.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use League\CommonMark\MarkdownConverter;
|
||||
use League\CommonMark\Environment\Environment;
|
||||
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
||||
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
|
||||
|
||||
final class MarkdownRenderer
|
||||
{
|
||||
private MarkdownConverter $converter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'html_input' => 'strip',
|
||||
'allow_unsafe_links' => false,
|
||||
];
|
||||
|
||||
$environment = new Environment($config);
|
||||
|
||||
// Core Markdown
|
||||
$environment->addExtension(new CommonMarkCoreExtension());
|
||||
|
||||
// GitHub Flavored Markdown (Tables, Strikethrough, Autolinks, Task Lists)
|
||||
$environment->addExtension(new GithubFlavoredMarkdownExtension());
|
||||
|
||||
$this->converter = new MarkdownConverter($environment);
|
||||
}
|
||||
|
||||
public function render(string $markdown): string
|
||||
{
|
||||
return (string) $this->converter->convert($markdown);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,11 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}Admin{% endblock %}</title>
|
||||
|
||||
<link href="/assets/styles/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link rel="stylesheet" href="/assets/styles/base.css">
|
||||
{% block stylesheets %}
|
||||
<link href="/assets/styles/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link rel="stylesheet" href="/assets/styles/base.css">
|
||||
<link rel="stylesheet" href="{{ asset('/assets/styles/admin-markdown.css') }}">
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="bg-dark text-light">
|
||||
@@ -111,6 +113,15 @@
|
||||
href="{{ path('admin_model_config_list') }}">
|
||||
Modell-Generierung
|
||||
</a>
|
||||
<hr class="border-secondary">
|
||||
<div class="text-info text-uppercase small mb-2">
|
||||
System-Guiide
|
||||
</div>
|
||||
|
||||
<a class="nav-link text-light {% if route starts with 'admin_model_config' %}active fw-bold{% endif %}"
|
||||
href="{{ path('admin_guides_index') }}">
|
||||
How-To & Leitfäden
|
||||
</a>
|
||||
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
54
templates/admin/guides/index.html.twig
Normal file
54
templates/admin/guides/index.html.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
{% extends 'admin/base.html.twig' %}
|
||||
|
||||
{% block title %}Guides{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 text-light">
|
||||
<div>
|
||||
<h1 class="h3 mb-0">How-To & Leitfäden</h1>
|
||||
<small class="text-muted">
|
||||
{{ guides|length }} Guide{{ guides|length == 1 ? '' : 's' }} verfügbar
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-black border-secondary shadow-sm text-light">
|
||||
<div class="card-body p-0">
|
||||
|
||||
{% if guides is empty %}
|
||||
<div class="p-4 text-center text-light">
|
||||
Keine Guides vorhanden.
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
<div class="list-group list-group-flush">
|
||||
{% for guide in guides %}
|
||||
<a href="{{ path('admin_guides_view', {slug: guide.slug}) }}"
|
||||
class="list-group-item list-group-item-action bg-black border-secondary guide-item">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fw-semibold text-light">
|
||||
{{ guide.title }}
|
||||
</div>
|
||||
<small class="text-light">
|
||||
{{ guide.slug }}
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<span class="text-muted small">
|
||||
→
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
15
templates/admin/guides/view.html.twig
Normal file
15
templates/admin/guides/view.html.twig
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends 'admin/base.html.twig' %}
|
||||
|
||||
{% block title %}Guide{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<a href="{{ path('admin_guides_index') }}" class="btn btn-sm btn-outline-secondary mb-3">
|
||||
← Zurück
|
||||
</a>
|
||||
|
||||
<div class="card bg-black border-secondary">
|
||||
<div class="card-body markdown-content">
|
||||
{{ html|raw }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user