Commit Graph

16 Commits

Author SHA1 Message Date
Disco DeDisco
400762c0e5 Game Sign picker @ /billboard/my-sign/ + billboard applet — Sprint 4a of My Sea roadmap — TDD
User scope (per design conv this session): split the room's sig-select responsibility off into a standalone billboard-context "My Significator" applet — branded "Game Sign" on the surface. Same 18-card pile as room sig-select (16 middle arcana + Major 0 & 1 filtered by Note unlocks); polarity collapses to a single FLIP choice (the FLIP btn in the picker carousel toggles User.significator_reversed). Selection persists globally on the User model + propagates to the billboard's Game Sign applet ; **naming convention locked**: "significator" stays at storage (User.significator FK + User.significator_reversed) + room sig-select context (DRY w. existing template/JS); "Sign" / "Game Sign" is the billboard-surface branding (file my_sign.html, URL /billboard/my-sign/, URL names my_sign + save_sign, applet name "Game Sign", page wordmark "Game Sign", btn label SAVE SIGN). Action URLs don't carry a trailing slash per project convention (/billboard/my-sign/save vs the page's /billboard/my-sign/) ; **schema**: User gains 2 fields — `significator: FK → epic.TarotCard (nullable, on_delete=SET_NULL)` + `significator_reversed: BooleanField(default=False)`. Migration lyric/0006_user_significator_user_significator_reversed.py auto-generated; reversible. Applet seed in applets/0009_seed_my_sig_applet.py adds the row (slug='my-sign', name='Game Sign', context='billboard', default_visible=True, grid_cols=4, grid_rows=6), idempotent update_or_create, reversible unseed() ; **picker page** (my_sign.html): solo lift of `_sig_select_overlay.html` — sig-stage-card scaffold + sig-stat-block + 18-card grid + SAVE SIGN form. Stripped: countdown / WebSocket / polarity / multi-user / reservations. Empty-state branch covers no-equipped-deck (link back to Game Kit; full Brief-redirect + Earthman-Backup fallback deferred to a follow-up sub-sprint). Minimal inline JS: click .sig-card → mark .sig-focused + set hidden card_id + enable SAVE SIGN; FLIP btn toggles .is-reversed + the hidden reversed input. Stage-card preview (name/qualifier population + keyword swap on FLIP) deferred — Sprint 4a follow-up will lift stage-card.js's populator into a non-room context ; **applet partial** (_applet-my-sign.html): renders user.significator's corner-rank + suit-icon + name_title if set; `.my-sign-applet-empty` "No sign chosen yet." otherwise. Header `<h2><a href="{% url 'billboard:my_sign' %}">Game Sign</a></h2>` links to the picker ; **helper refactor** (epic/models.py): extracted `_sig_unique_cards_for_deck(deck_variant)` from `_sig_unique_cards(room)`. New public `personal_sig_cards(user)` parallels `levity_sig_cards / gravity_sig_cards` but pulls from `user.equipped_deck` instead of `room.deck_variant`. Same Note-unlock filtering. No behavior change to existing room callers (3-line wrapper preserves the room signature) ; **TDD trail** — user called out mid-sprint that I'd skipped FTs; pivoted to FT-first. test_bill_my_sign.py (new, 3 FTs): T1 picker renders w. wordmark + target card present in grid; T2 click card → SAVE SIGN enables → POST persists → applet shows the card; T3 fresh user → applet renders empty-state. Initial reds — (a) setUp's `personal_sig_cards(user)` returned [] because StaticLiveServerTestCase → TransactionTestCase flushes migration-seeded DeckVariant + TarotCard between tests; fixed w. `serialized_rollback = True` on the test class (per [[feedback_transactiontestcase_flush]]); (b) h2 wordmark assertion against `MYSIGNIFICATOR` failed against the renamed "Game Sign" + the letter-splitter spreading chars across <span> children — switched to whitespace-stripped substring check `GAMESIGN`; (c) `.fan-corner-rank` text is CSS-hidden so Selenium returns "" — replaced corner-rank assertions w. data-card-id selectors (already-proven reliable from the parent .sig-card lookup) ; ITs (+12, in apps.billboard.tests.integrated.test_views): MySignViewTest (6 — login redirect, 200 + template, 16-card pile, save persists, invalid card_id → 403, GET save redirects); BillboardAppletMySignTest (3 — applet rendered, empty-state w/o sig, card+reversed class w. sig). PersonalSigCardsTest in apps.epic.tests.integrated.test_models (3 — happy path 16 cards, no-equipped-deck → [], schizo Note unlocks Major 1) ; pre-existing change picked up by the commit: my_sea.html branding "Game Sea" (user-modified mid-session; was "My Sea" in Sprint 3 — divergence captured in MEMORY.md follow-up) ; 1020 IT/UT green (+12) in 46s; 3 FTs green in 24s. Sprint 4a unblocks Sprint 4b (My Sea gating w. --terUser link to /billboard/my-sign/) + Sprint 4c (FT helper for mocking the sig choice across other FTs)

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:23:24 -04:00
Disco DeDisco
bc77296dd4 +52 IT/UT to close IT/UT-only coverage gaps (93% → 96%) — full suite 983 tests in 47s ; UTs in epic/tests/unit/test_models.py — TarotCardEmanationForTest (4) covers emanation_for(polarity) w. levity/gravity overrides + fallback to name_title for cards w.o a polarity split (cards 48-49 are the only polarity-split cards in the deck so this method is sparsely exercised by ITs); TarotCardReversalForTest (4) covers reversal_for(polarity) w. polarity-split + reversal_qualifier fallback + further fallthrough to emanation_for; TarotCardNameSplitTest (4) covers name_group/name_title colon-split parsing (prefix-w-colon / suffix / no-colon edge); TarotCardCautionsJsonTest (2) covers the cautions_json JSON serialiser ; UTs in epic/tests/unit/test_utils.py — PlanetHouseFallbackTest +1 happy-path test (degree=15 lands in house 1 w. sequential cusps) for the normal cusp-match branch alongside the existing pathological fallback test; TopCapacitorsTest (6) covers all top_capacitors() branches — empty dict / None / all-zero counts (the L56 max(counts.values()) <= 0 fallback that was uncovered) / single-winner / tie-clockwise-order / enriched dict {"count":N} input shape ; ITs in epic/tests/integrated/test_models.py — TarotDeckDrawTest extended w. 5 tests for remaining_count (happy + no-deck-variant fallback to 0) + draw() happy-path (returns n tuples of (TarotCard, bool) / appends to drawn_card_ids / never repeats cards across consecutive draws); existing ValueError + shuffle tests preserved ; ITs in epic/tests/integrated/test_views.py — SigEventRetractionTest (4 tests) covers the three data["retracted"] = True paths that the FT test_game_room_select_sig.py walks transitively but no IT pins directly: sig_unready retracts prior SIG_READY (L937), sig_ready retracts prior SIG_UNREADY (L907), sig_reserve action=release while ready retracts prior SIG_READY + records fresh SIG_UNREADY (L823); SigReserveInvalidCardIdTest (1) covers TarotCard.DoesNotExist → 400 (L840-841) ; SigSelectGravityContextTest (3) covers the user_polarity = 'gravity' branch (L322) + the gravity_sig_cards lookup (L357) — all existing SIG_SELECT context tests use the founder-as-PC-levity setup so these branches sat uncovered; logs in as gamers[5] (BC role) + asserts user_polarity + sig_cards match gravity_sig_cards() output ; SeaDeckViewTest (7) mirrors the test_game_room_select_sea.py FT but isolates the JSON contract — covers 403 when unseated, empty halves when seat has no deck_variant (L1255-1256 early-out), two-halves shape, ~even split, card_dict keys (id/name/arcana/corner_rank/suit_icon/name_group/name_title/reversed/qualifiers), reversed field is bool, claimed-significator exclusion via room.table_seats.exclude(significator__isnull=True) ; ITs in dashboard/tests/integrated/test_views.py — ProfileViewTest +2 (reserved-handle "adman" rejection — L116-117: username stays unchanged + redirect to /); KitBagViewTest (3) covers the kit_bag view's panel render w. TITHE-sort branch (L169-175) + login guard ; ITs in dashboard/tests/integrated/test_sky_views.py — SkyViewTest +2 (saved birth datetime renders in user's sky_birth_tz via astimezone L300-306 — 16:00 UTC → 12:00 EDT; invalid-tz string triggers ZoneInfoNotFoundError → swallowed pass → UTC fallback at 16:00) ; ITs in gameboard/tests/integrated/test_views.py — EquipTrinketViewTest +2 (POST equips trinket + returns 204 — L83-85; non-owner POST returns 404 via get_object_or_404); UnequipTrinketViewTest +2 (POST clears matching equipped_trinket — L107-110; POST of non-matching token is a 204 no-op, the implicit else branch) ; .coveragerc omit gains */reset_staging_db.py per user — mgmt cmd was the only 0%-stmt module that wasn't exercised by tests at all + we agreed it's deliberately untested staging-side code ; palette-monochrome-dark rebalance in rootvars.scss — --quiUser/--sixUser/--sepUser remapped to (secAg / quaAg / priPt) instead of (quaAg / terAg / secAg), shifting the secondary/subtle/deep-subtle anchors up the silver gradient so the palette reads more cleanly under the new sig-stage card colours from 3242873 ; uncovered remnants from earlier analysis intentionally left in place — consumers.py at 68% (channels-tag tests excluded; would need --tag=channels run), Carte Blanche slot navigation + sky_dice + tarot_deck preview view paths (the "bigger investments" tier from session triage; FT-covered + the IT setup is heavier than the immediate value), defensive except fallbacks that need contrived inputs to fire, and a handful of __str__s/pass branches not worth a test apiece — TDD
All checks were successful
ci/woodpecker/push/pyswiss Pipeline was successful
ci/woodpecker/push/main Pipeline was successful
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 01:07:13 -04:00
Disco DeDisco
1c2b8f96ab SIG SELECT: Nomad/Schizo locked by default; Note-unlock gate — TDD
- _filter_major_unlocks(cards, user): strips Major 0 (Nomad) and Major 1
  (Schizo) unless user has matching 'nomad'/'schizo' Note; unauthenticated
  users see 0 majors
