Reorganize into monorepo layout, move mitarbeiter-app to legacy reference
Consolidates the previously separate omsorgapp and omsorgCore repos (each had their own nested .git with GitHub history) plus the old root-level website/mitarbeiter-app into a single monorepo, matching the structure already documented in the root CLAUDE.md. Also moves the PHP employee app aside as omsorgWeb/mitarbeiter-app-legacy/ to serve as a template for a ground-up rewrite. Fixes .gitignore in the same pass: the config-secrets/uploads/data patterns were unanchored (relative to repo root, not depth-agnostic), so they silently stopped matching once the app moved under omsorgWeb/. Patterns are now **/-prefixed and cover both mitarbeiter-app and mitarbeiter-app-legacy, keeping DB/SMTP credentials and uploaded employee documents out of version control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8beb0fcf52
commit
b6c1389c55
@@ -0,0 +1,118 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is the OMSORG website plus **OMSORG Connect**, an internal employee web app ("Mitarbeiter-App") for a German nursing care company. There is no build system — everything is plain PHP, HTML, CSS, and vanilla JS deployed directly to a web server (`htdocs`).
|
||||
|
||||
This project is one part of the OMSORG monorepo — see the root `CLAUDE.md` (`../CLAUDE.md`) for the overall platform picture and `../REQUIREMENTS.md` for functional/non-functional requirements with FR-IDs. This app is the reference implementation for **OMSORG Connect**; its MySQL database is expected to eventually move behind the shared `omsorgCore` backend (currently empty, planned as C#/.NET + PostgreSQL) rather than staying a standalone data store.
|
||||
|
||||
## Deployment
|
||||
|
||||
Upload the full directory contents to the server's `htdocs` folder and overwrite existing files. After deploying, clear the browser cache or test in an incognito window.
|
||||
|
||||
There are no build steps, package managers, or test runners.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Public website (`/`)
|
||||
Static HTML with a contact form:
|
||||
- `index.html` — main landing page
|
||||
- `send-form.php` — handles the public contact form, sends email via PHP `mail()`
|
||||
- `send-status-template.php` — reusable status page template for form results
|
||||
- `datenschutz.html`, `impressum.html` — legal pages
|
||||
|
||||
### Employee app (`/mitarbeiter-app/`)
|
||||
A session-based PHP app with no framework, backed by a **MySQL database** (PDO).
|
||||
|
||||
#### Entry point
|
||||
- `index.php` — login page. Redirects to `pages/dashboard.php` if already logged in. Includes rate limiting: 5 failed attempts trigger a 10-minute lockout.
|
||||
- `setup.php` — one-time setup script (run once after first deploy to bootstrap the DB)
|
||||
|
||||
#### Library (`lib/`)
|
||||
- `auth.php` — included at the top of every protected page. Provides `require_login()`, `require_admin()`, `is_logged_in()`, `is_admin()`, `current_user()`, `current_name()`, `current_username()`, `csrf_token()`, `csrf_field()`, `verify_csrf()`, `e()`. Users are stored in the `users` DB table. Login is case-insensitive on username.
|
||||
- `db.php` — provides `db(): PDO` (singleton). Reads credentials from `config.php`, runs pending migrations on first connection, and sets `PDO::ERRMODE_EXCEPTION`.
|
||||
- `config.php` — returns array with MySQL DSN/credentials, SMTP settings, and mail recipient addresses. Import with `$config = require __DIR__ . '/config.php';`.
|
||||
- `layout.php` — shared sidebar layout. Call `layout_start($title, $current_page)` and `layout_end()` to wrap page content. Renders the sidebar nav, user avatar, and injects the service worker.
|
||||
- `mail.php` — provides `smtp_send($cfg, $to, $subject, $body, $attach = [])`. Raw SMTP implementation (no PHPMailer), supports SSL (port 465) and STARTTLS (port 587), and optional file attachments.
|
||||
|
||||
#### Pages (`pages/`)
|
||||
Each page is a standalone PHP file using `layout_start`/`layout_end`:
|
||||
- `dashboard.php` — main landing page after login; shows news and quick links
|
||||
- `stundennachweis.php` — upload monthly timesheet (PDF/image)
|
||||
- `urlaubsantrag.php` — vacation request form
|
||||
- `abwesenheitsantrag.php` — absence request form (sick leave, etc.)
|
||||
- `benefitsantrag.php` — employee benefits request
|
||||
- `fortbildungsantrag.php` — training request with optional file upload
|
||||
- `einsatzbewertung.php` — rate a deployment/assignment
|
||||
- `einsatzanweisung.php` — view/download personal assignment instructions (PDF)
|
||||
- `dokumentenarchiv.php` — personal document archive (upload/view own documents)
|
||||
- `downloads.php` — company-wide file downloads (admin-managed)
|
||||
- `dienstplan.php` — view personal shift schedule
|
||||
- `werben.php` — refer a new employee
|
||||
- `settings.php` — profile settings: change password, upload avatar
|
||||
- `admin.php` — admin-only: tabs for Anträge, Nutzer, Dienstplan, Downloads, Fortbildungsmaterial, Stundennachweis, Bewertungen, News, Einsatzanweisung, Login-Versuche (failed login attempts: lists recent attempts, shows currently locked IPs, and clears the `login_attempts` table)
|
||||
- `admin-dienstplan.php` — admin shift planner view
|
||||
- Serve pages (`*-serve.php`, `dokument-serve.php`, `download-serve.php`, etc.) — stream protected files from `uploads/`, `downloads/`, `fortbildung-materials/` with auth check
|
||||
|
||||
#### Actions (`actions/`)
|
||||
POST-only endpoints, each does one thing and redirects back:
|
||||
- `submit-urlaubsantrag.php`, `submit-abwesenheitsantrag.php`, `submit-benefitsantrag.php`, `submit-fortbildungsantrag.php`, `submit-stundennachweis.php`, `submit-einsatzbewertung.php`, `submit-werben.php` — insert into the matching `requests_*` DB table, send notification email via `smtp_send()`
|
||||
- `admin-action.php` — admin status updates (accept/reject requests), user management (add/delete/reset password), news CRUD
|
||||
- `save-dienstplan.php` — admin saves shift entries
|
||||
- `downloads-action.php`, `downloads-reorder.php` — admin manages downloadable files
|
||||
- `fortbildung-material-action.php`, `fortbildung-material-reorder.php` — admin manages training materials
|
||||
- `einsatzanweisung-action.php` — admin uploads/assigns personal instruction PDFs
|
||||
- `upload-dokument.php`, `delete-dokument.php` — user document archive management
|
||||
- `upload-avatar.php` — user uploads profile picture (stored in `assets/avatars/`)
|
||||
- `save-profile.php` — user changes own password
|
||||
- `logout.php` — destroys session, redirects to `../index.php`
|
||||
|
||||
#### Frontend
|
||||
- `app.css` — all styles (no framework)
|
||||
- `manifest.webmanifest` + `service-worker.js` — PWA support ("Add to Home Screen")
|
||||
|
||||
### Database schema (MySQL)
|
||||
Managed via migrations in `migrations/`. Key tables:
|
||||
- `users` — id, username, name, role, password_hash, active, created_at, email, telefon, avatar
|
||||
- `requests_urlaubsantrag` — vacation requests (von, bis, vertretung, nachricht, status, admin_note)
|
||||
- `requests_abwesenheitsantrag` — absence requests (von, bis, grund, vertretung, nachricht, status, admin_note)
|
||||
- `requests_benefitsantrag` — benefits requests
|
||||
- `requests_fortbildungsantrag` — training requests (with optional file upload)
|
||||
- `requests_stundennachweis` — timesheet uploads (monat, filename)
|
||||
- `requests_werben` — employee referrals
|
||||
- `dienstplan` — shift schedule (user_id, date, schicht; UNIQUE on user_id+date)
|
||||
- `downloads` — company download files (title, filename, sort_order)
|
||||
- `fortbildung_materials` — training material files (title, filename, sort_order)
|
||||
- `dokumente` — user personal document archive (user_id, kategorie, filename)
|
||||
- `einsatzbewertungen` — deployment ratings
|
||||
- `einsatzanweisung` — one PDF per user (UNIQUE on user_id)
|
||||
- `news` — company news posts (title, text, date)
|
||||
- `schema_migrations` — tracks applied migrations
|
||||
|
||||
### Migration system
|
||||
`db.php` runs `_run_migrations()` on every connection. Migrations are PHP files in `migrations/` returning `['description' => ..., 'up' => [...SQL...]]`. They are applied in filename order and tracked in `schema_migrations`. Already-existing DBs without the migrations table are stamped as fully applied on first run.
|
||||
|
||||
### File storage
|
||||
Uploaded files are stored outside webroot or protected by `.htaccess`:
|
||||
- `uploads/` — user form attachments (stundennachweis, fortbildung, einsatzanweisung). Filename pattern: `{date}_{username}_{type}_{randomhex}.{ext}`
|
||||
- `downloads/` — admin-managed company downloads (hashed filenames)
|
||||
- `fortbildung-materials/` — admin-managed training materials (hashed filenames)
|
||||
- `assets/avatars/` — user profile pictures (`{username}_{randomhex}.{ext}`)
|
||||
|
||||
Allowed upload types: pdf, doc, docx, jpg, jpeg, png. Max size: 12 MB.
|
||||
|
||||
### Security conventions
|
||||
- `lib/` is blocked from direct HTTP access via `lib/.htaccess`
|
||||
- `uploads/`, `downloads/`, `fortbildung-materials/`, `data/`, `migrations/` all have `.htaccess` denying direct access; files are served only through `*-serve.php` pages with auth checks
|
||||
- All output uses `e()` (alias for `htmlspecialchars`) to prevent XSS
|
||||
- Every POST form includes a CSRF token (`csrf_field()` in form, `verify_csrf()` in action)
|
||||
- Login rate-limiting: 5 failures → 10-minute session lockout
|
||||
- Uploads are renamed to random hex filenames before storage
|
||||
|
||||
### Email (configured in `config.php`)
|
||||
- SMTP via `smtp_send()` in `lib/mail.php`; credentials in `config.php`
|
||||
- `mail_info` → `info@omsorg-pflegedienste.de` (Geschäftsführung)
|
||||
- `mail_sabrina` → `s.berggoetz@omsorg-pflegedienste.de` (Disposition)
|
||||
- `mail_from` → `no-reply@omsorg-pflegedienste.de`
|
||||
Reference in New Issue
Block a user