sdp-request-watcher/CLAUDE.md
Skylar Grant f620cd96d4 Document hosted per-user setup and plan per-browser settings
README covers the Server-based Zoho client, the new .env settings,
deployment (image, compose, Nginx Proxy Manager), signing in and the
security model. NOTES records the Zoho OAuth gotchas and the decisions
behind the rebuild. ROADMAP describes the current architecture and the
planned per-browser settings panel. CLAUDE.md and SESSION.md are
brought up to date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:38:08 -04:00

3.5 KiB

CLAUDE.md

Context for Claude Code sessions in this repo. Keep this short. Longer notes live in docs/.

Project

A help desk dashboard for ManageEngine ServiceDesk Plus Cloud (ithelp.mainecc.edu). It's a stateless Node/Express server, shipped as the Docker image v0idf1sh/sdp-dashboard, running behind Nginx Proxy Manager with an MCCS IP allow list. Each user signs in with their own Zoho account; the session is an encrypted cookie. The central region (KVCC, EMCC, CMCC, MCCS) is configured through .env.

  • Goal and next steps: per-browser settings and panel modules. See docs/ROADMAP.md.
  • Decisions, API gotchas and known issues: docs/NOTES.md. Read it before touching any SDP query.
  • Latest session summary and handoff: SESSION.md.

Run

npm install
npm run app        # node src/server.js from the repo root; .env lives in the repo root

The app is served at http://localhost:3000. .env needs CLIENT_ID/CLIENT_SECRET from a Zoho Server-based Application client with http://localhost:3000/auth/callback as a redirect URI, plus a SESSION_SECRET of 32 or more characters.

Releases: push a v*-prod* tag. .gitea/workflows/docker.yml builds and pushes the image; the VPS is updated by hand.

Layout

  • src/server.js: reads .env, holds the region settings and timing, and starts Express.
  • src/auth.js: Zoho web OAuth (authorization URL, code exchange, renewal, revoke, user info).
  • src/session.js: the encrypted session cookie and the requireSession middleware, which renews the access token when it's due.
  • src/routes.js: /auth/* (login, callback, logout) and /api/* (session, closed, workload, weather; all need a sign-in).
  • src/tickets.js: all SDP queries (closed feed, status table, closed today, unassigned). A 401 from SDP is rethrown so the route signs the user out.
  • src/weather.js: OpenWeatherMap, cached for 10 minutes and shared by all users.
  • src/public/index.html: the whole front end in one file (inline CSS and JS, no build step). It runs the polling timers and keeps the closed feed.
  • Dockerfile, docker-compose.yml (example for the VPS), .gitea/workflows/docker.yml.

Working agreements

  • Never print or commit .env values (Zoho client secret, SESSION_SECRET, OpenWeatherMap key). Redact them when inspecting.
  • Never send Zoho tokens to the page or put them in logs. They stay inside the encrypted cookie and server memory for the length of a request.
  • There are no automated tests yet. Verify server logic by stubbing axios.get and axios.post. Resolve axios from the project with require.resolve('axios', { paths: [dir] }) so the stub hits the same instance. Verify the page by evaluating its <script> with stubbed document, fetch, location and history, or by taking a screenshot with headless Edge.
  • The sandbox can't bind TCP ports, but it can listen on a unix socket with a short relative path (cd to the scratchpad and listen on x.sock). To run server.js end to end, patch express.application.listen. Docker isn't available in the sandbox.
  • Match the existing style: 4-space indent and CommonJS on the server, 2-space indent in index.html, lowercase // comments explaining why rather than what. Some files have CRLF line endings, so use the Edit tool rather than sed for multi-line changes.
  • Keep the core closed-ticket watcher (feed and ding) working and on by default.
  • Don't commit unless asked. Commit messages end with the Co-Authored-By line for Claude.
  • Record new decisions and gotchas in docs/NOTES.md, and move roadmap items as they're done.