Root cause: cookie was set with Secure=true whenever NODE_ENV=production.
Browsers refuse to send Secure cookies over plain HTTP, so the session
cookie was dropped on every request after login — causing every protected
endpoint to return 401.
Fix: replace the NODE_ENV check with an explicit COOKIE_SECURE env var
(default false). Set COOKIE_SECURE=true only when running behind an HTTPS
reverse proxy. Direct HTTP installs (standard Unraid setup) work as-is.
Also updated UNRAID.md to document COOKIE_SECURE with a warning explaining
why it must stay false for plain-HTTP access.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add openssl + openssl-dev to Dockerfile apk install; Alpine does not
ship OpenSSL by default but Prisma's query engine binary requires it
- Add binaryTargets to schema.prisma generator:
native → used during docker build (npx prisma generate)
linux-musl-openssl-3.0.x → correct engine binary for Alpine at runtime
Without the explicit target Prisma defaults to openssl-1.1.x, which
does not exist on Alpine 3.18+, producing the "Could not parse schema
engine response" error at migrate/startup time
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GUI method: Docker tab field-by-field walkthrough (name, port, volume, env vars)
- CLI method: docker run one-liner with all required flags
- Building the image: local build on Unraid terminal + push-to-registry option
- JWT_SECRET generation tip using /proc/sys/kernel/random/uuid
- Updating, password change, backup, and troubleshooting sections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drag handle at bottom edge of each module (GripHorizontal icon)
- Pointer capture tracks vertical drag delta → U-size delta
- Clamped to: minimum 1U, rack bounds, first module below
- Shows current U-size label during active resize
- On release: PUT /modules/:id with new uSize (server validates collision)
- Optimistic store update via updateModuleLocal on success
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Full CRUD: create, inline-edit, delete with confirm dialog
- Table shows VLAN ID, name, description, color swatch
- Add-VLAN form at top; hover shows edit/delete actions per row
- Route registered in App.tsx under ProtectedRoute
- VLANs nav button added to RackToolbar and MapToolbar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Right-click on canvas → add any node type at cursor position
- Right-click on node → edit, duplicate, or delete
- Right-click on edge → toggle animation, set edge type (bezier/smooth/step/straight), delete
- Double-click a node → NodeEditModal (label, accent color, rack module link)
- ContextMenu component: viewport-clamped, closes on outside click or Escape
- All actions persist to API; React Flow state updated optimistically
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Complete project scaffold with working auth, REST API, Prisma/SQLite
schema, Docker config, and React frontend for both Rack Planner and
Service Mapper modules. Both server and client pass TypeScript strict
mode with zero errors. Initial migration applied.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>