vacation days planner
- JavaScript 87.8%
- CSS 6.6%
- HTML 5.5%
|
|
||
|---|---|---|
| data | ||
| lib | ||
| public | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| env.example | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| server.js | ||
Vacation Days
A lightweight, real-time collaborative Kanban board for small-group event and vacation planning. No accounts, no database — just share a board name and go.
Built with Node.js, Express, Socket.IO, and vanilla JavaScript. All data is stored as JSON files on the filesystem.
Created with LLM assistance over a long-ish weekend. Scale is not a goal.
Running
Node.js directly:
npm start
Runs on port 3000 by default.
Docker:
docker-compose build
docker-compose up -d
Exposed on port 59061 externally, mapped to 3000 internally.
Features
- Real-time sync — changes from any connected client are broadcast instantly via Socket.IO
- Kanban columns by date — add single days or date ranges; columns are sorted chronologically
- Tasks — add, edit, delete; supports notes, color coding, and completion state
- Done tasks sink to bottom — completed tasks are automatically sorted to the bottom of their column
- Per-column tags — label columns with color-coded tags
- Board description — freeform subtitle below the board title, editable inline
- Undo / redo — 20-step undo stack with descriptive toasts (e.g. "Undid: task added")
- Dark mode — toggleable light/dark theme, persisted across sessions
- Copy shareable link — one-click copy of the board URL
- Keyboard shortcuts — see below
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
n |
Add task to the column under the cursor |
Ctrl+Enter |
Submit the open modal |
Ctrl+Z |
Undo |
Ctrl+Shift+Z / Ctrl+Y |
Redo |
Escape |
Close open modal |
A full shortcuts reference is available via the ⌨ button on the home page.
Security
Access control is by board name only (security by obscurity). There is no authentication or user system.
- Board names are alphanumeric only; invalid names are rejected
- 5 failed board name attempts triggers a 15-minute IP lockout
- No board enumeration endpoint — board names cannot be listed
- Socket.IO events are scoped to board-specific rooms; data is never broadcast to unrelated clients
- Request body size is capped at 100 KB
X-Forwarded-Foris trusted for real IP detection behind reverse proxies