← back to Dw Activation Calendar

README.md

61 lines

# DW Calendar

Two surfaces in one Express app on `:9765` (DTD verdict **AX**, 2026-06-24).

## Tabs
- **Google Calendar** — live, **editable** view of the shared DW Google Calendar.
  Click any day or event → modal creates / edits / deletes real events
  (`events.insert` / `patch` / `delete`). Built on a fetch-only Google Calendar
  v3 client (`google-cal.js`) — **no `googleapis` SDK dependency**.
- **SKU Activation** — read-only projection of the staged-for-active SKU rollout
  (`/api/schedule`, sourced from `dw_unified.bulk_fivefield_worklist`). Unchanged
  from the original build.

## API
| Method | Path | Notes |
|---|---|---|
| GET | `/api/calendar/status` | `{oauth_configured, connected, calendar_id}` |
| GET | `/api/events?timeMin=&timeMax=` | events.list for a window |
| POST | `/api/events` | create — body `{summary,description?,location?,start,end,allDay?}` |
| PATCH | `/api/events/:id` | update (events.patch) |
| DELETE | `/api/events/:id` | delete |
| GET | `/api/oauth/start` | 302 → Google consent (503 if not configured) |
| GET | `/api/oauth/callback` | token exchange |
| POST | `/api/oauth/revoke` | disconnect |
| GET | `/api/schedule` | SKU-activation projection (existing) |

All event routes degrade gracefully when no credential is present: `409 not_connected`
/ `{connected:false}` — **never a 500**.

## Connecting the Google Calendar (Steve — GATED)
The OAuth credential, secrets-fan-out, and consent click are Steve-only. The full
runbook is queued at:

`~/.claude/yolo-queue/pending-approval/2026-06-24-dw-google-calendar-oauth-credential.md`

Short version:
1. Google Cloud Console → enable Calendar API → create a **Web application** OAuth
   client → add redirect URI `http://127.0.0.1:9765/api/oauth/callback`.
2. Route the secret: `node ~/Projects/secrets-manager/cli.js add GOOGLE_OAUTH_CLIENT_ID '<id>'`
   and `... GOOGLE_OAUTH_CLIENT_SECRET '<secret>'` (add a routes.json entry first
   so it lands in `./.env`). Optionally set `GOOGLE_DW_CALENDAR_ID` to a dedicated
   "DW Ops" calendar id; default is `primary`.
3. Visit `http://127.0.0.1:9765/api/oauth/start` and grant consent.
4. Verify: `curl -s http://127.0.0.1:9765/api/calendar/status` → `connected:true`.

## Env
```
PORT                       default 9765
GOOGLE_OAUTH_CLIENT_ID     (or GOOGLE_CLIENT_ID)
GOOGLE_OAUTH_CLIENT_SECRET (or GOOGLE_CLIENT_SECRET)
GOOGLE_OAUTH_REDIRECT_URI  default http://127.0.0.1:9765/api/oauth/callback
GOOGLE_DW_CALENDAR_ID      default 'primary'
GOOGLE_CAL_TOKEN_FILE      default ./.google-tokens.local.json (gitignored, 0600)
DATABASE_URL / PG*         dw_unified (for the SKU tab)
```

## Run
```
PORT=9765 node server.js
```