# Admin Guide The admin panel runs on a separate port (default `:8081`) and provides management capabilities for users, tickets, and repos. ## Authentication The admin server is protected by Tailscale identity verification. Every request triggers a whois lookup against the local Tailscale daemon (`http://100.100.100.100/localapi/v0/whois`) to identify the connecting user. Access is controlled by the `TAILSCALE_ALLOWED_USERS` environment variable — a comma-separated list of Tailscale login names (e.g. `user@example.com,admin@example.com`). **Dev mode**: If `TAILSCALE_ALLOWED_USERS` is empty, all requests are allowed without authentication. This is useful for local development where Tailscale may not be available. See [Configuration](./configuration.md#admin) for the variable reference. ## Dashboard The dashboard (`GET /`) displays aggregate counts: - Total users - Total tickets - Open tickets - In-progress tickets - Closed tickets ## Users ### List Users `GET /users` — Displays all users ordered by creation date (most recent first, up to 100). ### User Detail `GET /users/:id` — Shows user information (name, email, verification status, creation date) and their tickets with product and status. ### Create User `GET /users/new` — Form to create a new user. `POST /users` — Submits the form. Requires name and email. The system: 1. Generates a random 16-character temporary password. 2. Creates the user with email marked as verified. 3. Sends a welcome email with the temporary password and a link to log in. The admin is redirected to the new user's detail page. ## Tickets ### List Tickets `GET /tickets` — Displays all tickets with user name/email, product, and status. Supports filtering by status via the `status` query parameter (e.g. `?status=open`). Up to 100 tickets are shown. ### Ticket Detail `GET /tickets/:id` — Shows full ticket details: title, description, status, submitting user, associated product, and the comment thread. ### Update Status `POST /tickets/:id/status` — Changes a ticket's status. Send a `status` form field with one of: `open`, `in_progress`, `closed`. ## Repos Repos map customer-facing "products" to Forgejo repositories. Each repo defines where tickets are synced as issues and where webhooks come from. ### List Repos `GET /repos` — Shows all repos with their name, slug, Forgejo owner/repo, active status, and the webhook URL. ### Add Repo `GET /repos/new` — Form to add a new repo. `POST /repos` — Creates the repo. All fields are required: | Field | Description | |-------|-------------| | Name | Display name shown to customers in the product dropdown | | Slug | URL-safe identifier used in the webhook URL path | | Forgejo Owner | Owner (user or org) of the Forgejo repository | | Forgejo Repo | Name of the Forgejo repository | | Webhook Secret | Shared secret for HMAC-SHA256 webhook signature verification | | Active | Whether this product appears in the customer ticket creation form | ### Edit Repo `GET /repos/:id/edit` — Form to edit an existing repo, pre-filled with current values. Also displays the webhook URL. `POST /repos/:id` — Updates the repo with the submitted values. ### Webhook URL Each repo's webhook URL follows the pattern: ``` {BASE_URL}/webhooks/forgejo/{slug} ``` This URL should be configured in the Forgejo repository's webhook settings. See [Forgejo Integration](./forgejo-integration.md#webhook-setup) for detailed setup instructions.