Skip to content

chore(stylesheets): retire getDefaultStylesheetName's ?? 'sublime' fallback (cleanup, not drift risk) #376

Description

@obrien-k

Follow-up from #371, which named this but deliberately left it standing.

The remaining magic string

#371 framed the problem as a pair:

This retires a cross-repo magic string: today the ui recognises the name sublime, paired with getDefaultStylesheetName's ?? 'sublime' fallback here. Same shape that drifted on the seeded-avatar sentinel.

#371 retired the delivery half — Sublime's row now carries cssUrl = null, so the injector can branch on data instead of on a name (that's stellar-ui #196). The api-side half is untouched:

// src/modules/stylesheet.ts
export const getDefaultStylesheetName = async (tx?: Tx): Promise<string> => {
  const row = await db.stylesheet.findFirst({ where: { isDefault: true }, select: { name: true } });
  return row?.name ?? 'sublime';
};

Why it was left

It returns a name, written to UserSettings.siteAppearance at user creation (modules/user.ts, modules/auth.ts, routes/api/install.ts). That is a different axis from cssUrl delivery, and retiring it is not a rename — it forces a decision about what siteAppearance is when no row is marked default:

  • Return nullsiteAppearance becomes nullable, rippling through three creation paths, the settings read/write surface, and the ui's theme resolution.
  • Throw → user creation now fails on a registry with no default. Arguably correct, but it turns a soft fallback into a hard dependency on seed order.
  • Keep a fallback but source it from the schema default → user_settings.siteAppearance already has DEFAULT 'sublime' at the DB level (20260524181515_add_stylesheets), so the literal exists there too. Retiring one copy while the other stands may not be worth the churn.

Note the string is load-bearing in more than these two places, which is part of why it wasn't a quick fix — the DB column default, this fallback, and the fixture/registry naming all say sublime independently.

Worth checking first

Whether this is a real drift risk or a benign default. The seeded-avatar precedent (api SEEDED_AVATAR ↔ ui SEEDED_AVATAR_SENTINEL) drifted because two repos independently encoded the same sentinel. Here, after #371 + ui#196, the ui no longer reads the name at all — so the cross-repo half is already gone and what remains is api-internal. That may downgrade this to cleanup rather than risk.

Related


Update 2026-07-20 — re-scoped from risk to cleanup

The "worth checking first" question above has been checked, and it resolves to cleanup, not drift risk.

stellar-ui #196 (PR #200) merged and deleted the name comparison outright — the ui no longer reads the stylesheet name on any path. That removes the second independent encoding, which is the only thing that made the seeded-avatar precedent apply. What remains is a single api-internal default with no cross-repo counterpart to drift against.

Verified still accurate as of 4b29528:

  • src/modules/stylesheet.ts:13 — the fallback itself, unchanged.
  • Three creation paths confirmed: modules/user.ts:136, modules/auth.ts:181, routes/api/install.ts:199.
  • user_settings.siteAppearance still carries DEFAULT 'sublime' at the DB level (20260524181515_add_stylesheets).

That last point is the reason to be sceptical this is worth doing at all: retiring the code copy leaves the DB copy standing, so the churn buys a partial cleanup rather than the elimination of the literal. Decide whether it's worth doing before designing it — and if it is, the DB default should go in the same pass or the issue isn't actually closed.

Priority accordingly: low. Not a correctness or drift hazard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions