1
0
Files
medical-notes/.github/copilot-instructions.md
Johan Dahlin 50366b9b9c
All checks were successful
Deploy Quartz site to GitHub Pages / build (push) Successful in 2m29s
vault backup: 2025-12-26 02:09:22
2025-12-26 02:09:22 +01:00

46 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Architecture
- Notes live in [content](content) and ship to [public](public) via Quartz under [quartz](quartz); Django lives in [stroma](stroma) and hosts the quiz and ingest services.
- Static Quartz pages are configured through [quartz.config.ts](quartz.config.ts) and layouts in [quartz.layout.ts](quartz.layout.ts), while Django templates sit in [stroma/templates](stroma/templates) with HTMX-like partials in [stroma/templates/partials](stroma/templates/partials).
- Data flows: Obsidian markdown → question importer ([stroma/quiz/utils/importer.py](stroma/quiz/utils/importer.py#L1-L220)) → relational models ([stroma/quiz/models](stroma/quiz/models)) → quiz/session views → rendered partials front-end.
## Quartz Site Workflow
- Use Node 22+ and npm 10.9+ as enforced in [package.json](package.json#L1-L60); run `npm install` once, then `npm run docs` to build+serve Quartz against the `content` dir.
- The CLI is exposed via `npm run quartz` / `npx quartz ...` and reads custom config/theme in [quartz.config.ts](quartz.config.ts) plus layout definition in [quartz.layout.ts](quartz.layout.ts).
- [content](content) follows Obsidian conventions (Swedish folder names, embedded PDFs/CSV) and Quartz ignores private/templates per the `ignorePatterns` value.
- When editing markdown, keep Obsidian-flavored syntax and frontmatter tags because the quiz importer keys off tags like `frågetyp/mcq`.
## Django Quiz Service
- The project root is [stroma](stroma); run it with `uv run python manage.py runserver` (Python 3.13, deps in [stroma/pyproject.toml](stroma/pyproject.toml)).
- Core models: `QuizSession`, `QuizResult`, `QuizUser`, `Question`, `Tag`, `Exam`, etc. in [stroma/quiz/models](stroma/quiz/models); sessions filter questions via [stroma/quiz/views/get_session_questions_view.py](stroma/quiz/views/get_session_questions_view.py#L1-L35).
- Primary views live in [stroma/quiz/views](stroma/quiz/views) and always expect `request.quiz_user`; e.g. [stroma/quiz/views/get_next_question_view.py](stroma/quiz/views/get_next_question_view.py#L1-L40) renders partials consumed by the `quiz_mode` page.
- URL routing: [stroma/quiz/urls.py](stroma/quiz/urls.py) registers quiz endpoints under `/quiz/`, and [stroma/quiz/quiz_urls.py](stroma/quiz/quiz_urls.py#L1-L25) defines per-view paths (`session/<id>/question`, `/next/`, `/submit/`, etc.).
## Question Import Pipeline
- [stroma/quiz/utils/importer.py](stroma/quiz/utils/importer.py) parses Obsidian markdown, infers question type via `tags`, and stores options/matching_data plus tag slugs; the importer respects file mtimes and tracks stats.
- [stroma/quiz/utils/watcher.py](stroma/quiz/utils/watcher.py) plus [stroma/quiz/apps.py](stroma/quiz/apps.py#L1-L20) spin up a background Watchdog thread on startup (unless running management commands/tests) targeting `settings.QUESTION_WATCH_PATH` from [stroma/settings.py](stroma/settings.py#L1-L70).
- Management commands `uv run python manage.py import_questions [--folder ... --force]` and `populate_exams` live in [stroma/quiz/management/commands](stroma/quiz/management/commands) for bulk ingest/backfilling.
- The importer expects spoiler blocks for answers and tags like `frågetyp/mcq`; missing answers mark the file as TODO and skip DB writes, so keep metadata consistent.
## File Uploads & Assets
- The `file` app exposes `/file/upload/` + `/file/upload/api/` via [stroma/file/urls.py](stroma/file/urls.py); UI renders from [stroma/file/views/upload_files_page_view.py](stroma/file/views/upload_files_page_view.py#L1-L7).
- Upload handling in [stroma/file/views/upload_files_api_view.py](stroma/file/views/upload_files_api_view.py#L1-L130) mirrors the clients folder hierarchy, infers MIME types, stores text content when possible, and persists binaries under `uploads/`.
- Metadata/state for uploaded artifacts sit in [stroma/file/models/file_model.py](stroma/file/models/file_model.py#L1-L40) and are owned by `quiz.QuizUser`.
## Session & Request Patterns
- [stroma/quiz/middleware.py](stroma/quiz/middleware.py#L1-L21) auto-creates `QuizUser` records tied to Django session keys and attaches `request.quiz_user`; every view assumes this, so never bypass the middleware.
- `QuizResult` enforces one row per user+question via `unique_together` ([stroma/quiz/models/quiz_result_model.py](stroma/quiz/models/quiz_result_model.py#L1-L27)) and normalization logic in [submit_answer_view](stroma/quiz/views/submit_answer_view.py#L1-L60); reuse `update_or_create` when recording answers.
- Navigational/partial views such as [quiz_question_view](stroma/quiz/views/quiz_question_view.py#L1-L60) and [navigate_question_view](stroma/quiz/views/navigate_question_view.py#L1-L60) rely on consistent ordering from `get_session_questions`; maintain that helper when altering filtering behavior.
## Testing & Tooling
- Python deps/tests are run through `uv` (`uv sync`, then `uv run pytest`) per [stroma/AGENT.md](stroma/AGENT.md) and versions pinned in [stroma/pyproject.toml](stroma/pyproject.toml#L1-L20).
- Pytest config in [stroma/pytest.ini](stroma/pytest.ini#L1-L20) enables `--reuse-db` and short tracebacks; [stroma/conftest.py](stroma/conftest.py#L1-L70) switches to in-memory SQLite and provides markdown fixtures for parser tests.
- Comprehensive integration coverage exists in [stroma/quiz/tests/test_views.py](stroma/quiz/tests/test_views.py#L1-L210); extend these when touching quiz flows (session creation, submissions, difficulty ratings).
- SQLite WAL is default (see [stroma/settings.py](stroma/settings.py#L30-L65)); when debugging concurrency, clear `db.sqlite3-wal/shm` files before reruns.
## Coding Conventions
- Follow [stroma/AGENT.md](stroma/AGENT.md): Obsidian-flavored Markdown, no extra docstrings/comments unless asked, favor early returns, narrow `try/except`, and keep regexes as upper-case `_RE` constants with inline comments.
- Use type hints everywhere, prefer function-based Django views, and leverage django-stubs/pytest-django for typing/tests.
- When working in markdown ingestion, maintain tag-driven semantics (`frågetyp/*`, completion stats) and keep regex patterns centralized in parser modules.
- Tests should live beside implementations (e.g., `quiz/utils/tests`) and use parametrized `pytest` subtests when iterating over inputs.
- Keep new dependencies declared in `pyproject.toml` (Python) or `package.json` (Quartz) and prefer latest stable versions unless compatibility dictates otherwise.