Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Local Maven build outputs — re-generated inside the builder stage.
**/target/

# Local npm installs — frontend-maven-plugin runs `npm ci` inside the
# builder stage, so any host-side install would just bloat the build context.
**/node_modules/

# Per-deployment runtime config + logs + GTFS payload + Postgres bind data.
# Mounted into containers at runtime via volumes, not baked into the image.
.deploy/
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ __pycache__/
.playwright-mcp/
map-fixed.png

# Frontend npm installs (transitclockWebapp).
node_modules/

# Top-level docker-stack secrets (DB password, API key). .env.example is
# committed as a template; .env is per-deployment.
/.env
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Built from the repository root as a Maven multi-module project.

There is no lint step configured in the build.

The webapp module has a frontend toolchain (Vite + Vitest) wired into Maven via `frontend-maven-plugin`. `mvn package` on `transitclockWebapp` automatically downloads a pinned Node, runs `npm ci`, and runs `vite build` — its output (`target/frontend-dist/`) is folded into the WAR at `/dist`. `mvn verify` also runs Vitest. `-DskipTests` skips Vitest (the Vite build still runs because the WAR depends on its output).

## Code coverage

JaCoCo 0.8.12 is wired at the root `pom.xml`. It inherits into any module that declares `<parent>`, which today means `transitclock`, `transitclockBarefootClient`, and `transitclockTraccarClient`. `transitclockApi` and `transitclockWebapp` don't declare `<parent>`, so they currently produce no coverage data.
Expand Down Expand Up @@ -83,6 +85,7 @@ GTFS data in the DB is versioned by `configRev` and travel-time data by `travelT
- Bring tomcat up with the override: `docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d tomcat`. The override deletes `web.war` from the image at startup so it doesn't fight the bind mount.
- The override only affects `tomcat`; `core`, `db`, and `tools` keep their normal behavior.
- Java class changes (anything under `transitclockWebapp/src/main/java`, `transitclockApi`, or core) still require `mvn -pl transitclockWebapp -am package -DskipTests` followed by `docker compose -f docker-compose.yml -f docker-compose.dev.yml restart tomcat`. Only the JSP/CSS/JS/HTML/image loop is fast.
- For Tailwind / Vite-bundled assets, run `cd transitclockWebapp && npm run dev` in a second terminal — Vite watches `frontend/` and writes to `target/frontend-dist/`, which the dev override bind-mounts into Tomcat at `/dist`. Browser refresh shows the change.
- To return to the production-style baked-WAR flow, drop the `-f docker-compose.dev.yml` flag.

## Conventions to be aware of
Expand Down
9 changes: 8 additions & 1 deletion docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
# no docker rebuild, no compose restart.
#
# Usage:
# # one-time: populate target/web/WEB-INF/{lib,classes} for the JSPs
# # one-time: populate target/web/WEB-INF/{lib,classes} for the JSPs and
# # target/frontend-dist/ for the Vite-built Tailwind bundle.
# mvn -pl transitclockWebapp -am package -DskipTests
#
# # for fast Tailwind / frontend iteration, run Vite in watch mode in a
# # second terminal — output goes to target/frontend-dist/, which the
# # bind mount below picks up:
# cd transitclockWebapp && npm run dev
#
# # bring up tomcat with the override
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d tomcat
#
Expand All @@ -27,6 +33,7 @@ services:
- ./transitclockWebapp/src/main/webapp:/usr/local/tomcat/webapps/web
- ./transitclockWebapp/target/web/WEB-INF/lib:/usr/local/tomcat/webapps/web/WEB-INF/lib:ro
- ./transitclockWebapp/target/web/WEB-INF/classes:/usr/local/tomcat/webapps/web/WEB-INF/classes:ro
- ./transitclockWebapp/target/frontend-dist:/usr/local/tomcat/webapps/web/dist:ro
command:
- |
if [ -z "${TRANSITCLOCK_APIKEY:-}" ]; then
Expand Down
7 changes: 7 additions & 0 deletions transitclockWebapp/frontend/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import "tailwindcss";

@source "../src/main/webapp/**/*.jsp";
@source "../src/main/webapp/**/*.tag";
@source "../src/main/webapp/**/*.html";
@source "../src/main/webapp/**/*.js";
@source "../frontend/**/*.js";
3 changes: 3 additions & 0 deletions transitclockWebapp/frontend/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function classNames(...parts) {
return parts.filter(Boolean).join(' ');
}
12 changes: 12 additions & 0 deletions transitclockWebapp/frontend/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { describe, it, expect } from 'vitest';
import { classNames } from './utils.js';

describe('classNames', () => {
it('joins truthy parts with spaces', () => {
expect(classNames('a', 'b', 'c')).toBe('a b c');
});

it('skips falsy parts', () => {
expect(classNames('a', null, undefined, false, '', 'b')).toBe('a b');
});
});
Loading
Loading