Repository navigation
Description
Summary
Settings → Database shows cloud-tenant wording to every free user:
- an explainer paragraph: "A database is a local store on this machine — not a tenant. Each database can sync to one cloud tenant (its workspace) or stay local-only. Opening a database also switches which tenant syncs.";
- a "Local only · not synced" badge on every database row.
This issue replaces the paragraph with neutral local-database copy and drops the "Local only · not synced" branch.
The "Syncs to tenant · …" badge renders only for a database that a Pro build bound to a tenant. It stays until #3326.
Context
- ADR-081 (proposed) says core ships no Pro wording. ADR-082 §2.2 (proposed) names this paragraph's tenant sentences as Pro wording that leaves core. If the Pro app wants that explanation, it renders it in its own
database.actionsordatabase.rowcontribution. - This PR removes wording, not a Pro feature, so it does not wait for sync. It lowers the Pro-marker ratchet.
- In the free app no database is ever bound:
DatabaseInfo.boundTenantSchemais alwaysnull, so the{:else}branch renders on every row. - The Pro app gets its row decoration back from Add settings-section and database settings-slot extension points #3312's
database.rowslot once sync's replacement lands (Delete the Add synced database dialog and tenant badge from Database settings #3326's SYNC gate). Until then, and while the Pro GUI still builds from coreHEAD, Pro users lose the explainer and the "Local only · not synced" label on unbound databases. Bound databases keep "Syncs to tenant · X". - Add settings-section and database settings-slot extension points #3312 may land before or after this PR. It adds a
database.rowoutlet right after the badge block and leaves the badge alone. If it landed first, leave its outlet where it is.
Scope
packages/desktop-app/src/lib/components/settings/sections/database-settings.svelte (line numbers at af8ddb6):
- The explainer paragraph: the
<p class="text-muted-foreground mb-6 text-sm leading-relaxed">under the "Databases" header (117-122). Replace its content. - The per-row badge block: the
<div class="mt-1.5 text-xs">that holds{#if db.boundTenantSchema} … {:else} … Local only · not synced … {/if}(160-171). Keep only the bound case, and render the wrapper only whendb.boundTenantSchemais set.
packages/desktop-app/src/tests/components/settings/database-settings.test.ts (1-78): add one test and keep the three existing ones.
scripts/check-pro-boundary.ts: lower BASELINES.
Out of scope
- Delete the Add synced database dialog and tenant badge from Database settings #3326: the "Add synced database…" button and dialog,
tenantLabel(), the bound badge, and theproSyncandlabsFlagsimports. - Move Pro-owned data out of core's data model (ADR-083) #3345:
DatabaseInfo.boundTenantSchemaandboundTenantCollection. - Add the "Share / Sync this database" entry point that opens nodespace.ai #3362: the "Share / Sync this database" entry point.
- Add settings-section and database settings-slot extension points #3312's
database.rowoutlet.
Steps
- Startup sequence (CLAUDE.md):
- On the primary checkout:
git status, thengit fetch origin && git pull origin main. - Create the worktree:
EnterWorktree({name: "issue-<N>-db-settings-tenant-copy"}). - Inside it:
bun install, thenbun run testfor the baseline, thenbun run gh:comment <N> "Frontend: X passed". Self-assign withbun run gh:assign <N> "@me", thenbun run gh:status <N> "In Progress".
- On the primary checkout:
- Replace the paragraph. Keep the
<p>element and its classes so the spacing is unchanged, and replace its body (af8ddb6: 118-121).- Suggested copy:
A <span class="text-foreground font-medium">database</span> is a separate local store on this machine. Opening one switches the app to it. - The new copy must not contain "tenant", "sync", "cloud" or "workspace".
- Suggested copy:
- Replace the badge block with:
{#if db.boundTenantSchema} <div class="mt-1.5 text-xs"> <span class="text-primary bg-primary/10 rounded px-1.5 py-0.5 font-medium"> Syncs to tenant · {tenantLabel(db.boundTenantSchema)} </span> <span class="text-muted-foreground/60 ml-1 font-mono">{db.boundTenantSchema}</span> </div> {/if} - Add the test described under Tests.
- Lower the ratchet. Run
bun run scripts/check-pro-boundary.ts.- It fails with "lower
BASELINES.tenantWording" and prints aBASELINESblock. Paste that block intoscripts/check-pro-boundary.ts. - Expect
tenantWordingto drop by 3, one for each explainer line that says "tenant", and no other marker to move. bun run test:changeddoes not run the scripts tier for a frontend-only diff, so run the checker by hand.
- It fails with "lower
- Finish:
bun run test:changed.bun run quality:fix, then commit.git push origin HEAD:issue-<N>-db-settings-tenant-copy. The push runs lint only.gh pr create --repo NodeSpaceAI/nodespace-core --base main --head issue-<N>-db-settings-tenant-copy, thenbun run gh:status <N> "In Review".- Run
/pragmatic-code-review, then/address-review. - Merge only after the user approves, with
bun run merge <PR#>running in the background. ThenExitWorktree({action: "remove", discard_changes: true}).
Standards:
- No GitHub issue numbers in code comments.
- Use
createLogger, neverconsole.*. - Use
bun run test, neverbun test. - No lint suppression.
Acceptance criteria
- With an unbound database, Settings → Database shows no "tenant", "not synced" or "Local only" text, and no empty badge wrapper under the status line.
- In the diff, the bound branch's markup ("Syncs to tenant · {tenantLabel(…)}" plus the raw schema name) is unchanged apart from moving inside the
{#if}. - The explainer keeps its element, classes and position. Its copy contains none of "tenant", "sync", "cloud" or "workspace".
- The three existing "Add synced database…" tests pass unchanged.
-
bun run scripts/check-pro-boundary.tsexits 0,BASELINESis lowered in this PR, and no marker count rose. -
bun run quality:fixis clean andbun run test:changedpasses.
Tests and verification
Add this test to database-settings.test.ts. The file mocks no Tauri bridge, so databaseStore.load() produces the implicit "Default" database with boundTenantSchema: null.
it('describes databases in neutral, local-only terms'): renderDatabaseSettings,await findByText('Default'), then:This follows Add the Pro-boundary ratchet check and the CLAUDE.md Pro/sync placement rule #3299's absence-test convention: a test that asserts a marker is absent builds its needle from fragments, so it adds nothing to the ratchet. Keep the test title free of marker words too.// Built from fragments so this absence check adds no line to the boundary ratchet. const removedWording = new RegExp([['ten', 'ant'].join(''), 'not synced', 'local only'].join('|'), 'i'); expect(container.textContent).not.toMatch(removedWording);
- No test for the bound badge. Its fixture would need
boundTenantSchema: 'tenant_…', which addscloudBindStateandtenantWordinglines, and Delete the Add synced database dialog and tenant badge from Database settings #3326 deletes the badge anyway. Check the bound branch by reviewing the diff. - Mutation check. Restore the
{:else}branch and confirm the new test fails. Separately, restore the old paragraph and confirm the test fails.
Commands:
bun run --cwd packages/desktop-app test src/tests/components/settings/database-settings.test.ts
bun run scripts/check-pro-boundary.ts
bun run test:changed
bun run quality:fix
Manual check: run bun run dev:browser, open Settings → Database, and confirm that the new copy shows and the "Default" row has no badge.
Dependencies
- NodeSpaceAI/nodespace-docs#88 (ADR-081) (ADR-081, proposed): the rule that core carries no Pro wording.
- Add the Pro-boundary ratchet check and the CLAUDE.md Pro/sync placement rule #3299: the ratchet this PR lowers.
Risks and rollback
- Risk: until sync's
database.rowcontribution ships (Delete the Add synced database dialog and tenant badge from Database settings #3326's SYNC gate), Pro users lose the explainer and the "Local only · not synced" label on unbound databases. This is cosmetic, and bound databases keep their label. - Rollback: revert the PR, including its
BASELINESchange. It touches only markup, one test and the baseline.
Plan key: C5.1 (pro-boundary DAG).
🤖 Generated with Claude Code
Activity