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
|
||||
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 human_user_id [String, Integer, nil] Planka user id of the
|
||||
# human who must be able to see bot-created projects. Falls back to
|
||||
|
|
@ -94,9 +97,23 @@ module Backlog
|
|||
end
|
||||
|
||||
# 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)
|
||||
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.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>`
|
||||
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
|
||||
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:**
|
||||
```bash
|
||||
${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
|
||||
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
|
||||
client = FakePlankaClient.new
|
||||
ensurer = Backlog::BoardEnsurer.new(client: client, human_user_id: "human-1")
|
||||
|
|
|
|||
Loading…
Reference in New Issue