Add facilities, contracts, orders, value lists, audit log, and desktop app modules
Extends omsorgCore with full CRUD for Facility/Contract/Order plus configurable value lists and an audit trail, and wires the omsorgapp frontend up to the new facilities, settings, and audit-log modules; includes a sidebar active-nav-item highlight. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
ee74ed65f5
commit
e9e96a57dc
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
// Minimale Hülle für dieses Milestone - nur Dashboard im Nav, keine Admin-Sichtbarkeit
|
||||
// (Connect hat kategorisch keine Admin-Oberfläche, siehe CLAUDE.md).
|
||||
function layout_start(string $title): void {
|
||||
// Minimale Hülle für dieses Milestone - nur Dashboard/Einstellungen im Nav, keine
|
||||
// Admin-Sichtbarkeit (Connect hat kategorisch keine Admin-Oberfläche, siehe CLAUDE.md).
|
||||
function layout_start(string $title, string $currentPage = 'dashboard'): void {
|
||||
$name = current_name();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@@ -32,9 +32,12 @@ function layout_start(string $title): void {
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
<a href="dashboard.php" class="active">
|
||||
<a href="dashboard.php" class="<?= $currentPage === 'dashboard' ? 'active' : '' ?>">
|
||||
<span class="nav-icon">⊞</span><span class="nav-label"> Dashboard</span>
|
||||
</a>
|
||||
<a href="settings.php" class="<?= $currentPage === 'settings' ? 'active' : '' ?>">
|
||||
<span class="nav-icon">⚙</span><span class="nav-label"> Einstellungen</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-footer">
|
||||
|
||||
@@ -5,62 +5,108 @@
|
||||
//
|
||||
// Nur Auth-Endpunkte - Connect verwaltet keine anderen Nutzer/Rollen/Mitarbeiter (das bleibt
|
||||
// OMSORG Desktop vorbehalten), deshalb fehlen hier bewusst omsorgcore_users_*/roles_*/employees_*.
|
||||
//
|
||||
// Transport läuft über den generierten Client in ../api-client-php/ (openapi-generator, siehe
|
||||
// ../api-client-php/ANLEITUNG.md) statt über rohes cURL.
|
||||
|
||||
function omsorgcore_request(array $config, string $method, string $path, ?array $body = null, ?string $accessToken = null): array
|
||||
require_once __DIR__ . '/../api-client-php/vendor/autoload.php';
|
||||
|
||||
// Führt einen generierten Api-Aufruf aus und wandelt das Ergebnis in den einheitlichen
|
||||
// Vertrag ['ok', 'status', 'data'] um. $fn bekommt die fertige Configuration und muss
|
||||
// eine ...WithHttpInfo(...)-Methode aufrufen (liefert [$model, $status, $headers]).
|
||||
function omsorgcore_call(array $config, callable $fn): array
|
||||
{
|
||||
$url = rtrim($config['omsorg_core_url'], '/') . $path;
|
||||
$configuration = \OmsorgCoreClient\Configuration::getDefaultConfiguration()
|
||||
->setHost(rtrim($config['omsorg_core_url'], '/'));
|
||||
|
||||
$headers = ['Content-Type: application/json'];
|
||||
if ($accessToken !== null) {
|
||||
$headers[] = 'Authorization: Bearer ' . $accessToken;
|
||||
try {
|
||||
[$model, $status] = $fn($configuration);
|
||||
$data = $model !== null ? json_decode(json_encode($model), true) : null;
|
||||
return ['ok' => true, 'status' => $status, 'data' => $data];
|
||||
} catch (\OmsorgCoreClient\ApiException $e) {
|
||||
$status = $e->getCode();
|
||||
$body = $e->getResponseBody();
|
||||
$decoded = $body !== null ? json_decode($body, true) : null;
|
||||
$data = $decoded !== null ? $decoded : $body;
|
||||
|
||||
$result = ['ok' => false, 'status' => $status, 'data' => $data];
|
||||
if ($status === 0) {
|
||||
$result['error'] = $e->getMessage();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 15,
|
||||
CURLOPT_POSTFIELDS => $body !== null ? json_encode($body) : null,
|
||||
]);
|
||||
|
||||
$responseBody = curl_exec($ch);
|
||||
if ($responseBody === false) {
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return ['ok' => false, 'status' => 0, 'data' => null, 'error' => $error];
|
||||
}
|
||||
|
||||
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$data = null;
|
||||
if ($responseBody !== '') {
|
||||
$decoded = json_decode($responseBody, true);
|
||||
$data = json_last_error() === JSON_ERROR_NONE ? $decoded : null;
|
||||
}
|
||||
|
||||
return ['ok' => $status >= 200 && $status < 300, 'status' => $status, 'data' => $data];
|
||||
}
|
||||
|
||||
// --- Auth ---
|
||||
|
||||
function omsorgcore_login(array $config, string $username, string $password): array
|
||||
{
|
||||
return omsorgcore_request($config, 'POST', '/api/auth/login', ['username' => $username, 'password' => $password]);
|
||||
$loginRequest = new \OmsorgCoreClient\Model\LoginRequest(['username' => $username, 'password' => $password]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthLoginPostWithHttpInfo($loginRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_refresh(array $config, string $refreshToken): array
|
||||
{
|
||||
return omsorgcore_request($config, 'POST', '/api/auth/refresh', ['refreshToken' => $refreshToken]);
|
||||
$refreshRequest = new \OmsorgCoreClient\Model\RefreshRequest(['refresh_token' => $refreshToken]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthRefreshPostWithHttpInfo($refreshRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_logout(array $config, string $refreshToken): array
|
||||
{
|
||||
return omsorgcore_request($config, 'POST', '/api/auth/logout', ['refreshToken' => $refreshToken]);
|
||||
$logoutRequest = new \OmsorgCoreClient\Model\LogoutRequest(['refresh_token' => $refreshToken]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthLogoutPostWithHttpInfo($logoutRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_me(array $config, string $accessToken): array
|
||||
{
|
||||
return omsorgcore_request($config, 'GET', '/api/auth/me', null, $accessToken);
|
||||
return omsorgcore_call($config, function ($cfg) use ($accessToken) {
|
||||
$cfg->setAccessToken($accessToken);
|
||||
return (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))->apiAuthMeGetWithHttpInfo();
|
||||
});
|
||||
}
|
||||
|
||||
function omsorgcore_change_password(array $config, string $accessToken, string $currentPassword, string $newPassword): array
|
||||
{
|
||||
$changePasswordRequest = new \OmsorgCoreClient\Model\ChangePasswordRequest([
|
||||
'current_password' => $currentPassword,
|
||||
'new_password' => $newPassword,
|
||||
]);
|
||||
return omsorgcore_call($config, function ($cfg) use ($accessToken, $changePasswordRequest) {
|
||||
$cfg->setAccessToken($accessToken);
|
||||
return (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthChangePasswordPostWithHttpInfo($changePasswordRequest);
|
||||
});
|
||||
}
|
||||
|
||||
function omsorgcore_forgot_password_request(array $config, string $username): array
|
||||
{
|
||||
$forgotPasswordRequestRequest = new \OmsorgCoreClient\Model\ForgotPasswordRequestRequest(['username' => $username]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthForgotPasswordRequestPostWithHttpInfo($forgotPasswordRequestRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_forgot_password_verify(array $config, string $username, string $pin): array
|
||||
{
|
||||
$forgotPasswordVerifyRequest = new \OmsorgCoreClient\Model\ForgotPasswordVerifyRequest(['username' => $username, 'pin' => $pin]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthForgotPasswordVerifyPostWithHttpInfo($forgotPasswordVerifyRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_forgot_password_reset(array $config, string $resetToken, string $newPassword): array
|
||||
{
|
||||
$forgotPasswordResetRequest = new \OmsorgCoreClient\Model\ForgotPasswordResetRequest([
|
||||
'reset_token' => $resetToken,
|
||||
'new_password' => $newPassword,
|
||||
]);
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthForgotPasswordResetPostWithHttpInfo($forgotPasswordResetRequest));
|
||||
}
|
||||
|
||||
function omsorgcore_password_policy(array $config): array
|
||||
{
|
||||
return omsorgcore_call($config, fn($cfg) => (new \OmsorgCoreClient\Api\AuthApi(new \GuzzleHttp\Client(), $cfg))
|
||||
->apiAuthPasswordPolicyGetWithHttpInfo());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user