Skip to main content

issues-api

Issues API

  • User Base Path: /api/v1/issues
  • Admin Base Path: /api/admin/issues
  • Auth: required for every endpoint (user token for /api/v1, admin token for /api/admin)

Issue Model

  • _id: string (ObjectId)
  • description: string (user-provided text, required)
  • category: string (user-provided tag, required)
  • attachments: string[] (zero-or-more HTTPS URLs that the reporter has already uploaded elsewhere)
  • user: string (ObjectId) — reporter id; populated with email for admin reads
  • status: 'open' | 'in_progress' | 'closed' (defaults to open when the issue is created)
  • statusHistory: [\{ status, comment?, updatedAt, updatedBy? \}] (admin-only; newest first when returned from admin endpoints)
  • createdAt / updatedAt: string (ISO timestamp)

User-facing endpoints (/api/v1/issues)

List Issues

  • GET /api/v1/issues
  • Query params:
    • category (optional string) — exact match filter
    • mine (optional boolean) — true to fetch only the authenticated user's issues
  • Returns: Issue[] sorted with newest first
  • Notes: user tokens see only their own issues unless mine=false AND the token belongs to an admin user (our auth middleware still enforces standard visibility rules).

Create Issue

  • POST /api/v1/issues
  • Body:
    {
    "description": "Latitude won’t load leaderboard",
    "category": "app_bug",
    "attachments": ["https://cdn.example.com/issue-screens/123.png"]
    }
  • Returns: the created Issue (status fixed to open at this stage).
  • Validation:
    • description / category must be non-empty strings.
    • attachments, if present, must be an array of valid URLs.

Get Issue By Id

  • GET /api/v1/issues/:id
  • Returns: the matching Issue or 404.

Update Issue

  • PATCH /api/v1/issues/:id
  • Body: any subset of \{ description, category, attachments \} (all optional, but at least one must be present).
  • Returns: updated Issue.
  • Notes: reporters cannot change status or status history from the public API.

Delete Issue

  • DELETE /api/v1/issues/:id
  • Returns: 204 on success.

Admin endpoints (/api/admin/issues)

List Issues

  • GET /api/admin/issues
  • Query params: category (optional string)
  • Returns: Issue[] with reporter user populated to \{ _id, email \} and statusHistory sorted newest-first.

Get Issue

  • GET /api/admin/issues/:id
  • Same response shape as list item (includes statusHistory).

Update Issue

  • PATCH /api/admin/issues/:id
  • Body: any combination of description, category, attachments, status, plus optional statusComment when status is provided.
    {
    "status": "in_progress",
    "statusComment": "Reached out to the player for extra logs.",
    "category": "support"
    }
  • Behaviour:
    • When status changes, the server requires statusComment to be non-empty.
    • A history entry is appended with the new status, comment, timestamp, and the admin's user id.
  • Returns: updated issue (with fresh history ordering and reporter email).

Delete Issue

  • DELETE /api/admin/issues/:id
  • Returns: \{ ok: true \} when the issue was removed.

Frontend Guidance

  • Default new issues to status = 'open'; only admins should surface UI to transition statuses.
  • When calling the admin PATCH endpoint with a status change, always supply a comment string — the backend rejects empty comments.
  • Render status history in reverse chronological order (already pre-sorted from the API). Each entry may include the admin email when available; fall back to displaying the raw id if updatedBy was just an ObjectId.
  • For reporter details, the admin responses include a user.email — use it for quick Gmail compose links: https://mail.google.com/mail/?view=cm&fs=1&to=<email>.
  • Attachment URLs are plain strings; frontend should open them in a new tab and handle cases where the array is empty.