Skip to content

Commit e33d435

Browse files
Give Claude Code some guidelines (#1275)
1 parent bd5e1fb commit e33d435

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
LabKey Server is a large Java web application platform for biomedical research data management. It uses a modular monolith architecture with 150+ Gradle modules, built on Spring Boot 4 / Spring Framework 7 with embedded Tomcat 11. It targets Java 25 and supports both PostgreSQL and MS SQL Server databases.
8+
9+
## Build Commands
10+
11+
```bash
12+
# Configure IntelliJ IDEA project files
13+
./gradlew ijConfigure
14+
15+
# Select database (populates application.properties from templates)
16+
./gradlew pickPg # PostgreSQL
17+
./gradlew pickMssql # MS SQL Server
18+
19+
# Build and deploy to embedded Tomcat
20+
./gradlew deployApp
21+
22+
# Build a specific module
23+
./gradlew :server:modules:platform:core:build
24+
25+
# Build with a predefined module set
26+
./gradlew -PmoduleSet=community build
27+
28+
# Exclude test modules for faster builds
29+
./gradlew -PexcludeTestModules build
30+
31+
# Build a distribution
32+
./gradlew -PmoduleSet=distributions :distributions:base:dist
33+
```
34+
35+
## Running Tests
36+
37+
**Unit tests** are static `TestCase` inner classes within production source files. They are registered via the module's `getUnitTests()` method and run within the server JVM.
38+
39+
**Integration tests** require a running server and database. They are registered via `getIntegrationTests()`.
40+
41+
**Selenium UI tests** (in `server/testAutomation/`):
42+
```bash
43+
./gradlew :server:testAutomation:initProperties # Generate test.properties
44+
./gradlew :server:testAutomation:uiTests -Psuite=DRT # Run a test suite
45+
```
46+
UI tests require a running LabKey server, a browser driver (ChromeDriver or Geckodriver) on PATH, and configured `test.properties`.
47+
48+
## Architecture
49+
50+
### Module System
51+
52+
Each module lives under `server/modules/` and contains:
53+
- `module.properties` — metadata including `ModuleClass`, `SchemaVersion`, `SupportedDatabases`
54+
- `build.gradle` — uses `org.labkey.build.module` plugin
55+
- A module class extending `SpringModule` (which extends `DefaultModule` implementing `Module`)
56+
57+
Module lifecycle methods in order: `init()``versionUpdate()``afterUpdate()``startup()``startupAfterSpringConfig()``startBackgroundThreads()``destroy()`
58+
59+
In `init()`, modules register controllers via `addController("name", Controller.class)` and set up service implementations. Controllers follow the pattern `*Controller.java`.
60+
61+
### Core Platform Modules (`server/modules/platform/`)
62+
63+
The `api` module provides the core framework (Module interface, SpringModule base class, services, utilities). Other key platform modules: `core` (auth, security, admin), `query` (SQL engine), `experiment`, `study`, `assay`, `pipeline` (job processing), `search`, `audit`, `visualization`.
64+
65+
### Entry Point
66+
67+
`server/embedded/src/org/labkey/embedded/LabKeyServer.java` — a `@SpringBootApplication` that configures embedded Tomcat, SSL/TLS, Content Security Policy, and Log4J2.
68+
69+
### Database
70+
71+
Dual database support (PostgreSQL and MS SQL Server). Configuration lives in `server/configs/application.properties`, populated by `pickPg`/`pickMssql` tasks from `pg.properties`/`mssql.properties` templates. Each module declares its `SchemaVersion` in `module.properties` and manages its own schema migrations.
72+
73+
### Frontend
74+
75+
Mix of JSPs, React (via `@labkey/components`), and ExtJS. Modules with JavaScript/TypeScript have their own `package.json` and use npm builds. Node.js and npm versions are pinned in `gradle.properties` and downloaded during build.
76+
77+
### Distributions
78+
79+
The `distributions/` directory defines 60+ distribution configurations that select which modules to package. Distributions inherit from each other (most inherit from `:distributions:base`). Distribution directory names must not collide with module names.
80+
81+
### Dependency Management
82+
83+
All external library versions are centralized in `gradle.properties` (200+ version properties). The root `build.gradle` forces consistent versions across all modules via `resolutionStrategy`. Always consult before adding, removing, or updating a third-party dependency.
84+
85+
## Coding Conventions
86+
87+
- **Java Streams**: Prefer `Stream` API over traditional for-loops for collection processing.
88+
- **Resources**: Use try-with-resources for automatic resource management.
89+
- **Nullability**: Use `org.jetbrains.annotations.NotNull` and `@Nullable`. Be explicit in public API signatures.
90+
- **Logging**: Use Log4J2. Name the static logger `LOG`, initialized via `LogHelper.getLogger()`:
91+
```java
92+
private static final Logger LOG = LogHelper.getLogger(MyClass.class, "optional description");
93+
```
94+
- **Unit tests**: Create a static `TestCase` inner class extending `Assert` in the same file as production code. Use JUnit 4 annotations (`@Test`). Register new test classes in the owning module's `getUnitTests()`.
95+
- **Selenium tests**: Subclass `BaseWebDriverTest`. Use a `@BeforeClass` for setup and override `doCleanup()` for cleanup. See `SecurityTest` as an example.
96+
- **Formatting**: Follow IntelliJ IDEA project settings in `.idea/codeStyles/Project.xml`.
97+
98+
## Key Build Properties (`gradle.properties`)
99+
100+
- `sourceCompatibility`/`targetCompatibility`: Java 25
101+
- `buildFromSource`: true (build modules from source vs. pulling artifacts)
102+
- `useLocalBuild`: use locally built artifacts
103+
- `moduleSet`: select a predefined set of modules (e.g., `community`, `all`, `distributions`)
104+
- `excludedModules`: comma-separated list of modules to exclude
105+
106+
## Search Tips
107+
108+
When searching for Java method usages, always include `*.jsp` and `*.jspf` files in addition to `*.java`. JSP files contain inline Java code and are significant callers of API methods (especially anything in `JspBase`).
109+
110+
## Pull Request Format
111+
112+
PRs should include sections for: **Rationale** (why the change is needed), **Related Pull Requests**, and **Changes** (notable items).

0 commit comments

Comments
 (0)