rename: Note→Post/Line (dashboard); Recognition→Note (drama); new-post/my-posts to billboard

- dashboard: Note→Post, Item→Line across models, forms, views, API, urls & tests
- new-post (9×3) & my-posts (3×3) applets migrate from dashboard→billboard context; billboard view passes form & recent_posts
- drama: Recognition→Note, related_name notes; billboard URL /recognition/→/my-notes/, set-palette at /note/<slug>/set-palette
- recognition.js→note.js (module Note, data.note key); recognition-page.js→note-page.js; .recog-*→.note-*
- _recognition.scss→_note.scss; BillNotes page header; applet slug billboard-recognition→billboard-notes (My Notes)
- NoteSpec.js replaces RecognitionSpec.js; test_recognition.py→test_applet_my_notes.py
- 4 migrations applied: dashboard 0004, applets 0011+0012, drama 0005; 683 ITs green

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-04-22 22:32:34 -04:00
parent 6d9d3d4f54
commit 473e6bc45a
54 changed files with 1373 additions and 1283 deletions

View File

@@ -3,7 +3,7 @@
sky_view — GET /dashboard/sky/ → renders sky template
sky_preview — GET /dashboard/sky/preview → proxies to PySwiss (no DB write)
sky_save — POST /dashboard/sky/save → saves natal data to User model;
grants Stargazer Recognition on first save with real chart_data
grants Stargazer Note on first save with real chart_data
"""
import json
@@ -12,7 +12,7 @@ from unittest.mock import patch, MagicMock
from django.test import TestCase
from django.urls import reverse
from apps.drama.models import Recognition
from apps.drama.models import Note
from apps.lyric.models import User
@@ -233,8 +233,8 @@ _REAL_CHART = {
}
class SkySaveRecognitionTest(TestCase):
"""sky_save grants the Stargazer Recognition on the first save with real chart_data."""
class SkySaveNoteTest(TestCase):
"""sky_save grants the Stargazer Note on the first save with real chart_data."""
def setUp(self):
self.user = User.objects.create(email="star@test.io")
@@ -256,35 +256,35 @@ class SkySaveRecognitionTest(TestCase):
content_type="application/json",
)
def test_first_save_with_chart_data_returns_stargazer_recognition(self):
def test_first_save_with_chart_data_returns_stargazer_note(self):
data = self._post().json()
self.assertIn("recognition", data)
recog = data["recognition"]
self.assertIn("note", data)
recog = data["note"]
self.assertEqual(recog["slug"], "stargazer")
self.assertIn("title", recog)
self.assertIn("description", recog)
self.assertIn("earned_at", recog)
def test_first_save_creates_recognition_in_db(self):
def test_first_save_creates_note_in_db(self):
self._post()
self.assertEqual(Recognition.objects.filter(user=self.user, slug="stargazer").count(), 1)
self.assertEqual(Note.objects.filter(user=self.user, slug="stargazer").count(), 1)
def test_second_save_returns_null_recognition(self):
def test_second_save_returns_null_note(self):
self._post()
data = self._post().json()
self.assertIsNone(data["recognition"])
self.assertIsNone(data["note"])
def test_second_save_does_not_create_duplicate_recognition(self):
def test_second_save_does_not_create_duplicate_note(self):
self._post()
self._post()
self.assertEqual(Recognition.objects.filter(user=self.user, slug="stargazer").count(), 1)
self.assertEqual(Note.objects.filter(user=self.user, slug="stargazer").count(), 1)
def test_save_with_empty_chart_data_does_not_grant_recognition(self):
def test_save_with_empty_chart_data_does_not_grant_note(self):
data = self._post(chart_data={}).json()
self.assertIsNone(data["recognition"])
self.assertEqual(Recognition.objects.filter(user=self.user, slug="stargazer").count(), 0)
self.assertIsNone(data["note"])
self.assertEqual(Note.objects.filter(user=self.user, slug="stargazer").count(), 0)
def test_save_with_null_chart_data_does_not_grant_recognition(self):
def test_save_with_null_chart_data_does_not_grant_note(self):
data = self._post(chart_data=None).json()
self.assertIsNone(data["recognition"])
self.assertEqual(Recognition.objects.filter(user=self.user, slug="stargazer").count(), 0)
self.assertIsNone(data["note"])
self.assertEqual(Note.objects.filter(user=self.user, slug="stargazer").count(), 0)