-
Notifications
You must be signed in to change notification settings - Fork 0
IT Entwicklung
Caution
Diese Seite richtet sich ausschliesslich an Informatikerinnen und Informatiker. Nicht für Laien geeignet: Sie beschreibt Quellcode, Build und Tests. Ein selbst gebautes Paket ersetzt keine geprüfte Version des Herstellers. Ohne Fachkenntnisse bitte Installation Schritt für Schritt verwenden.
Für wen ist diese Seite? Für Entwicklerinnen und Entwickler, die am Quellcode von SmallTime 2027 arbeiten, Tests ausführen oder ein Betriebspaket bauen.
- Voraussetzungen
- Repository-Aufbau
- Backend
- Frontend
- Scripts
- Entwicklung starten
- Tests
- Release-Paket bauen
- Versionsnummer
- Konventionen
- Node.js 26.9.0 (
.nvmrcund.node-versionim Repository-Stamm),engines:>=26.9.0 <27; npm 11.19.1 (packageManager). - Getrennte Pakete
backend/undfrontend/mit je eigenerpackage-lock.json; kein Workspace im Stamm. - VS Code:
.vscode/settings.jsonkonfiguriert die Erweiterung «Node.js Test Runner» fürbackend/(Loaderbackend/node_modules/tsx/dist/loader.mjs); Vitest findetfrontend/vite.config.tsselbst.
SmallTime_2027.01/
├── backend/
│ ├── src/
│ │ ├── index.ts Einstieg (dotenv, createServer, start)
│ │ ├── server.ts Express-App, Middleware, Routen, Auslieferung des Frontends
│ │ ├── migrate.ts Migrationen separat
│ │ ├── cli/convert.ts Konverter SmallTime PHP (npm run convert)
│ │ ├── lib/ config, auth/JWT, csrf, cookies, security, network, rate-limit, logger, live-updates …
│ │ ├── middleware/ common (Helmet, CORS, Rate-Limit, Filter), csrf, auth, error-handler
│ │ ├── models/ Sequelize-Modelle, store.ts, migrations/
│ │ ├── modules/<feature>/ fachliche Module
│ │ └── types/
│ ├── tests/ node:test (*.test.ts), helpers/http-harness.ts, postman/
│ ├── scripts/build.mjs esbuild
│ ├── config/ backend.json, security.json
│ ├── docs/migrate.md Anleitung Migrationen/neue Tabellen
│ ├── Dockerfile, docker-entrypoint.sh
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── main.tsx, App.tsx Einstieg, Routing
│ │ ├── pages/ Admin, Home, Login, Time, Terminal, Security, …
│ │ ├── components/ gemeinsame Komponenten (Layout, LicenseBanner, PasswordChangeGate, …)
│ │ ├── api/ auth-context, auth-api-client, use-api (useApi, useLoad), live-updates
│ │ ├── i18n/locales/{de,en,fr,it}/*.json
│ │ ├── lib/, models/, styles/, test/
│ ├── config/frontend.json
│ ├── vite.config.ts
│ ├── Dockerfile, nginx.conf
├── scripts/package-dist.mjs Betriebspaket zusammenstellen
├── scripts/sync-release.mjs dist/ in den Git-Ordner release/ spiegeln
├── scripts/third-party-licenses.mjs THIRD-PARTY-LICENSES.md erzeugen
├── scripts/dist-files/ LICENSE und README.md für das Paket
├── dev.cmd, prod.cmd, release.cmd
├── _Doku - 2027/ Fachkonzept (Datenmodell, Berechnungslogik, Konvertierung, Sicherheit, API)
└── convert/ Quelldaten SmallTime PHP (nicht in Git)
Module (src/modules/<feature>/): auth, catalog, closings, content, documents, employees, files, groups, legacyConversion, license, notes, presence, reports, security, settings, setup, shared, system, terminals, timeEngine, timesheet.
Aufbau pro Modul:
| Datei | Inhalt |
|---|---|
<feature>.routes.ts |
Express-Router, Middleware (requireAuth, requireRole), Registrierung in server.ts
|
<feature>.service.ts |
Geschäftslogik, SQL |
<feature>.schemas.ts |
zod-Schemas (.strict()) für Eingaben |
<feature>.controller.ts |
optional |
-
timeEngineist rein: keine Datenbank, kein HTTP, keine Uhr. Eingaben rein, Ergebnis raus (Paarung Kommen/Gehen, Monats- und Saldoberechnung, Feiertage, Regeln). Dadurch direkt testbar. -
shared/: Datenbank-Helfer (Database), Datumsfunktionen (Temporal), Einstellungen, Audit, Berechtigungen. - Persistenz: Sequelize mit SQLite; Schemaänderungen nur über neue Migrationen in
src/models/migrations/(bestehende nie ändern), siehebackend/docs/migrate.md. - Fehler:
HttpErrormit Codes auslib/message-codes.ts(Sxxxx/Exxxx), zentralererror-handler. - Build:
scripts/build.mjsbündeltsrc/index.ts→dist/server.jsundsrc/migrate.ts→dist/migrate.js(ESM,platform: node,target: node26,packages: external, Source-Maps, minifiziert;--devohne Minify) und bettet__APP_VERSION__ein.
- React 19, React Router 7, MUI 9 (inkl. X Data Grid), i18next (de, en, fr, it), TipTap, Mermaid.
-
src/pages/…: Seiten;src/components/…: wiederverwendbare Komponenten. -
src/api/use-api.ts:-
useApi()– HTTP-Client mit Cookie-Session und CSRF-Header. -
useLoad(loader, key)– lädt Daten für einen Schlüssel. Jede Anfrage erhält einAbortController-Signal; bei Schlüsselwechsel oder Unmount wird die alte Anfrage abgebrochen und ihr Ergebnis verworfen (keine Race Conditions). Liefertdata,error,loading,reload()(Promise, löst nach dem Neuladen auf) undsetData().
-
-
src/api/live-updates.ts: WebSocket auf/api/live(gleicher Host), löstreload()betroffener Ansichten aus. -
/custom.csswird inmain.tsxnach den App-Styles eingebunden. - Build:
tsc -b && vite build→frontend/dist.vite.config.tsliest Ports und Upload-Endungen ausbackend/config/backend.jsonundfrontend/config/frontend.json.
Backend (backend/package.json):
| Script | Befehl | Zweck |
|---|---|---|
dev |
tsx watch src/index.ts |
Entwicklungsserver mit Reload (Port 55000) |
build |
node scripts/build.mjs |
Produktions-Build nach dist/
|
build:dev |
node scripts/build.mjs --dev |
Build ohne Minify |
start |
node dist/server.js |
gebautes Backend starten |
migrate |
tsx src/migrate.ts |
Migrationen (Quellcode) |
migrate:prod |
node dist/migrate.js |
Migrationen (Build) |
convert |
tsx src/cli/convert.ts |
Konverter SmallTime PHP, Optionen --dry-run, --replace, --start, --source, … |
test |
tsx --test tests/**/*.test.ts |
Tests (node:test) |
lint / lint:fix
|
eslint src tests --ext .ts |
Lint |
format / format:check
|
Prettier über src, tests, *.json, *.md
|
Formatierung |
typecheck |
tsc -p tsconfig.json --noEmit |
Typprüfung |
audit |
npm audit --audit-level=high |
Abhängigkeiten prüfen |
Frontend (frontend/package.json):
| Script | Befehl | Zweck |
|---|---|---|
dev |
vite |
Dev-Server Port 55001, Proxy /api (inkl. WS) und /custom.css → 55000 |
build |
tsc -b && vite build |
Typprüfung und Build nach dist/
|
preview |
vite preview |
Build lokal ansehen (ohne Backend-Proxy-Garantie) |
test |
vitest run |
Tests (jsdom) |
test:watch / test:coverage
|
vitest watch / vitest run --coverage
|
|
lint / lint:fix
|
eslint src --ext .ts,.tsx |
Lint (inkl. jsx-a11y, react-hooks) |
format / format:check
|
Prettier | Formatierung |
audit |
npm audit --audit-level=high |
Windows: dev.cmd im Repository-Stamm (installiert fehlende node_modules, erzeugt backend/.env aus .env.example, startet beide Server in eigenen Fenstern).
Manuell (alle Plattformen):
cd backend && npm ci && cp .env.example .env && npm run dev
cd frontend && npm ci && npm run dev- Frontend: http://localhost:55001 (Vite, leitet
/apiweiter) - Backend/API: http://localhost:55000/api
Mit NODE_ENV=development liefert das Backend kein Frontend aus. Datenbank und Uploads liegen in backend/data/ und backend/uploads/, der Importordner in convert/ im Repository-Stamm. Erster Login: admin / admin1234, sofern kein Import lief.
Backend – Node-Test-Runner (node:test) über tsx:
cd backend
npm test
npx tsx --test tests/time-engine.test.ts # einzelne Datei- Unit-Tests für
lib/und Services (*.lib.test.ts,*.service.test.ts,time-engine.test.ts,legacy-conversion.test.ts,license.test.ts,database-backup.test.ts, …). -
HTTP-Tests (
http-*.test.ts) übertests/helpers/http-harness.ts:startTestServer(security?)startet ein echtesExpressBackendauf einem freien Port mit eigener temporärer Datenbank (Migrationen, Initial-Adminadmin/admin1234),TestClientverwaltet Cookies und CSRF.nodeEnv: 'test',trustProxy: false, hohes API-Limit; Sicherheitsregeln pro Test überschreibbar. - Postman-Sammlung:
tests/postman/postman-collection.json.
Frontend – Vitest mit jsdom (src/test/setup.ts, Helfer src/test/render.tsx, time-fixtures.ts):
cd frontend
npm test
npm run test:coverageVor einem Commit: npm run lint, npm run typecheck (Backend), npm run format:check und npm test in beiden Paketen.
Windows: prod.cmd im Repository-Stamm. Manuell:
cd frontend && npm ci && npm run build
cd ../backend && npm ci && npm run build
cd .. && SMALLTIME_ORIGIN=https://zeit.example.ch node scripts/package-dist.mjsscripts/package-dist.mjs:
- Prüft, dass
frontend/distundbackend/distexistieren und dassdist/kein Git-Repository ist (sonst Abbruch). - Leert
dist/im Repository-Stamm (nur den Inhalt, damit ein geöffneter Ordner unter Windows nicht stört). - Kopiert
backend/dist→dist/dist,frontend/dist→dist/public(jeweils ohne Source-Maps, sie enthielten den vollständigen Quellcode),backend/config→dist/config,backend/package-lock.json. - Passt
dist/config/security.jsonfür Hosting ohne Länder-Header an:allowedCountries: [],allowLocalhost: false. - Schreibt
dist/package.json(Namesmalltime, Version ausbackend/package.json, nurdependencies,engines,overrides; Scriptsstart: node app.cjs,migrate: node dist/migrate.js). - Schreibt
dist/app.cjs(CommonJS, lädt./dist/server.jsperimport(), für Plesk/Passenger). - Schreibt
LICENSEundREADME.md(ausscripts/dist-files/, Version eingesetzt),THIRD-PARTY-LICENSES.md(alle Laufzeit-Abhängigkeiten von Backend und Frontend mit Lizenztexten),.node-versionund eine.gitignore(.env,data/,uploads/,convert/,node_modules/,*.sqlite). - Schreibt
dist/.env.example(ohne Secret) unddist/.envmitNODE_ENV=production,FRONTEND_ORIGINausSMALLTIME_ORIGIN(sonst Platzhalterhttps://smalltime.example.chmit Warnung), neuem zufälligemSESSION_SECRET(48 Byte),SECURE_COOKIE=true,TRUST_PROXY=true,ENABLE_COMPRESSION=true,BCRYPT_COST=12.
Nicht im Paket: node_modules/ (native Module müssen auf dem Zielsystem installiert werden), data/, uploads/, convert/. Auf dem Zielsystem: npm install --omit=dev, npm start.
Warning
- Jeder Lauf erzeugt ein neues
SESSION_SECRET. Diedist/.envbeim Verteilen eines Updates nicht mitliefern bzw. nicht überschreiben lassen. - Die Liste der Laufzeitabhängigkeiten stammt aus
backend/package.json→dependencies. Wird dort eine Abhängigkeit ergänzt, muss das Paket neu gebaut werden (esbuild bündelt Abhängigkeiten nicht). - Das Paket liefert eine
package-lock.jsondes Backends mit, die auch Dev-Abhängigkeiten beschreibt. Auf dem Zielsystem deshalbnpm install --omit=devverwenden.
dist/ ist reine Build-Ausgabe und wird bei jedem Lauf komplett ersetzt – es ist nie selbst ein Git-Repository. Veröffentlicht wird aus dem separaten Ordner release/, einem Klon von github.com/it-m-h/SmallTime-27:
Vor jeder Version: version in backend/package.json erhöhen und die Änderungen in scripts/dist-files/CHANGELOG.md eintragen (neueste Version zuoberst). Das Build-Skript kopiert CHANGELOG.md, LICENSE, README.md und images/ aus scripts/dist-files/ ins Paket.
rem einmalig
git clone https://github.com/it-m-h/SmallTime-27.git release
rem für jede Version: bauen + spiegeln
release.cmd
cd release
git status
git add -A
git commit -m "Version 1.0.0"
git tag v1.0.0
git push --follow-tagsDanach auf GitHub unter Releases → Draft a new release den Tag wählen, als Text den Abschnitt der Version aus CHANGELOG.md einfügen und bei -beta-Versionen Set as a pre-release anhaken.
scripts/sync-release.mjs lässt .git/.github im Release-Ordner unangetastet, löscht dort entfernte Dateien und kopiert nie .env, data/, uploads/, convert/ oder node_modules/. release/ steht in der .gitignore des Quellcode-Repositorys.
Die Version wird nur in backend/package.json → version gepflegt (src/lib/app-version.ts):
- Beim Build bettet esbuild sie als
__APP_VERSION__ein; in der Entwicklung wirdpackage.jsonim Arbeitsverzeichnis gelesen. -
package-dist.mjsübernimmt sie indist/package.json. - Anzeige: Administration, unten im Menü (
V1.0für1.0.0;.0als Patch wird weggelassen; Vorab-Versionen nach SemVer, z. B.0.9.5-beta→V0.9.5 Beta), zusammen mit Node-Version und Betriebssystem (GET /api/admin/settings/system). -
frontend/package.json→versionwird nicht angezeigt.
- Eingaben immer mit zod validieren; Benutzerkontext nur aus der Session (
/api/meohne ID). - Neue Tabellen/Spalten ausschliesslich per neuer Migration.
- Zeitlogik in
timeEnginehalten und dort testen; Services orchestrieren nur. - Texte im Frontend über i18n (alle vier Sprachen pflegen).
- Personendaten (
convert/, Konvertierungsberichte, echte Datenbanken) nie committen.
Weiter mit: Übersicht · Konfiguration · Docker
SmallTime 2027 · Version 1.0 · Zur Startseite · Fragen? Zuerst in den häufigen Fragen für Anwender oder Admins nachsehen.
👤 Anwender
🧑💼 Admins
- Erste Schritte
- Personen
- Arbeitsmodelle
- Ferien und Absenzen
- Saldo und Auszahlungen
- Monatsabschluss
- Gruppen und Rechte
- Stammdaten
- Einstellungen
- Terminals und Badges
- Protokoll und Sicherheit
- Häufige Fragen
🛠️ Einrichten
💻 Informatik (nur Fachleute)