Files
projektuebersicht/AGENTS.md
T

5.6 KiB

AGENTS.md

File structure

.
├── server.js                 # Express server with API endpoints
├── package.json             # Dependencies (express, cors)
├── public/
│   ├── Test.html            # Root HTML file (served at /)
│   ├── main.v2.js           # Complete frontend client app
│   └── styles.css           # UI styles
├── Docker/
│   └── Dockerfile           # Node.js Alpine image
├── docker-compose.yml       # Docker service definition
└── sessions/                # Data directory (bind-mounted in Docker)
    ├── ELT/                 # Elektro department
    ├── HLS/                 # HLS department
    └── ARCH/               # Architektur department

Overview

Single-page app for tracking engineering projects across weekly sessions ("Sitzungen"). Vanilla JS/HTML/CSS frontend (public/) + Node.js/Express server (server.js). No build step, no bundler. Data is persisted as CSV files under sessions/.

Running

  • npm install then npm start (executes node server.js).
  • Or with Docker: docker compose -f Docker/docker-compose.yml up --build.
  • Server runs on PORT env var or defaults to 3003; serves public/Test.html as root and API under /load-all, /save-csv, /delete-csv.
  • Frontend assumes the API lives at window.location.origin, falling back to http://localhost:3003 when opened as a local file. Opening Test.html directly without a server will load seed/demo data.

Operations

Local

npm install
npm start

Access at http://localhost:3003 (or PORT=3004 if occupied).

Docker

docker compose -f Docker/docker-compose.yml up --build

Access at http://localhost:3003 (or override with PORT=3004).

CSV format

  • Delimiter: semicolon (;)
  • Encoding: UTF-8 with BOM (\ufeff)
  • Structure:
    • sessions/<DEPT>/ contains department data
    • Week files: <Label>.csv (e.g., KW_30___2026.csv)
    • Global people: _people.csv with columns NAME;Rollen;Voller Name

Data layout

  • Data is split by department: sessions/ELT/, sessions/HLS/, sessions/ARCH/. Valid departments are hard-coded in server.js (VALID_DEPARTMENTS) and main.v2.js (DEPARTMENTS). Unknown department values fall back to ELT.
  • Each week is one CSV file named <Label>.csv with ; delimiter and UTF-8 BOM.
  • Each department has a global people list in _people.csv with columns NAME;Rollen;Voller Name. New people are added globally and copied into the current week. Historical weeks keep their own person copies so deleted global people remain visible in old sessions.
  • The app reads CSVs on startup via /load-all; localStorage is used only for the last-selected department/tab UI state. Do not store data in localStorage.
  • Editing CSVs by hand is possible but risky; prefer the UI.

Architecture notes

  • Frontend is in public/ (Test.html, main.v2.js, styles.css).
  • main.v2.js is the entire client app loaded as a classic non-module <script>; all functions are globals on window.
  • State lives in let db = { weeks: [], currentWeek, globalPeople: {} }.
  • Each week object has projects (with assign, lph, group, status, order) and people with session-local copies.
  • save() schedules syncAllToServer() debounced by 500 ms; this writes all weeks plus the global _people.csv to the server, not just the changed one.
  • Weeks are sorted by calendar week extracted from the label (KW XX / YYYY), not alphabetically.
  • applyAutoLock() locks every week except the chronologically last one after load/clone/new-week, so historical weeks are read-only unless explicitly unlocked.
  • Person IDs are derived from the person's abbreviation/name to stay stable across reloads (personIdForName in main.v2.js).

Docker

  • Dockerfile uses node:20-alpine as base image.
  • Copies only package.json/package-lock.json first (npm ci --production), then server files.
  • Excludes Docker/, node_modules/, .git, .gitignore via .dockerignore.
  • Runs as non-root node user; /app/sessions bind-mounted from host ./sessions.
  • HEALTHCHECK on /health endpoint; service restarts on failure (unless-stopped).
  • Frontend must be served via HTTP (not file://) for CORS to work.

Security / auth quirk

  • projects and people tabs plus week deletion are gated by a password modal. The check compares CryptoJS.SHA256(input) to PROTECTED_PASSWORD_HASH in main.v2.js. This is client-side only and not real security. CryptoJS is loaded from a CDN (cdnjs.cloudflare.com) in Test.html, so the password gate needs internet access.
  • User-provided status HTML is sanitized on render (small tag/attribute whitelist) to mitigate XSS while keeping formatting options.
  • Filenames sent to /save-csv and /delete-csv are strictly validated server side to prevent path traversal.

Conventions

  • UI strings, comments, and CSV content are German. Preserve German in user-facing text.
  • No linter, formatter, typecheck, or test suite is configured. Verify changes by running the server and exercising the relevant tab in the browser.
  • This is not a git repo. Don't assume git workflows.
  • Edit main.v2.js functions in place; the file is intentionally one large script with German header comments per section. Match that style.

Testing & verification

  • No automated test suite exists. Manual verification only:
    • Start server (npm start or Docker)
    • Open http://localhost:3003
    • Check /health endpoint returns {ok:true}
    • Exercise relevant tab in browser (Board, Projects, People)
    • Verify CSV persistence in sessions/ directory