feat(isac): link skill chips to abilities
This commit is contained in:
+43
-37
@@ -1,6 +1,6 @@
|
||||
# SHD.build architecture
|
||||
|
||||
This project is intentionally being built in vertical slices.
|
||||
The project is built in vertical slices.
|
||||
|
||||
## Planned stack
|
||||
|
||||
@@ -18,7 +18,8 @@ This project is intentionally being built in vertical slices.
|
||||
- Editor: manage builder source data.
|
||||
- Admin: manage users, roles, source data, and audit history.
|
||||
|
||||
Authorization must be checked on the server for every mutation. Hiding an admin link is not authorization.
|
||||
Server code checks authorization for each mutation. Hiding an admin link does
|
||||
not grant authorization.
|
||||
|
||||
Weapon and gear range calculations must preserve unrounded decimal endpoints
|
||||
and follow the empirically validated progression rules in
|
||||
@@ -26,16 +27,15 @@ and follow the empirically validated progression rules in
|
||||
linear rather than compounded and game-matching integer values are truncated
|
||||
only at the presentation boundary.
|
||||
|
||||
Local credentials are stored as Argon2id PHC strings with a unique random salt
|
||||
per password. Current work factors follow OWASP's 19 MiB / 2 iteration /
|
||||
single-lane minimum profile and can be increased over time; successful login
|
||||
will eventually rehash credentials whose parameters are outdated.
|
||||
Local credentials use Argon2id PHC strings with a unique random salt per
|
||||
password. Current work factors meet OWASP's 19 MiB / 2 iteration / single-lane
|
||||
minimum profile. Successful login rehashes credentials with outdated parameters.
|
||||
|
||||
## Database runtime
|
||||
|
||||
The application uses Turso Database in-process through its native Node package.
|
||||
It opens a local SQLite-compatible database file and does not use Turso Cloud,
|
||||
libSQL HTTP, remote replicas, auth tokens, or synchronization.
|
||||
It opens a local SQLite-compatible database file. The application does not use
|
||||
Turso Cloud, libSQL HTTP, remote replicas, auth tokens, or synchronization.
|
||||
|
||||
The database defaults to `./data/shd-build.db`. Production deployments must
|
||||
provide a persistent writable filesystem and can override the location with
|
||||
@@ -92,13 +92,12 @@ not locked by another process.
|
||||
|
||||
## Development database maintenance
|
||||
|
||||
The development database remains valuable persistent data, but it is no longer
|
||||
served to outside contributors and does not require a low-downtime migration
|
||||
window. Stop only this project's development server before backup, export,
|
||||
restore, migration, or other work requiring exclusive access. Create and verify
|
||||
a JSON backup, perform the prepared operation, verify schema state and critical
|
||||
record counts, then restart and health-check the application. Prefer additive,
|
||||
repeatable migrations and preserve the verified backup if maintenance fails.
|
||||
Treat the development database as persistent data. Stop this project's
|
||||
development server before backup, export, restore, migration, or other work
|
||||
requiring exclusive access. Create and verify a JSON backup, perform the
|
||||
prepared operation, verify schema state and critical record counts, then
|
||||
restart and health-check the application. Prefer additive, repeatable
|
||||
migrations and retain the verified backup if maintenance fails.
|
||||
|
||||
Production and staging remain shared persistent environments and retain the
|
||||
deployment, backup, synchronization, and maintenance safeguards documented in
|
||||
@@ -120,13 +119,14 @@ mutation rather than deletion or modification of the original event:
|
||||
before-snapshot.
|
||||
3. The UI requires a second, explicit confirmation.
|
||||
4. The server reloads the target and compares it with the original
|
||||
after-snapshot, ignoring bookkeeping timestamps. A mismatch means newer work
|
||||
exists and blocks automatic compensation.
|
||||
after-snapshot, ignoring bookkeeping timestamps. A mismatch indicates newer
|
||||
work and blocks automatic compensation.
|
||||
5. Referenced roles, permissions, and relationships are revalidated before
|
||||
restoration. Restoring administrator authority additionally requires full
|
||||
administrative access.
|
||||
6. The server restores the previous state and appends an `audit.reverted` event
|
||||
whose target is the original audit-event ID.
|
||||
7. A reverted event cannot be reverted again.
|
||||
|
||||
# Moderated game-data contributions
|
||||
|
||||
@@ -156,8 +156,6 @@ assignment, so it applies consistently to existing users and every account
|
||||
creation method. Registered agents can inspect live source data and submit
|
||||
moderated proposals, but cannot directly mutate canonical records, review the
|
||||
queue, or access unrelated ISAC operations without additional permissions.
|
||||
7. A successfully reverted event cannot be reverted again.
|
||||
|
||||
Unsupported destructive identity operations, account deletion, incomplete
|
||||
snapshots, stale targets, and events whose dependencies no longer exist are
|
||||
marked non-reversible or rejected. Recovery for those cases requires a
|
||||
@@ -256,7 +254,7 @@ from Firepower, Toughness, Engineering, Health, or Armor.
|
||||
The two secondary slots draw distinct attributes from one shared option pool.
|
||||
Each available secondary attribute stores its own minimum and maximum for all
|
||||
four qualities. Gear tier determines capacity without per-item configuration:
|
||||
T0 gear has one Gear Mod slot, while T1 and T2 gear have two.
|
||||
T0 gear has one Gear Mod slot; T1 and T2 gear have two.
|
||||
|
||||
Canonical data is stored in `gear_mods`, `gear_mod_quality_values`,
|
||||
`gear_mod_secondary_options`, and `gear_mod_secondary_quality_values`.
|
||||
@@ -274,37 +272,45 @@ and secondary options reference active attributes that define Skill Chip
|
||||
minimum and maximum roll values; a configured chip rolls one primary and two
|
||||
distinct secondary stats from those separate pools.
|
||||
|
||||
Every active Skill Chip definition belongs exclusively to one active
|
||||
specialization ability through `skill_chip_sets.specialization_ability_id`.
|
||||
An ability has capacity for exactly three active definitions. The save and
|
||||
restore actions enforce that capacity, while legacy rows may remain nullable
|
||||
until they are edited. A specialization focus is builder-ready only when each
|
||||
of its three assigned abilities has all three active Skill Chip definitions.
|
||||
Skill Chip mutations refresh readiness for focuses that reference both the
|
||||
previous and resulting ability.
|
||||
|
||||
Both set-bonus progression systems use the number of equipped High-end chips as
|
||||
the interpolation step. For `h` High-end chips, where `h` is zero through
|
||||
three, a configured minimum and maximum resolve as
|
||||
`minimum + (maximum − minimum) × h / 3`. Zero High-end chips therefore produce
|
||||
the minimum, while three produce the maximum. The editor stores only endpoints
|
||||
and previews all four states, preventing duplicated tier data from diverging.
|
||||
the minimum, while three produce the maximum. The editor stores endpoints and
|
||||
previews all four states, preventing duplicated tier data from diverging.
|
||||
Skill Chip mutations, owned relationships, and safe icon metadata are captured
|
||||
in the `game_data` audit stream.
|
||||
|
||||
# Game-data icon storage
|
||||
|
||||
Talents, brand sets, OS Protocols, and Skill Chips reference uploaded artwork through the
|
||||
polymorphic `game_data_icons` metadata table. Original uploads are never
|
||||
retained. The shared server pipeline accepts transparent SVG, PNG, WebP, and
|
||||
AVIF sources, rejects active or externally referenced SVG content, and uses
|
||||
Sharp’s asynchronous native worker pool to rasterize and normalize every
|
||||
accepted icon to a transparent 256 × 256 WebP.
|
||||
Talents, brand sets, OS Protocols, and Skill Chips reference uploaded artwork
|
||||
through the polymorphic `game_data_icons` metadata table. The shared server
|
||||
pipeline accepts transparent SVG, PNG, WebP, and AVIF sources, rejects active
|
||||
or externally referenced SVG content, and uses Sharp’s native worker pool to
|
||||
rasterize and normalize each accepted icon to a transparent 256 × 256 WebP.
|
||||
|
||||
Normalized files live beneath the ignored `data/game-icons/` directory and are
|
||||
served by the validated `/icons/game-data/[type]/[id]` endpoint with immutable
|
||||
cache headers and MIME sniffing disabled. ISAC save actions process files
|
||||
before mutation, apply upload or removal after record validation, and include
|
||||
only safe icon metadata—not image bytes—in their audit snapshots.
|
||||
safe icon metadata, rather than image bytes, in audit snapshots.
|
||||
|
||||
Icon metadata is optional. Canonical records and contributor proposals may be
|
||||
created without an upload, allowing values and artwork to be contributed in
|
||||
separate dependency-safe changes. Missing artwork is represented at render
|
||||
time by the static `/missing-item-icon.svg` asset through the shared
|
||||
`MISSING_ITEM_ICON_URL` constant and `ItemIcon` component; the placeholder is never inserted into
|
||||
`game_data_icons`. A later edit or proposal can attach the real icon without
|
||||
recreating or replacing the canonical item.
|
||||
`MISSING_ITEM_ICON_URL` constant and `ItemIcon` component. The placeholder does
|
||||
not enter `game_data_icons`. A later edit or proposal can attach the real icon
|
||||
without recreating the canonical item.
|
||||
# Oversight notification dispatch
|
||||
|
||||
New Data Change and Avatar Oversight review items are routed only to agents who
|
||||
@@ -321,11 +327,11 @@ scheduler instance:
|
||||
```
|
||||
|
||||
The dispatcher groups due rows by reviewer, queue, cadence, and delivery
|
||||
window. Daily rows are assigned to the next 10:00 AM wall-clock boundary in
|
||||
`America/New_York`, including daylight-saving transitions. Successfully
|
||||
dispatched rows retain `delivered_at` evidence and are never selected again.
|
||||
The existing ISAC notification delivery preferences still determine optional
|
||||
browser and email fan-out after the consolidated inbox message is created.
|
||||
window. Daily rows use the next 10:00 AM wall-clock boundary in
|
||||
`America/New_York`, including daylight-saving transitions. Dispatched rows
|
||||
retain `delivered_at` evidence and are excluded from later selection. Existing
|
||||
ISAC notification delivery preferences determine optional browser and email
|
||||
fan-out after the consolidated inbox message is created.
|
||||
|
||||
## Automated ISAC system messages
|
||||
|
||||
|
||||
Reference in New Issue
Block a user