Employers and resume visibility as CRUD, so both flows are commands - #48
Merged
Conversation
Documenting the two flows turned up the reason they had never been
documented: the CLI could not do them. There was no way to create an
employer without a browser, and `resume save` sent no visibility, so a
resume saved from a terminal was private with no command to list it. The
page had to tell you to copy a bearer token out of config.json and curl
the API, on a board whose whole pitch is that a client can drive it.
Employers get the rest of their CRUD:
- PATCH /api/v1/orgs/{slug} changes only the fields it carries. An absent
field is left alone and an explicit null clears it, so a caller that
knows about a name cannot blank a website it never read.
- A rename never moves the slug. That slug is the URL every listing, link
and directory row already points at, and a company becoming "Example
Works Inc" has not become a different employer.
- DELETE /api/v1/orgs/{slug} refuses with 409 once anything has gone live.
jobs.org_id cascades and applications.job_id cascades behind it, so the
honest delete is one that will not quietly take published listings and
the applications people sent to them. Drafts do not count: nobody has
seen one, and an employer whose listings are all drafts is almost always
one typed in wrong five minutes ago.
Resumes get the visibility half they were missing: `--visibility` on save
and import, `resume publish`, `unpublish`, `visibility <slug> <value>` and
`delete <slug> --yes`. A typo'd value is refused rather than dropped,
which is what the old silent isVisibility filter did.
"Saved." is now the address instead: the only question a candidate has
after saving is whether anyone can read it yet, and the URL is the answer.
Both flows are two commands on /docs now, with the REST calls kept as the
equivalent rather than the instruction. Also documents the swarm capacity
keys from #46, which shipped without reaching the page.
Verified end to end against a real board, not only in tests: created an
employer, renamed it and watched the slug hold, posted the exact front
matter the docs page shows, published it, had the delete refused, then
saved a resume, published it, and read the listed candidate back with its
skills split and its capacity priced.
Tests: 210 pass against Postgres. The four new ones cover the rename, the
partial patch, a stranger's 403 and the delete guard. The OpenAPI
coverage test caught both new routes missing from the published document,
which is what it is for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ai32QMBsKEs1nigijSiJ
ralyodio
added a commit
that referenced
this pull request
Sep 10, 2026
Minor rather than patch because commands and endpoints were added, and because the reason to cut this at all is that /docs is currently ahead of the published client: it tells people to run `agenticjobs employer create` and `agenticjobs resume publish`, and npm still ships 0.10.0, where neither exists. Since 0.10.1: - Employers and resume visibility as CRUD (#48). employer list/show/create/update/delete, resume publish/unpublish/visibility/ delete and --visibility on save and import, with PATCH and DELETE /api/v1/orgs/{slug} behind them. A rename keeps the slug; an employer that has published cannot be deleted. - Getting listed and hiring are documented at all (#45), and swarm capacity on a candidate profile (#46). - An address is withheld wherever it is written, and never from cache (#47). - Boolean CLI flags no longer swallow the command after them (#49). - Salary bounds read correctly in summaries and compare correctly across periods in search (#50, #51). - A JSON parse failure on a 200 is reported rather than swallowed (#52). - Job and DOCX imports keep titles, structure, tabs and line breaks (#53, #54). Both version files move together: package.json and VERSION in src/config.ts. Claude-Session: https://claude.ai/code/session_01D8ai32QMBsKEs1nigijSiJ Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Follow-up to #45. Documenting the two flows turned up the reason they had never been documented: the CLI could not do them. There was no way to create an employer without a browser, and
resume savesent novisibility, so a resume saved from a terminal was private with no command to list it. The docs page had to tell you to copy a bearer token out ofconfig.jsonand curl the API — on a board whose whole pitch is that a client can drive it.Both flows are now two commands.
Employers get the rest of their CRUD
PATCH /api/v1/orgs/{slug}changes only the fields it carries. An absent field is left alone and an explicitnullclears it, so a caller that knows about a name cannot blank a website it never read.DELETE /api/v1/orgs/{slug}refuses with 409 once anything has gone live.jobs.org_idcascades andapplications.job_idcascades behind it, so the honest delete is one that will not quietly take published listings and the applications people sent to them. Drafts do not count — nobody has seen one, and an employer whose listings are all drafts is almost always one typed in wrong five minutes ago.Resumes get the visibility half they were missing
--visibilityonsaveandimport, plusresume publish,unpublish,visibility <slug> <value>anddelete <slug> --yes. A typo'd value is now refused rather than silently dropped, which is what the oldisVisibilityfilter did."Saved."became the address instead. The only question a candidate has after saving is whether anybody can read it yet:Verified end to end, not only in tests
Against a real board on a real Postgres: created an employer, renamed it and watched the slug hold, posted the exact front matter the docs page shows, published it, had the employer delete refused with its reason, then saved a resume, published it, and read the listed candidate back — skills comma-split as documented and the swarm capacity priced (
10 agents, $100/agent, $1000/hr total).Tests
210 pass against Postgres. Four new ones cover the rename, the partial patch, a stranger's 403/401, and the delete guard. The existing OpenAPI coverage test caught both new routes missing from the published document, which is exactly what it is there for.
Docs also pick up the swarm capacity keys from #46, which shipped without reaching the page.
🤖 Generated with Claude Code
https://claude.ai/code/session_01D8ai32QMBsKEs1nigijSiJ