Nachtrag: Migration 0030 (App-Store-Batch-1-Merkmale) war im letzten
Commit versehentlich nicht mit dabei - jetzt nachgeholt (git status hat
es aufgedeckt).
Neue Tabelle workspace_webapps (Migration 0032): kundeneigene
{name, url}-Eintraege pro Workspace, kein fester Katalog wie bei
Merkmalen - jede Organisation/jeder Workspace hat ihre/seine eigene
Liste (Nutzer-Anforderung 09.09.2026: 'der Kunde hat diverse URLs').
app.py-Aenderungen:
- fetch_favicon(): bestes-Effort-Ermittlung des Website-Favicons
(erst <link rel=icon> per Regex aus dem HTML, sonst /favicon.ico an
der Domain-Wurzel) - bewusst ohne neue pip-Abhaengigkeit (nur
urllib, passt zum bisher sehr schlanken requirements.txt).
- CRUD-Endpunkte /api/v1/workspaces/{id}/webapps[/{webapp_id}]
(GET/POST/PUT/DELETE), Icon-Serving unter /webapp-icons/{filename}
(unauthentifiziert wie /golden-images/, gleicher
Path-Traversal-Schutz).
- Checkin-Response um 'webapps' erweitert (fetch_workspace_webapps(),
gleiches assignments->bereitstellungsvorlagen-Join-Muster wie
fetch_assigned_blueprints()).
- WICHTIG: Server komponiert nie eine eigene oeffentliche URL (ANODE_URL
ist nur client-seitig bekannt, siehe agent.py/backend.sh) - Checkin
liefert nur den relativen icon_path, der Agent haengt ANODE_URL davor.
Gehört zusammen mit admin/ansible-content (neue Rolle
webapp-shortcuts, echt end-to-end getestet) und admin/kundenplattform
(Admin-UI unter /admin/technik/workspaces/{id}, Icon-Proxy analog zum
bestehenden ISO-Download-Proxy-Muster).
Live auf anode angewendet: Migration 0032 (workspace_webapps-Tabelle).
app.py-Deployment (git pull + Neustart) folgt separat.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLk93dhDMrkPXefVdknMV9
29 lines
1.2 KiB
PL/PgSQL
29 lines
1.2 KiB
PL/PgSQL
BEGIN;
|
|
|
|
-- Webapp-Mechanismus (Phase 2, siehe project_phase2_app_store_merkmale-
|
|
-- Memory): kundeneigene URLs (kein fester Katalog wie bei Merkmalen -
|
|
-- jede Organisation/jeder Workspace hat ihre/seine eigenen), die als
|
|
-- Menü-/Desktop-Verknüpfung mit dem Favicon der Seite ausgeliefert werden.
|
|
-- Bewusst workspace-skaliert (nicht organisationsweit) - analog zu
|
|
-- workspace_merkmale, damit unterschiedliche Workspaces derselben
|
|
-- Organisation unterschiedliche Webapps bekommen können.
|
|
CREATE TABLE workspace_webapps (
|
|
id UUID PRIMARY KEY,
|
|
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
-- Favicon wird serverseitig beim Anlegen/Bearbeiten geholt (siehe
|
|
-- fetch_favicon() in app.py) und unter WEBAPP_ICONS_DIR abgelegt -
|
|
-- icon_filename ist NULL, solange kein Favicon gefunden werden konnte
|
|
-- (Fallback-Icon auf Geräteseite).
|
|
icon_filename TEXT,
|
|
icon_content_type TEXT,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_workspace_webapps_workspace_id ON workspace_webapps(workspace_id);
|
|
|
|
COMMIT;
|