Skip to content

Commit 88e908f

Browse files
authored
Contextual range refactor (#761)
* Enum refactor and slot_usage application * Add doc * Add data model comparison * Fix workflow * Template semantics * Update format
1 parent 97d4e46 commit 88e908f

File tree

10 files changed

+1927
-1046
lines changed

10 files changed

+1927
-1046
lines changed

.github/workflows/main-ci.yml

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,76 @@ jobs:
9595
- `registered-json-schemas/*.json` (Synapse JSON schemas)
9696
9797
**Note:** Artifacts are not committed to this PR to avoid merge conflicts. All artifacts will be automatically rebuilt and committed to `main` after merge.
98-
9998
100-
99+
- name: Upload artifacts for subsequent jobs
100+
uses: actions/upload-artifact@v4
101+
with:
102+
name: build-artifacts
103+
path: |
104+
NF.jsonld
105+
dist/NF.yaml
106+
dist/NF.ttl
107+
registered-json-schemas/*.json
108+
retention-days: 1
109+
110+
analyze:
111+
name: Analyze data model changes
112+
needs: [build]
113+
runs-on: ubuntu-latest
114+
permissions:
115+
pull-requests: write
116+
117+
steps:
118+
- uses: actions/checkout@v4
119+
with:
120+
ref: ${{ github.event.pull_request.head.ref }}
121+
fetch-depth: 0
122+
123+
- uses: actions/setup-python@v5
124+
with:
125+
python-version: '3.10.12'
126+
127+
- name: Install dependencies
128+
run: |
129+
pip install rdflib
130+
131+
- name: Get main branch pre-built NF.ttl for comparison
132+
run: |
133+
git fetch origin main:main
134+
git checkout main -- dist/NF.ttl
135+
mv dist/NF.ttl dist/NF_main.ttl
136+
git checkout ${{ github.event.pull_request.head.ref }}
137+
138+
- name: Download built NF.ttl from build job
139+
uses: actions/download-artifact@v4
140+
with:
141+
name: build-artifacts
142+
path: .
143+
144+
- name: Run comparison analysis
145+
run: |
146+
python utils/compare.py > analysis_output.md
147+
148+
- name: Post analysis as PR comment
149+
uses: mshick/add-pr-comment@v2
150+
with:
151+
message-id: data-model-analysis
152+
message-path: analysis_output.md
153+
101154
# Additionally test PRs
102155
test:
103156
name: Test with schematic current version
104157
needs: [build]
105158
runs-on: ubuntu-latest
106159
env:
160+
SCHEMATIC_VERSION: 24.7.2
107161
SCHEMATIC_SERVICE_ACCT_CREDS: ${{ secrets.SCHEMATIC_SERVICE_ACCT_CREDS }}
108162
permissions:
109163
pull-requests: write
110164
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip tests') }}
111165
# strategy:
112-
# matrix:
113-
# cannot actually do parallel/concurrent testing because of API rate limits,
166+
# matrix:
167+
# cannot actually do parallel/concurrent testing because of API rate limits,
114168
# so we currently only test with one schematic version because it takes much too long with sequential
115169

116170
steps:
@@ -121,8 +175,14 @@ jobs:
121175

122176
- uses: actions/setup-python@v5
123177
with:
124-
python-version: '3.10.12'
125-
178+
python-version: '3.10.12'
179+
180+
- name: Download built artifacts from build job
181+
uses: actions/download-artifact@v4
182+
with:
183+
name: build-artifacts
184+
path: .
185+
126186
- name: Setup schematic
127187
id: setup-schematic
128188
run: |
@@ -156,4 +216,4 @@ jobs:
156216
with:
157217
name: test-logs-${{ env.SCHEMATIC_VERSION }}
158218
path: tests/**/logs
159-
219+

docs/DESIGN.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Design Docs
2+
3+
## Contextual Enum Subsets
4+
5+
### Overview
6+
7+
The data model uses **contextual enum subsets** to provide users with relevant, focused dropdown options rather than presenting large monolithic enumerations containing hundreds of values.
8+
9+
This pattern leverages LinkML's [slot_usage](https://linkml.io/linkml/schemas/slots.html#slot-usage) feature to refine slot definitions within specific class contexts.
10+
11+
### Design Pattern
12+
13+
**Enum Organization:**
14+
- Large enums (assays, platforms, file formats) are split into domain-specific subsets
15+
- Each subset groups semantically related values (e.g., sequencing assays vs. imaging assays)
16+
- Base slot definitions (in `props.yaml`) use `any_of` to effectively define a union, accepting values from all relevant subsets
17+
18+
**Template Constraints:**
19+
Templates apply `slot_usage` to restrict slots to contextually appropriate enum subsets:
20+
21+
```yaml
22+
SequencingTemplate:
23+
slot_usage:
24+
assay:
25+
range: SequencingAssayEnum
26+
platform:
27+
range: SequencingPlatformEnum
28+
fileFormat:
29+
range: SequencingFileFormatEnum
30+
```
31+
32+
**Multiple Context Support:**
33+
When templates span multiple contexts, use `any_of` in slot_usage to define a union of enum subsets:
34+
35+
```yaml
36+
EpigenomicsAssayTemplate:
37+
slot_usage:
38+
platform:
39+
any_of:
40+
- range: SequencingPlatformEnum
41+
- range: ArrayPlatformEnum
42+
```
43+
44+
### Benefits
45+
46+
- **Better UX**: Users see only relevant options for their context
47+
- **Performance**: Templates are smaller and faster to load with constrained enum ranges
48+
- **Type Safety**: Templates enforce appropriate value constraints
49+
- **Maintainability**: Logical grouping makes enums easier to extend
50+
- **Backward Compatibility**: Generic templates remain flexible via `any_of`
51+
52+
### When to Use
53+
54+
- Create enum subsets when a general enum exceeds ~30-50 values
55+
- Apply slot_usage when templates have clear domain context (sequencing, imaging, clinical, etc.)
56+
- Use `any_of` for cross-domain templates or generic base templates

0 commit comments

Comments
 (0)