From 336bfafa0335fc52b4ecdfcd9ee33e095397cf8f Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:49:35 -0500 Subject: [PATCH] better --- docs/prompts/nicegui.md | 189 +++++++++++++++++++++++++++------------- 1 file changed, 128 insertions(+), 61 deletions(-) diff --git a/docs/prompts/nicegui.md b/docs/prompts/nicegui.md index cec3aae..f35e89b 100644 --- a/docs/prompts/nicegui.md +++ b/docs/prompts/nicegui.md @@ -43,6 +43,134 @@ Create a clean, maintainable app structure where: - Consider production-minded pool settings (`pool_pre_ping=True` and sensible recycle/timeout values). - Prefer Alembic for schema migrations. +## Suggested Project Structure + +Base structure (no database required): + +```text +. +├─ pyproject.toml +├─ .env.example +├─ README.md +├─ src/ +│ └─ app/ +│ ├─ __init__.py +│ ├─ main.py +│ ├─ config.py +│ ├─ logging.py +│ ├─ api/ +│ │ ├─ __init__.py +│ │ └─ health.py +│ ├─ services/ +│ │ ├─ __init__.py +│ │ └─ example_service.py +│ ├─ ui/ +│ │ ├─ __init__.py +│ │ ├─ components/ +│ │ │ ├─ __init__.py +│ │ │ └─ nav.py +│ │ └─ pages/ +│ │ ├─ __init__.py +│ │ ├─ home.py +│ │ ├─ dashboard.py +│ │ └─ about.py +│ └─ bootstrap.py +└─ tests/ + ├─ test_health.py + └─ test_pages_registration.py +``` + +### Conceptual boundaries for the base structure + +- `main.py`: application entrypoint only; wires `create_app()` and process startup concerns. +- `bootstrap.py`: app composition layer; owns app factory, router registration, page registration, and lifespan wiring. +- `config.py`: configuration boundary; centralizes settings parsing and typed config objects. +- `logging.py`: observability boundary; centralizes logging format/levels/handlers so modules do not configure logging ad hoc. +- `api/`: transport boundary for HTTP endpoints; validate/shape request-response objects and delegate business work to `services/`. +- `services/`: use-case/business boundary; orchestrates domain behavior and dependencies, independent of UI rendering. +- `ui/pages/`: route-level UI boundary; one module per page, focused on layout/event handling for that page. +- `ui/components/`: reusable presentation boundary; shared UI widgets/composition utilities with no business side effects. +- `tests/`: behavior boundary; verify public behavior (health endpoint, page registration, service outcomes), not private implementation details. + +### Dependency direction to keep clear + +- Prefer this dependency flow: + - `main/bootstrap` -> `config/logging` + `api` + `ui/pages` + `services` + - `api` -> `services` + - `ui/pages` -> `ui/components` + `services` + - `services` -> pure helpers/clients (and later `db/` if enabled) +- Avoid reverse imports (for example, `services` importing from `ui/pages` or `api`). +- Keep page modules and API handlers as thin adapters; keep business decisions in `services/`. + +## Extending This Pattern with a Database (Optional) + +If database access is needed, extend with: + +```text +. +├─ alembic.ini +├─ alembic/ +│ ├─ env.py +│ └─ versions/ +├─ src/ +│ └─ app/ +│ └─ db/ +│ ├─ __init__.py +│ ├─ base.py +│ ├─ session.py +│ ├─ models/ +│ │ ├─ __init__.py +│ │ └─ example.py +│ └─ repositories/ +│ ├─ __init__.py +│ └─ example_repo.py +└─ tests/ + └─ test_db_session_dependency.py +``` + +### Recommended database layering + +- Keep `db/` focused on persistence primitives: + - `session.py`: engine + session factory + dependency helpers + - `models/`: ORM table mappings only + - `repositories/`: query/persistence operations only +- Keep transaction orchestration in `services/`, not in UI pages. +- Keep `ui/pages/` free of SQLAlchemy details; pages call services. +- Keep API handlers thin and delegate data work to services/repositories. + +### Session and transaction pattern to request + +- Use one engine and one sessionmaker per process, initialized at app startup. +- Use a `get_db_session()` dependency with `yield` for request-scoped sessions. +- In write flows, always use context managers for commit/rollback safety. +- In read-only flows, avoid unnecessary transactions and keep queries narrowly scoped. +- Do not share a session across concurrent tasks; open a new session per task/unit of work. + +### Migration and schema workflow + +- Treat Alembic migrations as the source of truth for schema evolution. +- Prefer: + - `alembic revision --autogenerate -m "..."` + - review migration script + - `alembic upgrade head` +- Avoid relying on `metadata.create_all()` for production schema management. +- Include a lightweight startup check that logs current migration state (without mutating schema). + +### Configuration and runtime concerns + +- Read `DATABASE_URL` from settings (`pydantic-settings`) and keep secrets out of source control. +- Configure pool options appropriate for environment (for example: `pool_pre_ping`, timeout/recycle tuning). +- Keep SQL echo/debug logging disabled in production by default. +- Consider a readiness probe (`/readyz`) that verifies DB connectivity when your deployment needs it. + +### Testing guidance for DB-enabled projects + +- Unit test repositories against a disposable test database. +- Integration test `get_db_session()` lifecycle and rollback behavior on failures. +- Add migration tests that validate model changes are represented in Alembic revisions. +- Add API/service tests for critical read/write paths (including uniqueness and constraint errors). +- Keep DB tests isolated and deterministic (fresh schema + transactional cleanup per test module/session). + ## Extending This Pattern with LangGraph (Optional) If your app needs multi-step AI workflows, tool-calling loops, or human-in-the-loop approvals, a clean extension is to add a dedicated LangGraph domain layer. @@ -108,67 +236,6 @@ If your app needs multi-step AI workflows, tool-calling loops, or human-in-the-l - Add tests ensuring `thread_id` reuse resumes correctly and new IDs start fresh sessions. - Add regression tests for state-schema evolution and serialization compatibility. -## Suggested Project Structure - -Base structure (no database required): - -```text -. -├─ pyproject.toml -├─ .env.example -├─ README.md -├─ src/ -│ └─ app/ -│ ├─ __init__.py -│ ├─ main.py -│ ├─ config.py -│ ├─ logging.py -│ ├─ api/ -│ │ ├─ __init__.py -│ │ └─ health.py -│ ├─ services/ -│ │ ├─ __init__.py -│ │ └─ example_service.py -│ ├─ ui/ -│ │ ├─ __init__.py -│ │ ├─ components/ -│ │ │ ├─ __init__.py -│ │ │ └─ nav.py -│ │ └─ pages/ -│ │ ├─ __init__.py -│ │ ├─ home.py -│ │ ├─ dashboard.py -│ │ └─ about.py -│ └─ bootstrap.py -└─ tests/ - ├─ test_health.py - └─ test_pages_registration.py -``` - -If database access is needed, extend with: - -```text -. -├─ alembic.ini -├─ alembic/ -│ ├─ env.py -│ └─ versions/ -├─ src/ -│ └─ app/ -│ └─ db/ -│ ├─ __init__.py -│ ├─ base.py -│ ├─ session.py -│ ├─ models/ -│ │ ├─ __init__.py -│ │ └─ example.py -│ └─ repositories/ -│ ├─ __init__.py -│ └─ example_repo.py -└─ tests/ - └─ test_db_session_dependency.py -``` - ## Implementation Notes - Prefer an explicit page registration function pattern, for example: