-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Richard Lewis edited this page Jun 1, 2026
·
1 revision
Pew Pew Collection is a single-process Node.js / Express app rendering EJS server-side, backed by SQLite. There is no build step, no bundler, no frontend framework.
src/
├── server.js # Entry point — calls createApp() and listens
├── app/
│ ├── createApp.js # App factory — wires middleware + routes + DI
│ ├── middleware/auth.js # requireAuth + must-change-password redirect
│ └── routes/index.js # Mounts feature routers
├── features/
│ ├── auth/ # Login, change-password, profile, theme toggle
│ ├── firearms/ # Inventory CRUD, CSV import/export
│ └── home/ # Dashboard
│ └── (each contains <feature>.controller.js,
│ <feature>.routes.js,
│ <feature>.service.js,
│ <feature>.validators.js [if needed])
├── infra/
│ ├── config/index.js # Reads + validates env vars; exports getConfig()
│ └── db/
│ ├── client.js # better-sqlite3 connection
│ ├── migrate.js # Numbered SQL migration runner
│ ├── migrations/ # 001_initial_schema.sql, 002_settings_table.sql, ...
│ └── repositories/ # firearms.repository.js, settings.repository.js
├── services/
│ └── version.service.js # Opt-in GitHub Releases lookup (UPDATE_CHECK)
├── shared/utils/csv.js # CSV parse + serialise
├── public/
│ ├── css/styles.css # Single stylesheet, dark + light via [data-theme]
│ └── js/ # search.js, theme.js, firearm-form.js, etc.
└── views/ # EJS templates
├── partials/layout.ejs
├── auth/ firearms/ home/ errors/
└── (each feature has a *.ejs page + *-content.ejs partial)
- Controllers handle HTTP only and delegate to services.
- Services contain business logic and delegate to repositories.
- Repositories do SQL only — no business logic.
-
Views render EJS only; no inline styles (everything in
styles.css), and all mobile overrides go inside the existing@media (max-width: 640px)block.
-
server.jscallscreateApp()and binds the HTTP server. -
createApp()wires middleware:helmet,cookie-parser,express-session,csrf-csrf,morgan,method-override, and feature routers. - A request to e.g.
GET /firearms/:idhits the route infeatures/firearms/firearms.routes.js, which calls the controller. - The controller validates inputs via
firearms.validators.js, callsfirearms.service.js, and renders an EJS view. - The service calls
firearms.repository.js, which runs a parameterized SQL statement against the SQLite database. - The response renders
views/firearms/<view>.ejsinsidepartials/layout.ejs.
- SQLite via
better-sqlite3— synchronous, fast, single-file. - Schema changes are new numbered SQL migration files in
src/infra/db/migrations/(e.g.004_*.sql). - The migration runner records applied files in a
schema_migrationstable; shipped migrations are immutable. -
settingsis a key/value table holdingusername,password_hash,must_change_password,theme,update_check_enabled. -
maintenance_logsandrange_sessionstables exist in the initial schema but have no UI yet — intentional, reserved for future features.
| Layer | Technology |
|---|---|
| Runtime | Node.js >=20.0.0 <25.0.0 |
| HTTP | Express.js v5 |
| Templating | EJS, server-side rendered |
| Database | SQLite via better-sqlite3
|
| Auth | Session-based, single admin, bcrypt cost 12 |
| Sessions |
express-session + cookie-parser
|
| CSRF |
csrf-csrf double-submit cookie |
| Rate limiting | express-rate-limit |
| HTTP hardening |
helmet with CSP enabled |
| Logging |
morgan for requests, structured JSON for audit |
| Frontend assets | Plain CSS + vanilla JS in src/public/, no build step |
| Testing | Jest + Supertest, --runInBand
|
| Linting | ESLint flat config |
-
ci.yml— runs on every PR: lint,npm run test:ci,npm audit, Trivy filesystem scan, Hadolint Dockerfile scan, coverage upload. -
release.yml— runs on merge tomain: semantic-release builds and pushes the multi-arch Docker image to GHCR and tags the GitHub release. -
maintenance.yml— daily at 04:00 UTC: stale-bot for issues / PRs, deletes mergedcodex/*andcopilot/*branches after 2 days.
Pew Pew Collection · Self-hosted, offline-first firearm inventory · Business Source License 1.1
Getting started
Running it
Reference