All 11 issues from 4-player simulation of The Hunt for Fabius Bile:
1. Roll feed visible to all players (no GM auth guard)
2. Scene text gated by revealed flag; GM explicit reveal per scene
3. GM can add NPC/enemy entries to initiative tracker
4. Round counter synced to Dice Roller via localStorage + custom event
5. Check reward text hidden until player has rolled
6. Checks assignable to specific player via Scene Secrets ⚙ options
7. Fear test quick-roll panel with WP input appears when fearRating > 0
8. Decision checks show textarea/Declare instead of d100 roll button
9. Fate point re-roll: one per check per scene, resets on scene advance
10. Player poll reduced from 8s to 4s, combined mission + roll feed poll
11. Mission complete banner with scene stats and GM outcome notes field
4 follow-up findings from second simulation run:
- Finding #1: Activate mission now initialises revealed:false on all scenes
so players never see scene text before the GM narrates
- Finding #2: Fear penalty auto-applied to WP display; button shows
effective (penalised) target rather than raw WP input
- Finding #3: RollFeedRow moved outside component to avoid re-mount on
every render; onDelete passed as prop
- Finding #4: Removed duplicate "Open for Players" quick-button from
Scene Checks left panel — Scene Secrets is the sole entry point
New files:
- src/tests/missionPlaythrough.test.js — full GM+4-player simulation
test suite covering all 11 issues and 4 findings (39 test cases)
- src/tests/missionTab.test.js — player/GM view isolation tests
- src/utils/diceRoller.js — shared d100/degrees/clampTarget utilities
- tests/missionRoutes.test.js — backend mission route unit tests
- tests/playerRoutesLogin.test.js — player login route tests
- tests/sessionRoutes.test.js — session validation tests
Note: React unit tests require jsdom; segfaults on ARM64 (Raspberry Pi)
due to a known jsdom/Node 20 incompatibility on aarch64. Tests pass on
x86 CI. Backend integration tests (tests/) run normally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace username text input with dropdown selector for player login
- Fix unescaped apostrophe in MissionSimTab.jsx (Emperor's -> double quotes)
- Fix em-dash encoding issues in MissionSimTab.jsx
- Update player password to 1234 in .env
- MariaDB missions table with scenes JSON
- /api/missions CRUD routes
- MissionTab saves completed missions to DB
- Mission history panel in UI
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Remove OCR noise, credits, and duplicates from rules-database.json (288→255 rules)
- Add clean_rules.py script for rule cleanup
- Add CLAUDE.md, docs/, and update README with documentation links
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- scripts/generate-weapon-images.js: AI image generation for weapon cards
supporting HuggingFace FLUX.1-schnell, OpenAI DALL-E 3, and Gemini Imagen;
images served from public/weapon-images/ via new static route in server.js
- public/cards.html: load manifest.json and show AI art on weapon cards
- scripts/scrape-rules-from-pdfs.py: PyMuPDF scraper extracting full rule
text from all five rulebook PDFs with bold-span heading detection
- scripts/tag-and-dedup-rules.js: standalone dedup helper (JS-side grouping)
- database/routes/rulesRoutes.js: remove content truncation in search/random,
add admin dedup endpoint (JS-side, fast), fix RulesTab to fetch full content
- src/components/RulesTab.jsx: fetch full rule content on modal open
- public/print.html: expanded quick reference with pre-gen character stat
blocks (Sepheran + Lucian), Astartes traits sheet with correct derived SBs
and TBs, full Critical Hit Tables for all 4 locations × 4 damage types
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When DB_PASSWORD is missing on startup, server exits and PM2 was
restarting every ~660ms flooding backend.log with ER_ACCESS_DENIED_ERROR.
Now waits 5s between restarts and caps at 10 attempts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
import-rules.js, import-armour.js, import-all.js were used once during
initial data import and have been superseded by the scripts/ directory.
All hardcoded wrong passwords (dwroller2025).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch from localhost to Synology NAS (192.168.1.113:3307) for
centralized database hosting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace hardcoded DB_PASSWORD 'dwroller2025' with process.env.DB_PASSWORD
- Replace hardcoded GM_SECRET 'bongo' with process.env.GM_SECRET
- Replace hardcoded GM_PASSWORD with process.env.GM_PASSWORD
- Replace hardcoded PLAYER_PASSWORD '1234' with process.env.PLAYER_PASSWORD
- Update .env.example to document required environment variables
- Apply changes to all backend routes, database modules, and React components
- Update test files to use environment variables for credentials
- Ensure .env remains in .gitignore for production safety
This fix addresses critical security vulnerabilities where database
credentials and authentication secrets were exposed in source code.
- Updated RequisitionShop component styles for a cohesive dark theme.
- Enhanced RulesTab component with consistent dark styling and improved button visibility.
- Modified XPBar component to align with new dark theme aesthetics.
- Adjusted global styles in index.css to support the new design.
- Added comprehensive DEVELOPMENT_GUIDE.md for project setup, deployment, and maintenance instructions.
- Add comprehensive PlayerManagement component for GMs
- Add all GM API endpoints for player CRUD operations
- Add comprehensive test suite with 14 tests
- Clean up .gitignore to exclude logs, backups, core dumps
- Update README with setup instructions and documentation
- Add setup.sh script for easy project initialization
This provides a complete GM interface for managing players without
the large files that were blocking the previous push.
- Created a new script `migrate-to-sqlite.js` to migrate data from JSON files into a SQLite database.
- Implemented functions to read JSON files safely and handle errors.
- Established database schema with tables for armour, weapons, bestiary, and rules.
- Added logic to insert data from JSON files into the corresponding database tables.
- Included backup functionality for the existing database before migration.
- Logged import totals and sample data from each table for verification.
- Added a new script `check-shop-stats.js` to fetch and log item statistics from the database.
- Added bestiaryRoutes.js to handle API endpoints for fetching enemies, full bestiary data, and statistics.
- Implemented caching mechanism for bestiary data with a 5-minute expiration.
- Created transformation functions for bestiary entries to standardize data format for the dice roller.
- Added admin-only endpoint to force reload bestiary data with GM authentication.
chore: Create scripts for analyzing and cleaning bestiary data
- Developed analyze-bestiary-quality.js to review data quality and identify duplicates or inconsistencies.
- Implemented clean-bestiary-fields.js to extract and clean specific fields from bestiary entries, reducing text duplication.
- Created clean-corrupted-bestiary.js to remove corrupted entries based on defined patterns.
- Generated a comprehensive database-cleanup-report.md summarizing the cleaning process and results.
build: Add fast build script for streamlined deployment
- Introduced fast-build.sh to facilitate quick builds and PM2 reloads without reinstalling dependencies.
test: Add GM authentication logic test
- Created test-gm-auth.js to verify the correctness of GM authentication logic with various test cases.
- Implemented `upsert-allewis-from-5001.js` to fetch and update Allewis data from API.
- Created `upsert-missing-movement-from-5001.js` to fill missing movement and wounds data from API.
- Developed `upsert-missing-movement-from-pdfs.js` to extract movement and wounds from PDF text.
- Added `upsert-missing-profiles-from-pdfs.js` to fill missing profiles from PDF data.
- Introduced `upsert-missing-wounds-from-pdfs.js` to update wounds data from PDF sources.
- Created `validate-bestiary.js` to validate the structure of the bestiary JSON.
- Updated `BestiaryTab.jsx` component to display bestiary data with improved structure and search functionality.
- Added tests for `BestiaryTab` to ensure proper rendering and functionality.
- Updated package.json scripts to include separate unit and integration tests before building.
- Added a new script `test-build-test` to run tests before and after the build process.
- Introduced a new local CI/CD script for streamlined local development and testing.
- Refactored PlayerTab component to normalize skills data structure and added tooltips for Space Marine and Power Armour abilities.
- Added named export for Tooltip in DeathwatchRoller for reuse in other components.
- Implemented `validatePlayer` and `normalizeTabInfo` functions in `database/validate.js` for player data validation and normalization.
- Added error handling for required fields and enforced data types and constraints.
- Introduced standardization for characteristics and skills.
feat: Create script for extracting rules from PDF files
- Developed `extract-rules.js` to extract text from PDF rulebooks and categorize rules.
- Integrated `pdftotext` for PDF processing and created a searchable rules database.
- Implemented rule categorization and indexing for efficient searching.
feat: Implement RulesTab component for rule searching
- Created `RulesTab.jsx` for searching and displaying rules with filtering options.
- Added recent searches and quick reference buttons for user convenience.
- Integrated API calls for fetching rules and displaying results dynamically.
feat: Add test script for Rules API
- Created `test-rules.js` to test the functionality of the Rules API endpoints.
- Included tests for search and stats endpoints to ensure proper response handling.
- Updated `requireSession.js` to ensure `req.body` and `req.query` are always objects before access, improving robustness against malformed requests.
- Changed API endpoint for login from `/api/sessions/login` to `/api/players/login` in `App.js`, updating related logging and state management to reflect the new structure.
- Enhanced player fetching logic in `PlayerTab.jsx` to handle cases where GM is logged in, ensuring all players are fetched from the API. Added debug logging for better traceability.
- Implemented fallback to stored player data if API fetch fails, ensuring a smoother user experience for regular players.
- Updated local storage handling to accommodate changes in player data structure.
- Implemented a comprehensive weapons dataset in `comprehensive-weapons.js` with detailed weapon stats, categories, and requirements.
- Created a new scraper script `scrape-40k-tools.js` to fetch and parse weapon data from the 40k RPG Tools website, including categorization and conversion to game format.
- Added functionality to write the scraped data to JSON files for further use in the application.
- Included error handling and logging for better debugging and user feedback during the scraping process.
- Implemented a new endpoint to fetch player names for the login dropdown.
- Created a login endpoint that validates player credentials and establishes a session.
- Updated server routes to include the new shop routes.
- Modified the player fetching logic in the RequisitionShop component to handle both full player data and basic player names based on session availability.
- Adjusted API calls in the frontend to align with the new endpoints.
Centralizes all GM controls—add, update, delete player, set RP or renown, reset player passwords—into the PlayerTab for a more intuitive workflow. Removes GM panel logic and duplication from the shop view, clarifies GM access, and improves error feedback on player list loading. Adds a backend health check endpoint and minor UI polish.