From 6efe2eaa7a25107c80491158e7ca64bb9e45e26c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Apr 2026 22:30:09 +0000 Subject: [PATCH] Bridge request: Trinity Console Issue Tracker (Task #166) Mobile-first issue tracker for Holly. Screenshot upload from phone, minimal friction submission while in-game. Full schema, API routes, and UI spec for Code. Chronicler #89 --- .../requests/REQ-2026-04-14-issue-tracker.md | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 docs/code-bridge/requests/REQ-2026-04-14-issue-tracker.md diff --git a/docs/code-bridge/requests/REQ-2026-04-14-issue-tracker.md b/docs/code-bridge/requests/REQ-2026-04-14-issue-tracker.md new file mode 100644 index 0000000..f2968c9 --- /dev/null +++ b/docs/code-bridge/requests/REQ-2026-04-14-issue-tracker.md @@ -0,0 +1,123 @@ +# Code Bridge Request: Trinity Console Issue Tracker + +**Date:** 2026-04-14 +**From:** Chronicler #89 +**Priority:** High +**Task:** #166 + +--- + +## What We Need + +A full issue tracker module in Trinity Console. This is Holly's primary pain point — she infodumps bugs and requests in Discord DMs and Michael loses track. The issue tracker becomes the canonical location for all issues. + +## The Critical UX Requirement + +Holly plays Minecraft on her phone/PC. When something breaks, she screenshots it on her phone and needs to submit an issue **without tabbing out of the game**. This means: + +- **Mobile-first responsive design** — must work perfectly on a phone browser +- **Screenshot upload from camera roll** — tap, select photo, done +- **Minimal form fields** — title, description, screenshot, priority, category. That's it for submission. +- **Fast** — she's in-game, she wants to fire and forget + +## Database Schema + +### `issues` table +```sql +CREATE TABLE issues ( + id SERIAL PRIMARY KEY, + issue_number INTEGER UNIQUE, + title VARCHAR(255) NOT NULL, + description TEXT, + status VARCHAR(20) DEFAULT 'open', -- open, in-progress, blocked, resolved, closed + priority VARCHAR(20) DEFAULT 'medium', -- critical, high, medium, low + category VARCHAR(50) DEFAULT 'general', -- bug, feature, content, infrastructure, holly, general + submitted_by VARCHAR(100) NOT NULL, -- Discord username + assigned_to VARCHAR(100) DEFAULT 'unassigned', + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW(), + resolved_at TIMESTAMPTZ, + resolved_by VARCHAR(100) +); +``` + +### `issue_attachments` table +```sql +CREATE TABLE issue_attachments ( + id SERIAL PRIMARY KEY, + issue_id INTEGER REFERENCES issues(id) ON DELETE CASCADE, + filename VARCHAR(255) NOT NULL, + original_name VARCHAR(255), + mime_type VARCHAR(100), + file_size INTEGER, + uploaded_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +### `issue_comments` table +```sql +CREATE TABLE issue_comments ( + id SERIAL PRIMARY KEY, + issue_id INTEGER REFERENCES issues(id) ON DELETE CASCADE, + author VARCHAR(100) NOT NULL, + content TEXT NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +## API Routes + +``` +GET /api/internal/issues — list issues (with filters) +POST /api/internal/issues — create issue +GET /api/internal/issues/:id — get issue detail +PATCH /api/internal/issues/:id — update issue (status, assignment, etc.) +POST /api/internal/issues/:id/comments — add comment +POST /api/internal/issues/:id/upload — upload screenshot +GET /api/internal/issues/attachments/:filename — serve attachment +``` + +## UI Pages + +### `/admin/issues` — Issue List +- Filter chips: status, priority, category, submitter +- Sort by: newest, priority, recently updated +- Each row: issue number, title, status badge, priority badge, submitter, age +- Click → detail view (slide-out panel like tasks module) + +### `/admin/issues/new` — Submit Issue (Mobile-First) +- Title (required) +- Description (textarea, optional) +- Priority (dropdown, default medium) +- Category (dropdown, default general) +- Screenshot upload (file input accepting images, multiple allowed) +- Submit button +- Auto-fills submitted_by from Discord auth session + +### Issue Detail (slide-out or dedicated page) +- Full description +- Screenshot thumbnails (click to enlarge) +- Status workflow buttons (open → in-progress → resolved → closed) +- Assignment dropdown +- Comments thread +- Activity log + +## Discord Webhook + +On issue create and status change, POST to a `#issue-tracker` Discord channel: +- New issue: "🐛 Issue #42 opened by Holly: [title] (priority: high)" +- Status change: "✅ Issue #42 resolved by Michael" + +## Image Storage + +Store uploaded images to disk at `/opt/arbiter-3.0/uploads/issues/` (or similar). Serve via Express static middleware. Keep it simple — no need for NextCloud/S3 for this. + +## Reference + +- Task module (existing) is a good starting point for the UI pattern — filter chips, slide-out panels, sort +- Discord auth session already provides the username for submitted_by +- Existing admin middleware handles auth + +--- + +**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️