File size: 5,794 Bytes
7c1820c cf17b22 7c1820c cf17b22 7c1820c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | // ---------------------------------------------------------------------------
// shell/dbFrame.tsx — THE DATABASE FRAME, extracted so a SECOND surface can wear it.
//
// ⭐ WHY THIS FILE EXISTS. The owner's instruction for the Query module is one
// sentence: *"the query module should exactly BE looking like the database module,
// COMPLETELY, with all the views etc. The only difference is that user isn't the one
// creating the view, it's the AI that they prompt in the AI assistant module."*
//
// "Exactly" and "completely" are only satisfiable by mounting THE SAME frame and THE
// SAME grid — `shell-db-frame` + `DbHead` + `OverlayProvider` + `CustomerGrid`. A
// hand-rolled view list beside it would be a second, thinner answer to a question this
// product already answers. So the header and the topic→scope map moved OUT of
// `Shell.tsx` (where they were private) and into here, and both call sites import them.
//
// ⛔ `gridScopeFor` IS THE WHOLE REASON THIS IS NOT JUST A COMPONENT MOVE. A registry
// key and a grid scope are DIFFERENT SPELLINGS of the same database — `product_data` is
// the key, `product` is the scope; `customer_data` is the key, `customer` is the scope;
// a `ut_` key is its own scope. That map lived inline in one branch of `Shell.tsx`, and
// the Query module's saved rows carry the KEY (`routes_query.BUILTIN_SCOPES =
// ('customer_data', 'product_data')`). So a second inline copy — or worse, passing the
// key straight through — is not a tidiness question:
// · `CustomerGrid`'s VIEW_OPEN listener guards on `detail.topic !== scope`, i.e. the
// SCOPE spelling, and drops anything else SILENTLY (CustomerGrid.tsx:3151);
// · so an emit carrying `customer_data` at a grid mounted as `customer` never selects
// the view, and the click "worked".
// One question, one normaliser ([[one-question-two-normalizers]]).
// ---------------------------------------------------------------------------
/* ⚠ W36-T51 — FOUR IMPORTS WENT WITH `DbHead`, AND `tsc`'s unused-locals check is what named them
rather than a sweep: `ReactNode` (its `glyph`/`aside` props), `FolderMark` and `FolderIcon` (the
chip's chosen mark), and `dbChipClass` (the chip's tone). ⛔ Every one of those four is still
ALIVE elsewhere — `FolderMark` in the grid and the rail, `dbChipClass` on the Connectors tiles
and the Home cards — so what is deleted here is this file's USE of them, never the things. */
import type { SurfaceScope } from "../customer-grid/apiBridge";
/** The cylinder every database wears when it has never been given a mark. */
export function DbIcon() {
return (
<svg className="shell-nav-icon" viewBox="0 0 16 16" aria-hidden="true">
<ellipse cx="8" cy="3.6" rx="5.3" ry="2.1" />
<path d="M2.7 3.6v8.8c0 1.16 2.37 2.1 5.3 2.1s5.3-.94 5.3-2.1V3.6" />
<path d="M2.7 8c0 1.16 2.37 2.1 5.3 2.1S13.3 9.16 13.3 8" />
</svg>
);
}
/**
* A nav/registry KEY → the scope `CustomerGrid` is mounted with.
*
* ⛔ THE ONE PLACE THIS MAP IS WRITTEN. See the header: the two spellings are silently
* interchangeable-looking and are not interchangeable, and the failure they produce is a
* dropped event rather than an error.
*
* ⚠ `cohort` is a legal `SurfaceScope` and is deliberately NOT a case here: the `#/cohort`
* route left with its registry row in wave 16 (cohorts project as LOCKED VIEWS in the
* Customer rail), so no nav key resolves to it. The scope stays reachable server-side; it
* simply is not something a nav row names any more.
*/
export function gridScopeFor(key: string): SurfaceScope {
if (key === "product_data") return "product";
if (key.startsWith("ut_")) return key as `ut_${string}`;
return "customer";
}
/* ⛔⛔ `DbHead` IS DELETED — WAVE 36 · T51, OWNER ITEM 7, AND THIS NOTE IS THE POINT OF THE
DELETION. Owner, 2026-08-18: *"Remove the header for database completely. its a waste of white
space. User should be able to tell what database they are in just by seeing the first Unique ID
field. its ok."*
It was "THE UNIVERSAL DATABASE HEADER" (wave 20 item 4, R8): one 44px band on every database
carrying a coloured chip, the database's mark and its name as an `h1`. Wave 23 C13 then made it
the app's ONE title system and wave 35 T32 took it off the Agents surface; W36-T67 took it off
Query; this ticket takes it off the database and removes the component. **Three waves argued
about which surfaces should wear it and the answer turned out to be none of them.**
⭐ WHAT REPLACED IT IS NOT NOTHING, WHICH IS THE ONLY REASON THE DELETION IS SAFE: a database
grid's FIRST COLUMN is its identity, on screen, in every row, and the rail's active row plus the
view name say the rest. The owner's sentence is an argument, not just an instruction.
⚠ WHAT SURVIVES, AND THE SWEEP THAT WOULD HAVE TAKEN IT:
· `.shell-db-frame` — the rail-and-content GEOMETRY, not the title. `verify_automation_ui`
asserts its survival as hard as it asserts the head's absence, because dropping it collapses
the Agents surface's box.
· ⛔ `.shell-db-chip` — ONE CHARACTER from `.shell-db-head` in a grep, and used by
`connectors/ConnectorsPage.tsx`, `home/HomePage.tsx` and two `_shot` fixtures, with five tone
modifiers of its own. A sweep on `shell-db-` takes three live surfaces down with the header.
· `dbChipClass` (nav.ts) and `FolderMark` — both feed that chip and both keep other callers.
`.shell-db-head` and `.shell-db-name` DID die with it (index.css), having had exactly one user.
⚠ `aside` went too: it was added when this file was extracted so the Query module could put a
source picker in the row. Query owns its own answer now (W36-T67). */
|