MFR Controllers & Resources
app/Http/Controllers/Mfr/
Pro MFR-Entity gibt es einen Resource-Controller mit den Standard-Methoden index, show, store, update, destroy. Alle haben dasselbe Grundmuster — _ResourceController.php ist die Schablone.
Vorhandene Controller
| Controller | Endpoint-Prefix | Modell | Resource |
|---|---|---|---|
CompanyController | /v1/mfr/companies | Common\Mfr\Companies | CompanyResource |
ContactController | /v1/mfr/contacts | Common\Mfr\Contacts | ContactResource |
CostCenterController | /v1/mfr/costCenters | Common\Mfr\CostCenters | CostCenterResource |
DocumentController | /v1/mfr/documents | Common\Mfr\Documents | DocumentResource |
ItemController | /v1/mfr/items | Common\Mfr\Items | ItemResource |
ItemTypeController | /v1/mfr/itemTypes | Common\Mfr\ItemTypes | ItemTypeResource |
ItemUnitController | /v1/mfr/itemUnits | Common\Mfr\ItemUnits | ItemUnitResource |
ProductController | /v1/mfr/products | Common\Mfr\Products | ProductResource |
QualificationController | /v1/mfr/qualifications | Common\Mfr\Qualifications | QualificationResource |
ServiceObjectController | /v1/mfr/serviceObjects | Common\Mfr\ServiceObjects | ServiceObjectResource |
ServiceRequestController | /v1/mfr/serviceRequests | Common\Mfr\ServiceRequests | ServiceRequestResource |
StepListTemplateController | /v1/mfr/stepListTemplates | ... | StepListTemplateResource |
TagController | /v1/mfr/tags | ... | TagResource |
TimeEventController | /v1/mfr/timeEvents | ... | TimeEventResource |
UserController | /v1/mfr/users | ... | UserResource |
CRUD-Pattern (am Beispiel CompanyController)
index()
public function index() {
return response()->json([
'data' => CompanyResource::collection(Companies::paginate())
], 200);
}
store() — schreibt zuerst zu MFR, dann lokal
public function store(Request $request, bool $toMfr = true)
{
$request->validate([
'Id' => 'required|string|max:255',
'Version' => 'required|integer',
]);
if ($toMfr) {
$body = json_encode($request->all(), true);
$mfrResponse = $this->guzzle->post($this->entity, $body); // → MFR
}
$company = Companies::create([ // → Common-DB
'Id' => $mfrResponse['body']->Id ?? $request->Id,
'Version' => (int) $request->Version,
]);
return response()->json([
'data' => new CompanyResource($company),
'mfrResponse' => $mfrResponse ?? null,
], 201);
}
update() — mergt + erhöht Version
public function update(Request $request, Companies $company, bool $toMfr = true)
{
if ($toMfr) {
$helper = new Helper();
$merged = $helper->array_merge_deep_override($company->toArray(), $request->toArray());
++$merged['Version'];
$company->update($merged);
$body = $company->makeHidden(['created_at','updated_at','DateModified','DateOfCreation'])->toJson();
$mfrResponse = $this->guzzle->put($this->entity . '(' . $company->Id . 'L)', $body);
} else {
$company->update($request->all());
}
return response()->json([
'data' => new CompanyResource($company),
'mfrResponse' => $mfrResponse ?? null,
], 200);
}
Wichtig: bei
$toMfr = truewirdVersionimmer um 1 erhöht — MFR braucht das für sein Optimistic-Locking.
destroy()
public function destroy(Companies $company, bool $toMfr = true)
{
$commonResponse = $company->delete();
if ($toMfr) {
$mfrResponse = $this->guzzle->delete($this->entity . '(' . $company->Id . 'L)');
}
return response()->json([
'data' => $commonResponse,
'mfrResponse' => $mfrResponse ?? null,
], 204);
}
Scramble-Annotations
Die Resource-Controller benutzen Dedoc\Scramble\Attributes\PathParameter für die OpenAPI-Generierung:
#[PathParameter('company', description: 'Show Company for Mfr', type: 'string', format: 'id', example: '61149446314')]
public function show(Companies $company) { ... }
So sieht das /scramble/openapi.json mit korrekten Parametern aus, ohne dass im Body-Comment etwas stehen muss.
Resources
app/Http/Resources/Mfr/<Entity>Resource.php
Klassen erweitern JsonResource und definieren das Wire-Format (PascalCase) — sie sind die Translation-Layer zwischen Eloquent-Modellen und API-Response.
#[SchemaName(name: 'Companies')]
class CompanyResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'Id' => (string) $this->Id,
'Version' => (int) $this->Version,
'Name' => (string) $this->Name,
'IsPhysicalPerson' => (bool) $this->IsPhysicalPerson,
'Contacts' => (array) $this->Contacts,
'Tags' => (array) $this->Tags,
'ServiceObjects' => (array) $this->ServiceObjects,
// ... 20 weitere Felder
];
}
}
#[SchemaName('Companies')]sorgt dafür, dass Scramble in der OpenAPI-Schema-Liste den NamenCompaniesverwendet (und nichtCompanyResource).
_ResourceController.php als Schablone
app/Http/Controllers/Mfr/_ResourceController.php ist die Vorlage für alle weiteren Entities. Wenn du eine neue Entity anbinden willst:
- Datei kopieren als
<Entity>Controller.php protected string $entity = '<EntityNameInMFR>';setzen- Modell- und Resource-Imports anpassen (
Companies→ dein Modell) - Route in
routes/mfr.phpregistrieren - Modell unter
app/Models/Common/Mfr/erstellen + Migration schreiben
MfrController (Top-Level Sync-Tools)
App\Http\Controllers\MfrController (NICHT in Mfr/-Subordner) ist der Top-Level-Controller für Sync-/Setup-Operationen:
| Route | Methode | Zweck |
|---|---|---|
GET /api/v1/mfr/show | index | Verfügbare Entities ausgeben |
GET /api/v1/mfr/show/{e?}/{a?}/{v?} | show | Einzelnen Datensatz inspizieren |
GET /api/v1/mfr/sync/{entity?} | sync | OData-Pull → Common-DB |
GET /api/v1/mfr/setup/{stage?} | setup | initiales Setup je Stage |
GET /api/v1/mfr/post/{stage?}/{type?}/{e?} | post | Bulk-Push Common-DB → MFR |
Diese Routen sind primär als interne CLI-/Sync-Tools gedacht — sie laufen unter
auth:sanctum, sollten aber im Production-Frontend nicht direkt aufgerufen werden.