43 Commits

Author SHA1 Message Date
loki 9cbda65ab0 fix: all booking endpoints create new slots for parallel rendering
Build & Push Docker Image / build (push) Successful in 13s
- POST /api/public/bookings: creates new slot instead of reusing
- POST /api/bookings/manual: creates new slot instead of reusing
- POST /api/slots (with customer): creates new slot for the booking
- POST /api/public/book-slot: already fixed previously
- All 4 endpoints now produce parallel slot blocks
2026-05-20 22:45:09 +02:00
loki 4a731ab5c6 fix: overlap check only counts slots with bookings
Build & Push Docker Image / build (push) Successful in 15s
2026-05-20 21:29:35 +02:00
loki 827bf2a12b fix: book-slot always creates new slot for parallel rendering
Build & Push Docker Image / build (push) Successful in 13s
2026-05-20 20:48:30 +02:00
loki c383638f34 fix: use dayCap instead of slot.max_bookings for capacity check in public API
Build & Push Docker Image / build (push) Successful in 30s
2026-05-20 20:21:27 +02:00
loki 827eb724fc feat: slot click opens edit, status buttons for all states, manual entry without email
Build & Push Docker Image / build (push) Successful in 14s
2026-05-14 18:52:21 +02:00
loki 491ec0cbc4 fix: nullish coalescing operator precedence in overlap.ts
Build & Push Docker Image / build (push) Successful in 13s
2026-05-13 23:11:23 +02:00
loki f91d9754b1 feat: parallel slots side by side, overlap counting by capacity
Build & Push Docker Image / build (push) Failing after 9s
2026-05-13 22:58:06 +02:00
loki e7e93d74e5 fix: admin calendar shows capacity per day, no sub-blocks for free slots
Build & Push Docker Image / build (push) Successful in 13s
- Backend: dailyCapacities includes ALL dates (blocked + slot dates)
- Admin calendar slot blocks:
  - Title bar with slot name
  - Booking rows only for existing bookings/blocked slots
  - No 'Frei' sub-blocks shown
