os-backlog: board-ensure fails loudly when PLANKA_HUMAN_USER_ID is unset (card #1818408943538406701)
fix_visibility now raises MissingHumanUserIdError instead of silently creating a bot-only Planka project when no human user id is available. Existing projects still ensure without the env var. Supersedes card #1818396164853073182. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUGCrg5osQMLUaSfkBdVZE
This commit is contained in:
parent
b0a21d6211
commit
d303b957f5
|
|
@ -30,6 +30,9 @@ module Backlog
|
||||||
class BoardEnsurer
|
class BoardEnsurer
|
||||||
Result = Struct.new(:board, :created, :project, :lists_created, :labels_created, keyword_init: true)
|
Result = Struct.new(:board, :created, :project, :lists_created, :labels_created, keyword_init: true)
|
||||||
|
|
||||||
|
# Raised instead of silently creating a bot-only-visible Planka project.
|
||||||
|
class MissingHumanUserIdError < StandardError; end
|
||||||
|
|
||||||
# @param client [Planka::Client] an already-authenticated client
|
# @param client [Planka::Client] an already-authenticated client
|
||||||
# @param human_user_id [String, Integer, nil] Planka user id of the
|
# @param human_user_id [String, Integer, nil] Planka user id of the
|
||||||
# human who must be able to see bot-created projects. Falls back to
|
# human who must be able to see bot-created projects. Falls back to
|
||||||
|
|
@ -94,9 +97,23 @@ module Backlog
|
||||||
end
|
end
|
||||||
|
|
||||||
# Quirk 2: null the bot's sole ownerProjectManagerId and add the human
|
# Quirk 2: null the bot's sole ownerProjectManagerId and add the human
|
||||||
# as a project manager, so the project shows up for them.
|
# as a project manager, so the project shows up for them. Only reached
|
||||||
|
# right after find_or_create_project creates a brand-new project — an
|
||||||
|
# already-existing project never calls this and so never requires
|
||||||
|
# human_user_id.
|
||||||
def fix_visibility(project)
|
def fix_visibility(project)
|
||||||
return unless @human_user_id
|
unless @human_user_id
|
||||||
|
# The Planka API has no atomic create-with-manager call, so the
|
||||||
|
# project already exists (bot-only-visible) by the time we can
|
||||||
|
# detect the missing id — we deliberately don't try to roll it
|
||||||
|
# back/delete it here; raise loudly instead and let a human fix
|
||||||
|
# visibility (env var + rerun, or the Planka UI) after the fact.
|
||||||
|
raise MissingHumanUserIdError,
|
||||||
|
"cannot make new Planka project #{project.name.inspect} visible to a human: " \
|
||||||
|
"no human_user_id given and PLANKA_HUMAN_USER_ID is unset — the project was " \
|
||||||
|
"created bot-only; set the env var and fix visibility manually or via the " \
|
||||||
|
"Planka UI"
|
||||||
|
end
|
||||||
|
|
||||||
@client.projects.add_manager(project.id, @human_user_id)
|
@client.projects.add_manager(project.id, @human_user_id)
|
||||||
@client.projects.update(project.id, ownerProjectManagerId: nil)
|
@client.projects.update(project.id, ownerProjectManagerId: nil)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,9 @@ All commands use the plugin CLI at `${CLAUDE_PLUGIN_ROOT}/bin/os-backlog`.
|
||||||
`~/dev/`, `Clients` under `~/clients/`, `Servers` under `~/servers/`. Pass `--project <name>`
|
`~/dev/`, `Clients` under `~/clients/`, `Servers` under `~/servers/`. Pass `--project <name>`
|
||||||
to target (or create) any other project explicitly — board-ensure creates the project too if
|
to target (or create) any other project explicitly — board-ensure creates the project too if
|
||||||
it doesn't exist yet. There's no command to move an existing board between projects; that's a
|
it doesn't exist yet. There's no command to move an existing board between projects; that's a
|
||||||
manual step in the Planka UI.
|
manual step in the Planka UI. Creating a NEW Planka project requires `PLANKA_HUMAN_USER_ID`
|
||||||
|
(or an explicit human user id) — board-ensure fails loudly rather than silently creating a
|
||||||
|
bot-only project.
|
||||||
4. **Create the card at Backlog:**
|
4. **Create the card at Backlog:**
|
||||||
```bash
|
```bash
|
||||||
${CLAUDE_PLUGIN_ROOT}/bin/os-backlog card-add --board <board> --title "<short imperative title>" [--description "<context: repo, file paths, why>"]
|
${CLAUDE_PLUGIN_ROOT}/bin/os-backlog card-add --board <board> --title "<short imperative title>" [--description "<context: repo, file paths, why>"]
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,34 @@ class BoardEnsurerTest < Minitest::Test
|
||||||
assert_equal "Servers", result.project.name
|
assert_equal "Servers", result.project.name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_raises_missing_human_user_id_error_when_creating_new_project_without_one
|
||||||
|
original = ENV.delete("PLANKA_HUMAN_USER_ID")
|
||||||
|
client = FakePlankaClient.new
|
||||||
|
ensurer = Backlog::BoardEnsurer.new(client: client)
|
||||||
|
|
||||||
|
error = assert_raises(Backlog::BoardEnsurer::MissingHumanUserIdError) do
|
||||||
|
ensurer.ensure("llf-schema", project_name: "Dev")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_includes error.message, "PLANKA_HUMAN_USER_ID"
|
||||||
|
ensure
|
||||||
|
ENV["PLANKA_HUMAN_USER_ID"] = original
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ensure_against_existing_project_does_not_raise_without_human_user_id
|
||||||
|
original = ENV.delete("PLANKA_HUMAN_USER_ID")
|
||||||
|
client = FakePlankaClient.new
|
||||||
|
seeding_ensurer = Backlog::BoardEnsurer.new(client: client, human_user_id: "human-1")
|
||||||
|
seeding_ensurer.ensure("board-a", project_name: "Dev")
|
||||||
|
|
||||||
|
ensurer = Backlog::BoardEnsurer.new(client: client)
|
||||||
|
result = ensurer.ensure("board-b", project_name: "Dev")
|
||||||
|
|
||||||
|
refute result.project.nil?
|
||||||
|
ensure
|
||||||
|
ENV["PLANKA_HUMAN_USER_ID"] = original
|
||||||
|
end
|
||||||
|
|
||||||
def test_ensure_rejects_archived_prefixed_name
|
def test_ensure_rejects_archived_prefixed_name
|
||||||
client = FakePlankaClient.new
|
client = FakePlankaClient.new
|
||||||
ensurer = Backlog::BoardEnsurer.new(client: client, human_user_id: "human-1")
|
ensurer = Backlog::BoardEnsurer.new(client: client, human_user_id: "human-1")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue