restructure: flatten workspace nesting, move devcontainer to root

- backend/workspaces/backend/ → backend/
- backend/workspaces/frontend/ → frontend/
- backend/.devcontainer/ + .vscode/ → repo root (where VS Code expects them)
- loose scripts/SQL files → scripts/
- replace nested git repo with single repo at project root
- update docker-compose.yml build context and devcontainer.json path
- add root .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-15 11:47:58 +01:00
parent 7e725090fe
commit e63adb964d
155 changed files with 650 additions and 29 deletions

View File

@@ -0,0 +1,141 @@
import { error } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
export async function load({ fetch, locals }) {
// 1. Check Permissions (Adapt logic to your user object)
const user = locals.user;
// Assuming user.group.permissions is an array of strings
const hasAdmin = user?.groups.some(g => g.permissions.includes("ADMIN"));
if (!hasAdmin) throw error(403, 'Zugriff verweigert');
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
// 2. Load Data
const [usersRes, groupsRes, tagsRes] = await Promise.all([
fetch(baseUrl + '/api/users'),
fetch(baseUrl + '/api/groups'),
fetch(baseUrl + '/api/tags')
]);
return {
users: await usersRes.json(),
groups: await groupsRes.json(),
tags: await tagsRes.json()
};
}
export const actions = {
createUser: async ({ request, fetch }) => {
const data = await request.formData();
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
// Extract array of group IDs
// "groupIds" matches the name attribute in the <select>
const groupIds = data.getAll('groupIds');
const payload = {
username: data.get('username'),
initialPassword: data.get('password'),
groupIds: groupIds // Send array to backend
};
console.log("Payload", JSON.stringify(payload))
const res = await fetch(baseUrl + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!res.ok) return { success: false, message: 'Fehler beim Erstellen' };
return { success: true, message: 'User angelegt' };
},
deleteUser: async ({ request, fetch }) => {
const data = await request.formData();
const id = data.get('id');
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const res = await fetch(baseUrl + `/api/users/${id}`, {
method: 'DELETE'
});
if (!res.ok) {
return { success: false, message: 'Fehler beim Löschen des Benutzers' };
}
return { success: true, message: 'Benutzer erfolgreich gelöscht' };
},
updateTag: async ({ request, fetch }) => {
const data = await request.formData();
const id = data.get('id');
const name = data.get('name');
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
await fetch(baseUrl + `/api/tags/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name })
});
return { success: true };
},
deleteTag: async ({ request, fetch }) => {
const data = await request.formData();
const id = data.get('id');
await fetch(`/api/tags/${id}`, { method: 'DELETE' });
return { success: true };
},
createGroup: async ({ request, fetch }) => {
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const data = await request.formData();
const payload = {
name: data.get('name'),
permissions: data.getAll('permissions') // Gets all checked checkboxes
};
const res = await fetch(baseUrl + '/api/groups', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!res.ok) return { success: false, message: 'Fehler beim Erstellen der Gruppe' };
return { success: true };
},
updateGroup: async ({ request, fetch }) => {
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const data = await request.formData();
const id = data.get('id');
const payload = {
name: data.get('name'),
permissions: data.getAll('permissions')
};
const res = await fetch(baseUrl + `/api/groups/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!res.ok) return { success: false, message: 'Fehler beim Aktualisieren' };
return { success: true };
},
deleteGroup: async ({ request, fetch }) => {
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const data = await request.formData();
const id = data.get('id');
const res = await fetch(baseUrl + `/api/groups/${id}`, { method: 'DELETE' });
if (!res.ok) return { success: false, message: 'Gruppe kann nicht gelöscht werden (evtl. noch Benutzer zugeordnet?)' };
return { success: true };
}
};