| name | labkey-development |
| description | ALWAYS load when working on LabKey Server modules (MacCossLabModules, targetedms), in a LabKey enlistment directory, or on GitHub issues/PRs in LabKey repositories. |
LabKey Server Module Development
When working on LabKey Server modules, consult these documentation files.
Always Read
- ai/docs/labkey/labkey-feature-branch-workflow.md - Feature branch naming rules and merge process
Ask These Questions First
Ask the user the following questions upfront (can be combined into one message):
- Which module are you working on?
- Which LabKey enlistment are you using? Check both candidate locations and report what you find before touching any files:
C:/proj/labkeyEnlistment
C:/Users/vsharma/WORK/labkey/<checkout-name> (e.g. WORK/labkey/release-branch)
Ask the user to confirm which one to use if both exist or neither is obvious.
- Do you need to create a feature branch? If yes:
Module-Specific Docs
Based on the module the user is working on, read the appropriate doc(s):
| Module | Doc(s) to read |
|---|
testresults | ai/docs/labkey/testresults-module.md |
panoramapublic | ai/docs/labkey/panoramapublic-module.md AND ai/docs/labkey/panoramapublic/panoramapublic-coding-patterns.md |
| Other / unsure | Skip — rely on Key Patterns below |
Also read ai/docs/labkey-setup/README.md if environment setup is needed.
Read On Demand
- ai/docs/labkey/labkey-modules-coding-patterns.md - Full coding patterns reference (action types, forms, DOM builder, unit tests). Read when writing or modifying code — the Key Patterns section below covers the common cases.
- ai/docs/labkey/labkey-selenium-testing-guide.md - Selenium test patterns, commonly used methods, locators, assertions, and DRY practices. Read when writing or modifying Selenium tests.
- ai/docs/labkey/code-review-feedback-catalog.md - Recurring code-review feedback (and the LabKey-idiomatic fix) for targetedms/MacCossLabModules. Read when writing or reviewing code in these repos to pre-empt the issues reviewers reliably flag.
Skyline Team LabKey Modules
The LabKey enlistment spans multiple git repositories. Key ones:
| Repo path (relative to enlistment root) | Contains |
|---|
. (enlistment root) | LabKey platform, core modules |
server/modules/MacCossLabModules/ | MacCoss lab modules: signup, panoramapublic, testresults, pwebdashboard, skylinetoolsstore, etc. |
server/modules/targetedms/ | targetedms (Panorama) module |
Create a feature branch only in the repo(s) that actually have changes — and use the same branch name in each, because TeamCity matches branches across repos by name. Do NOT reflexively branch the enlistment root.
- Work confined to one module under
server/modules/MacCossLabModules/ (e.g. testresults, lincs, panoramapublic, signup, pwebdashboard): branch only MacCossLabModules. The enlistment root has no changes, so a root branch is pointless — it just clutters the enlistment and gives TeamCity a no-op branch.
- Work in
targetedms: branch only server/modules/targetedms/.
- Branch the enlistment root (
.) only when the root repo itself has tracked changes (platform/core modules, or a change that genuinely spans the root and a module).
cd <enlistment-root>/server/modules/MacCossLabModules
git checkout -b 26.3_fb_my-feature
cd <enlistment-root>
git checkout -b 26.3_fb_my-feature
where <enlistment-root> is the confirmed path (e.g. C:/proj/labkeyEnlistment or C:/Users/vsharma/WORK/labkey/release-branch).
Key Modules
- targetedms - The Panorama module. Our most important LabKey module overall. Stores and visualizes targeted mass spec data. Started by Vagisha, now largely maintained by LabKey with funding from pharma contracts. Foundation of the entire Panorama platform.
- panoramapublic - Panorama Public, our public-facing repository for publishable proteomics data as part of ProteomeXchange. Maintained by Vagisha. High external visibility.
- pwebdashboard - Panorama web dashboard. Maintained by Vagisha.
- testresults - Nightly test results dashboard on skyline.ms. Internal to the Skyline team but critical for development workflow. Primary data source for the LabKey MCP server that supports our
/pw-daily reporting system.
Build Commands
Run these from <enlistment-root> (the confirmed repo path — see "Ask These Questions First" above).
gradlew :server:modules:MacCossLabModules:testresults:deployModule
gradlew :server:modules:targetedms:deployModule
gradlew :server:modules:MacCossLabModules:<moduleName>:deployModule
./gradlew deployApp
MANDATORY: Always Build Before Committing
After making any code changes, always build before committing. A successful build confirms there are no compilation errors (e.g. references to deleted classes or JSP files).
- Single module changed → run
deployModule for that module (see commands above)
- Multiple modules changed → run
./gradlew deployApp
This is critical because JSP files are compiled at build time, not by the IDE — compilation errors in JSPs will not be caught by the IDE and will only surface during a build.
Running Tests
- Module unit tests (
TestCase inner classes run via junit-run.view): registration
in getUnitTests(), the run URLs, and the curl-based invocation are documented in
ai/docs/labkey/labkey-modules-coding-patterns.md (Unit Tests).
- Selenium UI tests (browser-driven,
gradlew :server:test:uiTests): see
ai/docs/labkey/labkey-selenium-testing-guide.md.
Key Patterns
- Controllers extend
SpringActionController with static inner action classes
- Actions use
@RequiresPermission, @RequiresSiteAdmin, or @RequiresNoPermission
- API actions extend
MutatingApiAction or ReadOnlyApiAction and return ApiSimpleResponse
- Views are JSP files under the module's
view/ directory
- SQL uses
SQLFragment with parameterized queries (never string concatenation for values)
- Transactions use
DbScope.Transaction with try-with-resources
- Schema access goes through static methods on the module's schema class (e.g.,
TestResultsSchema.getTableInfoTestRuns())
- CSRF — JSP forms use
<labkey:form> or DOM.LK.FORM; JavaScript POSTs include LABKEY.CSRF header
- JSP URL generation uses
jsURL(new ActionURL(...)) for JavaScript and h(new ActionURL(...)) for HTML attributes