Files
transcription/.github/instructions/ui.instructions.md
T
2026-08-20 16:35:20 -05:00

4.8 KiB

description, applyTo
description applyTo
Use when modifying the NiceGUI application under src/transcription/ui. Defines ownership and dependency boundaries for UI registration, pages, components, services, persistence, state, and static assets. src/transcription/ui/**/*.py

UI Conceptual Boundaries

Keep dependencies flowing in this direction:

ui/__init__.py -> pages -> components

Pages may depend on application services and framework-provided dependencies. Components may depend on smaller components and shared presentation helpers. Services and domain modules must never depend on the UI.

Cross-cutting error behavior must follow error-handling instructions.

Package Root

  • Keep ui/__init__.py as the UI composition root: register global assets, register pages, and mount NiceGUI on FastAPI.
  • Do not put feature rendering, service calls, persistence, or route-specific state in the package root.

Pages

  • Pages own route registration and route-level orchestration.
  • Resolve request or application dependencies, call services, adapt returned data for presentation when needed, and coordinate refresh, navigation, and notifications here.
  • Do not query, mutate, commit, or roll back the database from a page. Do not import database engines, sessions, operations, or query-building APIs. Persistence belongs to services or workflow functions.
  • Framework dependency types may cross into page handlers only to construct or invoke services; do not pass sessions or session factories into components.
  • Keep business rules, lifecycle transitions, transaction boundaries, and cross-service workflows out of page callbacks.

Components

  • Components own reusable rendering, widget-local state, input normalization, and presentation-only formatting.
  • Expose user actions through typed callback parameters. The calling page decides which service or workflow runs and what refresh or navigation follows.
  • Do not register routes, resolve request/app state, instantiate services, or access persistence from components.
  • Components may accept ORM models returned by services as read-only snapshots. Only use fields and relationships that the service loaded eagerly; never mutate models, trigger lazy loading, or expose session behavior.
  • A component may compose lower-level components, but it must not import from pages.

Shared UI Infrastructure

  • Keep app-wide navigation and layout primitives in components/app_shell.py.
  • Keep generic table/event adaptation in components/table/common.py; feature-specific columns, row read models, and formatting belong in the feature table module.
  • Keep exception normalization and user-facing error display in components/error_presenter.py; preserve AppError details and operation identifiers at page/component boundaries.
  • Use components/media_urls.py for media URL generation; do not hand-build upload/static paths in page code.

CSS Assets

  • Keep all application CSS in ui/static/theme.css; do not add page- or component-specific stylesheets or embed style blocks in Python components.
  • Load theme.css once from the composition root with ui.add_css(..., shared=True).
  • Read stylesheet text through importlib.resources.files(...) so loading works from installed packages and is independent of the working directory.
  • Centralize CSS reading in one typed helper cached by resource path.
  • Do not encode application behavior in CSS or other static assets.

State and Side Effects

  • Limit component state to ephemeral interaction state such as loading flags, form values, dialogs, and expansion state.
  • Application and worker state must be resolved at the page or application boundary and passed through narrow interfaces.
  • Keep filesystem, network, provider, and worker orchestration behind application services or dedicated adapters.

Media Route Safety Rules

Two patterns are approved:

  1. Record-validated API routes for print/export contexts.
  2. Controlled upload URL resolver (components/media_urls.py) for general UI media.

Prohibited patterns:

  • Direct file:// links or exposing local filesystem paths.
  • Manual URL construction from raw Path values in pages/components.
  • User-facing payloads containing local absolute paths.

Contract Alignment

  • Treat docs/ as the active baseline.
  • Resolve lifecycle and status semantics against src/transcription/db/models.py and docs/schema.md; do not introduce alternate status labels or implied legacy states in UI behavior.
  • Use status vocabulary exactly as modeled (queued, processing, transcribed, partial_success, failed; and pending, transcribed, failed, cancelled).
  • Print/export media flows must use record-validated routes; direct local filesystem paths are prohibited.
  • If lifecycle wording/behavior changes, update corresponding docs/ui/pages/*.md contracts in the same change.