Jobs Available on /hr, and a Careers tab for every member

Featurekamo-internal
Shipped
September 3, 2026 at 10:02 PM UTC
Author
Kamo
Commit
a8d0932

Two surfaces over one feature. /hr/careers is where HR writes the adverts and reads who applied; **************** is the internal board an employee browses and applies from. They share a vocabulary module and an API client and nothing else, because they answer different questions. THE HR SIDE Four sub-tabs, each carrying its count in its own label — Applicants (4), Available (7), On Hold (2), Archived (11). The count is IN the label rather than a badge beside it: a badge puts the number outside the word it belongs to and clips against the next tab. All four counts arrive in ONE console call, because the bar has to be drawable before any tab has been chosen; a per-tab fetch would leave three labels blank until somebody visited them. The masthead is the applicant population as one band, split into the seven pipeline states, sized in true proportion and drawn on load — the same thesis as the Training masthead, because it answers the same shape of question. Reading it takes no arithmetic: the width of the blue segment IS how much unread work is waiting. It is also the navigation; every segment deep-links into the Applicants queue filtered to that status. A posting card carries an applicant strip on the same principle. Two postings with eleven applicants each look completely different when one is eleven unread and the other is nine rejected and two at offer, and that difference is the first thing a hiring manager wants back when they return to a board a week later. The editor is a right-hand drawer at 62vw, not a modal — an advert is a document, the author refers back to the board while writing it, and a centred dialog on a 2560px monitor is a narrow column with grey either side. Three panes because the three are edited at different times: the advert is written once, the form is tuned per req, and the location is usually left alone. The description is the platform's Lexical editor with media off; that surface uploads into KB media, which is right for an article and wrong for a job advert. Location is a toggle, not a copy. "Use the company address" reads the org's own address live from Settings -> Essential Setup -> Behavior & Labeling; the six override fields stay mounted and filled even while it is on, so flipping the toggle back does not blank a form the author had already filled in. The application form is composed per posting — twelve questions, each Do not ask / Ask (optional) / Ask (required). A warehouse shift and a staff engineer do not want the same form, and forcing one on both is how an application becomes something people abandon halfway. The two school questions are NOT among the twelve: they are tied to the education requirement, so a posting that demands a degree always asks where it came from and there is no switch that can contradict the requirement three fields above it. THE MEMBER SIDE Available AND on-hold roles, as the brief asks and for the reason it asks: "we are not hiring for this right now" is information, and a role that vanishes is a role people ask about. Held roles are dimmed, labelled, and refuse the Apply button. Applying is two steps. Step one is the advert — read it, decide. Step two is the form, showing ONLY the questions this posting asks. Putting the form under the advert in one scroll makes every role look like a twenty-field commitment before the reader has decided whether they want it. A completeness bar counts only what this posting asks, so a short form never reports 30% because a long form's fields are absent. The advert renders through RichTextView, which escapes all text, emits a fixed tag set and checks every URL against a scheme allowlist. An advert can be written by anyone holding the HR right; it is not trusted markup. Submitting is two calls — the answers, then the file, because a resume attaches to an application that has to exist first. The second can fail on its own, and when it does the dialog says so precisely: the answers ARE stored, and "your application failed" would be false. WHAT MOVED OUTSIDE CAREERS WorkLocationType gains FLEXIBLE, so the posting editor's Arrangement field and the member profile's work location stay one list. Both member create forms gained it too — otherwise somebody created there could never be Flexible until edited later. The mirror test now pins four values in the enum's own order rather than three: the column is @Enumerated(ORDINAL), so that assertion is what keeps the list append-only. Two guards caught real defects on the way in. check-server-timestamps found daysSince parsing a bare "2026-08-22" with new Date(), which the engine reads as browser-LOCAL — a member west of Greenwich would have read a role posted today as posted yesterday. check-switch-aria found two Switches naming themselves through inputProps, which MUI 7 drops, leaving them with no accessible name at all. 42 unit tests over the vocabulary module, covering the parts a type cannot: that NONE never appears as an answer an applicant can give, that WITHDRAWN is never offered to HR, that a "no" and a zero count as answered while whitespace does not, and that the sub-tab ids round-trip so a bookmark cannot be re-pointed.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing