diff --git a/.gitignore b/.gitignore index 9d952393..23e49f5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ **/tools/_poetry - +**/tasks.md **/.env.langfuse **/.nx/* **/_poetry @@ -128,12 +128,21 @@ celerybeat.pid # Environments .env .venv +.venv*/ +**/.venv*/ env/ venv/ ENV/ env.bak/ venv.bak/ +# Local pip wrapper binaries inside ad-hoc venvs +**/.venv*/bin/pip +**/.venv*/bin/pip3 +**/.venv*/bin/pip3.* +**/.venv*/Scripts/pip.exe +**/.venv*/Scripts/pip3.exe + # Spyder project settings .spyderproject .spyproject diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 00000000..b5c30e4f --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,236 @@ +# GEMINI.md +> **Scope:** These instructions tune our **Gemini** code-generation agent (LLM via API/CLI) for this monorepo. They are **authoritative**: follow them over generic best practices. Output must compile, pass linters/tests, and fit our structure. + +--- + +## 1) Repository at a glance + +* **Monorepo:** Python backends + Vue 3/TypeScript frontend. +* **Structure:** + + * `libs/` – reusable Python packages (APIs, domain/services, repositories, schemas, utils) + * `services/` – thin Python apps composing `libs`; Vue/Nx frontend + * `infrastructure/` – Helm/Tilt/K3d, Terraform, values under `infrastructure/rag/values.yaml` + * `docs/` – docs & UI customization +* **Config:** Env-driven via `.env` (dev tooling only). Never hardcode secrets. + +> **Rule of thumb:** Business logic lives in **`libs`**. **`services`** only do bootstrapping, DI, routing, and wiring. + +--- + +## 2) Languages & toolchain + +* **Python:** 3.13, **FastAPI**, **Pydantic v2**, **Poetry** +* **Style/Quality:** `black` (line length **120**), `isort` (profile `black`), `flake8` (plugins), NumPy docstrings, type hints (PEP 484), absolute imports only +* **Testing:** `pytest` (+ coverage), optional `pytest-asyncio` for async code +* **Frontend:** Vue 3, TypeScript, Vite, Nx, Tailwind, Pinia, Vue I18n (Vitest + Cypress; ESLint) + +--- + +## 3) Agent behavior (important) + +* **Do not invent** secrets/URLs/paths. Use placeholders and `TODO:` comments. +* **Prefer libs over services:** Add APIs/logic in `libs/*`, wire in `services/*` (keep `main.py` thin: app import + container registration). +* **Always emit tests** with new Python code (≥1 happy path + ≥1 edge case). Keep unit tests isolated and fast. +* **Ask via comments if uncertain:** Start the diff with a short `# Assumptions:` block. +* **Respect performance & readability:** Small cohesive functions, avoid deep nesting/complexity. + +--- + +## 4) Output contract + +When asked to modify or add code, follow **one** of these formats: + +* **Single file (new):** + + ## path: libs//src//module.py + + ```python + # file content here + ``` + +* **Single file (edit):** provide a **unified diff**: + + ```diff + --- a/libs//src//module.py + +++ b/libs//src//module.py + @@ + - old line + + new line + ``` + +* **Multiple files:** repeat the above per file, in logical order (libs first, then services, then tests). + +* **Test plan:** end with a short block: + + ```txt + Build/Test + - poetry install + - pytest -q --maxfail=1 --cov + - black . && isort . && flake8 + ``` + +--- + +## 5) Python specifics + +### Typing & style + +* Use modern typing (`list[str]`, `dict[str, Any]`), avoid `Any` unless necessary. +* NumPy-style docstrings for public APIs. No wildcard imports. **Absolute imports only.** + +### FastAPI + +* Endpoints are **thin**; DI via `Depends`/container; no business logic in routers. +* Every route defines `response_model=...` and sanitizes outputs. +* Centralize exception mapping; never leak stack traces in prod. +* Prefer **async** endpoints for I/O-bound work. + +### Validation & config + +* **Pydantic v2**: use `field_validator`/`model_validator`; strict models at boundaries. +* **Configuration:** use `pydantic-settings` for environment-driven settings. `.env` is dev-only (Tilt/tests). Do not auto-load `.env` in production app code. + +### HTTP & concurrency + +* Use `httpx.AsyncClient` with explicit timeouts and retry/backoff. No `requests` in async code. +* Never use `time.sleep()`; use `asyncio.sleep()` (or anyio) in async contexts. + +### Repositories & services + +* Repositories are ports/adapters for DB/HTTP/queues. Services depend on repositories; routers depend on services. +* Transactions via context manager; avoid autocommit. Do not use raw SQL with f-strings. + +### Logging + +* Use `logging` (or `structlog`) with structured/contextual fields (`event`, `service`, `request_id`). No PII/secrets in logs. + +### File layout for new Python code + +* `libs//src//...` → APIs, services, repositories, schemas, utils +* `libs//tests/` → tests for the above +* `services//` → bootstrap, DI container, runtime config + +--- + +## 6) Testing + +* `pytest` with fixtures and mocks (`unittest.mock`, `pytest-mock`). No real network in unit tests; mock `httpx` (e.g., `respx`). +* Aim for **high coverage on core libs**. Mark slow tests with `@pytest.mark.slow`. +* Suggested `pytest.ini`: + + ```ini + [pytest] + addopts = -q --strict-markers --strict-config --maxfail=1 --cov=libs --cov-report=term-missing + markers = + slow: marks tests as slow (deselect with '-m "not slow"') + asyncio_mode = strict + ``` + +--- + +## 7) Frontend quick rules + +* Use `
diff --git a/services/frontend/apps/admin-app/src/App.vue b/services/frontend/apps/admin-app/src/App.vue index 39f77f43..74b1b253 100644 --- a/services/frontend/apps/admin-app/src/App.vue +++ b/services/frontend/apps/admin-app/src/App.vue @@ -4,8 +4,17 @@ import { NavigationContainer, OnyxIcon } from "@shared/ui"; import { useI18n } from "vue-i18n"; import { iconArrowSmallUpRightTop } from "@sit-onyx/icons"; +const runtimeConfig = (window as any).config || {}; +const isPlaceholder = (value: string | undefined) => + !value || /^VITE_[A-Z0-9_]+$/.test(value); +const pickValue = (...candidates: Array) => + candidates.find((v) => !isPlaceholder(v)); + const { t } = useI18n(); -const chatURL = import.meta.env.VITE_CHAT_URL; +const chatURL = pickValue( + runtimeConfig.VITE_CHAT_URL, + import.meta.env.VITE_CHAT_URL +);