Skip to content

Commit cd1e41b

Browse files
Tim020claude
andcommitted
Upgrade Node.js from v22 to v24 (Active LTS)
- Update .nvmrc to v24.12.0 - Update package.json engines to require Node >=24.0.0 <25 and npm >=11.0.0 <12 - Regenerate package-lock.json with npm 11 (lockfileVersion 3) - Update Dockerfile to use node:24-bookworm base image - Update GitHub Actions workflows to use Node 24 - Remove redundant npm global install steps (npm 11 bundled with Node 24) - Update documentation to reflect Node 24.x requirement This resolves Dependabot EBADENGINE errors by aligning with Dependabot's Node v24.12.0 / npm 11.7.0 environment. Tested locally: - npm install completes successfully - Build process works (npm run build) - Linting passes (npm run ci-lint) - Unit tests run (npm run test:run) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 845fcb1 commit cd1e41b

File tree

9 files changed

+1654
-1018
lines changed

9 files changed

+1654
-1018
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Setup Node.js
1616
uses: actions/setup-node@v4
1717
with:
18-
node-version: '22'
18+
node-version: '24'
1919
cache: 'npm'
2020
cache-dependency-path: 'client/package-lock.json'
2121
- name: Install dependencies

.github/workflows/client-test.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ jobs:
1616
- uses: actions/checkout@v3
1717
- uses: actions/setup-node@v3
1818
with:
19-
node-version: 22
20-
- name: Install npm 10
21-
run: npm install -g npm@10
19+
node-version: 24
2220
- name: Install dependencies
2321
run: npm ci
2422
- name: Run tests

.github/workflows/nodelint.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ jobs:
1212
- uses: actions/checkout@v3
1313
- uses: actions/setup-node@v3
1414
with:
15-
node-version: 22
16-
- run: npm install -g npm@10
15+
node-version: 24
1716
- run: npm ci
1817
- run: npm run ci-lint