- Customer calendar unchanged (still shows Frei/Belegt/Ausstehend/Bestätigt)
- Capacity header (± controls) now visible for all week days
2026-05-13 21:27:25 +02:00
loki 56ea1a6364 feat: daily capacity per day with ± controls in calendar header
Build & Push Docker Image / build (push) Successful in 13s
- New daily_capacity table with date-based overrides
- Default = COUNT of it_support users (dynamic)
- Backend: GET/PUT/DELETE /api/capacity/:date
- Backend: POST /api/capacity/batch for multiple dates
- Slots API returns dailyCapacities map alongside slots
- Public API: new slots get day_capacity as max_bookings
- WeekCalendar header: − N + ✕ capacity controls per day
- SlotsPage: capacity mutations + passes to calendar
- WeekCalendar slot blocks use day capacity for maxB
2026-05-13 20:47:04 +02:00
loki 6032630a4b fix: overlap check against ALL slots, not just those with bookings
Build & Push Docker Image / build (push) Successful in 1m0s
2026-05-13 00:08:05 +02:00
loki e6fbdd036d feat: prevent overlapping bookings across slots on same day
Build & Push Docker Image / build (push) Successful in 12s
2026-05-12 22:35:55 +02:00
loki 9cd0817f15 feat: technician assignment + webhooks (Slack/Teams)
Build & Push Docker Image / build (push) Successful in 12s
- Backend: assigned_to column on slots + GET /api/users
- SlotForm: technician dropdown to assign IT/AM staff
- SlotsPage: shows assigned technician name in detail panel
- Webhooks table + CRUD routes (POST/GET/PUT/DELETE /api/webhooks)
- Webhook sender with Slack-compatible format
- Webhooks triggered on booking.created/confirmed/cancelled
- Settings: new Webhooks tab with add/list/toggle/delete
- DB: webhooks table with migrations
2026-05-11 23:20:33 +02:00
loki 2c08046fb3 fix: URL kopieren button with toast popup instead of emoji
Build & Push Docker Image / build (push) Successful in 13s
2026-05-11 19:43:48 +02:00
loki 715b61ce58 feat: booking link copy, customer history, email templates
Build & Push Docker Image / build (push) Successful in 13s
- Copy booking link buttons in Slot panel and Bookings list
- Customer history modal from Slot panel (📋 icon)
- Backend: GET /api/bookings supports customer_email filter
- Backend: new GET/PUT /api/email-templates
- DB: email_templates table with 3 default templates
- Email transporter reads templates from DB with {{var}} placeholders
- Settings: new E-Mail tab with template editor + preview
- Placeholders: app_name, customer_name, slot_title, slot_date, start_time, end_time, booking_url
2026-05-11 19:04:45 +02:00
loki f2ae74d699 fix: seed runs Better-Auth migrations before creating admin user
Build & Push Docker Image / build (push) Successful in 13s
2026-05-11 00:03:37 +02:00
loki 72c7a2d9db fix: inline SQL schema in database.ts (no file dependency)
Build & Push Docker Image / build (push) Successful in 3s
2026-05-10 23:49:16 +02:00
loki 0acd654c5f feat: auto-seed admin user on first start (Docker-ready)
Build & Push Docker Image / build (push) Successful in 12s
- New server/src/seed.ts creates admin user via auth API if not exists
- Called from index.ts after app.listen
- Configurable via env: ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_NAME, ADMIN_ROLE
- Defaults match existing test account (admin@test.de / Test1234!)
- Settings table already seeded via schema.sql INSERT OR IGNORE
2026-05-10 23:22:22 +02:00
loki 929c985e51 fix: add cc_email and notes to manual booking and slot+booking creation
Build & Push Docker Image / build (push) Successful in 14s
2026-05-10 23:09:58 +02:00
loki 2412c7da1d fix: CC email receives same notification emails as customer
Build & Push Docker Image / build (push) Successful in 12s
2026-05-10 22:48:34 +02:00
loki d8cc5543de fix: show notes and CC email in admin bookings panel
Build & Push Docker Image / build (push) Successful in 12s
2026-05-10 22:34:29 +02:00
loki be81071e5a feat: customer notes and CC email for IT department
Build & Push Docker Image / build (push) Successful in 12s
- DB: bookings table gets cc_email and notes columns (with migration)
- Backend: all booking endpoints accept cc_email and notes
- Customer booking form: CC email field + notes textarea
- Email templates updated to show sender from CC config
2026-05-10 22:22:51 +02:00
loki e561416675 feat: expanded settings with working hours, booking rules, app name
Build & Push Docker Image / build (push) Failing after 8s
2026-05-10 22:16:47 +02:00
loki 683309eb94 feat: create slot + direct customer booking in one step
Build & Push Docker Image / build (push) Successful in 14s
- Backend POST /api/slots accepts optional customer fields (name, email, company, location)
- When customer data provided: creates slot + booking simultaneously
- Frontend SlotForm: toggleable 'Kunde direkt zuweisen' section
- IT/AM can create slot and immediately assign a customer
2026-05-10 21:31:13 +02:00
loki 19f41c695d feat: booking-to-slot navigation, tabbed settings with SMTP, email config from DB
Build & Push Docker Image / build (push) Successful in 13s
- BookingsPage: click booking -> navigates to /dashboard?slot_id=X&date=Y
- SlotsPage: reads query params, navigates to correct week, auto-selects slot
- SettingsPage: tabbed UI (Allgemein + SMTP) with separate field groups
- SMTP settings stored in DB settings table (smtp_host, smtp_port, etc.)
- Email transporter reads from DB settings with env var fallback
2026-05-10 13:36:25 +02:00
loki 87c09d6780 feat: blocked_count replaces is_blocked - fine-grained slot blocking
- Schema: blocked_count INTEGER (0 = none, max_bookings = all blocked)
- Backend: PUT /api/slots/:id/blocked-count with count param
- Admin panel: +/-/Alle buttons to set blocked slots per slot
- SlotForm: blocked_count stepper (increase/decrease per slot)
- Customer calendar: blocked sub-blocks shown red 'Blockiert'
- Admin calendar: blocks count displayed in slot details
- Public API: available = (blocked_count + total_booked) < max_bookings
- Migration: auto-adds blocked_count, copies old is_blocked data
2026-05-09 23:57:20 +02:00
loki 97297ccaa2 fix: show blocked slots in customer calendar with 'Blockiert' label
- Public API: no longer filters blocked slots out, includes is_day_blocked flag
- Public API response: includes blockedDates array for UI
- Customer calendar: blocked slots show 'Blockiert' with red dot
- Admin calendar: uses isSlotOrDayBlocked for styling
- SlotData interface: added is_day_blocked field
2026-05-09 23:42:16 +02:00
loki a49b27f7e2 feat: block entire days + visible blocked days in calendar
- New blocked_dates table (date, reason, created_by)
- Backend: GET/POST/DELETE /api/blocked-dates routes
- Backend: public API filters out slots on blocked dates
- Backend: slots API returns blockedDates alongside slots
- Frontend: blocked days shown with red striped pattern in calendar
- Frontend: blocked day header shows red background + diagonal stripes
- Frontend: 'Tag blocken' modal with reason input
- Frontend: blocked days summary bar with quick unblock (✕)
2026-05-09 23:13:43 +02:00
loki 046b246cc9 feat: slot block/unblock, manual customer entry, capacity per slot
- Schema: is_blocked column for slots
- Backend: POST /api/bookings/manual for IT/AM to enter customers manually
- Backend: PUT /api/slots/:id/block toggle
- Backend: public API filters out blocked slots
- Frontend SlotForm: block toggle checkbox
- Frontend SlotsPage: detail panel with block/entblock + customer entry form
- Frontend: blocked slots shown with red badge in calendar
- is_blocked in types, PublicSlot updated
2026-05-09 22:58:48 +02:00
loki 467cd59899 feat: slot bookings as vertically stacked sub-blocks in calendar
- Admin calendar: each capacity unit shown as sub-block with customer name
- Customer calendar: sub-blocks show Frei/Belegt/Ausstehend/Bestätigt per slot
- SlotsPage: detail panel right side with booking list + confirm/cancel
- Backend returns bookings array per slot via GET /api/slots
2026-05-09 14:24:42 +02:00
loki 3a9b0fe52b fix: disable email sending when SMTP not configured 2026-05-09 13:50:59 +02:00
loki 1116e19761 fix: add trustedOrigins to prevent invalid origin error 2026-05-09 13:43:20 +02:00
loki d6520319a6 feat: password show/hide, slot status colors, form persistence
- Password field: toggle visibility with 👁️/🙈 icon
- Customer calendar: slots colored by booking status
  - Amber = ausstehend (pending)
  - Green = bestätigt (confirmed)
  - Grey = storniert (cancelled)
  - Blue = frei (available)
  - Red = von anderen belegt
