11 KiB
Repository Instructions
SHD design-system maintenance
Treat docs/DESIGN_SYSTEM.md and the shared tokens and patterns in src/app.css
as maintained parts of the product.
Whenever a change makes a significant visual or interaction-design decision, update the design system in the same change. This includes:
- introducing or changing colors, typography, spacing, borders, elevation, or motion;
- creating a new reusable layout, navigation, table, editor, form, card, status, or feedback pattern;
- materially changing dashboard density, hierarchy, responsive behavior, or accessibility behavior;
- changing the semantic meaning of an existing visual state;
- establishing a pattern that future pages or components should follow.
For significant design changes:
- Reuse or extend the CSS custom properties in
src/app.css; do not scatter near-duplicate hard-coded values throughout new components. - Update
docs/DESIGN_SYSTEM.mdwith the new or revised rule, token, pattern, usage guidance, and responsive or accessibility considerations. - Refactor repeated UI into a reusable component when that makes the pattern clearer and reduces divergence.
- Preserve the SHD design principles: tactical but restrained, data-first, square and engineered, orange reserved for action and emphasis, and explicit textual state indicators.
- Verify hover, pressed, focus-visible, pending, disabled, error, success, and reduced-motion behavior where applicable.
- Run
npm run checkandnpm run buildbefore completing the change.
Minor alignment fixes, isolated bug fixes, and corrections that do not introduce or revise a reusable design decision do not require a documentation update.
If uncertain whether a visual change is significant, update the design system.
Reusable interface patterns
Favor shared, generic components whenever a visual or interaction pattern is
used in more than one place or is likely to recur. Before adding page-local
markup and styles, check src/lib/components and extend an appropriate shared
component when practical. When introducing a reusable pattern, migrate the
clearest existing duplicate in the same change so the component has more than
one real consumer.
For small, finite option sets, prefer the shared segmented-choice pattern over a dropdown. Use radio semantics for exactly one choice and checkbox semantics for additive independent choices. Reserve dropdowns for long, dynamic, or search-oriented option sets. Preserve native form semantics, keyboard access, focus-visible, selected, disabled, pressed, responsive, and reduced-motion behavior in shared controls.
ISAC editor lifecycle
All ISAC data-management editors must follow the same successful-save behavior:
- Saving an edit to an existing record closes the editor and returns the user to the registry.
- Saving a newly added record keeps the editor open with a fresh blank record so consecutive data entry remains fast.
- Validation errors keep the editor open and preserve the entered values.
- Server actions must return the add/edit mode and a unique result token; client-side reactive handling must consume each token only once to avoid repeated state updates.
- When a successful add keeps an icon-enabled editor open, increment the shared upload reset token so the native file input, generated preview, filename, drag/paste state, validation message, and removal state are fresh for the next record.
Apply this convention whenever an ISAC editor is added or materially changed.
ISAC audit logging
Every successful server-side mutation performed through ISAC must create an append-only audit event. Audit coverage is a required part of implementing or changing any ISAC module, action, endpoint, bulk operation, moderation control, identity operation, access-policy change, archive action, or destructive action.
Follow these rules:
- Use the shared audit utilities in
src/lib/server/audit.ts; do not invent module-specific audit formats or write directly toaudit_login new code. - Record the authenticated operator ID, stable category, specific action, target entity ID, timestamp, and useful before/after snapshots.
- Categories describe durable operational domains such as
game_data,user_access,user_moderation,identity, androle_management. Actions describe the exact event in namespaced past tense, such asweapon.updated,attribute.archived, ormoderation.blocked. - Capture relationship changes as well as the primary row. When an action replaces permission sets, compatible brands, talents, effects, tiers, or other linked records, include the meaningful previous and resulting sets.
- Create audit records only after validation succeeds and the requested mutation has completed. Rejected, unauthorized, or validation-failed requests must not appear as successful mutation events.
- Never include password hashes, session tokens, magic-link tokens, OAuth state, passkey public-key bytes, SMTP credentials, environment secrets, or other authentication secrets in audit snapshots. Minimize personal data to what is necessary for security, support, and accountability.
- Audit visibility is controlled by
audit.view. The read-onlyAuditorrole grantsisac.accessandaudit.view; it must not implicitly grant mutation, moderation, identity-management, or user-access permissions. - New audit categories and actions must remain searchable in the Audit History registry. Update its grouped filters when a new durable operational domain is introduced.
- Preserve audit history during normal record archival and soft deletion. Never add an ISAC action that edits or deletes audit records without an explicit retention policy, legal review, and separately audited authority.
- Tests and handoff verification for an ISAC mutation must include confirming that its audit event contains the correct actor, category, action, target, and change evidence.
- Audit reversion is a separately authorized compensating action, never a
history rewrite. Require
audit.revert, an explicit confirmation interaction, current-state comparison against the original after-snapshot, relationship validation, and a newaudit.revertedevent referencing the original event. Block stale, already-reverted, unsupported, destructive identity, and incomplete-snapshot events rather than guessing.
Database preservation
Development data is valuable and may be entered by non-technical contributors. Treat embedded database files as persistent user data, not disposable build artifacts.
Before deleting, replacing, recreating, renaming, or destructively migrating a
database—and before any major schema change—create a timestamped JSON backup
with npm run db:backup.
Database work must follow these rules:
- Confirm which environment and exact database path are in scope.
- Before every database backup or restore, inspect running processes and stop only this project's development-server process tree. The embedded Turso database holds an exclusive file lock while the dev server is running, so do not attempt the backup first and wait for a locking failure.
- Create and verify a JSON backup before destructive work.
- Never overwrite or delete the only available backup.
- Keep backups out of Git; they can contain user records and password hashes.
- Prefer additive, repeatable schema migrations over database recreation.
- After a restore, run the schema migration and verify record counts and critical entities before resuming data entry.
- Report the backup path when completing database-destructive work.
Use npm run db:restore -- <backup-file> only with an empty, migrated target
database. The restore script intentionally refuses to merge into a populated
database.
Low-downtime database migration windows
Friends and contributors may be actively entering game data in ISAC while development continues. Treat dev-server availability and unsaved contributor work as operational concerns whenever a schema change requires stopping the embedded database.
Use this sequence for every planned migration window:
Prepare while the server remains online
- Implement the application changes and the complete repeatable migration before stopping the server.
- Prefer additive, backward-compatible changes: new tables, new indexes, and nullable or safely defaulted columns. Avoid table copies, column removal, database recreation, or migrations that require the new application code to become active before the schema is ready.
- Make migrations idempotent by inspecting current schema state before each alteration. The migration must be safe to rerun after interruption.
- Batch related schema changes into one window instead of repeatedly stopping the server during the same task.
- Run
npm run checkandnpm run buildbefore the outage. Do not spend the offline interval editing code, resolving type errors, building assets, or performing ordinary UI review. - Identify the exact environment, database path, migration steps, verification queries, and rollback/restore backup before stopping anything.
Keep the offline window short
- Do not start the window while a known contributor is in the middle of an unsaved form or submission. When contributor activity is known, allow them to finish or explicitly coordinate the interruption.
- Inspect processes and stop only this project's dev-server process tree.
- Run
npm run db:backupimmediately, verify that it completed, and retain the reported backup path. - Run the already-prepared migration immediately after the backup.
- Perform only critical database checks while offline: migration success, expected columns/tables, record counts, and critical entity availability.
- Restart the dev server as soon as the database is safe for application use. Browser testing, extended regression checks, formatting, documentation review, and noncritical diagnostics happen after service is restored.
Failure and high-risk handling
- If backup, migration, or critical verification fails, do not repeatedly improvise against the live database. Preserve logs and the verified backup, determine whether the existing schema is still safe, and either restart the previous compatible application or follow the documented empty-database restore procedure.
- Separate destructive, data-rewriting, or predictably long migrations from routine additive windows. Report that a maintenance window is required before beginning one.
- Do not claim the service is available until the restarted dev server passes a basic health/page check.
- In the handoff, report the backup path, migration result, server restart, critical verification performed, and approximate offline interval when it can be determined.