Skip to content

UI add page visit#51

Merged
pendingintent merged 11 commits intomasterfrom
ui-add-page-visit
Jan 12, 2026
Merged

UI add page visit#51
pendingintent merged 11 commits intomasterfrom
ui-add-page-visit

Conversation

@pendingintent
Copy link
Owner

No description provided.

Copilot AI review requested due to automatic review settings January 12, 2026 21:06
@pendingintent pendingintent self-assigned this Jan 12, 2026
@pendingintent pendingintent added the enhancement New feature or request label Jan 12, 2026
@pendingintent pendingintent added this to the v1.2-beta milestone Jan 12, 2026
conn.close()
current = "X"
cell_html = f'<td hx-post="/ui/soa/{soa_id}/toggle_cell_instance" hx-vals=\'{{"instance_id": {instance_id}, "activity_id": {activity_id}}}\' hx-swap="outerHTML" class="cell">{current}</td>'
return HTMLResponse(cell_html)

Check warning

Code scanning / CodeQL

Reflected server-side cross-site scripting Medium

Cross-site scripting vulnerability due to a
user-provided value
.
Cross-site scripting vulnerability due to a
user-provided value
.
Cross-site scripting vulnerability due to a
user-provided value
.
Cross-site scripting vulnerability due to a
user-provided value
.
Cross-site scripting vulnerability due to a
user-provided value
.
Cross-site scripting vulnerability due to a
user-provided value
.

Copilot Autofix

AI 2 months ago

General approach: Any value derived from user input that is interpolated into HTML should be safely escaped for the relevant context (HTML/attribute/JS). In Python web apps, that typically means using html.escape() or a framework-provided escaping function before embedding user data into HTML strings.

Best concrete fix here: Explicitly escape soa_id, instance_id, and activity_id before inserting them into cell_html. Even though they are currently integers, converting them to strings and passing them through html.escape() ensures that, regardless of future type changes, no special characters can break out of HTML attributes or JSON-like structures. We can import html from the standard library and apply html.escape() when building the f-string. This change preserves existing functionality (the visual output is unchanged for numeric IDs) while eliminating the XSS concern and addressing all alert variants, since they all flow through the same cell_html expression.

Specific changes:

  • In src/soa_builder/web/app.py, add import html alongside the other imports near the top of the file (we are allowed to add standard-library imports).
  • In function ui_toggle_cell_instance, before building cell_html, compute escaped string versions of soa_id, instance_id, and activity_id using html.escape(str(...), quote=True).
  • Update the cell_html f-string to use these escaped string variables instead of interpolating the raw values directly.

No additional methods or complex definitions are needed—just the import and local escaping.


Suggested changeset 1
src/soa_builder/web/app.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/soa_builder/web/app.py b/src/soa_builder/web/app.py
--- a/src/soa_builder/web/app.py
+++ b/src/soa_builder/web/app.py
@@ -24,6 +24,7 @@
 import urllib.parse
 import tempfile
 import time
+import html
 from contextlib import asynccontextmanager
 from datetime import datetime, timezone
 from typing import Any, List, Optional
@@ -2569,7 +2570,14 @@
         conn.commit()
         conn.close()
         current = "X"
-    cell_html = f'<td hx-post="/ui/soa/{soa_id}/toggle_cell_instance" hx-vals=\'{{"instance_id": {instance_id}, "activity_id": {activity_id}}}\' hx-swap="outerHTML" class="cell">{current}</td>'
+    escaped_soa_id = html.escape(str(soa_id), quote=True)
+    escaped_instance_id = html.escape(str(instance_id), quote=True)
+    escaped_activity_id = html.escape(str(activity_id), quote=True)
+    cell_html = (
+        f'<td hx-post="/ui/soa/{escaped_soa_id}/toggle_cell_instance" '
+        f'hx-vals=\'{{"instance_id": {escaped_instance_id}, "activity_id": {escaped_activity_id}}}\' '
+        f'hx-swap="outerHTML" class="cell">{current}</td>'
+    )
     return HTMLResponse(cell_html)
 
 
EOF
@@ -24,6 +24,7 @@
import urllib.parse
import tempfile
import time
import html
from contextlib import asynccontextmanager
from datetime import datetime, timezone
from typing import Any, List, Optional
@@ -2569,7 +2570,14 @@
conn.commit()
conn.close()
current = "X"
cell_html = f'<td hx-post="/ui/soa/{soa_id}/toggle_cell_instance" hx-vals=\'{{"instance_id": {instance_id}, "activity_id": {activity_id}}}\' hx-swap="outerHTML" class="cell">{current}</td>'
escaped_soa_id = html.escape(str(soa_id), quote=True)
escaped_instance_id = html.escape(str(instance_id), quote=True)
escaped_activity_id = html.escape(str(activity_id), quote=True)
cell_html = (
f'<td hx-post="/ui/soa/{escaped_soa_id}/toggle_cell_instance" '
f'hx-vals=\'{{"instance_id": {escaped_instance_id}, "activity_id": {escaped_activity_id}}}\' '
f'hx-swap="outerHTML" class="cell">{current}</td>'
)
return HTMLResponse(cell_html)


Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a new page for managing "Encounters" (visits) in the UI and updates the data model to transition from visit-based to instance-based matrix cells. The changes support CDISC-compliant encounter metadata including environmental settings, timing, transition rules, and epoch associations.

Changes:

  • Added a dedicated encounters management page with full CRUD operations
  • Migrated matrix cells from visit_id to instance_id as the primary axis
  • Integrated CDISC Library API for environmental settings and controlled terminology

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/test_web_api.py Removed deprecated test file for old API
tests/test_ui_visit_create.py Removed deprecated UI visit creation tests
tests/test_ui_toggle.py Removed deprecated toggle tests
tests/test_ui_set_visit_epoch.py Removed deprecated epoch assignment tests
tests/test_exports.py Removed deprecated export tests
tests/test_deletion.py Removed deprecated deletion tests
tests/test_cell_clear.py Removed deprecated cell clearing tests
tests/test_bulk_import.py Updated matrix import to use instances instead of visits
src/soa_builder/web/utils.py Added functions for epoch/timing/environmental settings lookups
src/soa_builder/web/templates/*.html Updated templates to use instance-based matrix, added encounters page
src/soa_builder/web/static/style.css Added sidebar navigation styling
src/soa_builder/web/schemas.py Added fields to VisitCreate/Update, renamed MatrixVisit to MatrixInstance
src/soa_builder/web/routers/visits.py Major refactor: added UI endpoints, environmental settings integration
src/soa_builder/web/routers/timings.py Minor whitespace cleanup
src/soa_builder/web/routers/instances.py Added instance_options for UI dropdowns
src/soa_builder/web/migrate_database.py Added migration for matrix_cells.instance_id column
src/soa_builder/web/app.py Updated matrix operations to use instance_id, added toggle_cell_instance endpoint
scripts/check_ct_href.py New utility script for testing CDISC API integration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pendingintent pendingintent merged commit 2c5e774 into master Jan 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants