From 4651746427b4c7840c88eb1919ab1d7db5ecac2b Mon Sep 17 00:00:00 2001 From: bisco Date: Tue, 7 Apr 2026 17:41:53 +0200 Subject: [PATCH] feat: add shared scouting notes mvp --- README.md | 4 +- app/scouting/admin.py | 7 ++ app/scouting/migrations/0006_playernote.py | 30 +++++++++ app/scouting/models.py | 19 ++++++ .../templates/scouting/favorites_list.html | 1 + .../templates/scouting/player_detail.html | 26 +++++++ app/scouting/tests.py | 67 ++++++++++++++++++- app/scouting/urls.py | 2 + app/scouting/views.py | 25 ++++++- 9 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 app/scouting/migrations/0006_playernote.py diff --git a/README.md b/README.md index 6246eb6..591868e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ The current application baseline provides: - matching season/team/competition context on search results - result sorting and pagination - a shared development shortlist for favorite players +- shared plain-text scouting notes on player detail pages Accepted technical and product-shaping decisions live in: - `docs/ARCHITECTURE.md` @@ -48,7 +49,8 @@ Accepted technical and product-shaping decisions live in: 2. Apply migrations with `docker compose --env-file .env -f infra/docker-compose.yml exec -T app python manage.py migrate`. 3. Load sample data with `docker compose --env-file .env -f infra/docker-compose.yml exec -T app python manage.py seed_scouting_data`. 4. Visit `http://127.0.0.1:8000/players/` to explore the scouting search MVP. -5. Use `http://127.0.0.1:8000/favorites/` to review the shared development shortlist. +5. Use player detail pages to manage shortlist entries and shared scouting notes. +6. Use `http://127.0.0.1:8000/favorites/` to review the shared development shortlist. ## Workflow diff --git a/app/scouting/admin.py b/app/scouting/admin.py index 89b1eab..09aa45c 100644 --- a/app/scouting/admin.py +++ b/app/scouting/admin.py @@ -4,6 +4,7 @@ from .models import ( Competition, FavoritePlayer, Player, + PlayerNote, PlayerSeason, PlayerSeasonStats, Role, @@ -75,3 +76,9 @@ class PlayerSeasonStatsAdmin(admin.ModelAdmin): class FavoritePlayerAdmin(admin.ModelAdmin): list_display = ("player", "created_at") search_fields = ("player__full_name",) + + +@admin.register(PlayerNote) +class PlayerNoteAdmin(admin.ModelAdmin): + list_display = ("player", "created_at", "updated_at") + search_fields = ("player__full_name", "body") diff --git a/app/scouting/migrations/0006_playernote.py b/app/scouting/migrations/0006_playernote.py new file mode 100644 index 0000000..54c876a --- /dev/null +++ b/app/scouting/migrations/0006_playernote.py @@ -0,0 +1,30 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("scouting", "0005_favoriteplayer"), + ] + + operations = [ + migrations.CreateModel( + name="PlayerNote", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("body", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "player", + models.ForeignKey( + on_delete=models.CASCADE, + related_name="notes", + to="scouting.player", + ), + ), + ], + options={ + "ordering": ["-created_at", "-id"], + }, + ), + ] diff --git a/app/scouting/models.py b/app/scouting/models.py index a4e46ab..adfff75 100644 --- a/app/scouting/models.py +++ b/app/scouting/models.py @@ -178,3 +178,22 @@ class FavoritePlayer(models.Model): def __str__(self) -> str: return f"Favorite: {self.player.full_name}" + + +class PlayerNote(models.Model): + # Phase-2 MVP keeps notes shared within the local development environment so + # scouting observations can be used immediately without introducing auth yet. + player = models.ForeignKey( + Player, + on_delete=models.CASCADE, + related_name="notes", + ) + body = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + ordering = ["-created_at", "-id"] + + def __str__(self) -> str: + return f"Note for {self.player.full_name}" diff --git a/app/scouting/templates/scouting/favorites_list.html b/app/scouting/templates/scouting/favorites_list.html index 3ddb9cf..e26766a 100644 --- a/app/scouting/templates/scouting/favorites_list.html +++ b/app/scouting/templates/scouting/favorites_list.html @@ -16,6 +16,7 @@
  • {{ entry.player.full_name }} ({{ entry.player.position }}) + | Notes: {{ entry.note_count }}
    {% csrf_token %} diff --git a/app/scouting/templates/scouting/player_detail.html b/app/scouting/templates/scouting/player_detail.html index 9a7428c..295c279 100644 --- a/app/scouting/templates/scouting/player_detail.html +++ b/app/scouting/templates/scouting/player_detail.html @@ -51,6 +51,32 @@ {% endfor %}

    +

    Scouting Notes

    +

    Notes are shared across the local development shortlist workflow in this MVP.

    + + {% csrf_token %} + + + + +
    + + +

    Season Contexts