This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Source Code Portal (SCP) is an organizational dashboard that aggregates and displays status and documentation from GitHub repositories. It's designed for small to medium-sized organizations (<2500 commits/hour).
Key Capabilities:
- Aggregates repository data from GitHub organizations
- Groups multiple codebases into logical systems
- Displays commit logs, documentation, and build status
- Integrates with Jenkins, Snyk, and Shields.io for status badges
- Supports GitHub webhooks for real-time updates
- Renders Markdown and AsciiDoc documentation
Technology Stack:
- Java 21 LTS (with virtual threads enabled)
- Spring Boot 3.2.2 (primary mode) with Undertow 2.3.17 (embedded server)
- Thymeleaf 3.1.2 (server-side templating)
- Caffeine cache (Spring Cache abstraction) / JSR-107 JCache (legacy)
- Resilience4j 2.2.0 (circuit breaker pattern for external calls)
- Spring Boot Actuator (health checks, metrics, monitoring)
- JUnit 5.11.3 (test framework)
- Sass/SCSS (frontend styling)
- Maven (build system)
This file provides comprehensive guidance for Claude Code. For detailed guides organized by topic, see the docs/ directory:
- Getting Started - Quick start, building, running, configuration
- Architecture - System design, Spring Boot, controllers, caching, packages
- Features - Dashboard, repository groups, integrations, webhooks
- Operations - Docker, deployment, monitoring, troubleshooting
- Development - Contributing, testing, skills
Quick links:
- π Documentation Hub - Complete documentation index
- π Quick Start Guide - Get running in 5 minutes
- ποΈ Architecture Overview - System architecture
- π§ Troubleshooting Guide - Common issues
π For detailed build guide, see docs/getting-started/building.md
# Full clean build with tests
mvn clean install
# Build without tests (faster)
mvn clean install -DskipTests
# Compile Sass to CSS using Maven plugin (slower)
mvn com.github.warmuuh:libsass-maven-plugin:watch
# Compile Sass using native command (requires sass installed)
sass --watch src/main/sass/scss:target/classes/META-INF/views/css
# Run single test
mvn test -Dtest=TestClassName
# Run specific test method
mvn test -Dtest=TestClassName#methodNameπ For detailed running guide, see docs/getting-started/running.md
Spring Boot is the recommended mode for running the application. It provides modern Spring ecosystem features including dependency injection, auto-configuration, actuator endpoints, and better testability.
# Run with Maven
mvn spring-boot:run
# Run with Maven in dev mode (auto-reload)
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# Run JAR after building
mvn clean package
java -jar target/source-code-portal-*.jar
# Run with IntelliJ: Execute SpringBootServer.main()
# Run with custom profile
mvn spring-boot:run -Dspring-boot.run.profiles=prod
# Run with environment variables
SCP_GITHUB_ACCESS_TOKEN=your_token mvn spring-boot:run
# Default server URL: http://localhost:9090Spring Boot Actuator Endpoints:
/actuator/health- Overall health with custom indicators (GitHub, cache, executor)/actuator/health/github- GitHub API rate limit status/actuator/health/cache- Cache health and statistics/actuator/health/executor- Thread pool health/actuator/info- Application information (version, runtime, configuration)/actuator/metrics- Application metrics/actuator/prometheus- Prometheus metrics endpoint/actuator/caches- Cache manager details/actuator/scheduledtasks- Scheduled task list
Application Endpoints:
/ping- Simple health check/health- Health status (legacy endpoint, prefer /actuator/health)/docs- Main documentation portal/dashboardor/- Dashboard view/group/{groupId}- Group view/contents/{org}/{repo}/{branch}- Repository contents/commits/{org}/{repo}- Commit log/github/webhook- GitHub webhook receiver
The legacy Undertow mode is still available but deprecated. It will be removed in a future version.
# Run main class (after building)
mvn clean package
java -cp target/source-code-portal-*.jar no.cantara.docsite.Server
# Run with IntelliJ: Execute Server.main()
# Default server URL: http://localhost:9090Note: When running in legacy mode, Spring Boot actuator endpoints are not available. Use /health for basic health checks.
π For detailed configuration guide, see docs/getting-started/configuration.md
Configuration files are loaded in this order (later overrides earlier):
src/main/resources/application-defaults.properties(defaults)application.properties(custom overrides)security.properties(credentials)application_override.properties(final overrides)- Environment variables with
SCP_prefix - System properties
Repository Configuration:
- Primary config:
src/main/resources/conf/config.json - Defines GitHub organization, repository groups, and external service integrations
- Supports regex patterns for repository matching (e.g., "Whydah*")
- Each group has a
groupId,display-name,description, and list of repo patterns
GitHub Authentication:
Configure in security.properties:
github.oauth2.client.clientId=YOUR_CLIENT_ID
github.oauth2.client.clientSecret=YOUR_CLIENT_SECRET
github.client.accessToken=YOUR_ACCESS_TOKENTo generate an access token, use ObtainGitHubAccessTokenTestTool or Docker:
docker run -it -e SCP_github.oauth2.client.clientId=CLIENT_ID \
-e SCP_github.oauth2.client.clientSecret=CLIENT_SECRET \
cantara/sourcecodeportal /github-access-tokenπ For detailed architecture documentation, see docs/architecture/:
- Overview - System architecture and technology stack
- Spring Boot - Application initialization details
- Controllers - Request flow and Spring MVC
- Caching - Cache strategy and implementation
- Packages - Package structure and responsibilities
Spring Boot Application Initialization (SpringBootServer.java):
- Load configuration from Spring Boot properties (application.yml, environment variables, system properties)
- Initialize Spring context with auto-configuration
- Create CacheStore bean (Spring Cache with Caffeine backend)
- Create ExecutorService and ScheduledExecutorService beans
- Load RepositoryConfigLoader (parse config.json, fetch GitHub repos)
- Run SpringBootInitializer for startup tasks
- Enable PreFetchData (initial cache population)
- Start embedded Undertow server (via Spring Boot)
Request Flow (Spring Boot Mode):
HTTP Request
β Spring DispatcherServlet (Spring MVC)
β Spring MVC Controllers (@Controller / @RestController)
β Web Pages:
- DashboardWebController (/dashboard, /)
- GroupWebController (/group/{groupId})
- CommitsWebController (/commits/*)
- ContentsWebController (/contents/{org}/{repo}/{branch})
- WikiWebController (/wiki/{pageName})
β REST/API:
- PingRestController (/ping)
- HealthRestController (/health, /health/github, /health/threads)
- EchoRestController (/echo)
- GitHubWebhookRestController (/github/webhook)
β Resources:
- BadgeResourceController (/badge/*)
- Spring Boot Static Resource Handler (CSS, JS, images)
β ThymeleafViewEngineProcessor (render HTML for web pages)
Request Flow (Legacy Undertow Mode - Deprecated):
HTTP Request
β ApplicationController (routing) [@Deprecated]
β WebController (web pages) [@Deprecated]
β WebHandler implementations (DashboardHandler, CardHandler, etc.)
β ThymeleafViewEngineProcessor (render HTML)
β OR StaticContentController (static resources)
β OR HealthController (health checks)
β OR GithubWebhookController (webhook events)
no.cantara.docsite.cache - JCache-based caching layer
CacheStore- Central cache manager with typed caches for repositories, commits, contents, build status, etc.- Cache keys:
CacheKey,CacheRepositoryKey,CacheGroupKey,CacheShaKey
no.cantara.docsite.domain - Domain models and business logic
config/- Repository configuration loading and parsinggithub/- GitHub API models (repos, commits, releases, contents)renderer/- Markdown/AsciiDoc rendering logicjenkins/- Jenkins build status integrationsnyk/- Snyk security test integrationshields/- Shields.io badge integrationscm/- Source control abstractions (currently GitHub-only)
no.cantara.docsite.controller - HTTP request handlers
- Spring MVC Controllers (Recommended):
spring/- Spring MVC @Controller and @RestController classesDashboardWebController- Dashboard pageGroupWebController- Group view pageCommitsWebController- Commit history pageContentsWebController- Repository contents pageWikiWebController- Wiki pagePingRestController- Ping endpointHealthRestController- Health endpoints (/health, /health/github, /health/threads)EchoRestController- Echo diagnostic endpointGitHubWebhookRestController- GitHub webhook receiverBadgeResourceController- Badge serving (SVG images)
- Legacy Undertow Controllers (Deprecated):
ApplicationController- Main routing controller [@Deprecated since 0.10.17-SNAPSHOT]WebController- Web page routing [@Deprecated since 0.10.17-SNAPSHOT]handler/- Page-specific handlers (DashboardHandler, CardHandler, CommitsHandler, etc.) [@Deprecated]- See
DEPRECATED_UNDERTOW_CONTROLLERS.mdfor migration guide
no.cantara.docsite.commands - Resilience4j command pattern for external HTTP calls
BaseResilientCommand- Base class with circuit breaker, bulkhead, and time limiterGetGitHubCommand- GitHub API requests with circuit breakerGetCommand- Generic HTTP requestsGetShieldsCommand- Shields.io requests
no.cantara.docsite.fetch - Data fetching services
PreFetchData- Initial data population on startupScheduledFetchData- Periodic background updates
no.cantara.docsite.web - Web templating infrastructure
ThymeleafViewEngineProcessor- Thymeleaf renderingResourceContext- Request path parsingWebHandler- Handler interface
no.cantara.docsite.executor - Thread pool management
ExecutorService- Async task executorScheduledExecutorService- Scheduled periodic tasks
Caching Strategy:
- All GitHub data is cached using JSR-107 JCache (RI implementation)
- Cache keys are strongly typed:
CacheKey(org/repo/branch),CacheRepositoryKey(includes groupId), etc. - Data is prefetched on startup and refreshed periodically via scheduled tasks
- Webhooks trigger immediate cache updates for push events
Circuit Breaker Pattern:
- All external HTTP calls use Resilience4j commands (
BaseResilientCommand) - Implements Circuit Breaker (50% failure threshold, 60s open state)
- Implements Bulkhead (25 max concurrent calls)
- Implements Time Limiter (75s timeout)
- Uses Java 21 virtual threads for async execution
- Protects against API rate limits and network failures
Configuration-Driven Repository Groups:
config.jsondefines logical groupings of repositories- Supports regex patterns for dynamic repository inclusion
- Each group has a "default group repo" for navigation
Frontend Development: Install Node.js (10.x+) and Sass (3.5+) for live frontend development:
# Native Sass watch (fastest)
sass --watch src/main/sass/scss:target/classes/META-INF/views/css
# In IntelliJ: Map keyboard shortcut to Build > Rebuild
# Rebuild syncs templates to target/classes/META-INF/viewsThymeleaf templates are in src/main/resources/META-INF/views/:
template.html- Base layoutindex.html- Dashboardgroup/card.html- Group viewcontents/content.html- Repository contentscommits/commits.html- Commit history
Testing:
- Tests use JUnit 5 (Jupiter) framework
TestServerExtensionprovides embedded server for integration testsTestClientprovides HTTP client utilities- Test data can be dumped to files using
DumpTestDataToFile - Run tests:
mvn test - Run specific test:
mvn test -Dtest=TestClassName
π For detailed Docker guide, see docs/operations/docker.md
Build Docker image:
# Build specific version
docker build --build-arg DOCKER_TAG=0.10.17 -t cantara/sourcecodeportal .
# Build latest (downloads from Maven repository)
docker build -t cantara/sourcecodeportal .Run Docker container:
# Run with OAuth credentials
docker run --env github.oauth2.client.clientId=xyz \
--env github.oauth2.client.clientSecret=secret \
--rm -p 80:9090 cantara/sourcecodeportal
# Copy config to running container
docker inspect -f '{{.Id}}' cantara/sourcecodeportal
sudo cp config.json /var/lib/docker/aufs/mnt/CONTAINER_ID/home/sourcecodeportal/config_override/conf/config.jsonπ For detailed webhook guide, see docs/features/webhooks.md
To receive real-time updates from GitHub:
- Set up webhook at
https://github.com/organizations/YOUR_ORG/settings/hooks/ - URL:
https://your-server.com/github/webhook - Content type:
application/json - Secret: Same as
github.webhook.securityAccessTokeninsecurity.properties - Events: Branch or tag creation, Pushes, Releases
For local development with ngrok:
ngrok http 9090
# Use the ngrok URL for webhook: https://XXXXX.ngrok.io/github/webhookWebhook handling is in GitHubWebhookRestController (Spring MVC) or GithubWebhookController (legacy Undertow), which updates the cache when push events are received.
- ChromeDriver is required for GitHub OAuth token generation (not runtime)
- The application requires JDK 21 (LTS)
- Maven Shade plugin creates a fat JAR with all dependencies
- Virtual threads are enabled for better I/O performance
- Repository visibility (public/private/all) is controlled by
github.repository.visibilityproperty
Phase 1 (Complete):
PHASE1_COMPLETE.md- Full Phase 1 summaryMODERNIZATION_PHASE1.md- Technical detailsGOTCHAS_AND_LEARNINGS.md- Common issues and solutionsMIGRATION_JUNIT5_SUMMARY.md- Test framework migration
Next Phase: Phase 2 - Spring Boot Migration (see modernization plan)
IMPORTANT: After completing any significant task, always create or update Claude Code skills to capture learnings.
Skills are located in ~/.claude/skills/ and can be invoked with /skill-name:
-
/modernize-dependency- Safely update dependencies- Handles breaking changes
- API migration patterns
- Common gotchas (group ID changes, API renames)
- Use when: Updating any library version
-
/migrate-test-framework- Migrate test frameworks- TestNG β JUnit 5 (complete guide)
- Listener β Extension conversion
- Assertion order changes
- Use when: Changing test frameworks
-
/verify-build- Comprehensive build verification- Systematic error resolution
- Common fixes (dependencies, APIs, imports)
- Build optimization tips
- Use when: Build fails or after major changes
After completing a task, create or update skills following this process:
-
Identify reusable patterns:
- Did you solve a complex problem?
- Did you discover gotchas?
- Would this help in similar projects?
-
Create skill file:
~/.claude/skills/skill-name.yamlname: skill-name description: One-line description version: 1.0.0 invoke: prompt: | [Detailed instructions...]
-
Document learnings: Add to
GOTCHAS_AND_LEARNINGS.md- What went wrong?
- How you fixed it
- Code examples (before/after)
- Why it happened
-
Update CLAUDE.md: Add skill to list above
Good skill candidates:
- Complex migrations (framework upgrades, library replacements)
- Build issues with non-obvious solutions
- Multi-step processes (testing, deployment, configuration)
- Domain-specific patterns (this codebase's architecture)
What to include in skills:
- Step-by-step instructions
- Common gotchas with solutions
- Code examples (before/after)
- Verification steps
- Rollback procedures
- Tool commands (bash, mvn, etc.)
Example template:
name: example-skill
description: Do something useful
version: 1.0.0
invoke:
prompt: |
## 1. Analysis
[What to check first]
## 2. Process
[Step-by-step instructions]
## 3. Common Issues
[Gotchas and fixes]
## 4. Verification
[How to verify success]
## 5. Examples
[Code examples]Create skills after:
- β Completing Phase 1, 2, 3, etc. of a project
- β Solving a tricky build issue
- β Discovering non-obvious solutions
- β Migrating between technologies
- β Implementing complex patterns
Rule of thumb: If you spent >1 hour solving something, make it a skill.
- Version skills: Increment version when updating
- Test skills: Verify instructions work
- Keep current: Update when technology changes
- Share learnings: Document in GOTCHAS_AND_LEARNINGS.md
The application has been migrated from standalone Undertow to Spring Boot 3.2.2. Both modes are supported for backward compatibility, but Spring Boot is the recommended mode.
Infrastructure:
- Added Spring Boot 3.2.2 with BOM dependency management
- Added Spring Boot starters (web, cache, actuator, thymeleaf)
- Migrated configuration to Spring Boot properties (application.yml)
- Added Spring Boot Actuator for observability
Configuration:
- Type-safe configuration with @ConfigurationProperties (
ApplicationProperties.java) - Backward compatibility bridge for legacy code (
ConfigurationBridge.java) - Environment variable support (
SCP_*prefix) - Profile-based configuration (dev, prod, test)
Caching:
- Spring Cache abstraction with Caffeine backend
- Micrometer metrics integration
- Prometheus metrics export
Controllers:
- Spring MVC controllers (
@RestController,@Controller) - Automatic JSON serialization
- Declarative routing with annotations
- CORS configuration via
WebMvcConfiguration
Scheduling:
- Spring @Scheduled tasks replacing custom executors
- Configuration-driven intervals
- Actuator endpoint:
/actuator/scheduledtasks
Observability:
- Custom health indicators (GitHub, Cache, Executor)
- Custom info contributor (application metadata)
- Prometheus metrics
- Health probes for Kubernetes
Key Files Created:
src/main/java/no/cantara/docsite/SpringBootServer.java- Main entry pointsrc/main/resources/application.yml- Spring Boot configurationsrc/main/java/no/cantara/docsite/config/ApplicationProperties.java- Type-safe configsrc/main/java/no/cantara/docsite/config/ConfigurationBridge.java- Legacy compatibilitysrc/main/java/no/cantara/docsite/config/SpringBootInitializer.java- Startup initializationsrc/main/java/no/cantara/docsite/actuator/*- Custom health indicatorssrc/main/java/no/cantara/docsite/controller/spring/*- Spring MVC controllers
Documentation:
PHASE2_PROGRESS.md- Migration progress and statusTASK*_SUMMARY.md- Task-specific documentationCLAUDE_SKILLS.md- Skills for common tasks
See CLAUDE_SKILLS.md for detailed skill documentation. Key skills:
Tier 1 (Immediate Value):
/migrate-controller- Convert Undertow controller to Spring MVC/add-scheduled-task- Create Spring @Scheduled task/add-health-indicator- Create custom health indicator
Tier 2 (High Value):
/add-repository-group- Add repository group configuration/configure-spring-cache- Set up cache configuration/modernize-dependency- Safely update dependencies
Tier 3 (Strategic Value):
/add-spring-config- Add configuration properties/add-integration- Add external service integration/add-webhook-handler- Add webhook support/migrate-to-spring-boot- General migration orchestrator
# Run all tests
mvn test
# Run Spring Boot tests only
mvn test -Dtest=*SpringBoot*
# Run specific test class
mvn test -Dtest=SpringBootServerTest
# Run with specific profile
mvn test -Dspring.profiles.active=testThe application supports both Spring Boot and legacy Undertow modes:
Spring Boot Mode (Recommended):
mvn spring-boot:run
# or
java -jar target/source-code-portal-*.jarLegacy Undertow Mode (Deprecated):
java -cp target/source-code-portal-*.jar no.cantara.docsite.ServerMode can be configured via scp.server.mode property (values: spring-boot, undertow).
All Undertow controllers and handlers have been migrated to Spring MVC as part of Phase 2 completion. The legacy Undertow controllers are now deprecated and will be removed in a future version.
Controllers Migrated (13 total):
- StaticContentController β Spring Boot static resource configuration
- ImageResourceController β Spring Boot static resource configuration
- CORSController β
CorsConfiguration(Spring Boot CORS config) - EchoController β
EchoRestController(Spring MVC) - PingController β
PingRestController(already existed from Phase 2) - GithubWebhookController β
GitHubWebhookRestController(Spring MVC) - HealthController β
HealthRestController(enhanced with all legacy features) - DashboardHandler β
DashboardWebController(already existed from Phase 2) - CardHandler β
GroupWebController(Spring MVC) - CommitsHandler β
CommitsWebController(Spring MVC) - ContentsHandler β
ContentsWebController(Spring MVC) - CantaraWikiHandler β
WikiWebController(Spring MVC) - BadgeResourceHandler β
BadgeResourceController(Spring MVC)
Routing Controllers Deprecated:
ApplicationController- Marked @Deprecated (forRemoval = true)WebController- Marked @Deprecated (forRemoval = true)- These remain for Undertow standalone mode compatibility
Code Quality:
- 50-70% less boilerplate code with Spring MVC
- Cleaner code following Spring Boot conventions
- Better separation of concerns
- Comprehensive inline documentation
Developer Experience:
- Industry-standard patterns (Spring MVC)
- Better IDE support (Spring tooling)
- Easier testability with @WebMvcTest
- Constructor injection for dependencies
- Declarative routing with annotations
Backward Compatibility:
- All URLs unchanged (e.g.,
/dashboard,/group/{id},/health) - Identical JSON response formats maintained
- Dual-mode support (Spring Boot primary, Undertow legacy)
- Zero breaking changes for existing users
Observability:
- Spring Boot Actuator integration ready
- Better logging at controller level
- Metrics collection (future enhancement)
WEEK2-3_PROGRESS.md- Detailed migration progress and statisticsSESSION_SUMMARY.md- Complete session summaryDEPRECATED_UNDERTOW_CONTROLLERS.md- Deprecation guide and timelineDEPRECATED_UNDERTOW_CONTROLLERS.mdlists all deprecated controllers with Spring MVC replacements
Before (Undertow):
public class MyController implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
// Manual thread dispatch
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
// Manual JSON building
String json = "{\"result\": \"value\"}";
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
exchange.getResponseSender().send(json);
}
}After (Spring MVC):
@RestController
@RequestMapping("/my-endpoint")
public class MyRestController {
@GetMapping
public ResponseEntity<Map<String, Object>> handle() {
return ResponseEntity.ok(Map.of("result", "value"));
}
}Code Reduction: 50-70% (Spring handles boilerplate)
When starting work on this project:
- Read this file first (
CLAUDE.md) - Comprehensive overview for Claude Code - Browse documentation hub (docs/README.md) - Complete documentation index
- Review learnings (
LEARNINGS.md) - All gotchas and best practices - Check skills (
CLAUDE_SKILLS.md) - Automation skills available - For specific tasks, see:
- Getting Started - Setup, building, running, configuration
- Architecture - System design and patterns
- Features - Capabilities and integrations
- Operations - Deployment, monitoring, troubleshooting
- Use skills for common tasks:
/migrate-controller- Convert Undertow β Spring MVC/add-scheduled-task- Create @Scheduled tasks/add-health-indicator- Add health checks
- After task: Update
LEARNINGS.mdandCHANGELOG.md
Root Level (essential files, 7 total):
- README.md - Project overview
- CLAUDE.md - This file (Claude Code guide)
- CHANGELOG.md - Version history
- LEARNINGS.md - All gotchas & learnings
- VERIFICATION_GUIDE.md - Verify Spring Boot works
- CLAUDE_SKILLS.md - Automation skills
- TODO.md - Current work tracking
docs/ (organized detailed guides, 25+ files):
βββ README.md - Documentation hub (START HERE)
βββ getting-started/ - Quick start, building, running, config (5 files)
βββ architecture/ - System design, Spring Boot, caching, packages (6 files)
βββ features/ - Dashboard, groups, integrations, webhooks (6 files)
βββ operations/ - Docker, deployment, monitoring, troubleshooting (5 files)
βββ development/ - Contributing, testing, skills (3 files)
βββ history/ - Archived docs from Phase 1, 2, 3 (22 files)
βββ phase1/ - Java 21, JUnit 5 migration
βββ phase2/ - Spring Boot migration
βββ phase3/ - Frontend improvements
βββ testing/ - Test completion reports
βββ sessions/ - Session summaries
βββ planning/ - Historical planning
βββ skills/ - Skills proposals
βββ deprecated/ - Deprecation guides
βββ migration-notes/ - Gotchas and notes
- Phase 2 Complete: Spring Boot migration finished (see
PHASE2_PROGRESS.md) - Phase 2 Learnings: Consolidated in
LEARNINGS.md(Phase 2 section) - Historical Docs: Archived in
docs/history/(still accessible) - Next Steps: See
NEXT_STEPS.mdfor planned work