Repository navigation
docs: update README and docs for release readiness - #97
Merged
Merged
Conversation
- README: rewrite with clear value proposition, comparison table, features list, complete get-started guide, component catalog table. Remove stale archetype section. - CLAUDE.md: merge AGENTS.md content, update Java 25 / v0.13.1-SNAPSHOT, add module table (incl. graalvm, micrometer, opentelemetry), add release procedure, delete Past Issues (all fixed in code). - Delete AGENTS.md (content merged into CLAUDE.md). - docs/getting-started.md: restructure with numbered steps, add "What's next?" links, use kotowari instead of enkan-web. - docs/reference/components.md: add Micrometer component, mark Metrics as deprecated, add virtualThreads property to Jetty. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a find+sed step that updates all <version> tags in docs/src/content/**/*.md, ensuring getting-started.md and any future doc pages stay in sync with the release version. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add steps to update: - CLAUDE.md version string (plain text) - SECURITY.md supported version table (major.minor.x) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The self-executing JAR stub concatenates a shell script with the fat JAR. Without exit 0 after the exec line, the shell could interpret JAR binary bytes as additional arguments, causing args.length != 0 and skipping the auto-connect code path (readPortFile). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Doma2 converts camelCase field names to snake_case for SQL column mapping (postedAt -> posted_at). The DDL had 'postedat' (no underscore), causing H2 to create column POSTEDAT which does not match the generated SQL's POSTED_AT. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add V4 migration with seed customers (alice/bob, password: password) so the guestbook login actually works out of the box - Change password input from type="text" to type="password" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add PasswordEncoder using PBKDF2WithHmacSHA256 (JDK standard, no external dependencies). Stored format: iterations:salt:hash - Change login flow: query by email only (selectByEmail), then verify password hash in Java with constant-time comparison - Seed data (V4 migration) now stores hashed passwords via PasswordEncoder.encode() - Remove password from Customer.toString() to prevent log leakage - Rename loginByPassword.sql -> selectByEmail.sql Login credentials: alice@example.com / password, bob@example.com / password Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
close() was not idempotent — the shutdown hook called close() again after ConsoleHandler.run() already called it, causing raise(Signal.INT) to fire a second time and requiring a third Ctrl+C to actually exit. Use compareAndSet(true, false) to make close() a no-op on subsequent calls. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add end-to-end browser tests that start the full Enkan system and verify key user flows work correctly. Tagged @tag("smoke") and excluded from CI. Tests cover: - Index page loads with example links - Customer CRUD: list (shows seed data), new form, create + redirect - Guestbook: unauthenticated redirect to login, login with hashed password, post message - Session counter: increment across requests - Static resources: stylesheet links present - 404 handling Bugs found and fixed during test development: - MiscController.counter NPE on first visit (Integer unboxing of null) - Missing hibernate-validator dependency (ValidateBodyMiddleware failed silently in production mode) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Save full-page screenshots to target/screenshots/ for each test step: - 01-index, 02-customer-list, 03a/b/c-customer-new-form/filled/after-create - 10-guestbook-login-redirect, 11a/b/c-guestbook-login/list/after-post - 20a/b-counter-first/second, 50-not-found 12 screenshots total, viewport set to 1280x720. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When close() is called from within the run() loop (Ctrl+C, /exit, EOF, shutdown), readLine() is not blocking so raise(Signal.INT) is unnecessary and causes a spurious UserInterruptException that requires an extra Ctrl+C to exit. - closeQuietly(): used from run() loop — skips raise(INT), just sets isAvailable=false and closes sockets - close(): used from shutdown hook and monitor thread — raises INT to wake up a blocking readLine(), then closes sockets - Both are idempotent via compareAndSet(true, false) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
raise(Signal.INT) caused a re-entrant UserInterruptException that required a third Ctrl+C to exit. Replace with terminal.close() which interrupts readLine() via EndOfFileException — a path already handled by the run() loop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: JLine consumes SIGINT as UserInterruptException, so the JVM shutdown hook never fires and the non-daemon ExecutorService thread keeps the JVM alive indefinitely after run() returns. Fix: call clientThread.shutdown() immediately after execute() in main(), then awaitTermination() to block main until the console handler finishes. When run() returns (after Ctrl+C x2, /exit, EOF, or server shutdown), the executor thread terminates and the JVM exits naturally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The pending-exit state was shown both as a println message and as the next readLine prompt, causing two messages on a single Ctrl+C. Remove the prompt variant and keep only the println message. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Key changes in README
Test plan
🤖 Generated with Claude Code