Doku aktualisiert
This commit is contained in:
@@ -6,3 +6,4 @@ __pycache__/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
README.md
|
README.md
|
||||||
AGENTS.md
|
AGENTS.md
|
||||||
|
session-ses_*.md
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,4 +9,6 @@ media/
|
|||||||
*.mp4
|
*.mp4
|
||||||
*.mov
|
*.mov
|
||||||
agents.md
|
agents.md
|
||||||
opencode.md
|
opencode.md
|
||||||
|
session-ses_*.md
|
||||||
|
session-ses_1e96.md
|
||||||
|
|||||||
333
DESIGN.md
Normal file
333
DESIGN.md
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
---
|
||||||
|
version: alpha
|
||||||
|
name: CANCOM Simple Signage
|
||||||
|
description: "Digital-Signage-Plattform für CANCOM: Admin-UI zur Verwaltung von Screens, Playlists, Medien und Standorten sowie ein kioskartiger Player-Vollbildmodus."
|
||||||
|
|
||||||
|
colors:
|
||||||
|
primary: "#DA002D"
|
||||||
|
primary-hover: "#B00024"
|
||||||
|
header: "#2B2F36"
|
||||||
|
header-dark: "#0F1720"
|
||||||
|
surface: "#FFFFFF"
|
||||||
|
surface-dark: "#15181D"
|
||||||
|
bg: "#F4F6F8"
|
||||||
|
bg-dark: "#15181D"
|
||||||
|
text: "#212121"
|
||||||
|
text-dark: "#E5E7EB"
|
||||||
|
border: "#D9DEE3"
|
||||||
|
border-dark: "#2B3440"
|
||||||
|
muted: "#6B7280"
|
||||||
|
muted-dark: "#9AA4B2"
|
||||||
|
online: "#2FB344"
|
||||||
|
offline: "#D63939"
|
||||||
|
badge-admin: "#DA002D"
|
||||||
|
badge-superuser: "#8B5CF6"
|
||||||
|
badge-user: "#3B82F6"
|
||||||
|
newsticker-bg: "#DA002D"
|
||||||
|
newsticker-text: "#FFFFFF"
|
||||||
|
card-header-light: "#EEEEEE"
|
||||||
|
card-header-dark: "#1A1E24"
|
||||||
|
input-bg-dark: "#11161D"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
body:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontSize: 16px
|
||||||
|
fontWeight: 400
|
||||||
|
lineHeight: 1.5
|
||||||
|
heading:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontWeight: 600
|
||||||
|
heading-lg:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontSize: 1.75rem
|
||||||
|
fontWeight: 600
|
||||||
|
heading-md:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontSize: 1.25rem
|
||||||
|
fontWeight: 600
|
||||||
|
player-clock:
|
||||||
|
fontFamily: monospace
|
||||||
|
fontSize: 1.1em
|
||||||
|
newsticker-track:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontSize: 16px
|
||||||
|
fontWeight: 400
|
||||||
|
mute:
|
||||||
|
fontFamily: "Segoe UI, Arial, sans-serif"
|
||||||
|
fontSize: 0.82rem
|
||||||
|
|
||||||
|
rounded:
|
||||||
|
card: 16px
|
||||||
|
button: 20px
|
||||||
|
small: 4px
|
||||||
|
logo-box: 12px
|
||||||
|
full: 9999px
|
||||||
|
|
||||||
|
spacing:
|
||||||
|
xs: 4px
|
||||||
|
sm: 8px
|
||||||
|
md: 16px
|
||||||
|
lg: 24px
|
||||||
|
xl: 32px
|
||||||
|
xxl: 64px
|
||||||
|
gutter: 24px
|
||||||
|
page-top: 24px
|
||||||
|
footer-padding-y: 0.65rem
|
||||||
|
footer-padding-x: 1.5rem
|
||||||
|
card-header-padding: 16px
|
||||||
|
card-margin-bottom: 64px
|
||||||
|
|
||||||
|
components:
|
||||||
|
card:
|
||||||
|
backgroundColor: "{colors.surface}"
|
||||||
|
borderColor: "{colors.border}"
|
||||||
|
borderLeft: "6px solid {colors.primary}"
|
||||||
|
rounded: "{rounded.card}"
|
||||||
|
card-dark:
|
||||||
|
backgroundColor: "{colors.bg-dark}"
|
||||||
|
borderColor: "{colors.border-dark}"
|
||||||
|
card-header:
|
||||||
|
backgroundColor: "{colors.card-header-light}"
|
||||||
|
card-header-dark:
|
||||||
|
backgroundColor: "{colors.card-header-dark}"
|
||||||
|
btn-primary:
|
||||||
|
backgroundColor: "{colors.primary}"
|
||||||
|
textColor: "#FFFFFF"
|
||||||
|
rounded: "{rounded.button}"
|
||||||
|
btn-primary-hover:
|
||||||
|
backgroundColor: "{colors.primary-hover}"
|
||||||
|
action-button:
|
||||||
|
backgroundColor: "{colors.surface}"
|
||||||
|
textColor: "{colors.text}"
|
||||||
|
rounded: "{rounded.button}"
|
||||||
|
fontWeight: 600
|
||||||
|
online-badge:
|
||||||
|
backgroundColor: "{colors.online}"
|
||||||
|
textColor: "#FFFFFF"
|
||||||
|
offline-badge:
|
||||||
|
backgroundColor: "{colors.offline}"
|
||||||
|
textColor: "#FFFFFF"
|
||||||
|
newsticker-bar:
|
||||||
|
backgroundColor: "{colors.newsticker-bg}"
|
||||||
|
textColor: "{colors.newsticker-text}"
|
||||||
|
height: 40px
|
||||||
|
overlay-button:
|
||||||
|
backgroundColor: "{colors.surface}"
|
||||||
|
textColor: "{colors.text}"
|
||||||
|
rounded: "{rounded.button}"
|
||||||
|
fontWeight: 600
|
||||||
|
boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
CANCOM Simple Signage is a corporate digital-signage platform. The UI follows a **keyadmin dashboard** aesthetic: clean, card-based layouts with a dark header bar, a red navigation bar (CANCOM brand red #DA002D), and generous white space. The tone is professional, trustworthy, and functional — suitable for a B2B enterprise environment.
|
||||||
|
|
||||||
|
The admin UI manages screens, playlists, media uploads, and multi-site locations. The player UI is a fullscreen, kiosk-style view with no browser chrome, designed for unattended TV/monitor displays.
|
||||||
|
|
||||||
|
Two themes are supported: **light** (default, `data-bs-theme="light"`) and **dark** (`data-bs-theme="dark"`), persisted via `localStorage("signage-theme")`.
|
||||||
|
|
||||||
|
## Colors
|
||||||
|
|
||||||
|
The palette is rooted in CANCOM's corporate red and high-contrast neutrals.
|
||||||
|
|
||||||
|
- **Primary (#DA002D):** CANCOM signature red. Used for navigation bar, button backgrounds, card left-border accent, form-check focus rings, newsticker bar, and all primary interactive elements. The single most important action per screen uses this color.
|
||||||
|
- **Primary Hover (#B00024):** Darkened red for button hover/focus states.
|
||||||
|
- **Header (#2B2F36 / #0F1720 Dark):** Dark surface for top header bar. White text and icons on this surface.
|
||||||
|
- **Surface (#FFFFFF / #15181D Dark):** Card backgrounds and content areas.
|
||||||
|
- **Background (#F4F6F8 / #15181D Dark):** Page-level background.
|
||||||
|
- **Border (#D9DEE3 / #2B3440 Dark):** Card borders, table borders, form borders, list-group dividers.
|
||||||
|
- **Muted (#6B7280 / #9AA4B2 Dark):** Secondary text, captions, metadata, placeholders.
|
||||||
|
- **Online/Offline:** Green (#2FB344) for online status badge, Red (#D63939) for offline.
|
||||||
|
- **Role Badges:** Red for Admin, Purple (#8B5CF6) for Superuser, Blue (#3B82F6) for User.
|
||||||
|
- **Newsticker:** Red bar (#DA002D) with white text.
|
||||||
|
|
||||||
|
### States
|
||||||
|
|
||||||
|
Interactive elements use the following hover/active color shifts:
|
||||||
|
- **Primary button hover:** `primary-hover` (#B00024)
|
||||||
|
- **Secondary/outline buttons:** inherit background, use border with slight darkening
|
||||||
|
- **Dark-mode form controls:** input background #11161D
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
The typography strategy uses the system font stack **Segoe UI** for all text, ensuring consistent rendering across Windows-based signage players.
|
||||||
|
|
||||||
|
- **Body:** Segoe UI Regular at 16px base. Line-height 1.5 for readability. This is the default for all body text, form labels, table cells.
|
||||||
|
- **Headings:** Segoe UI Semi-Bold (600). Three levels: page-title (1.75rem), card-title (1.25rem), and section headings.
|
||||||
|
- **Player Clock:** Monospace font at 1.1em for the live clock in the newsticker bar.
|
||||||
|
- **Newsticker Track:** Same as body (16px, Segoe UI), scrolling horizontally in the red bar.
|
||||||
|
- **Footer/Muted Text:** 0.82rem for copyright and secondary information.
|
||||||
|
- **Button Labels:** 1rem (action buttons), 1.05rem (voice agent button), both weight 600.
|
||||||
|
- **Code/Monospace:** Used for IP addresses and file listings in info tabs.
|
||||||
|
|
||||||
|
## Layout & Spacing
|
||||||
|
|
||||||
|
The layout follows a **single-column fluid** model with a fixed max-width container (1320px) on the admin pages.
|
||||||
|
|
||||||
|
### Layout Structure
|
||||||
|
|
||||||
|
**Admin pages** follow a two-tier horizontal bar layout:
|
||||||
|
1. **Upper bar (brand-surface):** Logo, site dropdown, theme toggle, user menu
|
||||||
|
2. **Lower bar (nav-surface):** Red (#DA002D) navigation with action buttons
|
||||||
|
|
||||||
|
**Player pages** have no layout bars — the entire viewport is used for media display.
|
||||||
|
|
||||||
|
### Spacing Scale
|
||||||
|
|
||||||
|
A strict spacing scale is used with 4px as the base unit:
|
||||||
|
- `xs` (4px) — tight gaps, micro-adjustments
|
||||||
|
- `sm` (8px) — tight gaps between related elements
|
||||||
|
- `md` (16px) — standard padding inside cards, gaps between buttons
|
||||||
|
- `lg` (24px) — generous card internal padding, gap between sections
|
||||||
|
- `xl` (32px) — major section spacing
|
||||||
|
- `xxl` (64px) — spacing between screen cards
|
||||||
|
|
||||||
|
### Card Layout
|
||||||
|
|
||||||
|
Screen management cards have:
|
||||||
|
- Internal padding: 1rem (16px) on body
|
||||||
|
- Card-header padding: 1rem (16px) left, with font-weight 600
|
||||||
|
- Gap below each card: 64px (`mb-6`)
|
||||||
|
- Tab content offset: 1rem (16px) top padding
|
||||||
|
|
||||||
|
### Grid Areas
|
||||||
|
|
||||||
|
The playlist row uses a fixed grid: `28px 1fr 90px 80px 90px 32px` for checkbox, name, type badge, size, delete button, drag handle.
|
||||||
|
|
||||||
|
## Elevation & Depth
|
||||||
|
|
||||||
|
Elevation is conveyed primarily through **border distinction** rather than shadows. Cards use a 1px solid border plus a distinctive 6px left-border accent in primary red (#DA002D). This provides clear visual separation without heavy drop shadows.
|
||||||
|
|
||||||
|
- **Cards:** 1px border + 6px left red accent + 1rem border-radius
|
||||||
|
- **Logo preview boxes:** 2px dashed border with 0.75rem border-radius
|
||||||
|
- **Player overlay buttons:** Light box-shadow (0 2px 8px rgba(0,0,0,0.08)), elevated to 0 4px 12px on hover
|
||||||
|
- **Willkommensseite card:** Elevated with 0 20px 60px rgba(0,0,0,0.08) shadow for premium feel
|
||||||
|
|
||||||
|
In dark mode, depth is achieved through tonal layering: card backgrounds match the page background, but card headers use a slightly lighter/different shade (#1A1E24) to create subtle hierarchy.
|
||||||
|
|
||||||
|
## Shapes
|
||||||
|
|
||||||
|
The shape language is defined by **consistent generous rounding**.
|
||||||
|
|
||||||
|
- **Cards:** 1rem (16px) border-radius with 1rem inner border-radius
|
||||||
|
- **Buttons (admin):** Tabler default rounded (approximately 4px)
|
||||||
|
- **Player action buttons (custom URL + voice agent):** 20px border-radius for a pill-like appearance
|
||||||
|
- **Logo preview boxes:** 0.75rem (12px) border-radius
|
||||||
|
- **Interactive overlays:** 20px border-radius on the back button
|
||||||
|
- **Small avatars/badges:** Fully rounded (9999px)
|
||||||
|
- **Form controls:** Tabler default (approximately 4px)
|
||||||
|
|
||||||
|
### Consistency Rule
|
||||||
|
|
||||||
|
All interactive player buttons (custom URL, voice agent, overlay back button) share identical shape: 20px border-radius, white background, black text, font-weight 600. This ensures visual consistency across all floating buttons on the player screen.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### Header (brand-surface)
|
||||||
|
|
||||||
|
Dark background (`--ccm-header` / `#0F1720` in dark mode). Contains:
|
||||||
|
- **Logo:** CANCOM SVG (height: 1.85rem, width: auto)
|
||||||
|
- **Wordmark:** Two-line (brand name + subtitle), 0.92rem, white
|
||||||
|
- **Site Dropdown:** `btn-outline-secondary` style
|
||||||
|
- **Theme Toggle:** Square button (2.5rem), moon/sun icon
|
||||||
|
- **User Dropdown:** Email + role badge (Admin=red, Superuser=purple, User=blue)
|
||||||
|
|
||||||
|
### Navigation Bar (nav-surface)
|
||||||
|
|
||||||
|
Red background (`--ccm-primary`). Contains white outline buttons (`btn-white`):
|
||||||
|
- Active state: white background, red text, inset shadow
|
||||||
|
- Icons: 1rem, vertically centered at -2px
|
||||||
|
- Gap: 8px between buttons, 8px vertical padding
|
||||||
|
- Used on admin, customer, dashboard, priority pages
|
||||||
|
|
||||||
|
### Cards
|
||||||
|
|
||||||
|
- `rounded: 1rem`, `border: 1px solid var(--ccm-border)`
|
||||||
|
- `border-left: 6px solid var(--ccm-primary)`
|
||||||
|
- Header: `background: #eee` (light) / `#1a1e24` (dark), font-weight 600
|
||||||
|
- Body contains Tabler tabs (6 tabs for screen cards)
|
||||||
|
- Tab background matches card surface; tab link text uses muted color; active tab uses surface background
|
||||||
|
|
||||||
|
### Player Media Elements
|
||||||
|
|
||||||
|
- img, video, iframe: fullscreen (`100vw × 100vh`), fixed position, centered via `top:50%; left:50%; transform:translate(-50%,-50%)`
|
||||||
|
- Only one element visible at a time (`display:none` default)
|
||||||
|
- `object-fit: contain` for images and video
|
||||||
|
- Background: pure black (`#000`)
|
||||||
|
|
||||||
|
### Action Button (Custom URL / Voice Agent)
|
||||||
|
|
||||||
|
The player supports floating action buttons with identical styling:
|
||||||
|
- `background: #fff; color: #000; border: none; border-radius: 20px; font-size: 1rem; font-weight: 600; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,0.08)`
|
||||||
|
- 9 fixed positions: top/middle/bottom × left/center/right
|
||||||
|
- Bottom positions offset 56px from bottom when newsticker is active, 16px otherwise
|
||||||
|
- Two target behaviors: overlay (iframe with back button) or redirect (direct navigation)
|
||||||
|
|
||||||
|
### Voice Agent Button
|
||||||
|
|
||||||
|
Same base as action button plus:
|
||||||
|
- Integrated animated bars (5 bars, staggered delay 0–0.4s, 0.6s wave animation)
|
||||||
|
- Typewriter tagline: 11 multilingual phrases, character-by-character (50ms + 30ms random), 2.5s pause, 0.8s fade-out
|
||||||
|
- Optional DVA image (200px, aspect-ratio 648/596) above button
|
||||||
|
- Min-width: 280px, height: 56px, gap: 12px between icon and text
|
||||||
|
|
||||||
|
### Overlay (iframe Modal)
|
||||||
|
|
||||||
|
- Fullscreen (`position:fixed; inset:0; z-index:99999; background:#000`)
|
||||||
|
- iframe fills entire viewport
|
||||||
|
- Back button positioned at the same location as the clicked trigger button (9 positions)
|
||||||
|
- Closing the overlay resumes player (`playNext()`)
|
||||||
|
|
||||||
|
### Newsticker
|
||||||
|
|
||||||
|
- Fixed bottom bar: `height:40px; background:#DA002D; color:#fff; z-index:10000`
|
||||||
|
- Scrolling text: `animation: ticker-scroll 40s linear infinite`
|
||||||
|
- Live clock: monospace, right-aligned, hh:mm:ss, updated every second
|
||||||
|
|
||||||
|
### Online/Offline Status
|
||||||
|
|
||||||
|
- Online: green filled button (`btn-success`), not interactive
|
||||||
|
- Offline: red filled button (`btn-danger`), not interactive
|
||||||
|
- Tooltip on hover: browser, resolution, IP, last seen timestamp
|
||||||
|
- Determined by heartbeat file mtime (< 60s)
|
||||||
|
|
||||||
|
### Charts (Admin Dashboard)
|
||||||
|
|
||||||
|
- Sparkline area charts using ApexCharts
|
||||||
|
- Height: 32px, width: 100%, stroke width: 1.5, curve: straight
|
||||||
|
- Color: primary red (#DA002D), fill opacity: 0.25
|
||||||
|
- No tooltip, no animation
|
||||||
|
|
||||||
|
### Form Controls
|
||||||
|
|
||||||
|
- Switches use primary red for checked state
|
||||||
|
- Focus ring: `0 0 0 0.2rem rgba(218, 0, 45, 0.25)`
|
||||||
|
- Dark mode: background `#11161D`, text `#E5E7EB`, border `#2B3440`
|
||||||
|
|
||||||
|
### Dropdown Menus
|
||||||
|
|
||||||
|
- Hover/focus: `background: #e9ecef` (light) / `#3a3f45` (dark)
|
||||||
|
- Active item: primary red background with white text
|
||||||
|
|
||||||
|
### Alerts (Dark Mode)
|
||||||
|
|
||||||
|
- Danger: background `#2d0d0d`, text `#f0a0a0`, border `#4a1a1a`
|
||||||
|
- Success: background `#0d2b1d`, text `#a3d9b1`, border `#1a4730`
|
||||||
|
|
||||||
|
## Do's and Don'ts
|
||||||
|
|
||||||
|
- Do use primary red (#DA002D) only for the most important interactive elements and the nav bar
|
||||||
|
- Do maintain the two-tier header pattern (dark brand bar + red nav bar) on all admin pages
|
||||||
|
- Do keep player pages completely chromeless — no headers, navs, or footers
|
||||||
|
- Don't add shadows to cards; use border + left accent instead
|
||||||
|
- Don't use more than one red accent per card (the 6px left border is sufficient)
|
||||||
|
- Don't mix corner radii: cards use 1rem, player buttons use 20px — keep each category consistent
|
||||||
|
- Do set `data-bs-theme` synchronously before rendering to prevent dark-mode flash
|
||||||
|
- Do persist theme preference in `localStorage("signage-theme")`
|
||||||
|
- Don't use emojis in the UI; use Tabler Icons (`ti-*`) consistently
|
||||||
|
- Do respect the 9-position system for all floating player buttons
|
||||||
|
- Do offset bottom-positioned buttons 56px above the newsticker bar
|
||||||
|
- Do hide all media elements by default; show only the active one
|
||||||
|
- Do ensure WCAG AA contrast ratios for all text-on-background combinations
|
||||||
@@ -7,10 +7,13 @@ RUN pip install --no-cache-dir -r requirements.txt gunicorn
|
|||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN addgroup --system --gid 1000 app && adduser --system --uid 1000 --ingroup app --home /home/app app && \
|
RUN addgroup --system --gid 1000 app && \
|
||||||
mkdir -p /home/app && chown app:app /home/app && \
|
adduser --system --uid 1000 --ingroup app --disabled-password --disabled-login --no-create-home app && \
|
||||||
chown -R app:app /app && chmod -R u+w /app
|
chown -R app:app /app && chmod -R u+w /app && \
|
||||||
|
find / -perm /4000 -o -perm /2000 2>/dev/null | xargs -r chmod ug-s
|
||||||
|
|
||||||
USER app
|
USER app
|
||||||
|
ENV HOME=/tmp
|
||||||
|
|
||||||
EXPOSE 5005
|
EXPOSE 5005
|
||||||
|
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -133,10 +133,22 @@ Empfohlenes `docker-compose.yml` mit Bind-Mounts für persistente Daten:
|
|||||||
services:
|
services:
|
||||||
signage:
|
signage:
|
||||||
container_name: signage
|
container_name: signage
|
||||||
build: .
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
image: your-registry/signage:latest
|
||||||
ports:
|
ports:
|
||||||
- "5005:5005"
|
- "5005:5005"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
read_only: true
|
||||||
|
tmpfs:
|
||||||
|
- /tmp
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
volumes:
|
volumes:
|
||||||
- ./media:/app/media
|
- ./media:/app/media
|
||||||
- ./config.json:/app/config.json
|
- ./config.json:/app/config.json
|
||||||
@@ -144,13 +156,9 @@ services:
|
|||||||
- ./history.json:/app/history.json
|
- ./history.json:/app/history.json
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Berlin
|
- TZ=Europe/Berlin
|
||||||
|
|
||||||
networks:
|
|
||||||
default:
|
|
||||||
driver: bridge
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Der Container läuft als User mit **UID 1000**. Daher vor dem ersten Start die Berechtigungen setzen:
|
Der Container läuft als User mit **UID 1000** ohne Shell, auf **read-only Root-FS** ohne Capabilities. Daher vor dem ersten Start die Berechtigungen setzen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chown 1000:1000 config.json users.json history.json
|
chown 1000:1000 config.json users.json history.json
|
||||||
|
|||||||
@@ -11,4 +11,11 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "5005:5005"
|
- "5005:5005"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
read_only: true
|
||||||
|
tmpfs:
|
||||||
|
- /tmp
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
12
history.json
12
history.json
@@ -1,4 +1,16 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-28 16:04:39",
|
||||||
|
"action": "user_login",
|
||||||
|
"detail": "User 'erik.thiele@cancom.de' angemeldet (mit MFA)",
|
||||||
|
"user": "erik.thiele@cancom.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-28 16:04:11",
|
||||||
|
"action": "user_logout",
|
||||||
|
"detail": "User 'erik.thiele@cancom.de' abgemeldet",
|
||||||
|
"user": "erik.thiele@cancom.de"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": "2026-06-28 15:12:39",
|
"timestamp": "2026-06-28 15:12:39",
|
||||||
"action": "user_login",
|
"action": "user_login",
|
||||||
|
|||||||
6376
session-ses_1e96.md
6376
session-ses_1e96.md
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user