feat(labels): label/tag system with Gitea-compatible scope semantics - #5
Merged
Conversation
Adds Gitea-compatible columns to the labels table for both SQLite and MySQL schemas. Includes a SQLite boot-time ALTER migration (migrateLabelsTable) so existing DBs gain the columns idempotently. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Rewrites the label store functions (previously dead code with zero callers) into a full CRUD: create/update/archive/delete + list/get. Adds exclusive-scope support (Gitea scope/name syntax) — attaching an exclusive label evicts sibling labels sharing the same scope so an issue holds at most one label per scope. setIssueLabels replaces the full label set of an issue. Includes input validation (name charset, #RRGGBB color). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adds form-POST management routes (add/update/archive/delete) at /:o/:r/settings/labels/* mirroring the members/upstreams pattern, plus a JSON API at /api/:o/:r/issues/:n/labels (GET returns current+available, POST replaces the label set). Enforces admin role for management, writer role for issue-label edits. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
buildIssue previously hardcoded labels: [] in every emitted Gitea-shaped payload (issues + issue_comment events). Now fetches the issue's labels via listLabelsForIssue and maps them to the PayloadLabel shape, threaded through buildIssuePayload/buildCommentPayload. Fixes the latent bug where downstream consumers never received label data. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Adds a project settings tab (labels) with a full management page: create/edit/archive/delete labels with a color palette and exclusive-scope hint, plus an edit dialog. On the issue detail page, label chips render in the meta-status row next to the state badge, with a picker dialog (label-picker.js) that toggles labels via the JSON API and reflects exclusive-scope mutual exclusion in the UI. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…bulk replace 23 tests covering: labelScope parsing, createLabel validation (empty name, invalid color, illegal chars, scope/name syntax), partial/full updateLabel, archive visibility filtering, deleteLabel cascade, and the exclusive-scope mutual-exclusion semantics (same-scope eviction, different-scope coexistence, non-exclusive coexistence, detach, idempotent re-attach, bulk replace with dedup). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements a full label/tag system for ework-web. The
labels+issue_labelstables already existed (Gitea-aligned, per-project scope) but had zero UI, zero API, and the store functions were dead code. This PR brings them to life.description,exclusive,is_archivedcolumns (Gitea-compatible) to both SQLite + MySQL, with a SQLite boot-time ALTER migration for existing DBsscope/namesyntax where one issue holds at most one label per scope/:o/:r/settings/labels/*) + JSON issue-label API (/api/:o/:r/issues/:n/labels)labels: [])Test plan
bun run check(tsc clean)bun test(83 pass, 0 fail)