5868852686
App features: - Personal-best records per metric: manually settable in Settings and auto-updated when a session beats them; shown in the log modal and a new dashboard "Personal records" card. - Juggling now counts by 1 instead of 5. - 1-on-1 with Elijah gains Technical Skill and Effort scores (out of 10) as manual inputs, plus an optional per-session note. - Service worker now uses a controlled update flow: an in-app "new version ready" banner activates the update on tap and reloads. Data model: - category_metrics gains track_record + record; entries gains note. - Idempotent migrations bring existing databases up to date (juggling step/record, Elijah score metrics) alongside the updated seed. StartOS package: - Bump to 0.1.2:0 with release notes. - Build x86_64 only (drop aarch64) per deployment target.
155 lines
6.2 KiB
Markdown
155 lines
6.2 KiB
Markdown
<p align="center">
|
|
<img src="icon.svg" alt="Premier Gunner Logo" width="21%">
|
|
</p>
|
|
|
|
# Premier Gunner on StartOS
|
|
|
|
> **Upstream repo:** <https://github.com/ten31/premier-gunner>
|
|
|
|
Premier Gunner is a kid-friendly, mobile-friendly soccer training tracker for a single player. It logs daily training across categories, plans future sessions, tracks goals, and shows progress toward a big reward. This repository packages the app as a StartOS `.s9pk` service for StartOS 0.4.0.x.
|
|
|
|
## Getting Started
|
|
|
|
This package builds its own Docker image from the vendored Node app (it does **not** pull a prebuilt image from a registry). The build copies the app source into `./app` and installs/compiles its dependencies inside the image.
|
|
|
|
```sh
|
|
npm ci # install the start-sdk packaging deps
|
|
make # vendor the app, build images, and pack the .s9pk(s)
|
|
```
|
|
|
|
To learn the general workflow, see the [StartOS Packaging Guide](https://docs.start9.com/packaging/0.4.0.x/).
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
- [Image and Container Runtime](#image-and-container-runtime)
|
|
- [Volume and Data Layout](#volume-and-data-layout)
|
|
- [Installation and First-Run Flow](#installation-and-first-run-flow)
|
|
- [Configuration Management](#configuration-management)
|
|
- [Network Access and Interfaces](#network-access-and-interfaces)
|
|
- [Actions (StartOS UI)](#actions-startos-ui)
|
|
- [Backups and Restore](#backups-and-restore)
|
|
- [Health Checks](#health-checks)
|
|
- [Dependencies](#dependencies)
|
|
- [Build Layout](#build-layout)
|
|
- [Quick Reference for AI Consumers](#quick-reference-for-ai-consumers)
|
|
|
|
---
|
|
|
|
## Image and Container Runtime
|
|
|
|
| Property | Value |
|
|
| ------------- | ---------------------------------------------- |
|
|
| Image | Built locally from `./Dockerfile` (Node 22) |
|
|
| Architectures | x86_64, aarch64 |
|
|
| Command | `node src/server.js` (cwd `/app`) |
|
|
|
|
---
|
|
|
|
## Volume and Data Layout
|
|
|
|
| Volume | Mount Point | Purpose |
|
|
| ------ | ----------- | ------------------------------------------------------------- |
|
|
| `main` | `/data` | SQLite database, sessions, and `store.json` (login password) |
|
|
|
|
The app reads `PG_DATA_DIR=/data` and writes its SQLite DB there. The package's `store.json` (managed by StartOS) lives in the same volume and holds the login password.
|
|
|
|
---
|
|
|
|
## Installation and First-Run Flow
|
|
|
|
1. On install, a 16-character random login password is generated and written to `store.json`.
|
|
2. On every start, `main` reads the password from `store.json` and injects it as `PG_PASSWORD`. The app treats this env var as authoritative and (re)hashes it, so the login password always matches what StartOS holds.
|
|
3. The user opens the **ui** interface, logs in, and (recommended) sets their own password via the **Set Login Password** action.
|
|
|
|
---
|
|
|
|
## Configuration Management
|
|
|
|
The only user-managed setting is the login password, handled by the **Set Login Password** action — not a config form. The action writes to `store.json`; the resulting change triggers a daemon restart (via a reactive `.const` read) so the new password takes effect immediately.
|
|
|
|
**StartOS-managed environment variables injected into the app:**
|
|
|
|
| Variable | Value | Source |
|
|
| ------------- | -------------- | ------------------------------- |
|
|
| `NODE_ENV` | `production` | static (enables `Secure` cookie)|
|
|
| `PG_HOST` | `0.0.0.0` | static |
|
|
| `PG_PORT` | `3000` | `utils.uiPort` |
|
|
| `PG_DATA_DIR` | `/data` | `main` volume mount |
|
|
| `PG_PASSWORD` | (random/user) | `store.json` → reactive read |
|
|
|
|
---
|
|
|
|
## Network Access and Interfaces
|
|
|
|
| Interface | Port | Protocol | Purpose |
|
|
| --------------- | ---- | -------- | ---------------------- |
|
|
| `ui` | 3000 | HTTP | Premier Gunner web app |
|
|
|
|
**Access methods:** LAN IP, `<hostname>.local`, Tor `.onion`, and custom clearnet domains.
|
|
|
|
### Clearnet via StartTunnel
|
|
|
|
The app serves plain HTTP; StartOS/StartTunnel terminate TLS. Point a StartTunnel domain at the **ui** interface (see the [StartTunnel docs](https://docs.start9.com/start-tunnel/1.0.x/)). Because `NODE_ENV=production` sets the session cookie's `Secure` flag, the app must be reached over HTTPS — which StartTunnel provides.
|
|
|
|
---
|
|
|
|
## Actions (StartOS UI)
|
|
|
|
| Action | Input | Effect |
|
|
| -------------------- | ------------------- | ------------------------------------------------------------------- |
|
|
| Set Login Password | Password (≥4 chars) | Writes the password to `store.json`; service restarts; sessions cleared |
|
|
|
|
---
|
|
|
|
## Backups and Restore
|
|
|
|
**Included in backup:** the `main` volume (database + `store.json`). Restored fully before the service starts.
|
|
|
|
---
|
|
|
|
## Health Checks
|
|
|
|
| Check | Method | Messages |
|
|
| ------------- | ---------------------- | ------------------------------------------------------------------------------- |
|
|
| Web Interface | Port listening (3000) | Success: "The web interface is ready" / Error: "The web interface is not ready" |
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
None.
|
|
|
|
---
|
|
|
|
## Build Layout
|
|
|
|
- `Dockerfile` — multi-stage Node 22 build; compiles `better-sqlite3`, copies the app, runs `node src/server.js`.
|
|
- `Makefile` — `prep` vendors the app from the parent repo into `./app` (excluding `node_modules`/`data`), then delegates to `s9pk.mk` to build both arches.
|
|
- `startos/` — the start-sdk package definition (manifest, main, interfaces, actions, fileModels/store, versions, i18n).
|
|
- `./app` — generated, git-ignored vendor copy of the Node app used as the Docker build context.
|
|
|
|
---
|
|
|
|
## Quick Reference for AI Consumers
|
|
|
|
```yaml
|
|
package_id: premier-gunner
|
|
image: built locally from ./Dockerfile (node:22-bookworm-slim)
|
|
architectures: [x86_64, aarch64]
|
|
volumes:
|
|
main: /data
|
|
ports:
|
|
ui: 3000
|
|
dependencies: none
|
|
startos_managed_env_vars:
|
|
PG_PASSWORD: from store.json (login password, authoritative)
|
|
PG_PORT: 3000
|
|
PG_DATA_DIR: /data
|
|
PG_HOST: 0.0.0.0
|
|
NODE_ENV: production
|
|
actions:
|
|
- set-password (Set Login Password)
|
|
```
|