- levity_sig_cards(room, user) / gravity_sig_cards(room, user): accept user
  param; default 16 court cards, up to 18 with both Note unlocks
- View wires user into both calls; _sig_unique_cards / sig_deck_cards unchanged
  (game-table deck still includes all 18 unique)
- _full_sig_setUp: seats now carry deck_variant=earthman
- SigCardHelperTest: 4 new ITs (default 16, nomad +1, schizo +1); empty-deck
  test updated to clear seats + owner
- SigSelectRenderingTest: 18-card test updated to 16-default + 3 Note-unlock ITs

Pending: superusers auto-granted nomad + schizo Notes on creation (ask user)

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 01:05:25 -04:00
Disco DeDisco
758c9c5377 COVERAGE: patch 91% → 96%+ — 603 tests, tasks.py at 100%
New/extended tests across billboard, dashboard, drama, epic, gameboard,
and lyric to cover previously untested branches: dev_login view, scroll
position endpoints, sky preview error paths, drama to_prose/to_activity
branches, consumer broadcast handlers, tarot deck draw/shuffle, astrology
model __str__, character model, sig reserve/ready/confirm views, natus
preview/save views, and the full tasks.py countdown scheduler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 23:23:28 -04:00
Disco DeDisco
df421fb6c0 added PICK SKY ready gate: SigReservation.ready + countdown_remaining fields, Room.SKY_SELECT status + sig_select_started_at, sig_ready + sig_confirm views, WS notifiers for countdown_start/cancel/polarity_room_done/pick_sky_available, migration 0031, PICK SKY btn in hex center at SKY_SELECT, tray cell 2 sig card placeholder; FTs SRG1-8 written (pending JS/consumer)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 01:17:24 -04:00
Disco DeDisco
520fdf7862 Sig select: caution tooltip, FLIP/FYI stat block, keyword display
- TarotCard.cautions JSONField + cautions_json property; migrations
  0027–0029 seed The Schizo (number=1) with 4 rival-interaction cautions
  (Roman-numeral card refs: I. The Pervert / II. The Occultist, etc.)
