Skip to content

Release v 1.3#211

Open
pendingintent wants to merge 40 commits into
masterfrom
release-v-1.3
Open

Release v 1.3#211
pendingintent wants to merge 40 commits into
masterfrom
release-v-1.3

Conversation

@pendingintent
Copy link
Copy Markdown
Owner

No description provided.

pendingintent and others added 21 commits April 22, 2026 11:30
…e cross-site scripting'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…e cross-site scripting'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…e cross-site scripting'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… remote source'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…t,epoch.type,epoch.epoch_uid; rollback deletes entities in coirrect order; made safe for legacy db deployments
@pendingintent pendingintent added this to the v1.3 milestone May 4, 2026
@pendingintent pendingintent self-assigned this May 4, 2026
Copilot AI review requested due to automatic review settings May 4, 2026 16:49
@pendingintent pendingintent added bug Something isn't working documentation Improvements or additions to documentation labels May 4, 2026
@pendingintent pendingintent added the enhancement New feature or request label May 4, 2026
Copilot AI review requested due to automatic review settings May 8, 2026 19:34
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread src/soa_builder/web/routers/freezes.py Dismissed
Comment on lines +191 to +192
f"<div class='error' style='color:#c62828;'>"
f"Amendment creation failed: {err}</div>",
Copy link
Copy Markdown
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

Copilot reviewed 77 out of 80 changed files in this pull request and generated 4 comments.

primary_reason_other: str = Form(""),
):
if not soa_exists(soa_id):
raise HTTPException(404, "SOA not found")
Comment on lines +420 to +424
def _require_other_reason(self):
if self.primary_reason_code == "C17649" and not self.primary_reason_other:
raise ValueError(
"otherReason is required when primary reason code is C17649"
)
Comment thread src/soa_builder/web/templates/amendment_form_fields.html Outdated
Comment thread src/soa_builder.egg-info/top_level.txt
Copilot AI review requested due to automatic review settings May 8, 2026 19:47
Copy link
Copy Markdown
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

Copilot reviewed 77 out of 80 changed files in this pull request and generated 5 comments.

Comment thread src/soa_builder/web/schemas.py
Comment thread src/soa_builder/web/schemas.py
Comment thread src/soa_builder/web/routers/freezes.py Outdated
Comment thread src/soa_builder/web/routers/freezes.py Outdated
Comment thread src/soa_builder.egg-info/SOURCES.txt
Copilot AI review requested due to automatic review settings May 8, 2026 20:15
@pendingintent pendingintent moved this from Todo to In Progress in @pendingintent's version 1.3 May 8, 2026
Copy link
Copy Markdown
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

Copilot reviewed 77 out of 80 changed files in this pull request and generated 6 comments.

Comment on lines +410 to +444
class StudyAmendmentCreate(BaseModel):
name: str
number: str
summary: str
label: Optional[str] = None
description: Optional[str] = None
primary_reason_code: str
primary_reason_other: Optional[str] = None

@model_validator(mode="after")
def _require_other_reason(self):
if self.primary_reason_code == "C17649" and not self.primary_reason_other:
raise ValueError(
"otherReason is required when primary reason code is C17649"
)
return self


class StudyAmendmentUpdate(BaseModel):
name: Optional[str] = None
number: Optional[str] = None
summary: Optional[str] = None
label: Optional[str] = None
description: Optional[str] = None


class StudyAmendmentReasonCreate(BaseModel):
code: str
other_reason: Optional[str] = None

@model_validator(mode="after")
def _require_other(self):
if self.code == "C17649" and not self.other_reason:
raise ValueError("otherReason is required when reason code is C17649")
return self
Comment on lines +26 to +33
<label class="am-field-label">Primary Reason <span class="am-required">*</span></label>
<select name="primary_reason_code" required class="am-select"
onchange="var o=this.options[this.selectedIndex];document.getElementById('primary-other-row').style.display=o.getAttribute('data-code')==='C17649'?'flex':'none';">
<option value="" disabled selected>— select reason —</option>
{% for code, sv in reason_terms.items()|sort(attribute='1') %}
<option value="{{ sv }}" data-code="{{ code }}">{{ sv }}</option>
{% endfor %}
</select>
Comment on lines +22 to +31
<select name="code" required class="am-select"
onchange="var o=this.options[this.selectedIndex];this.closest('form').querySelector('.other-reason-box').style.display=o.getAttribute('data-code')==='C17649'?'flex':'none';">
<option value="" disabled selected>— select reason —</option>
{% for code, sv in reason_terms.items()|sort(attribute='1') %}
<option value="{{ sv }}" data-code="{{ code }}">{{ sv }}</option>
{% endfor %}
</select>
<div class="other-reason-box am-field" style="display:none">
<input name="other_reason" class="am-input" placeholder="Specify other reason" />
</div>
Comment thread src/usdm/usdm_utils.py
Comment on lines +408 to +417
if not code_uid:
return {
"id": f"Code_{kind}Level_unknown",
"extensionAttributes": [],
"code": "",
"codeSystem": "",
"codeSystemVersion": "",
"decode": "",
"instanceType": "Code",
}
Comment on lines +422 to +463
def get_next_biomedical_concept_property_uid(cur: Any, soa_id: int) -> str:
"""Compute next unique BiomedicalConceptProperty_N for the given SOA.

Assumes `cur` is a sqlite cursor within an open transaction.
"""
cur.execute(
"SELECT biomedical_concept_property_uid FROM"
" biomedical_concept_property WHERE soa_id=?"
" AND biomedical_concept_property_uid LIKE"
" 'BiomedicalConceptProperty_%'",
(soa_id,),
)
existing = [x[0] for x in cur.fetchall() if x[0]]
n = 1
if existing:
try:
n = max(int(x.split("_")[1]) for x in existing) + 1
except Exception:
n = len(existing) + 1
return f"BiomedicalConceptProperty_{n}"


