MoveIssuesOnProjectColumn updated `project_issue` with a WHERE clause on
issue_id only. An issue assigned to several projects has one project_issue
row per project, so moving it within one project rewrote project_board_id
for every project the issue belonged to, detaching it from all the others.
Scope the UPDATE to (issue_id, project_id) so only the target project's
row changes. Mirrors the fix already present in upstream/main.
Adds an integration regression test asserting an issue in two user
projects keeps its column in the other project after a move. Fixes#17.
Adds two improvements to the user/org/repo project-board REST API:
* state filter on column-issues endpoints (issue #4)
GET /api/v1/{users,orgs}/{name}/-/projects/{id}/columns/{col}/issues
GET /api/v1/repos/{owner}/{repo}/projects/{id}/columns/{col}/issues
Now accept ?state=open|closed|all (default open), matching the convention
on the project-list endpoint and on /repos/.../issues. Applied at the
IssuesOptions layer so all three scopes inherit the filter.
* populated num_issues / num_open_issues / num_closed_issues on column-list
(issue #5)
ColumnList.LoadIssueCounts runs two grouped queries against project_issue
joined with issue (one open, one closed). All three List*Columns handlers
call it before converting, so num_issues stops being null and consumers
can render a kanban summary in a single round trip instead of N+1.
Tests:
* unit: empty-input fast path on ColumnList.LoadIssueCounts.
* integration: extended testAPIListProjectColumnIssues / -User / -Org to
close an issue, then verify default=open hides it, state=closed and
state=all return it, and the column-list response carries the correct
open/closed/total split.
Closes#4, closes#5
Adds the missing REST surface that mirrors the existing repo-scope project
API onto user and organization namespaces, so projects at /{owner}/-/projects/
become programmatically manageable (linking issues, listing column membership,
moving cards between columns) without browser-session auth.
Routes registered under /api/v1/users/{username}/projects/... and
/api/v1/orgs/{org}/projects/..., gated by AccessTokenScopeCategoryIssue.
User-scope writes require owner==doer or site admin; org-scope writes
require org membership. Handlers copy the repo-scope shape rather than
refactoring the existing repo handlers, keeping shipping code untouched.
Integration tests cover CRUD, columns, issue add/remove/move, listing per
column, and the permission matrix (owner/non-member/admin) for both scopes.