- Public API: returns myStatus per slot for logged-in customer token
- Form fields persist when switching time slots (no reset)
2026-05-09 13:17:55 +02:00
loki 7660a7aec2 feat: customer can click any free cell 08-15 to book
- New POST /api/public/book-slot endpoint
- Creates slot + booking in one step if no slot exists
- Reuses existing slot if one exists at that time
- Customer mode: cell click opens booking form
- Backend validates capacity, auto-calculates end_time
- Admin slot blocks still clickable for editing
2026-05-09 12:39:38 +02:00
loki b799e0e5d3 fix: use toNodeHandler, fromNodeHeaders, dotenv, and migrate BA tables 2026-05-08 22:50:59 +02:00
loki 3071635f7e fix: add static serve for production + info page for dev 2026-05-08 22:39:07 +02:00
loki 832274d629 fix: resolve TS errors in Card and SlotForm 2026-05-07 22:49:43 +02:00
loki 21472d3695 feat: add email system with booking templates 2026-05-07 22:27:30 +02:00
loki d102e6da1c feat: add public customer booking API with token auth 2026-05-07 22:23:45 +02:00
loki d05973a33d feat: add bookings API with confirm/cancel 2026-05-07 22:23:35 +02:00
loki ec789a46f9 feat: add slots CRUD API routes 2026-05-07 22:23:11 +02:00
loki 4d56df1bc8 fix: remove FK reference to users table (created by Better-Auth) 2026-05-07 22:11:51 +02:00
loki 7c23efc90c feat: add SQLite schema and database init 2026-05-07 22:07:55 +02:00
loki 2c73633d98 chore: scaffold project structure with Vite, Express, Tailwind 2026-05-07 21:56:59 +02:00