harbor-schedule is the production-facing Harbor calendar app.

Current implementation stack:

  • Node.js + Express backend
  • React + Vite frontend
  • FullCalendar interaction layer
  • PostgreSQL persistence

Current scope:

  • public per-user schedule pages at /<username>/
  • guest read access
  • owner/admin write access
  • PostgreSQL-backed schedule storage
  • recurring events:
    • none
    • daily
    • weekly
    • biweekly
    • monthly_same_day
  • fixed event colors:
    • red
    • pink
    • green
    • blue
    • cyan
    • yellow
    • purple
    • brown
  • Harbor-served theme shell, header, footer, timezone, and theme preferences
  • floating event editor panel
  • native browser page scrolling with the calendar toolbar and date headings floating beneath Harbor’s header
  • automatic initial page scroll to the first occupied week row in Month view and the earliest visible event in Week/Day views, leaving space for the floating bars; empty views start at the page top, and event edits preserve manual scrolling
  • Unix-socket management API for Harbor lifecycle control

Runtime contract:

  • public localhost HTTP server
  • management HTTP API on a Unix socket
  • YAML config loading via --config
  • Harbor-injected identity, permission, timezone, and theme context
  • optional harbor_database_url for startup ownership backfill against Harbor’s user table

Permissions used by the draft:

  • schedule.read
  • schedule.write

Guests may view schedules. Authenticated users with schedule.write may edit their own schedule. The admin permission may edit any existing schedule, but only the owner may create the first schedule for a user. Ownership is keyed to Harbor’s stable userId, while the public username slug remains a cached route identifier that can be updated when the owner renames their Harbor account. On startup, Schedule automatically backfills legacy username-owned rows from Harbor’s user table and refuses to start if any legacy rows remain unresolved.

Development:

npm install
npm run build:client
node server/server.mjs --config /path/to/schedule.yml

Calendar browser regression check (against an existing schedule in a running local Harbor deployment; event responses are replaced with deterministic fixtures):

npm install --no-save --package-lock=false playwright
npx playwright install chromium
node scripts/test-calendar.mjs http://localhost:5086/schedule/alice/

Harbor build packaging:

npm run build:harbor -- --app-dir /path/to/harbor-release/apps/schedule