Disco DeDisco
5f6002aa70
buddies sprint phase 1: User.buddies M2M(self,symm=False) + my_buddies aperture page + add_buddy JSON endpoint + buddy btn slide-out — TDD; My Contacts applet renamed → My Buddies (slug + name + partial)
...
- lyric/0004 adds User.buddies = ManyToManyField('self', symmetrical=False, blank=True, related_name='added_as_buddy'). Asymmetric one-way add: A.buddies.add(B) doesn't reciprocate. Reverse via B.added_as_buddy.all() — load-bearing for the future "buddy changed username" snapshot-accept flow noted in design.
- applets/0006 renames slug my-contacts → my-buddies + name 'Contacts' → 'My Buddies'. Existing migrations 0003/0004 untouched (historical artifacts).
- billboard.views.my_buddies + add_buddy:
• my_buddies: GET /billboard/my-buddies/ → renders the aperture page with request.user.buddies.all().
• add_buddy: POST /billboard/buddies/add → JSON {buddy: {id, username, email}|null}. Privacy: returns null when email isn't a registered User OR is the requester's own; never leaks membership. Idempotent on re-add (M2M dedup).
- templates:
• _applet-my-contacts.html → _applet-my-buddies.html (heading + link to /billboard/my-buddies/).
• my_buddies.html — bottom-anchored aperture list of buddies w. {% empty %} fallback "No buddies yet."
• _buddy_add_panel.html — bottom-left handshake btn + slide-out, mirrors _buddy_panel.html (post share) but POSTs to add_buddy and appends to #id_buddies_list. Skips append if data-buddy-id already in DOM (race-safe). Drops the .buddy-entry--empty row on first add.
- SCSS: page-billbuddies joins the body-class aperture trio; .buddies-page extends %billboard-page-base + flex-column + bottom-anchor for #id_buddies_list. id_applet_my_contacts → id_applet_my_buddies (test references + grid placement).
- tests: new test_buddies.py — 14 ITs covering UserBuddiesM2MTest (asymmetric, idempotent), MyBuddiesViewTest (lists own buddies only, anon redirect), AddBuddyViewTest (registered/unregistered/self/idempotent/email-fallback/405). Existing test_views/test_billboard/test_game_kit references swapped to my-buddies. New test_my_buddies.py FT — 4 tests: pre-existing buddies render, empty state, add via panel appends entry w. username, unregistered silent no-op.
- 841 ITs (+14) + 4 my_buddies FTs green.
Code architected by Disco DeDisco <discodedisco@outlook.com >
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-08 22:31:42 -04:00
Disco DeDisco
6f76f6c176
post aperture refactor (May-8b): Post.title field; Line.author PROTECT FK + created_at; Note.grant_if_new admin-vs-Look! format dispatch w. note-ref anchor; bottom-anchored aperture w. shared-between header + per-Line user/timestamp; dotted-? Brief square; reserved adman seed — TDD
...
- schema: billboard/0004 adds Post.title (CharField 35) + Line.author (PROTECT FK, related_name=authored_lines) + Line.created_at (auto_now_add); RunPython backfill stamps existing rows (note_unlock → "Notes & recognitions" + author=adman; user_post → first-line glean + author=Post.owner).
- lyric/0003 seeds adman User (system author for note unlock + share invite Lines); apps.lyric.models gains RESERVED_USERNAMES = {"adman"}, is_reserved_username() guard in dashboard.set_profile, get_or_create_adman() lazy fetch (TransactionTestCase flushes the seed).
- drama: Note.grant_if_new dispatches via _ADMIN_NOTE_SLUGS = {"super-schizo","super-nomad"} — admin slugs use "The administration recognizes…" prose; everyone else uses "Look!—new Note unlocked." Both wrap Note name in `<a class="note-ref">`. Header Line dropped (test_two_different_grants_share_one_post asserts 2 lines, not 3). Note.display_name property added (slug.title() default — "super-schizo" → "Super-Schizo"). User.active_title_display returns donned recognition title or "Earthman" default.
- billboard models: Post.name property removed → my_posts.html, _applet-my-posts.html, PostSerializer switched to Post.title. LineForm.save(for_post, author) + ExistingPostLineForm.save(author) signature + all callers (api.views, billboard.views.new_post + view_post + share_post). billboard.views.share_post authors via get_or_create_adman; new_post truncates first line for Post.title via _truncate_post_title.
- post.html: <h3> post title heading; .post-shared-recipients (commas only) + .post-shared-self lines ("just me, X the Earthman" / "& me, X the Y" 0/≥1 split); #id_post_table is now a <ul> w. justify-content: flex-end + per-Line 3-col grid (author/text/time); adman Lines render |safe + .post-line--system italic; #id_text → #id_post_line_text rename (post.html only — /billboard/ new-post applet keeps #id_text); page_class page-billpost (joins billboard+billscroll body-class trio).
- SCSS _billboard.scss: .post-page extends %billboard-page-base, adds bottom-anchored flex-column scroll + 3-col .post-line grid + .post-line-form pinned at bottom. _note.scss: a.note-banner__image picks up .note-item__image-box dashed-? styling for the Brief square.
- _buddy_panel.html JS rewired for new layout: _appendLine builds <li class="post-line post-line--system"> w. adman+timestamp; _appendRecipientChip handles 0→1+ transition (rewrites "just me," → "& me,", inserts .post-shared-recipients line above self).
- FT post_page.py: get_table_rows queries .post-line; wait_for_row_in_post_table matches by text containment (line_number arg ignored — kept for backwards compat); get_line_input_box probes #id_post_line_text first, falls back to #id_text; get_post_owner reads textContent (hidden span). test_applet_new_post_line_validation switched to input[name="text"]:invalid/:valid for cross-page selectors.
- rootvars.scss: minor plutonium + fuschia tweaks (pre-existing).
- 818 ITs + 35 FTs (buddy/new-post/sharing/validation/layout/jasmine/my-notes/my-posts) green.
Code architected by Disco DeDisco <discodedisco@outlook.com >
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-08 21:29:21 -04:00
Disco DeDisco
29493c4f74
pronouns: per-user pronouns ideology + Pronouns applet on Game Kit; provenance prose uses actor.pronouns at render time — TDD
...
- User.pronouns CharField w. choices=[pluralism (default), bawlmorese, misogyny, misandry, misanthropy] + pronoun_subj/obj/poss properties; PRONOUN_TABLE single source of truth in apps.lyric.models; mig 0002_user_pronouns
- drama.GameEvent.to_prose() drops module-level PRONOUN_* constants; SIG_READY/SIG_UNREADY/ROLE_SELECTED now resolve poss/subj from self.actor.pronouns at render time, so flipping a user's preference rewrites all their existing scroll prose; default actor → "their"
- SIG_READY prose strips a leading "The " from card_name so "the The Wanderer" reads "the Wanderer" and "the Engraven The Nomad" reads "the Engraven Nomad"; minor arcana ("Maid of Brands") untouched
- new applets/0005 seeds 'pronouns' applet (3x3, game-kit, default visible); _game_kit_sections.html grows a #id_gk_pronouns block w. 5 .gk-pronoun-card items labeled by ideology slug (italic) and tagged data-pronoun + data-trio
- card click → window.showGuard(card, "Set pronoun preference?<span class='guard-pronoun-trio'>{trio}</span>", commitCb); on OK fetches POST /dashboard/set-pronouns w. CSRF cookie + reloads so .active class moves and provenance prose re-renders; NVM dismisses
- dashboard.set_pronouns view (POST-only, login_required, 204/400/405) at /dashboard/set-pronouns; rejects choices not in PRONOUN_TABLE
- _game-kit.scss extends shared card rule to .gk-pronoun-card w. .active fill state + italic ideology label; #id_guard_portal .guard-pronoun-trio styled small/dim/centered under the question
- billscroll aperture: padding-right 0.75rem on #id_drama_scroll inside .applet-scroll so the timestamp column no longer sits beneath the scrollbar
Code architected by Disco DeDisco <discodedisco@outlook.com >
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-04 01:11:40 -04:00
Disco DeDisco
6ad736413b
super-schizo + super-nomad Notes: auto-grant to superusers; sig unlock; navbar titles — TDD
...
- drama/models.py: _NOTE_DISPLAY dict; Note.display_title / .display_greeting
properties; super-schizo → "21st Century" + "Schizoid Man";
super-nomad → "Howdy," + "Stranger"
- billboard/views.py: _NOTE_META super-schizo/nomad entries with mark_safe
HTML descriptions ("card-ref"-styled card names), swatch_label "I"/"0",
no palette_options; swatch_label added to note_items context
- lyric/models.py post_save: new superusers get super-schizo + super-nomad
Notes automatically; setup_sig_session grants them explicitly too
- epic/models.py _filter_major_unlocks: accepts super-nomad / super-schizo
as valid unlocks alongside their plain counterparts
- _navbar.html: display_greeting|safe + display_title replace slug|capfirst
- my_notes.html: note-item__image-box--label branch for swatch_label
- _note.scss: .note-item__image-box--label modifier (bold italic, solid border)
- _base.scss: .ord global ordinal superscript class (21st etc.)
- ITs: SuperuserNoteGrantTest (3); SigSelectRenderingTest +2 (super- variants)
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:30:02 -04:00
Disco DeDisco
214120ef2d
note title equip: DON/DOFF buttons outside top-left corner; User.active_title FK; don/doff views; greeting updated via JS — TDD
...
- lyric/models.py: active_title = ForeignKey('drama.Note', null=True, SET_NULL)
- lyric migration 0020_add_active_title
- billboard/views.py: don_title + doff_title views; is_equipped per note_item context
- billboard/urls.py: note/<slug>/don + note/<slug>/doff routes
- _navbar.html: id_greeting_name span; shows active_title.slug|capfirst when set
- my_notes.html: .note-don-doff buttons (DON/DOFF, × when disabled); data-don-url/doff-url/title attrs
- note-page.js: _bindDonDoff() — DON POST sets greeting + swaps btn state; DOFF restores Earthman
- _note.scss: .note-don-doff position:absolute left:-1rem top:0; flex-direction:column gap:1.25rem
- ITs: NoteEquipTitleViewTest (5 tests); UserModelTest.test_active_title_* (3 tests)
- FT: NoteEquipTitleTest.test_don_equips_title_greeting_and_doff_restores
Code architected by Disco DeDisco <discodedisco@outlook.com >
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-23 01:44:58 -04:00
Disco DeDisco
5c05bd6552
sky: store birth_tz, prefill form from User model, drop localStorage
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-21 21:54:34 -04:00
Disco DeDisco
abf8be8861
MY SKY: dashboard applet + full-page natal chart — TDD
...
ci/woodpecker/push/pyswiss Pipeline was successful
ci/woodpecker/push/main Pipeline was successful
- User model: sky_birth_dt/lat/lon/place/house_system/chart_data fields (lyric migration 0018)
- Applet seed: my-sky (6×6, dashboard context) via applets migration 0009
- dashboard/sky/ — full monoapplet page: natus form + D3 wheel, LS key scoped to dashboard:sky; saves to User model
- dashboard/sky/preview/ — PySwiss proxy (same logic as epic:natus_preview, no seat check)
- dashboard/sky/save/ — persists 6 sky fields to User via update_fields
- _applet-my-sky.html: tile with h2 link to /dashboard/sky/
- 2 FTs (applet→link→form, localStorage persistence) + 12 ITs — all green
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-16 03:03:19 -04:00
Disco DeDisco
ca38875660
fixed reverse chronological ordering in a pair of FTs clogging the pipeline; added ActivityPub to project; new apps.ap for WebFinger, Actor, Outbox views; apps.lyric.models now contains ap_public_key, ap_private_key fields + ensure_keypair(); new apps.lyric migration accordingly; new in drama.models are to_activity() w. JoinGate, SelectRole, Create compat. & None verb support; new core.urls for /.well-known/webfinger + /ap/ included; cryptography installed, added to reqs.txt; 24 new green UTs & ITs; in sum, project is now read-only ActivityPub node
ci/woodpecker/push/woodpecker Pipeline was successful
2026-04-02 15:22:04 -04:00
Disco DeDisco
befa61e1e9
several fixes, incl. location of templates/apps/epic/tarot_deck.html to apps/gameboard/tarot_deck.html; added this convention to CLAUDE.md; Game Kit applet items now plentiful enough to bother w. text wrapping in _gameboard.scss; unlocked_decks differentiates from equipped_deck in apps.lyric.models; new migrations accordingly; apps.gameboard.views accounts for only unlocked_decks in deck_variants now; apps.epic.views redirected to new tarot_deck.html location
2026-03-24 22:25:25 -04:00
Disco DeDisco
588358a20f
added default Earthman 108-card tarot deck, 78-card Minchiate Fiorentine deck, admin tests for each; DeckVariant model governs deck toggle; ran new migrations for apps.epic, apps.lyric; seeded DeckVariant migration to ensure Earthman is default deck; added min. tarot url; most new FTs passing
2026-03-24 21:07:01 -04:00
Disco DeDisco
4239245902
add Carte Blanche trinket: equip system, gatekeeper multi-slot, mini tooltip portal; new token type Token.CARTE ('carte') with fa-money-check icon; migrations 0010-0012:
...
ci/woodpecker/push/woodpecker Pipeline failed
CARTE type, User.equipped_trinket FK, Token.slots_claimed field; post_save signal sets
equipped_trinket=COIN for new users, PASS for staff; kit bag now shows only the equipped
trinket in Trinkets section; Game Kit applet mini tooltip portal shows Equipped or Equip
Trinket per token; AJAX POST equip-trinket id updates equippedId in-place; equip btn
now works for COIN, PASS, and CARTE (data-token-id added to all three); Gatekeeper CARTE
flow: drop_token sets current_room (no slot reserved); each empty slot up to
slots_claimed+1 gets a drop-token-btn; slots_claimed high-water mark advances on fill,
never decrements; highest CARTE-filled slot gets NVM (release_slot); token_return_btn
resets current_room + slots_claimed + un-fills all CARTE slots; gate_status always returns
full template so launch-game-btn persists via HTMX when gate_status == OPEN; room.html
includes gatekeeper when GATHERING or OPEN; new FT test_trinket_carte_blanche.py (2
tests, both passing); 299 tests green
2026-03-16 00:07:52 -04:00
Disco DeDisco
ace9a4888e
updated description text on Backstage Pass to more accurately describe its unlimited capacity
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-15 17:54:58 -04:00
Disco DeDisco
74d1a43559
#id_dash_applet_menu now outside #id_applets_container to avoid clipping, other issues (FTs passed locally, but not in headless CI pipeline); selenium now calls wait_for when looking for is_displayed on kit bag menu (hopefully another CI fix)
ci/woodpecker/push/woodpecker Pipeline failed
2026-03-15 01:46:11 -04:00
Disco DeDisco
2d453dbc78
new _kit_bag_panel.html partial in core to allow user to manage equipped kit items from anywhere on site; #id_kit_btn moved from _footer.html partial directly into a base.html include; new trinket for superusers now incl. in apps.lyric.models; apps.gameboard.views handles this new type of PASS token; apps.epic.views allows payment with several different token types based on rarity & expiration hierarchy; kit bag and PASS functionality now handled in apps.dashboard.views; /kit-bag/ now pathed in .urls; styles abound; fully passing test suite (tho much work to be done, chiefly with stacking like coins in FEFO order)
ci/woodpecker/push/woodpecker Pipeline failed
2026-03-15 01:17:09 -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
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
aa1cef6e7b
new migration in apps.applets to seed wallet applet models; many expanded styles in wallet.js, chiefly concerned w. wallet-oriented FTs tbh; some intermittent Windows cache errors quashed in dash view ITs; apps.dash.views & .urls now support wallet applets; apps.lyric.models now discerns tithe coins (available for purchase soon); new styles across many scss files, again many concerning wallet applets but also applets more generally and also unorthodox media query parameters to make UX more usable; a slew of new wallet partials
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-11 00:58:24 -04:00
Disco DeDisco
791510b46d
many styling fixes, esp. for both landscape & portrait mobile UX tooltips & navbar; core.settings now permits another device on local net to access dev server
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-10 14:11:53 -04:00
Disco DeDisco
d2861077a4
tooltips now fully styled, appearing above applet container to avoid clipping issues; new methods added to apps.lyric.models.Token
2026-03-09 23:48:20 -04:00
Disco DeDisco
bd72135a2f
full passing test suite w. new stripe integration across multiple project nodes; new gameboard django app; stripe in test mode on staging
ci/woodpecker/push/woodpecker Pipeline failed
2026-03-09 01:07:16 -04:00
Disco DeDisco
076d75effe
new apps/dashboard/wallet.html for stripe payment integration and user's consumables; nav added to _footer.html & also dynamic copyright year with django now Y template; new apps.dash.tests ITs & UTs reflect new wallet functionality in .urls & .views
2026-03-08 15:14:41 -04:00
Disco DeDisco
c099479740
'theme_switcher,' 'theme-picker' & 'theme' renamed everywhere to simply 'palette'; new urls & views & their corresponding ITs ensure applet menu checkbox functionality
2026-03-05 14:45:55 -05:00
Disco DeDisco
e142e5d4d7
new FT test_theme for theme switcher functionality; theme-switcher content added to home.html, several dashboard views & urls, all appropriate ITs & UTs; lyric user model saves theme (migrations run); django-compressor and django-libsass libraries added to dependencies
2026-03-02 13:57:03 -05:00
Disco DeDisco
4aa63c74e2
added username (models.CharField) & searchable (models.BooleanField) to User model in lyric app; new ITs confirm functionality here; dashboard views now ensure that sharing a list w. an email address (as opposed to a username) neither confirms nor denies whether that email address has a registered account (ITs green)
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-01 21:19:12 -05:00
Disco DeDisco
025a59938b
reenabled admin area; outfitted apps.lyric.models w. AbstractBaseUser instead of custom user class; many other fns & several models updated to accomodate, such as set_unusable_password() method to base user model; reset staging db to prepare for refreshed lyric migrations to accomodate for retrofitted pw field
ci/woodpecker/push/woodpecker Pipeline was successful
2026-02-19 20:31:29 -05:00
Disco DeDisco
0c413a9cc2
pre–db-reset commit; attempting to update User model w. uuid pk enumeration
2026-02-07 20:15:27 -05:00
Disco DeDisco
ae63861adb
migrations run for lyric models; authentication & views & their tests now account more fully for uuid over email as pk
2026-01-30 21:33:30 -05:00
Disco DeDisco
41f4ff1725
new apps.lyric.authenticate model PasswordlessAuthenticationBackend and authenticate() function help determine Token authenticity, login to existing accounts, or create new ones; associated .tests.test_authentication class asserts this functionality; apps.lyric.models & .tests.models now handles token uid instead of id, completing the transition away from email-as-pk
2026-01-30 19:10:17 -05:00
Disco DeDisco
4b1906b1ee
new apps.lyric.urls, .tests.test_views files to test & execute mock email sending; apps.lyric.models, .tests.test_models now test & execute unique token autogen to integrate w. magic link login using only email; core.settings updated w. new urlpatterns to accommodate
2026-01-30 16:21:32 -05:00
Disco DeDisco
d724e03c3c
custom user model that maintains id as pk
2026-01-30 15:04:47 -05:00
Disco DeDisco
a734901b80
started lyric app (in earnest this time); added bootstrap-classed navbar w. login form to base.html; tweaked apps.dashboard.tests.test_views to accomodate multiple forms on same page
2026-01-29 15:21:54 -05:00