Commit Graph

20 Commits

Author SHA1 Message Date
gamer147
998402ebc3 refactor(tutorial-presents): promote static catalogue to seed-driven TutorialPresentEntries table
The five tutorial gifts every fresh viewer is given at signup used to live as a
static C# array in SVSim.Database/SeedData/TutorialPresents.cs — outside the
seed-JSON pipeline used by all 40+ other globals tables. Editing a gift required
a code change + rebuild instead of a JSON edit + bootstrap re-run.

Now authored in SVSim.Bootstrap/Data/seeds/tutorial-presents.json and loaded into
a new TutorialPresentEntries table via TutorialPresentsImporter (clear-and-rewrite,
mirroring HomeDialogs). ViewerRepository.RegisterAnonymousViewer reads the table
at signup and projects each row into a ViewerPresent with Source="tutorial".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 09:53:10 -04:00
gamer147
2ce399ff87 feat(signup): seed tutorial gifts as ViewerPresent rows on /tool/signup 2026-06-08 20:34:48 -04:00
gamer147
d3488c3bc6 fix(viewer): default ClassExp.Level to 1 for new viewers
Client RankMatchUI.onOpen indexes _classCharaExpList[level - 1]
unconditionally; level 0 (the prior default) throws IOOR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 18:49:45 -04:00
gamer147
89b3d23bde feat(viewer-repo): add LoadForMatchContextAsync for battle-node ctx build
Focused AsNoTracking load with Info.SelectedEmblem/SelectedDegree includes
for the new MatchContextBuilder. Single test locks the include graph.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 12:37:44 -04:00
gamer147
0b859f1c8e fix(check): merge anonymous resignup viewer into Steam-linked viewer
GameStart already detects the Steam-vs-UDID mismatch produced by
wipe-and-resignup; it now also reclaims the orphan. New
ViewerRepository.MergeAnonymousViewerInto transfers the fresh UDID
from V_new onto V_old in one save (freeing the unique-index slot),
then deletes V_new in a second save. Partial-failure mode is a
benign null-UDID viewer; two rows never contend for the same UDID.
Side benefit: future GetViewerByUdid lookups now short-circuit to
V_old without going through the Steam handler.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 01:59:47 -04:00
gamer147
22c01ed11a fix(viewer): fresh signups start with empty DisplayName
Verified against Wizard.Title/UserNameInput.cs:30 in the 2026-05-23
decompile:

    IsFinished = !string.IsNullOrEmpty(PlayerStaticData.UserName);

Any non-empty seeded value — including the prior " - " placeholder
this method was passing — sets IsFinished=true on the first frame and
silently skips both the input dialog and the /tutorial/update_action #1
+ /account/update_name calls that travel with it. The in-source comment
described the opposite behavior; empty string is what actually triggers
the dialog.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:19:03 -04:00
gamer147
b50a884af9 fix(viewer): RegisterViewer defaults to post-tutorial TutorialState=100
BuildDefaultViewer hardcoded TutorialState=1 — correct for fresh anonymous
signups (RegisterAnonymousViewer) but wrong for AdminController.ImportViewer
and Steam-social signups, which both go through RegisterViewer and expect a
prod-replica viewer that boots to the home screen. Add an initialTutorialState
parameter (default 1 preserves RegisterAnonymousViewer behavior); RegisterViewer
passes 100.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 20:07:05 -04:00
gamer147
1af0e03eeb fix(viewer): fresh signup defaults match prod tutorial capture
Three corrections to BuildDefaultViewer + RegisterAnonymousViewer
verified against data_dumps/traffic_prod_tutorial.ndjson:

- TutorialState now 1 (TUTORIAL_STEP0), not 0 (PRE_TUTORIAL_STEP).
  Wizard.Title.NextSceneSwitcher routes step==1 to the Prologue scene;
  any other non-{31,41,100} step routes to AreaSelect at section 0,
  which has no chapter data and crashes the client with a LINQ
  Single() "Sequence contains no matching element" from
  AreaSelectUI.SelectChapter. Prod's first /check/game_start returns
  now_tutorial_step="1"; step 0 is a pre-existence state we never
  want to expose on the wire.

- DisplayName " - " (literal space-dash-space), not "Player".
  Wizard.Title.UserNameInput.Start short-circuits with
  IsFinished=true on !string.IsNullOrEmpty(PlayerStaticData.UserName),
  silently skipping the name dialog AND the tutorial sub-step it
  drives (/tutorial/update_action #1 + /account/update_name). Prod
  uses " - " as the unset placeholder.

- viewer.Info.SelectedEmblem/SelectedDegree assigned from the default
  emblem/degree the loadout grants. Without this, /load/index emits
  selected_emblem_id=0 and selected_degree_id=0 for a fresh viewer
  that owns those cosmetics — prod sends the real granted IDs.

Also surfaces the actual Postgres constraint name in the unique-
violation re-raise (ExtractConstraintName), instead of always
saying "UDID" — the original message was misleading whenever the
real constraint was on owned-collection rows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 18:02:52 -04:00
gamer147
f233a8c8d6 fix(viewer): fresh signups start at tutorial_state=0, not 100
Previously RegisterAnonymousViewer auto-completed the tutorial, which
prevented the client from ever entering the tutorial flow. SeedViewerAsync
gains a tutorialState parameter (default 100) so existing tests keep
their pre-completed-tutorial assumption.
2026-05-28 11:27:37 -04:00
gamer147
529fd13668 signup: close two concurrency holes from final review
(1) RegisterAnonymousViewer now catches the unique-violation
    race (SQLSTATE 23505 on Postgres / code 19 on SQLite) and
    re-reads by UDID, returning the existing row instead of
    surfacing 500 to the second concurrent /tool/signup caller.
    New repo test exercises the back-to-back register path.

(2) Add unique index on SocialAccountConnection (AccountType,
    AccountId). The auth handler's find-or-link path claimed
    this index existed as the dedup backstop; the claim was
    accurate as design intent but the schema was missing. Now
    matched. Comment in handler updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:46:19 -04:00
gamer147
f85589d208 repo(viewer): restore dropped rationale comment, add link-idempotency assertion
Review polish on the prior commit (30874c6):
- BuildDefaultViewer extract dropped the "filter out Id=0 placeholders
  and dedupe" comment from the leader-skin grant block — restored.
- LinkSteamToViewer test now calls link twice and asserts count stays
  at 1, exercising the alreadyLinked short-circuit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:06:35 -04:00
gamer147
30874c681f repo(viewer): add UDID lookup, anonymous register, Steam link helpers
Extracts the default-loadout body into a private BuildDefaultViewer
helper shared by the existing Steam-import path and a new
RegisterAnonymousViewer for /tool/signup. LinkSteamToViewer is the
seam SteamSessionAuthenticationHandler will call on first-Steam-touch
of a UDID-keyed viewer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:01:02 -04:00
gamer147
c14408ba06 Seeding reorg 2026-05-24 21:13:15 -04:00
gamer147
d9ef9fe1fc Pack logic cleanup 2026-05-24 09:27:10 -04:00
gamer147
499e218be7 Deck fixes 2026-05-23 21:36:27 -04:00
gamer147
6b70850b7b More features 2026-05-23 14:18:01 -04:00
gamer147
b2024af852 Lots of data and model setup 2025-05-18 02:27:17 -04:00
gamer147
79505e0c1a DTOs for index mostly done, doing DB models 2024-09-12 00:35:31 -04:00
gamer147
ac3b002d74 Stuff works 2024-09-08 10:27:12 -04:00
gamer147
7e4bce9ac5 Testing more garbage encryption 2024-09-07 22:14:24 -04:00