cache-bust local assets; narrow the language facet to scores >= 3

Part 1 — asset versioning: every local <script src> and <link rel=stylesheet> on the
tracked pages now carries ?v=<sha256-of-the-file> (10 hex), computed at BUILD time from
the file's bytes by work/build-asset-versions.py — never hand-typed, and idempotent
(re-running with no file change rewrites nothing). This is what makes an edited
focus-rule.js / photo-upload.js a new URL instead of a stale cache hit.

Part 2 — language facet: a language now counts for the Language filter only when its
0-5 self-assessment is >= LANG_FACET_MIN (3 = 'works in it'). The constant sits beside
the 15-point rule in the page script and its mirror in build-directory.py. Nothing
stored changes; the card's languages chart still prints every language above 0, the
search box is unchanged, and the facet stays an exact membership test against the
card's value. A '1' language no longer offers the person under that language.
This commit is contained in:
webmaster committed 2026-11-03 21:26:58 +00:00
1 parent c83186f809
commit bd0881f882
51 files changed
+138 -118

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@
onload="this.media='all'"
/>
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Marcellus&display=swap" /></noscript>
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/style.css?v=3332fbba93" />
<style>
/* ---- Freelancer records — admin (page-scoped). Internal page, never linked. ---- */
.adm-bar {
+26 -6
View File
@@ -29,7 +29,7 @@
onload="this.media='all'"
/>
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Marcellus&display=swap" /></noscript>
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/style.css?v=3332fbba93" />
<style>
/* ---- "Odoo Community developers" directory (page-scoped; additive).
Reuses the top bar, band rhythm, hero, FAQ and final-CTA treatment already
@@ -2039,9 +2039,9 @@
</div>
</footer>
<script defer src="/static/lang.js"></script>
<script src="/static/focus-rule.js"></script>
<script src="/static/photo-upload.js"></script>
<script defer src="/static/lang.js?v=3ec49a7e62"></script>
<script src="/static/focus-rule.js?v=22ac72a8f0"></script>
<script src="/static/photo-upload.js?v=c17638457b"></script>
<script>
/* ============================================================================
Odoo freelancer directory — page script.
@@ -2089,6 +2089,14 @@
var FOCUS_AXES = ["functional", "system", "modules", "integration", "ai"];
var FOCUS_TOTAL = O4PFocus.TOTAL; // the shared rule (static/focus-rule.js)
var FOCUS_MAX = O4PFocus.MAX;
// THE FACET THRESHOLD — sits beside the 15-point rule. Mirrored verbatim in
// work/build-directory.py (`LANG_FACET_MIN`). A language counts for the Language
// FILTER only when its 0-5 self-assessment is >= this (3 = "works in it",
// 5 = native). It is OUR reading, not the freelancer's: it changes nothing stored
// and nothing the card shows (the chain below still prints every language above 0).
// Without it, a "1" offered the person under that language and the facet could not
// narrow. Do not change any stored score.
var LANG_FACET_MIN = 3;
var FOCUS_AXIS_LABELS = {
functional: "Functional", system: "System", modules: "Modules",
integration: "Integration", ai: "AI"
@@ -2368,6 +2376,18 @@
return out;
}
/* The languages the Language FILTER matches on — score >= LANG_FACET_MIN. Separate
from liveLangsDeclared(): the facet is narrower than the card's list, so a "1"
language is still shown on the card but no longer offers the person under it.
This feeds ONLY the facet attribute + the filter options, never the card. */
function liveLangsFacet(rec) {
var scores = liveLangScores(rec), out = [];
LANG_FIELDS.forEach(function (p) {
if (scores[p[1]] >= LANG_FACET_MIN) out.push(p[1]);
});
return out;
}
function liveAxisRows(rec) {
var rows = [];
FOCUS_AXES.forEach(function (axis) {
@@ -2426,7 +2446,7 @@
return (isNaN(n) || n <= 0) ? "" : "yes";
}
if (kind === "oca") return liveOcaLink(rec) ? "1" : "";
if (kind === "langnum") return liveLangsDeclared(rec).map(fold).join("|");
if (kind === "langnum") return liveLangsFacet(rec).map(fold).join("|");
return liveValues(rec, field).map(fold).join("|");
}
@@ -2592,7 +2612,7 @@
} else if (kind === "langnum") {
var seenL = [];
records.forEach(function (r) {
liveLangsDeclared(r).forEach(function (v) {
liveLangsFacet(r).forEach(function (v) {
if (!seenL.some(function (s) { return fold(s) === fold(v); })) seenL.push(v);
});
});