Skip to content

Add Slack-authenticated bathroom timer with chat commands and UTC leaderboards#267

Draft
sfreeman422 with Copilot wants to merge 7 commits into
masterfrom
copilot/add-slack-auth-bathroom-timer
Draft

Add Slack-authenticated bathroom timer with chat commands and UTC leaderboards#267
sfreeman422 with Copilot wants to merge 7 commits into
masterfrom
copilot/add-slack-auth-bathroom-timer

Conversation

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown

Adds a Slack-authenticated bathroom timer flow to the existing web UI, backed by persisted timer sessions, Slack slash-command controls, and UTC leaderboards sorted from least to most total bathroom time. The change keeps Slack ID as the user identity, enforces one active timer per user, and exposes the required timer/me/leaderboard endpoints plus chat integrations.

  • Backend: bathroom timer domain + APIs

    • Added BathroomUser and BathroomTimer TypeORM models for persisted user profiles and timer sessions.
    • Added /api/me, /api/timer/start, /api/timer/stop, and /api/leaderboard.
    • Enforced a single active timer per user and persisted duration_seconds on stop.
    • Leaderboard aggregates completed timer overlap within the selected UTC range and sorts ascending by total time.
    • Added shared leaderboard aggregation for daily, weekly, monthly, and lifetime reporting.
  • Auth/session flow

    • Extended Slack OAuth callback to upsert the bathroom user profile from Slack identity data.
    • Switched frontend session continuity to an HTTP-only cookie while retaining bearer-token compatibility for existing authenticated routes.
    • Added logout handling for the cookie-backed session.
  • Frontend: timer UX on home page

    • Updated the unauthenticated landing page copy to reflect the bathroom timer use case.
    • Added home-page timer state, start/stop toggle, current active elapsed time, date selector, and daily leaderboard rendering.
    • Reused existing auth-protected fetch patterns via a shared authenticated request helper.
  • Slack chat integration

    • Added signed Slack slash-command endpoints for /start, /stop, and /bathroom.
    • /start and /stop let a user manage their own bathroom timer directly in chat.
    • /bathroom [daily|weekly|monthly|lifetime|all] returns the requested leaderboard view(s) in Slack.
    • Slash-command users are upserted into the bathroom user table so chat-first usage works without requiring the web UI first.
  • Docs/config

    • Documented SESSION_SECRET, Slack callback expectations, bathroom timer endpoints, Slack slash-command URLs, and UTC leaderboard behavior in README.md.
    • Updated backend .env.example with the new session secret requirement.
  • Representative API shape

    GET /api/me
    {
      "user": {
        "slack_id": "U123",
        "display_name": "alice",
        "avatar_url": "https://..."
      },
      "active_timer": {
        "id": 42,
        "start_at": "2026-06-30T12:00:00.000Z",
        "end_at": null,
        "duration_seconds": null
      }
    }
Original prompt

Add Slack-authenticated bathroom timer feature with daily leaderboard

Summary:
Implement a feature that allows users to visit the site, sign in with Slack (use Slack ID as the user identity), and start/stop a personal bathroom timer. The system must enforce one active timer per user. Persist timer sessions in the database. Provide a daily leaderboard shown on the frontend that lists users sorted from least to most total bathroom time for the selected day (default: today). The frontend should show login, a start/stop toggle, current active timer status, and the day's leaderboard.

Requirements & constraints (from conversation):

  • Repository: dev-chat/mocker
  • Open a pull request when finished.
  • Only one active timer per user.
  • No anonymization: leaderboard shows user display names.

Tech stack & defaults (use these unless the repo already dictates otherwise):

  • Backend: Node.js + Express
  • Frontend: React
  • DB: PostgreSQL
  • ORM/query: Knex or Sequelize (implementer may choose based on repo); include SQL migration if ORM not present

Auth & identity:

  • Use Slack OAuth to authenticate users. Identify users by their Slack ID that comes from the Slack OAuth response.
  • Required env vars: SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_REDIRECT_URI, SESSION_SECRET, DATABASE_URL
  • Store minimal user profile: slack_id (unique), display_name, avatar_url (optional), created_at