def get_next_extension_attribute_uid(cur: Any, soa_id: int) -> str:
"""Compute next unique ExtensionAttribute_N for the given SOA.

Assumes `cur` is a sqlite cursor within an open transaction.
"""
cur.execute(
"SELECT extension_attribute_uid FROM activity_concept_dss"
" WHERE soa_id=?"
" AND extension_attribute_uid LIKE 'ExtensionAttribute_%'",
(soa_id,),
)
existing = [x[0] for x in cur.fetchall() if x[0]]
n = 1
if existing:
try:
n = max(int(x.split("_")[1]) for x in existing) + 1
except Exception:
n = len(existing) + 1
return f"ExtensionAttribute_{n}"

Comment on lines +58 to +72
echo "Retrieving storage account key..."
STORAGE_KEY=$(az storage account keys list \
--resource-group "$RESOURCE_GROUP" \
--account-name "$STORAGE_ACCOUNT" \
--query '[0].value' \
--output tsv 2>&1)

if [ $? -ne 0 ]; then
echo -e "${RED}Error: Failed to retrieve storage account key${NC}"
echo "Please verify:"
echo " 1. Resource group '$RESOURCE_GROUP' exists"
echo " 2. Storage account '$STORAGE_ACCOUNT' exists"
echo " 3. You have permission to access the storage account"
exit 1
fi
Copilot AI review requested due to automatic review settings May 12, 2026 14:24
Copy link
Copy Markdown
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

Copilot reviewed 77 out of 80 changed files in this pull request and generated 5 comments.

Comment thread startup.sh
Comment on lines +18 to +26
# Run database migrations (handled by app lifespan)
# Start gunicorn with uvicorn worker
gunicorn soa_builder.web.app:app \
--bind 0.0.0.0:8000 \
--workers 1 \
--worker-class uvicorn.workers.UvicornWorker \
--timeout 120 \
--access-logfile - \
--error-logfile - No newline at end of file
Comment on lines +13 to +17
# Configuration - UPDATE THESE VALUES
RESOURCE_GROUP="rg-soa-workbench-prod"
STORAGE_ACCOUNT="soaworkbenchsa" # Replace <uniqueid> with your storage account suffix
FILE_SHARE="soa-workbench-data"
LOCAL_DB="soa_builder_web.db"
Comment on lines +57 to +72
# Get storage account key
echo "Retrieving storage account key..."
STORAGE_KEY=$(az storage account keys list \
--resource-group "$RESOURCE_GROUP" \
--account-name "$STORAGE_ACCOUNT" \
--query '[0].value' \
--output tsv 2>&1)

if [ $? -ne 0 ]; then
echo -e "${RED}Error: Failed to retrieve storage account key${NC}"
echo "Please verify:"
echo " 1. Resource group '$RESOURCE_GROUP' exists"
echo " 2. Storage account '$STORAGE_ACCOUNT' exists"
echo " 3. You have permission to access the storage account"
exit 1
fi
Comment thread src/usdm/usdm_utils.py
Comment on lines +420 to +427
cur.execute(
"SELECT codelist_table, codelist_code, code "
"FROM code_association WHERE soa_id=? AND code_uid=? LIMIT 1",
(soa_id, code_uid),
)
row = cur.fetchone()
conn.close()
if not row:
Comment on lines 1 to 7
LICENSE
README.md
pyproject.toml
src/sdtm/generate_ta.py
src/sdtm/generate_te.py
src/sdtm/generate_tv.py
src/soa_builder/__init__.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants