chore(privacy): remove identity/locale signals and dangling private-doc refs

Found by an actual read-through of every 1.1/1.2 file, not keyword search:

- src/utils.ts, src/view/chart.ts, esbuild.config.mjs: comments/code named
  a specific timezone (CEST), keyboard layout (Swedish), and locale code
  (sv-SE) used only for its date-format side effect — three independent
  signals triangulating toward the same nationality. Genericized all three;
  esbuild.config.mjs now formats the build timestamp manually instead of
  depending on any locale string at all.
- main.ts, src/view/table.ts, src/view/toolbar.ts: "iPhone"/"iCloud"
  framed as the author's own device/sync setup — genericized to "mobile"/
  "sync".
- main.ts, src/inline-view.ts, src/travel-data.ts, src/travel-view.ts:
  dangling "see handoff"/"HANDOFF" references to handoff.md, which is
  gitignored and not part of the public repo. Replaced each with a
  self-contained inline explanation instead of a pointer nobody can follow.
- docs/architecture.md: "Built for the author's book library and habit
  tracking" softened to describe original use case without first-person
  ownership framing.
- docs/dev-workflow.md: the project-tree diagram was stale (referenced
  test-mobile-dashboards.mjs and xlsx-to-csv-roundtrip.mjs, both long gone)
  and garbled (a cut-off local/ bullet with a "hardcoded-path caveat"
  aside). Rewritten to match the actual current file list.

Tests: 115 passed, 0 failed. Typecheck clean. Build unaffected.
This commit is contained in:
SVM0N 2026-07-16 12:56:45 +00:00
parent 0893a4a52c
commit 6351d84e16
10 changed files with 28 additions and 22 deletions

View file

@ -7,10 +7,12 @@ const isWatch = process.argv.includes("--watch");
// (about 50% on the SheetJS-heavy bundle).
// Build-time timestamp injected into the bundle. Lets a tiny "Built: …"
// menu entry in the plugin show the user which build they're actually
// running — useful on iPhone where iCloud sync of the deployed bundle
// can lag behind the desktop build and there's no obvious way to confirm
// the new code arrived. Format: ISO-ish "YYYY-MM-DD HH:mm" in local time.
const buildTime = new Date().toLocaleString("sv-SE", { hour12: false }).slice(0, 16);
// running — useful on mobile where sync of the deployed bundle can lag
// behind the desktop build and there's no obvious way to confirm the new
// code arrived. Format: "YYYY-MM-DD HH:mm" in local time.
const now = new Date();
const pad = (n) => String(n).padStart(2, "0");
const buildTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`;
const buildOptions = {
entryPoints: ["main.ts"],

File diff suppressed because one or more lines are too long

11
main.ts
View file

@ -45,7 +45,7 @@ let worldMapSvgCache: string | null | undefined = undefined;
// Injected by esbuild at build time (see esbuild.config.mjs). Surfaced via
// the ⋯ menu so the user can confirm which build is actually loaded —
// handy on iPhone where iCloud sync of the deployed bundle can lag.
// handy on mobile where sync of the deployed bundle can lag.
declare const __BUILD_TIME__: string;
@ -207,9 +207,8 @@ export class CardView extends FileView {
// ── Title highlight ────────────────────────────────────────────────────────
// Per-file, keyed by the title-column value (like collapsedGroups) rather
// than a row index/id — the CSV has no stable identity column (see the
// optimistic-concurrency TODO in handoff.md), and a value-based key is
// resilient to row reordering/sort changes.
// than a row index/id — the CSV has no stable identity column, and a
// value-based key is resilient to row reordering/sort changes.
isHighlighted(row: CSVRow): boolean {
return (this.fileCfg.highlightedTitles ?? []).includes(this.getTitle(row));
@ -778,7 +777,9 @@ export class CardView extends FileView {
/**
* Load the world-map SVG shipped alongside the plugin. Cached at module
* level so it's read once per session (it's ~110 KB). Kept out of the JS
* bundle deliberately see handoff. Returns null if the asset is missing.
* bundle deliberately inlining it would only shrink the bundle by
* ~12 KB, not worth the size/complexity tradeoff. Returns null if the
* asset is missing.
*/
private async loadMapSvg(): Promise<string | null> {
if (worldMapSvgCache !== undefined) return worldMapSvgCache;

View file

@ -16,7 +16,8 @@
// row menu, the inline note editor, + Add, delete) write back to the source
// CSV via app.vault.modify, the same path the full view uses. Other open
// views of the same file (a .csv tab, or another csv-view block) re-sync off
// the vault `modify` event. See HANDOFF for the concurrency model.
// the vault `modify` event. This is last-write-wins at the whole-file level —
// no check that the file changed underneath between load and save.
import {
App,

View file

@ -4,9 +4,11 @@
// This module is DOM-free and side-effect-free so it can be unit-tested.
// The companion `travel-view.ts` renders the model this produces.
//
// Source format: the flat `travel_flat.csv` emitted by travel.py — one header,
// uniform rows, with a `source` column (confirmed | inferred | conflict).
// See docs / handoff "Travel / world-map view" for the overlap rules.
// Source format: a flat CSV with one header, uniform rows, and a `source`
// column (confirmed | inferred | conflict). Overlap rule: confirmed rows are
// authoritative — conflict rows are dropped entirely, and an inferred row is
// used only where it doesn't overlap a confirmed range (prevents double-
// counting days a trip is confirmed for).
import { CSVRow } from "./types";

View file

@ -4,9 +4,9 @@
// choropleth, per-country day totals, a year-by-year timeline, and the trip
// tables (confirmed + collapsed photo-inferred + collapsed conflicts).
//
// Coloring rule (see handoff): gold = confirmed countries, blue = countries
// seen only via photo-inferred rows, grey = unvisited. Conflict rows and
// inferred rows overlapping a confirmed range are excluded from map/timeline.
// Coloring rule: gold = confirmed countries, blue = countries seen only via
// photo-inferred rows, grey = unvisited. Conflict rows and inferred rows
// overlapping a confirmed range are excluded from map/timeline.
import { CSVRow, ResidencyRule } from "./types";
import {

View file

@ -103,8 +103,8 @@ export function isTruthyVal(val: string): boolean {
/**
* yyyy-mm-dd in *local* time. Everything user-facing must use this rather
* than toISOString().slice(0,10) that's the UTC date, which is yesterday/
* tomorrow near midnight in any non-UTC timezone (a habit logged at 00:30
* CEST landed on the previous day's row).
* tomorrow near midnight in any non-UTC timezone (a habit logged just after
* midnight landed on the previous day's row).
*/
export function localISODate(d: Date = new Date()): string {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;

View file

@ -20,7 +20,7 @@ import { localISODate, isMultiValueColName } from "../utils";
/**
* Parse a cell into a finite number, or null. Tolerates thousands separators
* ("1,234" / "1 234") and a European decimal comma ("3,5") data typed on a
* Swedish keyboard should chart without a cleanup pass.
* European keyboard layout should chart without a cleanup pass.
*/
export function parseNumeric(raw: string): number | null {
let s = (raw ?? "").trim();

View file

@ -70,7 +70,7 @@ export function renderTable(view: CardView, container: HTMLElement): void {
// Skip the clip-detection on touch — the fade gradient it triggers is
// a hover affordance and irrelevant without a cursor. Saves N rAFs × N
// forced reflows per render on phones (the prime cause of table-view lag
// on iPhone when the file has hundreds of rows).
// on mobile when the file has hundreds of rows).
const isTouch = matchMedia("(pointer: coarse)").matches;
const tbody = table.createEl("tbody");
filteredRows.forEach((row) => {

View file

@ -252,7 +252,7 @@ export function renderToolbar(view: CardView, root: HTMLElement): void {
menu.addItem(i => i.setTitle("Sync to Anki").setIcon("layers").onClick(openAnki));
menu.addSeparator();
// Build timestamp baked in at compile time. Lets the user confirm on
// iPhone that iCloud has actually synced the latest deploy.
// mobile that sync has actually delivered the latest deploy.
menu.addItem(i => i.setTitle(`Built ${__BUILD_TIME__}`).setIcon("info").setDisabled(true));
menu.showAtMouseEvent(e);
});