Backend API endpoints to implement:

  • GET /auth/slack -> redirect to Slack's OAuth authorize URL
  • GET /auth/slack/callback -> handle OAuth callback, create or update user record, create server session (cookie-based), then redirect to front-end home
  • POST /api/timer/start -> start a new timer for the authenticated user. Return 409 if an active timer exists.
    Request: none (user is authenticated via cookie/session)
    Response: 201 with timer id and start timestamp
  • POST /api/timer/stop -> stop the active timer for the authenticated user. Return 404 if no active timer.
    Response: 200 with timer id, start, end, duration_seconds
  • GET /api/leaderboard?date=YYYY-MM-DD -> returns leaderboard for the given date (UTC or server timezone; document default). Response: list of { slack_id, display_name, total_seconds }
  • GET /api/me -> returns current authenticated user and active timer info (if any)

Database schema (migrations):

  • users: id (pk), slack_id (unique), display_name, avatar_url, created_at, updated_at
  • timers: id (pk), user_id (fk -> users.id), start_at (timestamp with tz), end_at (timestamp with tz, nullable), duration_seconds (integer, nullable), created_at, updated_at
  • Enforce index on timers.user_id and timers.start_at

Business logic details:

  • Starting a timer: ensure user has no timers where end_at IS NULL; if exists, return an error. Otherwise insert a timer with start_at = now.
  • Stopping a timer: find timers where user_id = current and end_at IS NULL; set end_at = now and duration_seconds = EXTRACT(EPOCH FROM end_at - start_at) rounded to integer.
  • Leaderboard calculation: for a given date (server-local or UTC — choose and document), sum duration_seconds for timers WHERE start_at >= date at 00:00 and start_at < date+1 day OR timers that overlap the day. Simpler approach: include timers whose start_at is on that date. Document limitation if any. Sort ascending (least -> most). Include zero-time users? Include only users with at least one timer entry that day. Frontend can show top N or full list.

Frontend changes:

  • Home page: show Slack login button when not authenticated.
  • When authenticated: show current active timer status and a Start/Stop button. Button text toggles based on active timer.
  • Show today's leaderboard: list of users sorted least -> most with display name and formatted total time (mm:ss or H:mm).
  • Small responsive UI; minimal styling acceptable.

Testing & docs:

  • Add unit/integration tests for start/stop endpoints and leaderboard calculation if repo has testing setup; otherwise add at least one end-to-end manual test plan in README.
  • Update README with required env vars and Slack app setup steps (OAuth redirect URL matching SLACK_REDIRECT_URI), plus migration instructions.

Implementation notes / acceptance criteria:

  • A reviewer can run migrations, set env vars, start server, and authenticate with Slack to use start/stop timers.
  • Leaderboard must be visible on the front page and sort users from least to most total bathroom time for the day.
  • Server must prevent multiple active timers per user.
  • Use session cookies to maintain login state; security best practices (SESSION_SECRET, secure cookies) should be noted in README.

Files likely to change (examples):

  • backend: routes/auth.js, routes/timer.js, routes/leaderboard.js, models/user.js, models/timer.js, migrations/*.sql or knexfile
  • frontend: src/components/TimerButton.jsx, src/components/Leaderboard.jsx, src/pages/Home.jsx, auth integration files
  • docs: README.md (env, Slack setup, run/migrate steps)

Please implement this feature in repository...

This pull request was created from Copilot chat.

Copy link
Copy Markdown
Collaborator

@copilot also add an integration to let you do /start and /stop in chat - also /bathroom to view daily, weekly, monthly and lifetime leaderboards

Copilot AI changed the title [WIP] Add Slack-authenticated bathroom timer feature with daily leaderboard Add Slack-authenticated bathroom timer with daily leaderboard Jun 30, 2026
Copilot AI requested a review from sfreeman422 June 30, 2026 18:06

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Author

@copilot also add an integration to let you do /start and /stop in chat - also /bathroom to view daily, weekly, monthly and lifetime leaderboards

Addressed in ec2de71 and 9e9e9d3. /start and /stop now manage the caller’s bathroom timer from Slack, and /bathroom returns daily, weekly, monthly, and lifetime leaderboards (or a single scope via daily|weekly|monthly|lifetime|all).

Copilot AI changed the title Add Slack-authenticated bathroom timer with daily leaderboard Add Slack-authenticated bathroom timer with chat commands and UTC leaderboards Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants