122 lines
4.5 KiB
Markdown
122 lines
4.5 KiB
Markdown
# SHD.build
|
||
|
||
A SvelteKit community application for _The Division Resurgence_. SHD.build
|
||
combines a public game database, loadout builder, shared builds, guides, account
|
||
management, and the ISAC data-management console.
|
||
|
||
See `docs/architecture.md` for the implementation model.
|
||
|
||
## Database
|
||
|
||
The server uses the in-process `@tursodatabase/database` package and a local
|
||
SQLite-compatible file. Turso Cloud is not required.
|
||
|
||
Create or update the local database:
|
||
|
||
```sh
|
||
npm run db:migrate
|
||
```
|
||
|
||
The Infisical `dev` environment sets the local file to
|
||
`./data/shd-build-development.db`.
|
||
|
||
Store custom avatars as metadata-free 256 × 256 WebP files. Set
|
||
`TDR_AVATAR_STORAGE_PATH` to a persistent, writable directory in production; it
|
||
defaults to `data/avatars`. The same configuration works on Windows and Linux.
|
||
|
||
Seed the initial local accounts once:
|
||
|
||
```sh
|
||
npm run db:seed-users
|
||
```
|
||
|
||
The seed creates `Aewyn` and `Quartermaster` with the standard user role. It
|
||
generates and displays strong temporary passwords once, then stores only salted
|
||
Argon2id hashes. `DEFAULT_ADMIN_PASSWORD` is the password variable name for
|
||
`Aewyn`; it does not grant administrator authority.
|
||
|
||
Sign-in never grants administrator authority automatically. For local
|
||
development, give the target account a verified email, enroll TOTP at
|
||
`/account/security`, and save its one-time recovery codes. Stop the development
|
||
server, then run:
|
||
|
||
```sh
|
||
npm run admin:bootstrap -- <verified-email>
|
||
```
|
||
|
||
The offline command requires an active TOTP factor and an unused recovery code,
|
||
revokes the target account's sessions, and refuses to run when an active full
|
||
administrator already exists. Restart the development server after it succeeds.
|
||
See [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) for staging and production
|
||
operation.
|
||
|
||
## Develop
|
||
|
||
```sh
|
||
npm run dev
|
||
```
|
||
|
||
## Infisical secrets
|
||
|
||
The committed `.infisical.json` connects the project to the self-hosted
|
||
Infisical instance at `https://secrets.jb.codes`. Authenticate the local CLI
|
||
once. The CLI uses its configured system vault and can fall back to an encrypted
|
||
file vault when the operating-system keyring is unavailable.
|
||
|
||
```sh
|
||
npx infisical login --domain=https://secrets.jb.codes
|
||
npm run dev
|
||
```
|
||
|
||
Local commands use the `dev` environment. Application configuration lives under
|
||
`/app`; the scheduler bearer token lives under `/shared/scheduler`. Staging and
|
||
production commands select the `staging` and `prod` environments explicitly.
|
||
`npm run check`, `npm test`, and `npm run build` do not contact Infisical.
|
||
|
||
Staging and production containers authenticate at startup with separate
|
||
Universal Auth identities. Gitea stores each client secret, while repository
|
||
variables hold the matching non-secret client IDs. The containers fetch current
|
||
values before migration or startup and stop if authentication or validation
|
||
fails.
|
||
|
||
## Containers and staging deployment
|
||
|
||
The application uses the official SvelteKit Node adapter and a multi-stage
|
||
`Dockerfile`. Keep database files, database backups, user avatars, and uploaded
|
||
game-data icons under `/app/data` on a persistent volume. Inject runtime secrets
|
||
when the container starts; keep them out of the image.
|
||
|
||
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) documents the staging and production
|
||
Compose topologies. A push to `main` triggers both deployment workflows. Each
|
||
workflow validates Infisical access and the candidate image while the current
|
||
service stays online, then stops its application and scheduler for backup and
|
||
migration.
|
||
|
||
## Passwordless authentication
|
||
|
||
Use passkeys as the preferred sign-in method. Set `APP_ORIGIN` to the exact
|
||
public origin for registration and authentication. Set `PASSKEY_RP_ID` to that
|
||
hostname or a registrable parent domain. Hosted environments use `shd.build`,
|
||
which permits credentials on `shd.build`, `stage.shd.build`, and
|
||
`dev.shd.build`. Use `localhost` for direct local development.
|
||
|
||
Magic links require `SMTP_HOST` and `SMTP_FROM`. `SMTP_PORT` defaults to `587`.
|
||
Set `SMTP_SECURE=true` for implicit TLS, normally on port 465; the default
|
||
`false` uses STARTTLS. If the SMTP server requires authentication, set both
|
||
`SMTP_USER` and `SMTP_PASSWORD`. An account owner activates an email identity by
|
||
following a 15-minute, single-use verification link.
|
||
|
||
## Validate
|
||
|
||
```sh
|
||
npm run check
|
||
npm run build
|
||
```
|
||
|
||
The shared visual language and dashboard conventions are documented in
|
||
[docs/DESIGN_SYSTEM.md](docs/DESIGN_SYSTEM.md).
|
||
|
||
Empirically derived weapon and gear level-range calculations, rounding rules,
|
||
validation boundaries, and regression observations are documented in
|
||
[docs/STAT_LEVEL_SCALING.md](docs/STAT_LEVEL_SCALING.md).
|