Architektur-Analyse und Korrektur-Konzept
- Umfassende Analyse der aktuellen Implementierung durchgeführt - Identifiziert: Zwei getrennte User-Systeme (users vs gateway_users) - Problem: API verwendet falsche Tabelle (users statt gateway_users) - Lösung: Kompletter Implementierungsplan für korrekte Architektur - Dokument: ARCHITEKTUR.md mit 6-Tage-Umsetzungsplan erstellt - Enthält: Custom API-Key Guard, Gateway-User-Credentials, Budget-System - Swagger/Scramble Paket hinzugefügt (für spätere API-Dokumentation) Status: Bereit für Implementierung (Start: Tag 1 - Datenbank & Models)
This commit is contained in:
@@ -16,8 +16,18 @@ class ChatCompletionController extends Controller
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Handle chat completion request
|
||||
*
|
||||
* Create a chat completion
|
||||
*
|
||||
* Accepts OpenAI-compatible chat completion requests and routes them to the appropriate
|
||||
* LLM provider (OpenAI, Anthropic, DeepSeek, Google Gemini, or Mistral AI).
|
||||
*
|
||||
* The request uses the authenticated user's API keys for the specified provider.
|
||||
* Cost tracking, budget checking, and rate limiting are applied automatically.
|
||||
*
|
||||
* Returns an OpenAI-compatible response with usage statistics and cost information.
|
||||
*
|
||||
* @tags Chat
|
||||
*
|
||||
* @param ChatCompletionRequest $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"dedoc/scramble": "^0.13.4",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"livewire/livewire": "^3.6.4",
|
||||
|
||||
310
laravel-app/composer.lock
generated
310
laravel-app/composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "48bc009539e7af0a89770c8e30f8e9a3",
|
||||
"content-hash": "f90d326460fd22f5fbd0e5a7a7456c1a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@@ -135,6 +135,86 @@
|
||||
],
|
||||
"time": "2024-02-09T16:56:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dedoc/scramble",
|
||||
"version": "v0.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dedoc/scramble.git",
|
||||
"reference": "773f9d41b68a9bd52120648e55068bfbe9be567e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dedoc/scramble/zipball/773f9d41b68a9bd52120648e55068bfbe9be567e",
|
||||
"reference": "773f9d41b68a9bd52120648e55068bfbe9be567e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^10.0|^11.0|^12.0",
|
||||
"myclabs/deep-copy": "^1.12",
|
||||
"nikic/php-parser": "^5.0",
|
||||
"php": "^8.1",
|
||||
"phpstan/phpdoc-parser": "^1.0|^2.0",
|
||||
"spatie/laravel-package-tools": "^1.9.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"larastan/larastan": "^3.3",
|
||||
"laravel/pint": "^v1.1.0",
|
||||
"nunomaduro/collision": "^7.0|^8.0",
|
||||
"orchestra/testbench": "^8.0|^9.0|^10.0",
|
||||
"pestphp/pest": "^2.34|^3.7",
|
||||
"pestphp/pest-plugin-laravel": "^2.3|^3.1",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^10.5|^11.5.3",
|
||||
"spatie/laravel-permission": "^6.10",
|
||||
"spatie/pest-plugin-snapshots": "^2.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Dedoc\\Scramble\\ScrambleServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dedoc\\Scramble\\": "src",
|
||||
"Dedoc\\Scramble\\Database\\Factories\\": "database/factories"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Lytvynenko",
|
||||
"email": "litvinenko95@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Automatic generation of API documentation for Laravel applications.",
|
||||
"homepage": "https://github.com/dedoc/scramble",
|
||||
"keywords": [
|
||||
"documentation",
|
||||
"laravel",
|
||||
"openapi"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dedoc/scramble/issues",
|
||||
"source": "https://github.com/dedoc/scramble/tree/v0.13.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/romalytvynenko",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-16T07:10:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
@@ -2259,6 +2339,66 @@
|
||||
],
|
||||
"time": "2025-03-24T10:02:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/collections": "<1.6.8",
|
||||
"doctrine/common": "<2.13.3 || >=3 <3.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "^1.6.8",
|
||||
"doctrine/common": "^2.13.3 || ^3.2.2",
|
||||
"phpspec/prophecy": "^1.10",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/DeepCopy/deep_copy.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Create deep copies (clones) of your objects",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"copy",
|
||||
"duplicate",
|
||||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-01T08:46:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.10.3",
|
||||
@@ -2738,6 +2878,53 @@
|
||||
],
|
||||
"time": "2025-08-21T11:53:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
|
||||
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/annotations": "^2.0",
|
||||
"nikic/php-parser": "^5.3.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpstan/phpstan-strict-rules": "^2.0",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"symfony/process": "^5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPStan\\PhpDocParser\\": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
|
||||
},
|
||||
"time": "2025-08-30T15:50:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
"version": "1.0.0",
|
||||
@@ -3427,6 +3614,67 @@
|
||||
},
|
||||
"time": "2025-09-04T20:59:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-package-tools",
|
||||
"version": "1.92.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-package-tools.git",
|
||||
"reference": "f09a799850b1ed765103a4f0b4355006360c49a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5",
|
||||
"reference": "f09a799850b1ed765103a4f0b4355006360c49a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^9.28|^10.0|^11.0|^12.0",
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.5",
|
||||
"orchestra/testbench": "^7.7|^8.0|^9.0|^10.0",
|
||||
"pestphp/pest": "^1.23|^2.1|^3.1",
|
||||
"phpunit/php-code-coverage": "^9.0|^10.0|^11.0",
|
||||
"phpunit/phpunit": "^9.5.24|^10.5|^11.5",
|
||||
"spatie/pest-plugin-test-time": "^1.1|^2.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\LaravelPackageTools\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Tools for creating Laravel packages",
|
||||
"homepage": "https://github.com/spatie/laravel-package-tools",
|
||||
"keywords": [
|
||||
"laravel-package-tools",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/laravel-package-tools/issues",
|
||||
"source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-17T15:46:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.3.0",
|
||||
@@ -6668,66 +6916,6 @@
|
||||
},
|
||||
"time": "2024-05-16T03:13:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/collections": "<1.6.8",
|
||||
"doctrine/common": "<2.13.3 || >=3 <3.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "^1.6.8",
|
||||
"doctrine/common": "^2.13.3 || ^3.2.2",
|
||||
"phpspec/prophecy": "^1.10",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/DeepCopy/deep_copy.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Create deep copies (clones) of your objects",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"copy",
|
||||
"duplicate",
|
||||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-01T08:46:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v8.8.2",
|
||||
|
||||
136
laravel-app/config/scramble.php
Normal file
136
laravel-app/config/scramble.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
use Dedoc\Scramble\Http\Middleware\RestrictedDocsAccess;
|
||||
|
||||
return [
|
||||
/*
|
||||
* Your API path. By default, all routes starting with this path will be added to the docs.
|
||||
* If you need to change this behavior, you can add your custom routes resolver using `Scramble::routes()`.
|
||||
*/
|
||||
'api_path' => 'api',
|
||||
|
||||
/*
|
||||
* Your API domain. By default, app domain is used. This is also a part of the default API routes
|
||||
* matcher, so when implementing your own, make sure you use this config if needed.
|
||||
*/
|
||||
'api_domain' => null,
|
||||
|
||||
/*
|
||||
* The path where your OpenAPI specification will be exported.
|
||||
*/
|
||||
'export_path' => 'api.json',
|
||||
|
||||
'info' => [
|
||||
/*
|
||||
* API version.
|
||||
*/
|
||||
'version' => env('API_VERSION', '1.0.0'),
|
||||
|
||||
/*
|
||||
* Description rendered on the home page of the API documentation (`/docs/api`).
|
||||
*/
|
||||
'description' => '',
|
||||
],
|
||||
|
||||
/*
|
||||
* Customize Stoplight Elements UI
|
||||
*/
|
||||
'ui' => [
|
||||
/*
|
||||
* Define the title of the documentation's website. App name is used when this config is `null`.
|
||||
*/
|
||||
'title' => null,
|
||||
|
||||
/*
|
||||
* Define the theme of the documentation. Available options are `light`, `dark`, and `system`.
|
||||
*/
|
||||
'theme' => 'light',
|
||||
|
||||
/*
|
||||
* Hide the `Try It` feature. Enabled by default.
|
||||
*/
|
||||
'hide_try_it' => false,
|
||||
|
||||
/*
|
||||
* Hide the schemas in the Table of Contents. Enabled by default.
|
||||
*/
|
||||
'hide_schemas' => false,
|
||||
|
||||
/*
|
||||
* URL to an image that displays as a small square logo next to the title, above the table of contents.
|
||||
*/
|
||||
'logo' => '',
|
||||
|
||||
/*
|
||||
* Use to fetch the credential policy for the Try It feature. Options are: omit, include (default), and same-origin
|
||||
*/
|
||||
'try_it_credentials_policy' => 'include',
|
||||
|
||||
/*
|
||||
* There are three layouts for Elements:
|
||||
* - sidebar - (Elements default) Three-column design with a sidebar that can be resized.
|
||||
* - responsive - Like sidebar, except at small screen sizes it collapses the sidebar into a drawer that can be toggled open.
|
||||
* - stacked - Everything in a single column, making integrations with existing websites that have their own sidebar or other columns already.
|
||||
*/
|
||||
'layout' => 'responsive',
|
||||
],
|
||||
|
||||
/*
|
||||
* The list of servers of the API. By default, when `null`, server URL will be created from
|
||||
* `scramble.api_path` and `scramble.api_domain` config variables. When providing an array, you
|
||||
* will need to specify the local server URL manually (if needed).
|
||||
*
|
||||
* Example of non-default config (final URLs are generated using Laravel `url` helper):
|
||||
*
|
||||
* ```php
|
||||
* 'servers' => [
|
||||
* 'Live' => 'api',
|
||||
* 'Prod' => 'https://scramble.dedoc.co/api',
|
||||
* ],
|
||||
* ```
|
||||
*/
|
||||
'servers' => null,
|
||||
|
||||
/**
|
||||
* Determines how Scramble stores the descriptions of enum cases.
|
||||
* Available options:
|
||||
* - 'description' – Case descriptions are stored as the enum schema's description using table formatting.
|
||||
* - 'extension' – Case descriptions are stored in the `x-enumDescriptions` enum schema extension.
|
||||
*
|
||||
* @see https://redocly.com/docs-legacy/api-reference-docs/specification-extensions/x-enum-descriptions
|
||||
* - false - Case descriptions are ignored.
|
||||
*/
|
||||
'enum_cases_description_strategy' => 'description',
|
||||
|
||||
/**
|
||||
* Determines how Scramble stores the names of enum cases.
|
||||
* Available options:
|
||||
* - 'names' – Case names are stored in the `x-enumNames` enum schema extension.
|
||||
* - 'varnames' - Case names are stored in the `x-enum-varnames` enum schema extension.
|
||||
* - false - Case names are not stored.
|
||||
*/
|
||||
'enum_cases_names_strategy' => false,
|
||||
|
||||
/**
|
||||
* When Scramble encounters deep objects in query parameters, it flattens the parameters so the generated
|
||||
* OpenAPI document correctly describes the API. Flattening deep query parameters is relevant until
|
||||
* OpenAPI 3.2 is released and query string structure can be described properly.
|
||||
*
|
||||
* For example, this nested validation rule describes the object with `bar` property:
|
||||
* `['foo.bar' => ['required', 'int']]`.
|
||||
*
|
||||
* When `flatten_deep_query_parameters` is `true`, Scramble will document the parameter like so:
|
||||
* `{"name":"foo[bar]", "schema":{"type":"int"}, "required":true}`.
|
||||
*
|
||||
* When `flatten_deep_query_parameters` is `false`, Scramble will document the parameter like so:
|
||||
* `{"name":"foo", "schema": {"type":"object", "properties":{"bar":{"type": "int"}}, "required": ["bar"]}, "required":true}`.
|
||||
*/
|
||||
'flatten_deep_query_parameters' => true,
|
||||
|
||||
'middleware' => [
|
||||
'web',
|
||||
RestrictedDocsAccess::class,
|
||||
],
|
||||
|
||||
'extensions' => [],
|
||||
];
|
||||
Reference in New Issue
Block a user