CLAUDE.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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+
DigiScript is a full-stack web application for cueing theatrical shows. It provides real-time script display, cue management, and show control capabilities.
8+
9+
**Stack**: Vue.js 2 frontend + Python Tornado backend + SQLite database
10+
11+
**Version Requirements**: Node 24.x, Python 3.13.x
12+
13+
## Development Commands
14+
15+
### Frontend Development
16+
17+
```bash
18+
# Build frontend (outputs to ../server/static/)
19+
cd client
20+
npm ci
21+
npm run build
22+
23+
# Linting
24+
npm run lint # ESLint with auto-fix
25+
npm run ci-lint # CI mode (no auto-fix)
26+
```
27+
28+
### Backend Development
29+
30+
```bash
31+
# Run server (serves at http://localhost:8080)
32+
cd server
33+
python3 main.py
34+
35+
# Linting and formatting
36+
ruff check server/ # Fast linting (replaces pylint)
37+
ruff format server/ # Code formatting (replaces black)
38+
39+
# Testing
40+
pytest # Run all tests
41+
pytest test/ # Run specific directory
42+
```
43+
44+
### Docker Deployment
45+
46+
```bash
47+
# Full stack with Prometheus/Grafana monitoring
48+
docker-compose up -d
49+
```
50+
51+
## Architecture
52+
53+
### Frontend Architecture (Vue.js 2)
54+
55+
**State Management**: Vuex with modular structure
56+
- `store/modules/user/` - User authentication and settings
57+
- `store/modules/websocket/` - WebSocket connection management
58+
- `store/modules/system/` - System-wide state
59+
- `store/modules/show/` - Show data
60+
- `store/modules/script/` - Script content
61+
- `store/modules/scriptConfig/` - Script configuration
62+
- State persisted to localStorage via vuex-persistedstate
63+
64+
**Component Organization**:
65+
- `views/` - Page-level components (routes)
66+
- `vue_components/` - Reusable components organized by feature
67+
- `vue_components/config/show/` - Complex nested structure for show configuration:
68+
- `script/` - Script editing interface
69+
- `cues/` - Cue management
70+
- `cast/` - Cast assignment
71+
- `mics/` - Microphone allocation
72+
73+
**Build Process**: Vite builds to `../server/static/` (co-located with backend)
74+
- Manual chunking: `bootstrap-vendor.js`, `vue-vendor.js`, `utils-vendor.js`, `websocket-vendor.js`, `vendor.js`
75+
76+
### Backend Architecture (Python Tornado)
77+
78+
**Decorator-Based Routing**: Controllers use `@route()` decorator for automatic registration
79+
- Controllers in `controllers/api/` are auto-discovered via `module_discovery.py`
80+
- No manual route registration required
81+
82+
**SQLAlchemy 2.0**: Recently migrated from 1.x
83+
- **IMPORTANT**: Use `select()` API, not legacy `Query` interface
84+
- Example: `session.execute(select(Model).where(...))` not `session.query(Model).filter(...)`
85+
86+
**RBAC System**: Fine-grained permissions via `rbac/rbac.py`
87+
- Role/permission bitmasks for access control
88+
- Integrated into controller decorators
89+
90+
**JWT Authentication**: Stateless auth with refresh tokens
91+
- JWT service: `utils/web/jwt_service.py`
92+
- Token validation on protected routes
93+
94+
**Database Migrations**: Alembic in `alembic_config/`
95+
- Auto-checked on server startup
96+
- Generate migrations: `alembic revision --autogenerate -m "description"`
97+
98+
**Script Revision System**: Complex FK relationships require careful handling
99+
100+
**Core Principle - Lines Exist Within Association Context**:
101+
- A `ScriptLine` only exists within the context of a `ScriptLineRevisionAssociation`
102+
- Lines are NOT independently shared across revisions
103+
- When creating a new revision, the `line_id` is copied (same line object reused)
104+
- Lines should ONLY be deleted when NO associations reference them
105+
106+
**FK References That Must Be Checked Before Line Deletion**:
107+
- `ScriptLineRevisionAssociation.line_id` (primary reference)
108+
- `ScriptLineRevisionAssociation.next_line_id` (linked list pointer)
109+
- `ScriptLineRevisionAssociation.previous_line_id` (linked list pointer)
110+
- `CueAssociation.line_id` (revision-scoped cue placement)
111+
112+
**Revision-Scoped Associations** (must be migrated when line objects change):
113+
- `CueAssociation`: `(revision_id, line_id, cue_id)` - where a cue appears
114+
- `ScriptCuts`: `(revision_id, line_part_id)` - which line parts are cut
115+
116+
**Line Update Pattern** (`controllers/api/show/script/script.py:609-662`):
117+
When updating a line via PATCH, new `ScriptLine` and `ScriptLinePart` objects are created.
118+
ALL revision-scoped associations MUST be migrated to the new objects:
119+
1. Migrate `CueAssociation`: `(revision, old_line_id)``(revision, new_line_id)`
120+
2. Migrate `ScriptCuts`: `(revision, old_line_part_id)``(revision, new_line_part_id)`
121+
3. Use `part_index` to map old line_parts to new line_parts
122+
123+
**Cascade Deletion Pattern** (`models/script.py:127-169`):
124+
Use `post_delete` hooks with `session.no_autoflush` context:
125+
- `post_delete`: Executes AFTER association removed (avoids FK errors during cascade)
126+
- `no_autoflush`: Prevents lazy loading from triggering premature autoflush mid-cascade
127+
- Check ALL FK references before deleting orphaned lines
128+
129+
**Testing Script Revisions**:
130+
- ✅ Use API endpoints to create test data (POST/PATCH/DELETE)
131+
- ❌ Avoid manually creating FK references that can't occur via API
132+
- ❌ Don't create lines referenced only as `next_line_id`/`previous_line_id` (not as `line_id`)
133+
134+
See Issue #670 / PR #758 for detailed implementation examples.
135+
136+
### WebSocket Messaging Protocol
137+
138+
**Server → Client Message Format**:
139+
```json
140+
{
141+
"OP": "SOME_OP_CODE",
142+
"DATA": {},
143+
"ACTION": "SOME_ACTION"
144+
}
145+
```
146+
147+
**Client Handling** (in `client/src/store/store.js`):
148+
1. Vuex mutation `SOCKET_ONMESSAGE` - Called for every message, handles OP codes
149+
2. Vuex action `SOME_ACTION` - Called if `ACTION` key is present in message
150+
151+
This pattern enables real-time show updates, cue triggering, and multi-client synchronization.
152+
153+
## Key Technical Details
154+
155+
### Recent Migrations
156+
- **SQLAlchemy 2.0**: Use `select()` API, not legacy query methods
157+
- **Ruff**: Replaces black, isort, and pylint for Python code quality
158+
- **Vite**: Frontend build system (replaced webpack)
159+
160+
### Important Version Notes
161+
- **Vue Version**: Vue 2.7 (NOT Vue 3) - different API, especially Composition API
162+
- **Bootstrap**: Bootstrap 4.6 + Bootstrap Vue 2.23
163+
- **Python**: 3.13.x with asyncio support
164+
- **Node**: 24.x (npm 11.x)
165+
166+
### Configuration
167+
- **Server config**: `server/conf/digiscript.json` (created at runtime)
168+
- **Database**: SQLite file, path configurable in server config
169+
- **Settings system**: Hierarchical, editable via API endpoints
170+
171+
## Project Structure Highlights
172+
173+
### Backend Key Directories
174+
- `controllers/` - Request handlers with `@route()` decorator
175+
- `controllers/ws_controller.py` - WebSocket handler for real-time messaging
176+
- `models/` - SQLAlchemy ORM models (2.0 style)
177+
- `schemas/` - Marshmallow serialization schemas for API responses
178+
- `rbac/` - Role-based access control implementation
179+
- `utils/module_discovery.py` - Dynamic module loading for controllers/models
180+
- `alembic_config/` - Database migration scripts
181+
182+
### Frontend Key Directories
183+
- `store/modules/` - Vuex modular store pattern (feature-based modules)
184+
- `vue_components/config/show/` - Complex nested show configuration UI
185+
- `js/http-interceptor.js` - Global fetch/HTTP request interceptor
186+
- `js/customValidators.js` - Vuelidate custom validation rules
187+
188+
## CI/CD Pipeline
189+
190+
GitHub Actions workflows (`.github/workflows/`):
191+
- `nodelint.yml` - ESLint on client code
192+
- `pylint.yml` - Ruff linting on server code
193+
- `python-test.yml` - Run pytest suite
194+
- `check-database-migrations.yml` - Verify Alembic migrations
195+
- `docker-image-build.yml` / `docker-publish.yml` - Container builds
196+
197+
## Important Notes from Tim
198+
199+
- Always run formatting checks on both client and server side code before committing to avoid CI build failures
200+
- When opening issues in GitHub, always add the `claude` label to them
201+
- When working on new features and creating pull requests, create a feature branch that will target the `dev` branch
202+
- When adding new features, or changing the behaviour of existing ones, make sure to update the user documentation in the docs/ directory, including adding screenshots as needed
203+
- Use the reStructuredText format for docstrings for Python code

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
FROM node:22-bookworm AS node_build
1+
FROM node:24-bookworm AS node_build
22

3-
RUN npm install npm@10 -g
3+
# npm 11 bundled with Node 24, no separate install needed
44
RUN mkdir -p /server/static
55

66
COPY /client/package.json /client/package.json

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ A digital script project for cueing theatrical shows
1414

1515
### Requirements
1616

17-
* Node v22.x (npm 10.x)
17+
* Node v24.x (npm 11.x)
1818
* Python 3.13.x
1919

2020
### Client

client/.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v24.12.0

0 commit comments

Comments
 (0)