Commit graph

23 commits

Author SHA1 Message Date
2da7a6ec51 docs: add automated security review findings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 05:52:50 +02:00
root
1d1557d511 docs: mark tickets as deprecated — moved to Domus
Ticket management has moved to Domus (domus.welvaert.org). The homelab-tickets
MCP now points at Domus over the network (domus-mcp.welvaert.org, API-key auth);
mcp_server.py here is retired. See domus/docs/rewrite/mcp.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:59:54 +00:00
caoimhinr
762ae81345 feat: add export/import buttons to tickets UI 2026-06-03 21:03:49 +02:00
caoimhinr
f354c0ea89 fix: register export/import before parameterised ticket route
GET /api/tickets/export was being matched by GET /api/tickets/{ticket_id}
because FastAPI matches in registration order. Moved export/import routes
before the /{ticket_id} route so they are resolved first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 20:59:27 +02:00
caoimhinr
9eef5fd195 feat: add ticket import/export endpoints
GET /api/tickets/export — portable JSON dump of all environments,
tickets, and attachments (version 1 format with _id/_parent_id for
relationship reconstruction).

POST /api/tickets/import — additive import; upserts environments by
prefix, creates tickets preserving parent-child structure, creates
attachments. Compatible with the matching Domus implementation so
tickets can be transferred between the two systems.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 20:56:11 +02:00
root
0097055c15 security: fix command injection, XSS, prefix validation, cycle detection
- mcp_server.py: use shlex.quote() on all shell-interpolated values to
  prevent command injection via ticket title/description/human_id
- corvid/router.py: add alphanumeric-only regex validation for environment
  prefix; add full ancestor cycle detection before setting parent_id;
  import re
- Add SECURITY_REVIEW.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 13:27:20 +00:00
caoimhinr
dd4eaa6f77 feat(mcp): expose startup_script as direct parameter on update_ticket
Allows agents to set an explicit startup script without triggering a
title/description/type change. Auto-generation still fires when those
fields change and startup_script is not provided.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 16:39:42 +02:00
caoimhinr
6e2c62288d docs: add IaC sync reminder to CLAUDE.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:44:38 +02:00
caoimhinr
b068699f80 fix: child toggle always visible; showDetail fetches missing tickets; extraTickets cache
- Toggle now shows whenever a ticket has children (not gated on local filter visibility)
- showDetail() is async and fetches from API when ticket isn't in the local array,
  caching results in extraTickets so subsequent navigation and row rendering work
- Sidepane async child fetch stores results in extraTickets for the same reason

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 10:05:30 +02:00
caoimhinr
39bb53a72b fix: correct stale childCount reference to visibleCount in renderTicketRow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:45:26 +02:00
root
e0b898df8e fix: _default_env_id uses scalars().first() instead of scalar_one_or_none()
scalar_one_or_none() raises MultipleResultsFound when more than one environment
exists. Use scalars().first() to pick the lowest-ID environment as the default.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 07:36:30 +00:00
caoimhinr
a9ef13afa8 refactor: simplify startup_script to bare claude command (drop bash header and cd)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:20:30 +02:00
caoimhinr
87f5993149 fix: show child count badge for filtered-out children; fetch missing child details in sidepane
Children outside the active status filter weren't in the local tickets array, causing
the row-level child count/toggle to be hidden and the sidepane to fall back to "#ID"
labels. Count badge now uses t.child_ids.length directly; sidepane fetches any missing
children via /api/tickets/{id} asynchronously.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:15:24 +02:00
root
018f2f40a2 feat: add environment_id to update_ticket MCP tool
Allows reassigning tickets between environments (e.g. HOME → GAME).
create_ticket and list_tickets already supported environment_id.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:01:52 +00:00
caoimhinr
2322abe8dd fix: include templates/ and static/ in installed package
Setuptools was omitting non-Python files; add package-data glob so
templates and static assets are present after pip install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:28:54 +02:00
caoimhinr
508c85b5ed refactor: split tickets.html into tickets_base.html + thin wrapper
tickets_base.html is the canonical implementation; tickets.html just
extends it with no overrides, used by the standalone app.
The dashboard can now extend tickets_base.html directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:24:05 +02:00
caoimhinr
d5f3ce0667 feat: add environments — parametric ticket ID prefixes, env selector UI, MCP tools
- Environment model (prefix, name, description) with CRUD API
- Ticket.human_id now computed from environment prefix (e.g. PROJ-001)
- Migration 0002: environments table + backfill existing tickets to HOME env
- Router: list/create/get/patch/delete environments; list_tickets + create_ticket accept environment_id
- MCP: list_environments, create_environment tools; environment_id added to list_tickets + create_ticket
- UI: env pill selector with dropdown, new-environment modal, filter tickets by env

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:14:59 +02:00
caoimhinr
2a7686f398 feat: app icon (SVG crow), static file serving, favicon
- Add corvid.svg — stylised blue crow on dark background
- Mount /static via StaticFiles in main.py
- Wire favicon in base.html
- Add aiofiles dep (required by StaticFiles)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:03:12 +02:00
caoimhinr
961fc67528 security: timing-safe API key comparison, remove hardcoded DB password
- Use hmac.compare_digest for constant-time key check (router.py)
- Move POSTGRES_PASSWORD out of docker-compose.yml into .env (was a
  public default "corvid" now that the repo is public)
- Add .env.example with placeholder values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:46:25 +02:00
caoimhinr
3bd431bea0 docs: update deploy notes — corvid pulled from Forgejo, no vendor/ bundling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:39:39 +02:00
caoimhinr
dd799cea8e feat: add standalone web UI — tickets page with same style as homelab-dashboard
- corvid/templates/base.html: simplified nav (Corvid logo, Tickets link only),
  no user footer, no SSO — identical dark theme and component styles
- corvid/templates/tickets.html: copied verbatim from homelab-dashboard
  (all API paths are relative, no user-specific references)
- corvid/main.py: /tickets HTML route + / redirect; templates loaded from
  package dir so they work whether installed or run from source
- corvid/router.py: allow open access when TICKETS_API_KEY is not set
  (local/dev mode) — set the key to require auth for external access
- pyproject.toml: add jinja2>=3.1 dependency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:30:43 +02:00
caoimhinr
ff7620d5ed chore: add .gitignore, remove tracked pycache and egg-info
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:23:17 +02:00
caoimhinr
37b2c21720 feat: initial corvid — standalone ticket service extracted from homelab-dashboard
Extracts the ticket/attachment system into a reusable pip-installable package.
Centralises homelab MCP server (tickets, attachments, system logs) here.

- corvid package: models, router (make_router factory), config, standalone main
- Alembic migration chain for fresh standalone deployments
- Docker Compose for standalone deployment (port 8090)
- mcp_server.py: moved from homelab-dashboard, CORVID_REPO_PATH configurable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:23:07 +02:00