- Sig-select overlay: FLIP (stat-block toggle) + FYI (caution tooltip)
  buttons; nav PRV/NXT portaled outside tooltip at bottom corners (z-70);
  caution tooltip covers stat block (inset:0, z-60, Gaussian blur);
  tooltip click dismisses; FLIP/FYI fully dead while btn-disabled;
  nav wraps circularly (4/4 → 1/4, 1/4 → 4/4)
- SCSS: btn-disabled specificity fix (!important); btn-nav-left/right
  classes; sig-caution-* layout; stat-face keyword lists
- Jasmine suite expanded: stat block + FLIP (5 specs), caution tooltip
  (16 specs) including wrap-around and disabled-button behaviour
- IT tests: TarotCardCautionsTest (5), SigSelectRenderingTest (8)
- Role-card SVG icons added to static/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 00:22:04 -04:00
Disco DeDisco
c3ab78cc57 many deck changes, including pentacles to crowns, middle arcana, and major arcana fa icons 2026-04-05 22:32:40 -04:00
Disco DeDisco
c7370bda03 sig-select sprint: SigReservation model + sig_reserve view (OK/NVM hold); full sig-select.js rewrite with stage preview, WS hover cursors, reservation lock (must NVM before OK-ing another card — enforced server-side 409 + JS guard); sizeSigModal() + sizeSigCard() in room.js (JS-based card sizing avoids libsass cqw/cqh limitation); stat block hidden until OK pressed; mobile touch: dismiss stage on outside-grid tap when unfocused; 17 IT + Jasmine specs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 22:01:23 -04:00
Disco DeDisco
b3bc422f46 new migrations in apps.epic for .models additions, incl. Significator select order (= Start Role seat order), which cards of whom go into which deck, which are brought into Sig select; new select-sig urlpattern in .views; room.html supports this stage of game now
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2026-03-25 01:50:06 -04:00
Disco DeDisco
c0016418cc hopefully plugged pipeline fail for FT to assert stock card deck version; 11 new test_models ITs & 12 new test_views ITs in apps.epic.tests 2026-03-25 01:30:18 -04:00
Disco DeDisco
01de6e7548 Django Channels role-select sprint: turn_changed, roles_revealed, role_select_start consumer handlers; WS URL changed from room_slug to room_id UUID; TableSeat model - room, gamer, slot_number, role, role_revealed, seat_position fields; Room.table_status field with ROLE_SELECT, SIG_SELECT, IN_GAME choices; migration 0006_table_status_and_table_seat; pick_roles and select_role views; _role_select_context helper; _notify_turn_changed, _notify_roles_revealed, _notify_role_select_start notifiers; all gate-mutation views now call _notify_gate_update; ChannelsFunctionalTest base class with serve_static, screenshot, dump helpers; SQLite TEST NAME set to file path for ChannelsLiveServerTestCase; InMemoryChannelLayer added to test CHANNEL_LAYERS settings; FT 5 and FT 6 now passing - active seat arc and turn advance via WS, no page refresh; room.js, gatekeeper.js, role-select.js added to apps/epic/static; applets.js, game-kit.js, dashboard.js, wallet.js relocated to app-scoped static dirs; room.html: hex table, table-seat arcs, card-stack, inventory panel, role-card hand, WS scripts; _room.scss: room-shell flex layout, .table-hex polygon clip-path, .table-seat and .seat-card-arc, .card-stack eligible/ineligible states, .card flip animation, .inv-role-card stacked hand, .role-select-backdrop; gear btn and room menu always position: fixed; 375 tests, 0 skipped 2026-03-17 00:24:23 -04:00
Disco DeDisco
4baaa63430 new model fields & migrations for apps.epic & apps.lyric; new FTs, ITs & UTs passing
; some styling changes effected primarily to _gatekeetper.html modal
2026-03-14 22:00:16 -04:00
Disco DeDisco
dddffd22d5 covered some test lacunae; gatekeeper now waits for +6 gamers to commit tokens to unblock game room 2026-03-13 22:51:42 -04:00
Disco DeDisco
e0d1f51bf1 new migrations in apps.epic app; new models, urls, views handle the founder of a New Game inviting a friend via email to a game gatekeeper; ea. may drop coin in any of up to 6 avail. slots; FTs & ITs passing 2026-03-13 18:37:19 -04:00
Disco DeDisco
6a42b91420 new migrations in apps.epic & apps.lyric apps; new Token fields of latter articulate upon Room model helper fns of former; new FTs, ITs & UTs capture new behavior accordingly; new template partial content in templates/apps/gameboard 2026-03-13 17:31:52 -04:00
Disco DeDisco
5773462b4c massive additions made thru somewhat new apps.epic.models, .urls, .views; new html page & partial in apps/gameboard; new apps.epic FT & ITs (all green); New Game applet now actually leads to game room feat. token-drop gatekeeper mechanism intended for 6 gamers 2026-03-13 00:31:17 -04:00