- Shipped
- September 4, 2026 at 4:53 AM UTC
- Author
- Kamo
- Commit
- 44ba665
Eight things, all behind the anonymous careers surface, and all sharing the rules the single-org board already enforces rather than growing their own. APPLY-FIRST. PublicApplyService files an application before its author has an account and emails a claim link. The posting is loaded through the same public predicate — an archived or internal-only req answers 404, never 403 — the answers go through the SAME validator as a member's, and the résumé through the same store, because a second copy of those rules is a second way in. Duplicates are caught on email, which is the only identity a public applicant has. THE NETWORK. A cross-organization board, gated twice: it is refused unless the request arrives on the platform's own careers host (read from the forwarded host, failing closed), and an organization must have opted in. It reuses PublicCareersService's own mapper and assembler, so a rule about what the public may see cannot be weaker there than on a tenant's own board. Every card links to the advert on the EMPLOYER's domain — the network sends traffic, it does not capture it. RELEVANCE. Free-text search was "every term appears somewhere", so a warehouse advert mentioning engineers in passing ranked level with the Staff Engineer role. It is now field-weighted with whole-word bonuses, and relevance leads the order only when somebody actually searched. THE FUNNEL. Impressions, opens and apply clicks, buffered in memory and flushed every thirty seconds. A row per event would be the platform's largest table within a month and would answer nothing the counters do not; an UPDATE per view would be a write transaction per page load on an anonymous site. The cost is honest: a pod restart loses up to thirty seconds. TALENT ALERTS with double opt-in, a never-expiring unsubscribe token, an eighteen-month expiry, and a sweep that deletes addresses nobody ever confirmed. The subscribe endpoint answers the same way whatever the address's history is — distinguishing them would be an oracle for who is watching a company's jobs. TRANSLATION on publish, on a separate bean so @Async is not bypassed by a self-invocation, REQUIRES_NEW per locale so one failure does not discard twenty, and fingerprinted so an edit invalidates every language at once. INDEXING via Google's JobPosting-specific API — off and logged until a service account exists, working the moment one does. URL_DELETED when a role closes, which is what stops a board accumulating results that lead nowhere. RETENTION: a nightly batched sweep, plus an HR erasure endpoint for a subject request. 21 new tests.