Reorganize into monorepo layout, move mitarbeiter-app to legacy reference
Consolidates the previously separate omsorgapp and omsorgCore repos (each had their own nested .git with GitHub history) plus the old root-level website/mitarbeiter-app into a single monorepo, matching the structure already documented in the root CLAUDE.md. Also moves the PHP employee app aside as omsorgWeb/mitarbeiter-app-legacy/ to serve as a template for a ground-up rewrite. Fixes .gitignore in the same pass: the config-secrets/uploads/data patterns were unanchored (relative to repo root, not depth-agnostic), so they silently stopped matching once the app moved under omsorgWeb/. Patterns are now **/-prefixed and cover both mitarbeiter-app and mitarbeiter-app-legacy, keeping DB/SMTP credentials and uploaded employee documents out of version control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8beb0fcf52
commit
b6c1389c55
@@ -0,0 +1,73 @@
|
||||
const { request } = require('./httpClient.cjs');
|
||||
|
||||
// Kapselt /api/auth/* von omsorgCore. Kennt die Feldnamen der LoginResponse
|
||||
// (camelCase, da ASP.NET Core standardmäßig camelCase-JSON ausgibt).
|
||||
function toTokenPair(data) {
|
||||
return {
|
||||
accessToken: data.accessToken,
|
||||
refreshToken: data.refreshToken,
|
||||
expiresAt: data.expiresAt,
|
||||
mustChangePassword: !!data.mustChangePassword
|
||||
};
|
||||
}
|
||||
|
||||
async function login(username, password) {
|
||||
const result = await request('POST', '/api/auth/login', { body: { username, password } });
|
||||
if (!result.ok) {
|
||||
return { ok: false, status: result.status, error: result.error || result.data?.error };
|
||||
}
|
||||
return { ok: true, ...toTokenPair(result.data) };
|
||||
}
|
||||
|
||||
async function refresh(refreshToken) {
|
||||
const result = await request('POST', '/api/auth/refresh', { body: { refreshToken } });
|
||||
if (!result.ok) return { ok: false, status: result.status };
|
||||
return { ok: true, ...toTokenPair(result.data) };
|
||||
}
|
||||
|
||||
async function logout(refreshToken) {
|
||||
const result = await request('POST', '/api/auth/logout', { body: { refreshToken } });
|
||||
return { ok: result.ok, status: result.status };
|
||||
}
|
||||
|
||||
async function me(accessToken) {
|
||||
const result = await request('GET', '/api/auth/me', { accessToken });
|
||||
if (!result.ok) return { ok: false, status: result.status };
|
||||
return { ok: true, username: result.data.username, role: result.data.role, permissions: result.data.permissions };
|
||||
}
|
||||
|
||||
async function requestPasswordReset(username) {
|
||||
const result = await request('POST', '/api/auth/forgot-password/request', { body: { username } });
|
||||
if (!result.ok) return { ok: false, status: result.status };
|
||||
return { ok: true, status: result.data.status };
|
||||
}
|
||||
|
||||
async function verifyPasswordResetCode(username, pin) {
|
||||
const result = await request('POST', '/api/auth/forgot-password/verify', { body: { username, pin } });
|
||||
if (!result.ok) return { ok: false, status: result.status, error: result.data?.error };
|
||||
return { ok: true, resetToken: result.data.resetToken };
|
||||
}
|
||||
|
||||
async function resetPassword(resetToken, newPassword) {
|
||||
const result = await request('POST', '/api/auth/forgot-password/reset', { body: { resetToken, newPassword } });
|
||||
return { ok: result.ok, status: result.status };
|
||||
}
|
||||
|
||||
async function changePassword(accessToken, currentPassword, newPassword) {
|
||||
const result = await request('POST', '/api/auth/change-password', {
|
||||
body: { currentPassword, newPassword },
|
||||
accessToken
|
||||
});
|
||||
return { ok: result.ok, status: result.status, data: result.data };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
login,
|
||||
refresh,
|
||||
logout,
|
||||
me,
|
||||
requestPasswordReset,
|
||||
verifyPasswordResetCode,
|
||||
resetPassword,
|
||||
changePassword
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
// Einzige Stelle im Projekt, die die Adresse von omsorgCore kennt.
|
||||
// Default passt zum lokalen `dotnet run --project src/OmsorgCore.Api` (http-Profil, Port 5245),
|
||||
// überschreibbar per Umgebungsvariable für andere Umgebungen (Produktion, anderer Rechner, ...).
|
||||
module.exports = {
|
||||
API_BASE: process.env.OMSORG_CORE_URL || 'http://localhost:5245'
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
const { request } = require('./httpClient.cjs');
|
||||
|
||||
// Kapselt /api/employees von omsorgCore (EmployeesController). Feldnamen sind
|
||||
// camelCase, da ASP.NET Core standardmäßig camelCase-JSON ausgibt.
|
||||
async function listEmployees(accessToken, { search, status, employmentType, page = 1, pageSize = 20 } = {}) {
|
||||
const params = new URLSearchParams();
|
||||
if (search) params.set('search', search);
|
||||
if (status) params.set('status', status);
|
||||
if (employmentType) params.set('employmentType', employmentType);
|
||||
params.set('page', page);
|
||||
params.set('pageSize', pageSize);
|
||||
|
||||
return request('GET', `/api/employees?${params.toString()}`, { accessToken });
|
||||
}
|
||||
|
||||
async function createEmployee(accessToken, payload) {
|
||||
return request('POST', '/api/employees', { body: payload, accessToken });
|
||||
}
|
||||
|
||||
async function getEmployee(accessToken, id) {
|
||||
return request('GET', `/api/employees/${id}`, { accessToken });
|
||||
}
|
||||
|
||||
async function updateEmployee(accessToken, id, payload) {
|
||||
return request('PUT', `/api/employees/${id}`, { body: payload, accessToken });
|
||||
}
|
||||
|
||||
module.exports = { listEmployees, createEmployee, getEmployee, updateEmployee };
|
||||
@@ -0,0 +1,34 @@
|
||||
const { API_BASE } = require('./config.cjs');
|
||||
|
||||
// Einzige Stelle, die fetch/API_BASE/Authorization-Header kennt. Kennt keine konkreten
|
||||
// Endpunkte - die kommen aus den <kategorie>Client.cjs-Dateien (z.B. authClient.cjs).
|
||||
async function request(method, path, { body, accessToken } = {}) {
|
||||
const headers = { 'Content-Type': 'application/json' };
|
||||
if (accessToken) headers.Authorization = `Bearer ${accessToken}`;
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(`${API_BASE}${path}`, {
|
||||
method,
|
||||
headers,
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined
|
||||
});
|
||||
} catch (err) {
|
||||
return { ok: false, status: 0, data: null, error: err.message };
|
||||
}
|
||||
|
||||
if (response.status === 204) {
|
||||
return { ok: true, status: 204, data: null };
|
||||
}
|
||||
|
||||
let data = null;
|
||||
try {
|
||||
data = await response.json();
|
||||
} catch {
|
||||
data = null;
|
||||
}
|
||||
|
||||
return { ok: response.ok, status: response.status, data };
|
||||
}
|
||||
|
||||
module.exports = { request };
|
||||
@@ -0,0 +1,12 @@
|
||||
const { request } = require('./httpClient.cjs');
|
||||
|
||||
// Kapselt /api/users von omsorgCore (UsersController).
|
||||
async function listUsers(accessToken) {
|
||||
return request('GET', '/api/users', { accessToken });
|
||||
}
|
||||
|
||||
async function createUser(accessToken, payload) {
|
||||
return request('POST', '/api/users', { body: payload, accessToken });
|
||||
}
|
||||
|
||||
module.exports = { listUsers, createUser };
|
||||
Reference in New Issue
Block a user