From b4cddf41ea5c17592ea622b15b068f8ee8eee743 Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Sun, 28 Dec 2025 12:39:28 -0800 Subject: [PATCH] feat: Initialize Fediversion multi-band platform - Fork elmeg-demo codebase for multi-band support - Add data importer infrastructure with base class - Create band-specific importers: - phish.py: Phish.net API v5 - grateful_dead.py: Grateful Stats API - setlistfm.py: Dead & Company, Billy Strings (Setlist.fm) - Add spec-kit configuration for Gemini - Update README with supported bands and architecture --- .agent/workflows/deploy.md | 73 + .forgejo/workflows/deploy.yml | 41 + .gemini/commands/speckit.analyze.toml | 188 + .gemini/commands/speckit.checklist.toml | 298 + .gemini/commands/speckit.clarify.toml | 185 + .gemini/commands/speckit.constitution.toml | 86 + .gemini/commands/speckit.implement.toml | 139 + .gemini/commands/speckit.plan.toml | 93 + .gemini/commands/speckit.specify.toml | 262 + .gemini/commands/speckit.tasks.toml | 141 + .gemini/commands/speckit.taskstoissues.toml | 34 + .gitignore | 9 + .specify/memory/constitution.md | 50 + .specify/scripts/bash/check-prerequisites.sh | 166 + .specify/scripts/bash/common.sh | 156 + .specify/scripts/bash/create-new-feature.sh | 297 + .specify/scripts/bash/setup-plan.sh | 61 + .specify/scripts/bash/update-agent-context.sh | 799 + .specify/specs/fediversion-multi-band.md | 185 + .specify/templates/agent-file-template.md | 28 + .specify/templates/checklist-template.md | 40 + .specify/templates/plan-template.md | 104 + .specify/templates/spec-template.md | 115 + .specify/templates/tasks-template.md | 251 + DEPLOY.md | 48 + LOCAL_DEV.md | 125 + README.md | 121 + VPS_HANDOFF.md | 130 + backend/Dockerfile | 11 + backend/alembic.ini | 147 + backend/alembic/README | 1 + backend/alembic/env.py | 79 + backend/alembic/script.py.mako | 28 + .../versions/1305863562e7_add_groups.py | 76 + .../32ebf231693a_add_user_preferences.py | 42 + .../341b95b6e098_add_gamification_models.py | 58 + .../366067fc1318_add_review_system.py | 48 + .../versions/65c515b4722a_add_slugs.py | 213 + .../6659cb1e0ca5_add_review_targets.py | 45 + .../83e6fd46fa2b_add_moderation_system.py | 59 + .../a0b7abe57112_add_core_enhancements.py | 122 + .../a526deda28e0_add_notifications.py | 57 + ...dd_review_created_at_and_report_details.py | 53 + .../bc32a0b7efbb_add_performance_nicknames.py | 52 + .../c26cc8212061_add_social_models.py | 59 + .../e50a60c5d343_add_user_bio_and_avatar.py | 39 + .../f5ca1b7c50b1_initial_migration.py | 113 + backend/auth.py | 61 + backend/check_missing_videos.py | 52 + backend/comprehensive_import.py | 230 + backend/database.py | 17 + backend/dependencies.py | 15 + backend/discover_audio_links.py | 213 + backend/email_service.py | 146 + backend/fast_import_setlists.py | 128 + backend/fetch_youtube.py | 207 + backend/fix_numeric_slugs.py | 89 + backend/fix_set_names.py | 108 + backend/fix_tour_dates.py | 56 + backend/fix_tours.py | 29 + backend/helpers.py | 19 + backend/import_bandcamp_catalog.py | 114 + backend/import_by_date.py | 103 + backend/import_elgoose.py | 399 + backend/import_per_show.py | 161 + backend/import_setlists_direct.py | 167 + backend/import_setlists_smart.py | 186 + backend/import_songs_only.py | 199 + backend/import_youtube.py | 255 + backend/importers/__init__.py | 4 + backend/importers/base.py | 321 + backend/importers/grateful_dead.py | 245 + backend/importers/phish.py | 246 + backend/importers/setlistfm.py | 275 + backend/inspect_api.py | 18 + backend/main.py | 62 + backend/migrate_honking.py | 159 + backend/migrations/99_fix_db_data.py | 288 + backend/migrations/add_email_verification.py | 34 + backend/migrations/add_link_columns.py | 35 + backend/migrations/add_parent_id_column.py | 15 + backend/migrations/add_rating_venue_tour.py | 43 + backend/migrations/add_reaction_table.py | 26 + backend/migrations/add_slugs.py | 225 + backend/migrations/add_youtube_links.py | 28 + backend/migrations/migrate_artists.py | 85 + backend/migrations/migrate_musicians.py | 69 + backend/models.py | 427 + backend/models_tickets.py | 140 + backend/populate_links.py | 155 + backend/quick_seed.py | 118 + backend/repro_review_crash.py | 57 + backend/requirements.txt | 15 + backend/routers/admin.py | 652 + backend/routers/artists.py | 50 + backend/routers/attendance.py | 84 + backend/routers/auth.py | 192 + backend/routers/badges.py | 32 + backend/routers/chase.py | 327 + backend/routers/feed.py | 131 + backend/routers/gamification.py | 371 + backend/routers/groups.py | 128 + backend/routers/leaderboards.py | 135 + backend/routers/moderation.py | 330 + backend/routers/musicians.py | 138 + backend/routers/nicknames.py | 44 + backend/routers/notifications.py | 77 + backend/routers/performances.py | 198 + backend/routers/preferences.py | 42 + backend/routers/reviews.py | 93 + backend/routers/search.py | 122 + backend/routers/sequences.py | 213 + backend/routers/shows.py | 117 + backend/routers/social.py | 285 + backend/routers/songs.py | 112 + backend/routers/stats.py | 26 + backend/routers/tickets.py | 371 + backend/routers/tours.py | 65 + backend/routers/users.py | 411 + backend/routers/venues.py | 42 + backend/routers/videos.py | 130 + backend/schemas.py | 401 + backend/scripts/cron_weekly_digest.sh | 6 + backend/seed.py | 52 + backend/seed_activity.py | 399 + backend/seed_demo.py | 300 + backend/seed_output.txt | 72 + backend/seed_ratings.py | 64 + backend/services/chase_notifications.py | 87 + backend/services/email_service.py | 363 + backend/services/gamification.py | 488 + backend/services/stats.py | 81 + backend/services/weekly_digest.py | 220 + backend/slugify.py | 134 + backend/start.sh | 17 + backend/sync_artists.py | 104 + backend/test_seed.py | 13 + backend/test_smtp_connection.py | 110 + backend/tests/conftest.py | 56 + backend/tests/test_shows.py | 70 + backend/youtube_videos.json | 4962 ++++++ docker-compose.yml | 182 + docs/API.md | 26 + docs/AUDIT_AND_PLAN.md | 295 + docs/AWS_SES_BROWSER_AGENT.md | 127 + docs/AWS_SES_SETUP.md | 141 + docs/BANDCAMP_NUGS_SPEC.md | 217 + docs/BUGS_TRACKER_SPEC.md | 248 + docs/CHANGELOG.md | 67 + docs/DEVELOPER.md | 118 + docs/HANDOFF_2025_12_21.md | 62 + docs/HANDOFF_2025_12_22.md | 36 + docs/INFRASTRUCTURE_STANDARDS.md | 100 + docs/MAILGUN_SETUP.md | 233 + docs/PLATFORM_ENHANCEMENT_SPEC.md | 323 + docs/ROADMAP.md | 241 + docs/USER_GUIDE.md | 59 + docs/VIDEO_INTEGRATION_SPEC.md | 177 + email/README.md | 147 + email/package-lock.json | 5183 +++++++ email/package.json | 33 + email/scripts/deploy-templates.ts | 234 + email/src/email-service.ts | 209 + email/src/examples.ts | 176 + email/templates/README.md | 306 + email/tsconfig.json | 26 + frontend/.gitignore | 41 + frontend/Dockerfile | 11 + frontend/README.md | 36 + frontend/__tests__/badge-list.test.tsx | 18 + frontend/app/about/page.tsx | 96 + frontend/app/admin/artists/page.tsx | 237 + frontend/app/admin/layout.tsx | 93 + frontend/app/admin/musicians/page.tsx | 260 + frontend/app/admin/nicknames/page.tsx | 12 + frontend/app/admin/page.tsx | 413 + frontend/app/admin/reports/page.tsx | 12 + frontend/app/admin/sequences/page.tsx | 486 + frontend/app/admin/shows/page.tsx | 300 + frontend/app/admin/songs/page.tsx | 237 + frontend/app/admin/venues/page.tsx | 253 + frontend/app/archive/page.tsx | 29 + frontend/app/artists/[slug]/page.tsx | 161 + frontend/app/bugs/known-issues/page.tsx | 143 + frontend/app/bugs/my-tickets/page.tsx | 146 + frontend/app/bugs/page.tsx | 298 + frontend/app/bugs/ticket/[id]/page.tsx | 241 + frontend/app/favicon.ico | Bin 0 -> 25931 bytes frontend/app/forgot-password/page.tsx | 110 + frontend/app/globals.css | 143 + frontend/app/groups/[id]/page.tsx | 83 + frontend/app/groups/create/page.tsx | 104 + frontend/app/groups/page.tsx | 69 + frontend/app/icon.png | Bin 0 -> 408682 bytes frontend/app/layout.tsx | 63 + frontend/app/leaderboards/page.tsx | 290 + frontend/app/login/page.tsx | 108 + frontend/app/mod/page.tsx | 594 + frontend/app/not-found.tsx | 125 + frontend/app/page.tsx | 253 + frontend/app/performances/[slug]/page.tsx | 398 + frontend/app/performances/page.tsx | 142 + frontend/app/privacy/page.tsx | 192 + frontend/app/profile/[slug]/page.tsx | 158 + frontend/app/profile/page.tsx | 268 + frontend/app/register/page.tsx | 138 + frontend/app/reset-password/page.tsx | 171 + frontend/app/robots.ts | 12 + frontend/app/settings/page.tsx | 778 + frontend/app/shows/[slug]/loading.tsx | 57 + frontend/app/shows/[slug]/page.tsx | 376 + frontend/app/shows/loading.tsx | 23 + frontend/app/shows/page.tsx | 146 + frontend/app/shows/upcoming/page.tsx | 121 + frontend/app/sitemap.ts | 22 + frontend/app/songs/[slug]/page.tsx | 238 + frontend/app/songs/loading.tsx | 19 + frontend/app/songs/page.tsx | 70 + frontend/app/terms/page.tsx | 151 + frontend/app/tours/[slug]/page.tsx | 171 + frontend/app/tours/page.tsx | 93 + frontend/app/venues/[slug]/page.tsx | 254 + frontend/app/venues/page.tsx | 231 + frontend/app/verify-email/page.tsx | 107 + frontend/app/videos/page.tsx | 315 + frontend/app/welcome/page.tsx | 241 + frontend/components.json | 22 + frontend/components/admin/nickname-queue.tsx | 155 + frontend/components/admin/report-queue.tsx | 91 + .../components/chase/mark-caught-button.tsx | 112 + frontend/components/feed/activity-feed.tsx | 161 + .../gamification/level-progress.tsx | 147 + .../gamification/xp-leaderboard.tsx | 149 + frontend/components/groups/group-feed.tsx | 80 + .../components/groups/join-group-button.tsx | 51 + frontend/components/layout/footer.tsx | 71 + frontend/components/layout/navbar.tsx | 223 + .../components/layout/notification-bell.tsx | 140 + .../notifications/notification-bell.tsx | 170 + .../components/profile/attendance-summary.tsx | 209 + .../components/profile/avatar-settings.tsx | 149 + frontend/components/profile/badge-list.tsx | 43 + .../components/profile/chase-songs-list.tsx | 259 + .../profile/user-attendance-list.tsx | 61 + .../components/profile/user-groups-list.tsx | 54 + .../components/profile/user-reviews-list.tsx | 46 + .../components/reviews/entity-reviews.tsx | 135 + frontend/components/reviews/review-card.tsx | 77 + frontend/components/reviews/review-form.tsx | 74 + frontend/components/shows/show-attendance.tsx | 87 + .../shows/suggest-nickname-dialog.tsx | 117 + .../components/social/comment-section.tsx | 117 + frontend/components/social/entity-rating.tsx | 162 + frontend/components/social/social-wrapper.tsx | 22 + .../components/songs/performance-list.tsx | 150 + .../songs/rate-performance-dialog.tsx | 109 + .../components/songs/song-evolution-chart.tsx | 132 + frontend/components/theme-provider.tsx | 11 + frontend/components/theme-toggle.tsx | 58 + frontend/components/ui/attendance-button.tsx | 42 + frontend/components/ui/avatar.tsx | 62 + frontend/components/ui/badge.tsx | 35 + frontend/components/ui/button.tsx | 59 + frontend/components/ui/card.tsx | 78 + frontend/components/ui/checkbox.tsx | 30 + frontend/components/ui/command.tsx | 193 + frontend/components/ui/comment-section.tsx | 62 + frontend/components/ui/dialog.tsx | 143 + frontend/components/ui/dropdown-menu.tsx | 200 + frontend/components/ui/input.tsx | 25 + frontend/components/ui/label.tsx | 24 + frontend/components/ui/popover.tsx | 48 + frontend/components/ui/progress.tsx | 28 + frontend/components/ui/radio-group.tsx | 44 + frontend/components/ui/rating-input.tsx | 192 + frontend/components/ui/scroll-area.tsx | 48 + frontend/components/ui/search-dialog.tsx | 217 + frontend/components/ui/select.tsx | 160 + frontend/components/ui/separator.tsx | 28 + frontend/components/ui/skeleton.tsx | 97 + frontend/components/ui/star-rating.tsx | 125 + frontend/components/ui/switch.tsx | 40 + frontend/components/ui/tabs.tsx | 66 + frontend/components/ui/textarea.tsx | 24 + frontend/components/ui/user-avatar.tsx | 42 + frontend/components/ui/wiki-text.tsx | 61 + frontend/components/ui/youtube-embed.tsx | 45 + frontend/contexts/auth-context.tsx | 90 + frontend/contexts/preferences-context.tsx | 98 + frontend/eslint.config.mjs | 18 + frontend/jest.config.js | 18 + frontend/jest.setup.js | 1 + frontend/lib/api-config.ts | 12 + frontend/lib/utils.ts | 6 + frontend/next.config.ts | 23 + frontend/package-lock.json | 12654 ++++++++++++++++ frontend/package.json | 53 + frontend/postcss.config.mjs | 7 + frontend/public/file.svg | 1 + frontend/public/globe.svg | 1 + frontend/public/next.svg | 1 + frontend/public/vercel.svg | 1 + frontend/public/window.svg | 1 + frontend/tsconfig.json | 34 + traefik-routes.yml | 77 + youtube.md | 38 + 306 files changed, 62807 insertions(+) create mode 100644 .agent/workflows/deploy.md create mode 100644 .forgejo/workflows/deploy.yml create mode 100644 .gemini/commands/speckit.analyze.toml create mode 100644 .gemini/commands/speckit.checklist.toml create mode 100644 .gemini/commands/speckit.clarify.toml create mode 100644 .gemini/commands/speckit.constitution.toml create mode 100644 .gemini/commands/speckit.implement.toml create mode 100644 .gemini/commands/speckit.plan.toml create mode 100644 .gemini/commands/speckit.specify.toml create mode 100644 .gemini/commands/speckit.tasks.toml create mode 100644 .gemini/commands/speckit.taskstoissues.toml create mode 100644 .gitignore create mode 100644 .specify/memory/constitution.md create mode 100755 .specify/scripts/bash/check-prerequisites.sh create mode 100755 .specify/scripts/bash/common.sh create mode 100755 .specify/scripts/bash/create-new-feature.sh create mode 100755 .specify/scripts/bash/setup-plan.sh create mode 100755 .specify/scripts/bash/update-agent-context.sh create mode 100644 .specify/specs/fediversion-multi-band.md create mode 100644 .specify/templates/agent-file-template.md create mode 100644 .specify/templates/checklist-template.md create mode 100644 .specify/templates/plan-template.md create mode 100644 .specify/templates/spec-template.md create mode 100644 .specify/templates/tasks-template.md create mode 100644 DEPLOY.md create mode 100644 LOCAL_DEV.md create mode 100644 README.md create mode 100644 VPS_HANDOFF.md create mode 100644 backend/Dockerfile create mode 100644 backend/alembic.ini create mode 100644 backend/alembic/README create mode 100644 backend/alembic/env.py create mode 100644 backend/alembic/script.py.mako create mode 100644 backend/alembic/versions/1305863562e7_add_groups.py create mode 100644 backend/alembic/versions/32ebf231693a_add_user_preferences.py create mode 100644 backend/alembic/versions/341b95b6e098_add_gamification_models.py create mode 100644 backend/alembic/versions/366067fc1318_add_review_system.py create mode 100644 backend/alembic/versions/65c515b4722a_add_slugs.py create mode 100644 backend/alembic/versions/6659cb1e0ca5_add_review_targets.py create mode 100644 backend/alembic/versions/83e6fd46fa2b_add_moderation_system.py create mode 100644 backend/alembic/versions/a0b7abe57112_add_core_enhancements.py create mode 100644 backend/alembic/versions/a526deda28e0_add_notifications.py create mode 100644 backend/alembic/versions/b16ef2228130_add_review_created_at_and_report_details.py create mode 100644 backend/alembic/versions/bc32a0b7efbb_add_performance_nicknames.py create mode 100644 backend/alembic/versions/c26cc8212061_add_social_models.py create mode 100644 backend/alembic/versions/e50a60c5d343_add_user_bio_and_avatar.py create mode 100644 backend/alembic/versions/f5ca1b7c50b1_initial_migration.py create mode 100644 backend/auth.py create mode 100644 backend/check_missing_videos.py create mode 100644 backend/comprehensive_import.py create mode 100644 backend/database.py create mode 100644 backend/dependencies.py create mode 100644 backend/discover_audio_links.py create mode 100644 backend/email_service.py create mode 100644 backend/fast_import_setlists.py create mode 100644 backend/fetch_youtube.py create mode 100644 backend/fix_numeric_slugs.py create mode 100644 backend/fix_set_names.py create mode 100644 backend/fix_tour_dates.py create mode 100644 backend/fix_tours.py create mode 100644 backend/helpers.py create mode 100644 backend/import_bandcamp_catalog.py create mode 100644 backend/import_by_date.py create mode 100644 backend/import_elgoose.py create mode 100644 backend/import_per_show.py create mode 100644 backend/import_setlists_direct.py create mode 100644 backend/import_setlists_smart.py create mode 100644 backend/import_songs_only.py create mode 100644 backend/import_youtube.py create mode 100644 backend/importers/__init__.py create mode 100644 backend/importers/base.py create mode 100644 backend/importers/grateful_dead.py create mode 100644 backend/importers/phish.py create mode 100644 backend/importers/setlistfm.py create mode 100644 backend/inspect_api.py create mode 100644 backend/main.py create mode 100644 backend/migrate_honking.py create mode 100644 backend/migrations/99_fix_db_data.py create mode 100644 backend/migrations/add_email_verification.py create mode 100644 backend/migrations/add_link_columns.py create mode 100644 backend/migrations/add_parent_id_column.py create mode 100644 backend/migrations/add_rating_venue_tour.py create mode 100644 backend/migrations/add_reaction_table.py create mode 100644 backend/migrations/add_slugs.py create mode 100644 backend/migrations/add_youtube_links.py create mode 100644 backend/migrations/migrate_artists.py create mode 100644 backend/migrations/migrate_musicians.py create mode 100644 backend/models.py create mode 100644 backend/models_tickets.py create mode 100644 backend/populate_links.py create mode 100644 backend/quick_seed.py create mode 100644 backend/repro_review_crash.py create mode 100644 backend/requirements.txt create mode 100644 backend/routers/admin.py create mode 100644 backend/routers/artists.py create mode 100644 backend/routers/attendance.py create mode 100644 backend/routers/auth.py create mode 100644 backend/routers/badges.py create mode 100644 backend/routers/chase.py create mode 100644 backend/routers/feed.py create mode 100644 backend/routers/gamification.py create mode 100644 backend/routers/groups.py create mode 100644 backend/routers/leaderboards.py create mode 100644 backend/routers/moderation.py create mode 100644 backend/routers/musicians.py create mode 100644 backend/routers/nicknames.py create mode 100644 backend/routers/notifications.py create mode 100644 backend/routers/performances.py create mode 100644 backend/routers/preferences.py create mode 100644 backend/routers/reviews.py create mode 100644 backend/routers/search.py create mode 100644 backend/routers/sequences.py create mode 100644 backend/routers/shows.py create mode 100644 backend/routers/social.py create mode 100644 backend/routers/songs.py create mode 100644 backend/routers/stats.py create mode 100644 backend/routers/tickets.py create mode 100644 backend/routers/tours.py create mode 100644 backend/routers/users.py create mode 100644 backend/routers/venues.py create mode 100644 backend/routers/videos.py create mode 100644 backend/schemas.py create mode 100644 backend/scripts/cron_weekly_digest.sh create mode 100644 backend/seed.py create mode 100644 backend/seed_activity.py create mode 100644 backend/seed_demo.py create mode 100644 backend/seed_output.txt create mode 100644 backend/seed_ratings.py create mode 100644 backend/services/chase_notifications.py create mode 100644 backend/services/email_service.py create mode 100644 backend/services/gamification.py create mode 100644 backend/services/stats.py create mode 100644 backend/services/weekly_digest.py create mode 100644 backend/slugify.py create mode 100644 backend/start.sh create mode 100644 backend/sync_artists.py create mode 100644 backend/test_seed.py create mode 100644 backend/test_smtp_connection.py create mode 100644 backend/tests/conftest.py create mode 100644 backend/tests/test_shows.py create mode 100644 backend/youtube_videos.json create mode 100644 docker-compose.yml create mode 100644 docs/API.md create mode 100644 docs/AUDIT_AND_PLAN.md create mode 100644 docs/AWS_SES_BROWSER_AGENT.md create mode 100644 docs/AWS_SES_SETUP.md create mode 100644 docs/BANDCAMP_NUGS_SPEC.md create mode 100644 docs/BUGS_TRACKER_SPEC.md create mode 100644 docs/CHANGELOG.md create mode 100644 docs/DEVELOPER.md create mode 100644 docs/HANDOFF_2025_12_21.md create mode 100644 docs/HANDOFF_2025_12_22.md create mode 100644 docs/INFRASTRUCTURE_STANDARDS.md create mode 100644 docs/MAILGUN_SETUP.md create mode 100644 docs/PLATFORM_ENHANCEMENT_SPEC.md create mode 100644 docs/ROADMAP.md create mode 100644 docs/USER_GUIDE.md create mode 100644 docs/VIDEO_INTEGRATION_SPEC.md create mode 100644 email/README.md create mode 100644 email/package-lock.json create mode 100644 email/package.json create mode 100644 email/scripts/deploy-templates.ts create mode 100644 email/src/email-service.ts create mode 100644 email/src/examples.ts create mode 100644 email/templates/README.md create mode 100644 email/tsconfig.json create mode 100644 frontend/.gitignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/README.md create mode 100644 frontend/__tests__/badge-list.test.tsx create mode 100644 frontend/app/about/page.tsx create mode 100644 frontend/app/admin/artists/page.tsx create mode 100644 frontend/app/admin/layout.tsx create mode 100644 frontend/app/admin/musicians/page.tsx create mode 100644 frontend/app/admin/nicknames/page.tsx create mode 100644 frontend/app/admin/page.tsx create mode 100644 frontend/app/admin/reports/page.tsx create mode 100644 frontend/app/admin/sequences/page.tsx create mode 100644 frontend/app/admin/shows/page.tsx create mode 100644 frontend/app/admin/songs/page.tsx create mode 100644 frontend/app/admin/venues/page.tsx create mode 100644 frontend/app/archive/page.tsx create mode 100644 frontend/app/artists/[slug]/page.tsx create mode 100644 frontend/app/bugs/known-issues/page.tsx create mode 100644 frontend/app/bugs/my-tickets/page.tsx create mode 100644 frontend/app/bugs/page.tsx create mode 100644 frontend/app/bugs/ticket/[id]/page.tsx create mode 100644 frontend/app/favicon.ico create mode 100644 frontend/app/forgot-password/page.tsx create mode 100644 frontend/app/globals.css create mode 100644 frontend/app/groups/[id]/page.tsx create mode 100644 frontend/app/groups/create/page.tsx create mode 100644 frontend/app/groups/page.tsx create mode 100644 frontend/app/icon.png create mode 100644 frontend/app/layout.tsx create mode 100644 frontend/app/leaderboards/page.tsx create mode 100644 frontend/app/login/page.tsx create mode 100644 frontend/app/mod/page.tsx create mode 100644 frontend/app/not-found.tsx create mode 100644 frontend/app/page.tsx create mode 100644 frontend/app/performances/[slug]/page.tsx create mode 100644 frontend/app/performances/page.tsx create mode 100644 frontend/app/privacy/page.tsx create mode 100644 frontend/app/profile/[slug]/page.tsx create mode 100644 frontend/app/profile/page.tsx create mode 100644 frontend/app/register/page.tsx create mode 100644 frontend/app/reset-password/page.tsx create mode 100644 frontend/app/robots.ts create mode 100644 frontend/app/settings/page.tsx create mode 100644 frontend/app/shows/[slug]/loading.tsx create mode 100644 frontend/app/shows/[slug]/page.tsx create mode 100644 frontend/app/shows/loading.tsx create mode 100644 frontend/app/shows/page.tsx create mode 100644 frontend/app/shows/upcoming/page.tsx create mode 100644 frontend/app/sitemap.ts create mode 100644 frontend/app/songs/[slug]/page.tsx create mode 100644 frontend/app/songs/loading.tsx create mode 100644 frontend/app/songs/page.tsx create mode 100644 frontend/app/terms/page.tsx create mode 100644 frontend/app/tours/[slug]/page.tsx create mode 100644 frontend/app/tours/page.tsx create mode 100644 frontend/app/venues/[slug]/page.tsx create mode 100644 frontend/app/venues/page.tsx create mode 100644 frontend/app/verify-email/page.tsx create mode 100644 frontend/app/videos/page.tsx create mode 100644 frontend/app/welcome/page.tsx create mode 100644 frontend/components.json create mode 100644 frontend/components/admin/nickname-queue.tsx create mode 100644 frontend/components/admin/report-queue.tsx create mode 100644 frontend/components/chase/mark-caught-button.tsx create mode 100644 frontend/components/feed/activity-feed.tsx create mode 100644 frontend/components/gamification/level-progress.tsx create mode 100644 frontend/components/gamification/xp-leaderboard.tsx create mode 100644 frontend/components/groups/group-feed.tsx create mode 100644 frontend/components/groups/join-group-button.tsx create mode 100644 frontend/components/layout/footer.tsx create mode 100644 frontend/components/layout/navbar.tsx create mode 100644 frontend/components/layout/notification-bell.tsx create mode 100644 frontend/components/notifications/notification-bell.tsx create mode 100644 frontend/components/profile/attendance-summary.tsx create mode 100644 frontend/components/profile/avatar-settings.tsx create mode 100644 frontend/components/profile/badge-list.tsx create mode 100644 frontend/components/profile/chase-songs-list.tsx create mode 100644 frontend/components/profile/user-attendance-list.tsx create mode 100644 frontend/components/profile/user-groups-list.tsx create mode 100644 frontend/components/profile/user-reviews-list.tsx create mode 100644 frontend/components/reviews/entity-reviews.tsx create mode 100644 frontend/components/reviews/review-card.tsx create mode 100644 frontend/components/reviews/review-form.tsx create mode 100644 frontend/components/shows/show-attendance.tsx create mode 100644 frontend/components/shows/suggest-nickname-dialog.tsx create mode 100644 frontend/components/social/comment-section.tsx create mode 100644 frontend/components/social/entity-rating.tsx create mode 100644 frontend/components/social/social-wrapper.tsx create mode 100644 frontend/components/songs/performance-list.tsx create mode 100644 frontend/components/songs/rate-performance-dialog.tsx create mode 100644 frontend/components/songs/song-evolution-chart.tsx create mode 100644 frontend/components/theme-provider.tsx create mode 100644 frontend/components/theme-toggle.tsx create mode 100644 frontend/components/ui/attendance-button.tsx create mode 100644 frontend/components/ui/avatar.tsx create mode 100644 frontend/components/ui/badge.tsx create mode 100644 frontend/components/ui/button.tsx create mode 100644 frontend/components/ui/card.tsx create mode 100644 frontend/components/ui/checkbox.tsx create mode 100644 frontend/components/ui/command.tsx create mode 100644 frontend/components/ui/comment-section.tsx create mode 100644 frontend/components/ui/dialog.tsx create mode 100644 frontend/components/ui/dropdown-menu.tsx create mode 100644 frontend/components/ui/input.tsx create mode 100644 frontend/components/ui/label.tsx create mode 100644 frontend/components/ui/popover.tsx create mode 100644 frontend/components/ui/progress.tsx create mode 100644 frontend/components/ui/radio-group.tsx create mode 100644 frontend/components/ui/rating-input.tsx create mode 100644 frontend/components/ui/scroll-area.tsx create mode 100644 frontend/components/ui/search-dialog.tsx create mode 100644 frontend/components/ui/select.tsx create mode 100644 frontend/components/ui/separator.tsx create mode 100644 frontend/components/ui/skeleton.tsx create mode 100644 frontend/components/ui/star-rating.tsx create mode 100644 frontend/components/ui/switch.tsx create mode 100644 frontend/components/ui/tabs.tsx create mode 100644 frontend/components/ui/textarea.tsx create mode 100644 frontend/components/ui/user-avatar.tsx create mode 100644 frontend/components/ui/wiki-text.tsx create mode 100644 frontend/components/ui/youtube-embed.tsx create mode 100644 frontend/contexts/auth-context.tsx create mode 100644 frontend/contexts/preferences-context.tsx create mode 100644 frontend/eslint.config.mjs create mode 100644 frontend/jest.config.js create mode 100644 frontend/jest.setup.js create mode 100644 frontend/lib/api-config.ts create mode 100644 frontend/lib/utils.ts create mode 100644 frontend/next.config.ts create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/postcss.config.mjs create mode 100644 frontend/public/file.svg create mode 100644 frontend/public/globe.svg create mode 100644 frontend/public/next.svg create mode 100644 frontend/public/vercel.svg create mode 100644 frontend/public/window.svg create mode 100644 frontend/tsconfig.json create mode 100644 traefik-routes.yml create mode 100644 youtube.md diff --git a/.agent/workflows/deploy.md b/.agent/workflows/deploy.md new file mode 100644 index 0000000..3111e70 --- /dev/null +++ b/.agent/workflows/deploy.md @@ -0,0 +1,73 @@ +--- +description: how to deploy elmeg changes safely +--- + +# Elmeg Safe Deployment + +## CRITICAL: Never wipe the database + +When deploying changes to elmeg, **ONLY rebuild the backend and frontend containers**. The database must NEVER be rebuilt or recreated. + +## Safe deployment command + +### Production (`elmeg.xyz`) - tangible-aacorn + +```bash +# turbo +ssh tangible-aacorn "cd /srv/containers/elmeg-demo && git pull && docker compose up -d --build --no-deps backend frontend" +``` + +### Staging (`elmeg.runfoo.run`) - nexus-vector + +```bash +# turbo +ssh nexus-vector "cd /srv/containers/elmeg-demo && git pull && docker compose up -d --build --no-deps backend frontend" +``` + +## DANGEROUS - Do NOT use these commands + +```bash +# These will WIPE THE DATABASE: +docker compose up -d --build # Rebuilds ALL containers including db +docker compose down && docker compose up -d # Recreates all containers +docker compose up -d --force-recreate # Force recreates all +``` + +## Backup before any deployment (optional but recommended) + +```bash +# turbo +ssh nexus-vector "docker exec elmeg-demo-db-1 pg_dump -U elmeg elmeg > /srv/containers/elmeg-demo/backup-\$(date +%Y%m%d-%H%M%S).sql" +``` + +## Restore from backup if needed + +```bash +ssh nexus-vector "cat /srv/containers/elmeg-demo/backup-YYYYMMDD-HHMMSS.sql | docker exec -i elmeg-demo-db-1 psql -U elmeg elmeg" +``` + +## Data Import (Recovery) + +If the database is wiped or fresh, use the Smart Import script to populate shows and setlists. This script is memory-optimized and checks for infinite loops. + +### Production (tangible-aacorn) + +```bash +ssh tangible-aacorn "docker exec elmeg-backend-1 python import_setlists_smart.py" +``` + +### Staging (nexus-vector) + +```bash +ssh nexus-vector "docker exec elmeg-demo-backend-1 python import_setlists_smart.py" +``` + +## Git Configuration (Production) + +To ensure `git pull` works correctly on production: + +```bash +# On nexus-vector +cd /srv/containers/elmeg-demo +git branch --set-upstream-to=origin/main main +``` diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml new file mode 100644 index 0000000..fa21561 --- /dev/null +++ b/.forgejo/workflows/deploy.yml @@ -0,0 +1,41 @@ +name: Deploy Elmeg + +on: + push: + branches: + - testing + - production + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set deployment target + id: target + run: | + if [ "${{ github.ref_name }}" = "testing" ]; then + echo "server=nexus-vector" >> $GITHUB_OUTPUT + echo "domain=elmeg.runfoo.run" >> $GITHUB_OUTPUT + elif [ "${{ github.ref_name }}" = "production" ]; then + echo "server=tangible-aacorn" >> $GITHUB_OUTPUT + echo "domain=elmeg.xyz" >> $GITHUB_OUTPUT + fi + + - name: Deploy to ${{ steps.target.outputs.server }} + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ steps.target.outputs.server == 'nexus-vector' && '216.158.230.94' || '159.69.219.254' }} + username: root + key: ${{ secrets.DEPLOY_SSH_KEY }} + script: | + cd /srv/containers/elmeg-demo + git fetch origin ${{ github.ref_name }} + git checkout ${{ github.ref_name }} + git reset --hard origin/${{ github.ref_name }} + docker compose build --no-cache + docker compose up -d + docker compose exec -T backend alembic upgrade head + echo "Deployed ${{ github.ref_name }} to ${{ steps.target.outputs.domain }}" diff --git a/.gemini/commands/speckit.analyze.toml b/.gemini/commands/speckit.analyze.toml new file mode 100644 index 0000000..fbc847c --- /dev/null +++ b/.gemini/commands/speckit.analyze.toml @@ -0,0 +1,188 @@ +description = "Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation." + +prompt = """ +--- +description: Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation. +--- + +## User Input + +```text +$ARGUMENTS +``` + +You **MUST** consider the user input before proceeding (if not empty). + +## Goal + +Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/speckit.tasks` has successfully produced a complete `tasks.md`. + +## Operating Constraints + +**STRICTLY READ-ONLY**: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually). + +**Constitution Authority**: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/speckit.analyze`. + +## Execution Steps + +### 1. Initialize Analysis Context + +Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths: + +- SPEC = FEATURE_DIR/spec.md +- PLAN = FEATURE_DIR/plan.md +- TASKS = FEATURE_DIR/tasks.md + +Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command). +For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\\''m Groot' (or double-quote if possible: "I'm Groot"). + +### 2. Load Artifacts (Progressive Disclosure) + +Load only the minimal necessary context from each artifact: + +**From spec.md:** + +- Overview/Context +- Functional Requirements +- Non-Functional Requirements +- User Stories +- Edge Cases (if present) + +**From plan.md:** + +- Architecture/stack choices +- Data Model references +- Phases +- Technical constraints + +**From tasks.md:** + +- Task IDs +- Descriptions +- Phase grouping +- Parallel markers [P] +- Referenced file paths + +**From constitution:** + +- Load `.specify/memory/constitution.md` for principle validation + +### 3. Build Semantic Models + +Create internal representations (do not include raw artifacts in output): + +- **Requirements inventory**: Each functional + non-functional requirement with a stable key (derive slug based on imperative phrase; e.g., "User can upload file" → `user-can-upload-file`) +- **User story/action inventory**: Discrete user actions with acceptance criteria +- **Task coverage mapping**: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases) +- **Constitution rule set**: Extract principle names and MUST/SHOULD normative statements + +### 4. Detection Passes (Token-Efficient Analysis) + +Focus on high-signal findings. Limit to 50 findings total; aggregate remainder in overflow summary. + +#### A. Duplication Detection + +- Identify near-duplicate requirements +- Mark lower-quality phrasing for consolidation + +#### B. Ambiguity Detection + +- Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria +- Flag unresolved placeholders (TODO, TKTK, ???, ``, etc.) + +#### C. Underspecification + +- Requirements with verbs but missing object or measurable outcome +- User stories missing acceptance criteria alignment +- Tasks referencing files or components not defined in spec/plan + +#### D. Constitution Alignment + +- Any requirement or plan element conflicting with a MUST principle +- Missing mandated sections or quality gates from constitution + +#### E. Coverage Gaps + +- Requirements with zero associated tasks +- Tasks with no mapped requirement/story +- Non-functional requirements not reflected in tasks (e.g., performance, security) + +#### F. Inconsistency + +- Terminology drift (same concept named differently across files) +- Data entities referenced in plan but absent in spec (or vice versa) +- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note) +- Conflicting requirements (e.g., one requires Next.js while other specifies Vue) + +### 5. Severity Assignment + +Use this heuristic to prioritize findings: + +- **CRITICAL**: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality +- **HIGH**: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion +- **MEDIUM**: Terminology drift, missing non-functional task coverage, underspecified edge case +- **LOW**: Style/wording improvements, minor redundancy not affecting execution order + +### 6. Produce Compact Analysis Report + +Output a Markdown report (no file writes) with the following structure: + +## Specification Analysis Report + +| ID | Category | Severity | Location(s) | Summary | Recommendation | +|----|----------|----------|-------------|---------|----------------| +| A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version | + +(Add one row per finding; generate stable IDs prefixed by category initial.) + +**Coverage Summary Table:** + +| Requirement Key | Has Task? | Task IDs | Notes | +|-----------------|-----------|----------|-------| + +**Constitution Alignment Issues:** (if any) + +**Unmapped Tasks:** (if any) + +**Metrics:** + +- Total Requirements +- Total Tasks +- Coverage % (requirements with >=1 task) +- Ambiguity Count +- Duplication Count +- Critical Issues Count + +### 7. Provide Next Actions + +At end of report, output a concise Next Actions block: + +- If CRITICAL issues exist: Recommend resolving before `/speckit.implement` +- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions +- Provide explicit command suggestions: e.g., "Run /speckit.specify with refinement", "Run /speckit.plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'" + +### 8. Offer Remediation + +Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.) + +## Operating Principles + +### Context Efficiency + +- **Minimal high-signal tokens**: Focus on actionable findings, not exhaustive documentation +- **Progressive disclosure**: Load artifacts incrementally; don't dump all content into analysis +- **Token-efficient output**: Limit findings table to 50 rows; summarize overflow +- **Deterministic results**: Rerunning without changes should produce consistent IDs and counts + +### Analysis Guidelines + +- **NEVER modify files** (this is read-only analysis) +- **NEVER hallucinate missing sections** (if absent, report them accurately) +- **Prioritize constitution violations** (these are always CRITICAL) +- **Use examples over exhaustive rules** (cite specific instances, not generic patterns) +- **Report zero issues gracefully** (emit success report with coverage statistics) + +## Context + +{{args}} +""" diff --git a/.gemini/commands/speckit.checklist.toml b/.gemini/commands/speckit.checklist.toml new file mode 100644 index 0000000..7951c88 --- /dev/null +++ b/.gemini/commands/speckit.checklist.toml @@ -0,0 +1,298 @@ +description = "Generate a custom checklist for the current feature based on user requirements." + +prompt = """ +--- +description: Generate a custom checklist for the current feature based on user requirements. +--- + +## Checklist Purpose: "Unit Tests for English" + +**CRITICAL CONCEPT**: Checklists are **UNIT TESTS FOR REQUIREMENTS WRITING** - they validate the quality, clarity, and completeness of requirements in a given domain. + +**NOT for verification/testing**: + +- ❌ NOT "Verify the button clicks correctly" +- ❌ NOT "Test error handling works" +- ❌ NOT "Confirm the API returns 200" +- ❌ NOT checking if code/implementation matches the spec + +**FOR requirements quality validation**: + +- ✅ "Are visual hierarchy requirements defined for all card types?" (completeness) +- ✅ "Is 'prominent display' quantified with specific sizing/positioning?" (clarity) +- ✅ "Are hover state requirements consistent across all interactive elements?" (consistency) +- ✅ "Are accessibility requirements defined for keyboard navigation?" (coverage) +- ✅ "Does the spec define what happens when logo image fails to load?" (edge cases) + +**Metaphor**: If your spec is code written in English, the checklist is its unit test suite. You're testing whether the requirements are well-written, complete, unambiguous, and ready for implementation - NOT whether the implementation works. + +## User Input + +```text +$ARGUMENTS +``` + +You **MUST** consider the user input before proceeding (if not empty). + +## Execution Steps + +1. **Setup**: Run `.specify/scripts/bash/check-prerequisites.sh --json` from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS list. + - All file paths must be absolute. + - For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\\''m Groot' (or double-quote if possible: "I'm Groot"). + +2. **Clarify intent (dynamic)**: Derive up to THREE initial contextual clarifying questions (no pre-baked catalog). They MUST: + - Be generated from the user's phrasing + extracted signals from spec/plan/tasks + - Only ask about information that materially changes checklist content + - Be skipped individually if already unambiguous in `$ARGUMENTS` + - Prefer precision over breadth + + Generation algorithm: + 1. Extract signals: feature domain keywords (e.g., auth, latency, UX, API), risk indicators ("critical", "must", "compliance"), stakeholder hints ("QA", "review", "security team"), and explicit deliverables ("a11y", "rollback", "contracts"). + 2. Cluster signals into candidate focus areas (max 4) ranked by relevance. + 3. Identify probable audience & timing (author, reviewer, QA, release) if not explicit. + 4. Detect missing dimensions: scope breadth, depth/rigor, risk emphasis, exclusion boundaries, measurable acceptance criteria. + 5. Formulate questions chosen from these archetypes: + - Scope refinement (e.g., "Should this include integration touchpoints with X and Y or stay limited to local module correctness?") + - Risk prioritization (e.g., "Which of these potential risk areas should receive mandatory gating checks?") + - Depth calibration (e.g., "Is this a lightweight pre-commit sanity list or a formal release gate?") + - Audience framing (e.g., "Will this be used by the author only or peers during PR review?") + - Boundary exclusion (e.g., "Should we explicitly exclude performance tuning items this round?") + - Scenario class gap (e.g., "No recovery flows detected—are rollback / partial failure paths in scope?") + + Question formatting rules: + - If presenting options, generate a compact table with columns: Option | Candidate | Why It Matters + - Limit to A–E options maximum; omit table if a free-form answer is clearer + - Never ask the user to restate what they already said + - Avoid speculative categories (no hallucination). If uncertain, ask explicitly: "Confirm whether X belongs in scope." + + Defaults when interaction impossible: + - Depth: Standard + - Audience: Reviewer (PR) if code-related; Author otherwise + - Focus: Top 2 relevance clusters + + Output the questions (label Q1/Q2/Q3). After answers: if ≥2 scenario classes (Alternate / Exception / Recovery / Non-Functional domain) remain unclear, you MAY ask up to TWO more targeted follow‑ups (Q4/Q5) with a one-line justification each (e.g., "Unresolved recovery path risk"). Do not exceed five total questions. Skip escalation if user explicitly declines more. + +3. **Understand user request**: Combine `$ARGUMENTS` + clarifying answers: + - Derive checklist theme (e.g., security, review, deploy, ux) + - Consolidate explicit must-have items mentioned by user + - Map focus selections to category scaffolding + - Infer any missing context from spec/plan/tasks (do NOT hallucinate) + +4. **Load feature context**: Read from FEATURE_DIR: + - spec.md: Feature requirements and scope + - plan.md (if exists): Technical details, dependencies + - tasks.md (if exists): Implementation tasks + + **Context Loading Strategy**: + - Load only necessary portions relevant to active focus areas (avoid full-file dumping) + - Prefer summarizing long sections into concise scenario/requirement bullets + - Use progressive disclosure: add follow-on retrieval only if gaps detected + - If source docs are large, generate interim summary items instead of embedding raw text + +5. **Generate checklist** - Create "Unit Tests for Requirements": + - Create `FEATURE_DIR/checklists/` directory if it doesn't exist + - Generate unique checklist filename: + - Use short, descriptive name based on domain (e.g., `ux.md`, `api.md`, `security.md`) + - Format: `[domain].md` + - If file exists, append to existing file + - Number items sequentially starting from CHK001 + - Each `/speckit.checklist` run creates a NEW file (never overwrites existing checklists) + + **CORE PRINCIPLE - Test the Requirements, Not the Implementation**: + Every checklist item MUST evaluate the REQUIREMENTS THEMSELVES for: + - **Completeness**: Are all necessary requirements present? + - **Clarity**: Are requirements unambiguous and specific? + - **Consistency**: Do requirements align with each other? + - **Measurability**: Can requirements be objectively verified? + - **Coverage**: Are all scenarios/edge cases addressed? + + **Category Structure** - Group items by requirement quality dimensions: + - **Requirement Completeness** (Are all necessary requirements documented?) + - **Requirement Clarity** (Are requirements specific and unambiguous?) + - **Requirement Consistency** (Do requirements align without conflicts?) + - **Acceptance Criteria Quality** (Are success criteria measurable?) + - **Scenario Coverage** (Are all flows/cases addressed?) + - **Edge Case Coverage** (Are boundary conditions defined?) + - **Non-Functional Requirements** (Performance, Security, Accessibility, etc. - are they specified?) + - **Dependencies & Assumptions** (Are they documented and validated?) + - **Ambiguities & Conflicts** (What needs clarification?) + + **HOW TO WRITE CHECKLIST ITEMS - "Unit Tests for English"**: + + ❌ **WRONG** (Testing implementation): + - "Verify landing page displays 3 episode cards" + - "Test hover states work on desktop" + - "Confirm logo click navigates home" + + ✅ **CORRECT** (Testing requirements quality): + - "Are the exact number and layout of featured episodes specified?" [Completeness] + - "Is 'prominent display' quantified with specific sizing/positioning?" [Clarity] + - "Are hover state requirements consistent across all interactive elements?" [Consistency] + - "Are keyboard navigation requirements defined for all interactive UI?" [Coverage] + - "Is the fallback behavior specified when logo image fails to load?" [Edge Cases] + - "Are loading states defined for asynchronous episode data?" [Completeness] + - "Does the spec define visual hierarchy for competing UI elements?" [Clarity] + + **ITEM STRUCTURE**: + Each item should follow this pattern: + - Question format asking about requirement quality + - Focus on what's WRITTEN (or not written) in the spec/plan + - Include quality dimension in brackets [Completeness/Clarity/Consistency/etc.] + - Reference spec section `[Spec §X.Y]` when checking existing requirements + - Use `[Gap]` marker when checking for missing requirements + + **EXAMPLES BY QUALITY DIMENSION**: + + Completeness: + - "Are error handling requirements defined for all API failure modes? [Gap]" + - "Are accessibility requirements specified for all interactive elements? [Completeness]" + - "Are mobile breakpoint requirements defined for responsive layouts? [Gap]" + + Clarity: + - "Is 'fast loading' quantified with specific timing thresholds? [Clarity, Spec §NFR-2]" + - "Are 'related episodes' selection criteria explicitly defined? [Clarity, Spec §FR-5]" + - "Is 'prominent' defined with measurable visual properties? [Ambiguity, Spec §FR-4]" + + Consistency: + - "Do navigation requirements align across all pages? [Consistency, Spec §FR-10]" + - "Are card component requirements consistent between landing and detail pages? [Consistency]" + + Coverage: + - "Are requirements defined for zero-state scenarios (no episodes)? [Coverage, Edge Case]" + - "Are concurrent user interaction scenarios addressed? [Coverage, Gap]" + - "Are requirements specified for partial data loading failures? [Coverage, Exception Flow]" + + Measurability: + - "Are visual hierarchy requirements measurable/testable? [Acceptance Criteria, Spec §FR-1]" + - "Can 'balanced visual weight' be objectively verified? [Measurability, Spec §FR-2]" + + **Scenario Classification & Coverage** (Requirements Quality Focus): + - Check if requirements exist for: Primary, Alternate, Exception/Error, Recovery, Non-Functional scenarios + - For each scenario class, ask: "Are [scenario type] requirements complete, clear, and consistent?" + - If scenario class missing: "Are [scenario type] requirements intentionally excluded or missing? [Gap]" + - Include resilience/rollback when state mutation occurs: "Are rollback requirements defined for migration failures? [Gap]" + + **Traceability Requirements**: + - MINIMUM: ≥80% of items MUST include at least one traceability reference + - Each item should reference: spec section `[Spec §X.Y]`, or use markers: `[Gap]`, `[Ambiguity]`, `[Conflict]`, `[Assumption]` + - If no ID system exists: "Is a requirement & acceptance criteria ID scheme established? [Traceability]" + + **Surface & Resolve Issues** (Requirements Quality Problems): + Ask questions about the requirements themselves: + - Ambiguities: "Is the term 'fast' quantified with specific metrics? [Ambiguity, Spec §NFR-1]" + - Conflicts: "Do navigation requirements conflict between §FR-10 and §FR-10a? [Conflict]" + - Assumptions: "Is the assumption of 'always available podcast API' validated? [Assumption]" + - Dependencies: "Are external podcast API requirements documented? [Dependency, Gap]" + - Missing definitions: "Is 'visual hierarchy' defined with measurable criteria? [Gap]" + + **Content Consolidation**: + - Soft cap: If raw candidate items > 40, prioritize by risk/impact + - Merge near-duplicates checking the same requirement aspect + - If >5 low-impact edge cases, create one item: "Are edge cases X, Y, Z addressed in requirements? [Coverage]" + + **🚫 ABSOLUTELY PROHIBITED** - These make it an implementation test, not a requirements test: + - ❌ Any item starting with "Verify", "Test", "Confirm", "Check" + implementation behavior + - ❌ References to code execution, user actions, system behavior + - ❌ "Displays correctly", "works properly", "functions as expected" + - ❌ "Click", "navigate", "render", "load", "execute" + - ❌ Test cases, test plans, QA procedures + - ❌ Implementation details (frameworks, APIs, algorithms) + + **✅ REQUIRED PATTERNS** - These test requirements quality: + - ✅ "Are [requirement type] defined/specified/documented for [scenario]?" + - ✅ "Is [vague term] quantified/clarified with specific criteria?" + - ✅ "Are requirements consistent between [section A] and [section B]?" + - ✅ "Can [requirement] be objectively measured/verified?" + - ✅ "Are [edge cases/scenarios] addressed in requirements?" + - ✅ "Does the spec define [missing aspect]?" + +6. **Structure Reference**: Generate the checklist following the canonical template in `.specify/templates/checklist-template.md` for title, meta section, category headings, and ID formatting. If template is unavailable, use: H1 title, purpose/created meta lines, `##` category sections containing `- [ ] CHK### ` lines with globally incrementing IDs starting at CHK001. + +7. **Report**: Output full path to created checklist, item count, and remind user that each run creates a new file. Summarize: + - Focus areas selected + - Depth level + - Actor/timing + - Any explicit user-specified must-have items incorporated + +**Important**: Each `/speckit.checklist` command invocation creates a checklist file using short, descriptive names unless file already exists. This allows: + +- Multiple checklists of different types (e.g., `ux.md`, `test.md`, `security.md`) +- Simple, memorable filenames that indicate checklist purpose +- Easy identification and navigation in the `checklists/` folder + +To avoid clutter, use descriptive types and clean up obsolete checklists when done. + +## Example Checklist Types & Sample Items + +**UX Requirements Quality:** `ux.md` + +Sample items (testing the requirements, NOT the implementation): + +- "Are visual hierarchy requirements defined with measurable criteria? [Clarity, Spec §FR-1]" +- "Is the number and positioning of UI elements explicitly specified? [Completeness, Spec §FR-1]" +- "Are interaction state requirements (hover, focus, active) consistently defined? [Consistency]" +- "Are accessibility requirements specified for all interactive elements? [Coverage, Gap]" +- "Is fallback behavior defined when images fail to load? [Edge Case, Gap]" +- "Can 'prominent display' be objectively measured? [Measurability, Spec §FR-4]" + +**API Requirements Quality:** `api.md` + +Sample items: + +- "Are error response formats specified for all failure scenarios? [Completeness]" +- "Are rate limiting requirements quantified with specific thresholds? [Clarity]" +- "Are authentication requirements consistent across all endpoints? [Consistency]" +- "Are retry/timeout requirements defined for external dependencies? [Coverage, Gap]" +- "Is versioning strategy documented in requirements? [Gap]" + +**Performance Requirements Quality:** `performance.md` + +Sample items: + +- "Are performance requirements quantified with specific metrics? [Clarity]" +- "Are performance targets defined for all critical user journeys? [Coverage]" +- "Are performance requirements under different load conditions specified? [Completeness]" +- "Can performance requirements be objectively measured? [Measurability]" +- "Are degradation requirements defined for high-load scenarios? [Edge Case, Gap]" + +**Security Requirements Quality:** `security.md` + +Sample items: + +- "Are authentication requirements specified for all protected resources? [Coverage]" +- "Are data protection requirements defined for sensitive information? [Completeness]" +- "Is the threat model documented and requirements aligned to it? [Traceability]" +- "Are security requirements consistent with compliance obligations? [Consistency]" +- "Are security failure/breach response requirements defined? [Gap, Exception Flow]" + +## Anti-Examples: What NOT To Do + +**❌ WRONG - These test implementation, not requirements:** + +```markdown +- [ ] CHK001 - Verify landing page displays 3 episode cards [Spec §FR-001] +- [ ] CHK002 - Test hover states work correctly on desktop [Spec §FR-003] +- [ ] CHK003 - Confirm logo click navigates to home page [Spec §FR-010] +- [ ] CHK004 - Check that related episodes section shows 3-5 items [Spec §FR-005] +``` + +**✅ CORRECT - These test requirements quality:** + +```markdown +- [ ] CHK001 - Are the number and layout of featured episodes explicitly specified? [Completeness, Spec §FR-001] +- [ ] CHK002 - Are hover state requirements consistently defined for all interactive elements? [Consistency, Spec §FR-003] +- [ ] CHK003 - Are navigation requirements clear for all clickable brand elements? [Clarity, Spec §FR-010] +- [ ] CHK004 - Is the selection criteria for related episodes documented? [Gap, Spec §FR-005] +- [ ] CHK005 - Are loading state requirements defined for asynchronous episode data? [Gap] +- [ ] CHK006 - Can "visual hierarchy" requirements be objectively measured? [Measurability, Spec §FR-001] +``` + +**Key Differences:** + +- Wrong: Tests if the system works correctly +- Correct: Tests if the requirements are written correctly +- Wrong: Verification of behavior +- Correct: Validation of requirement quality +- Wrong: "Does it do X?" +- Correct: "Is X clearly specified?" +""" diff --git a/.gemini/commands/speckit.clarify.toml b/.gemini/commands/speckit.clarify.toml new file mode 100644 index 0000000..af1f9a6 --- /dev/null +++ b/.gemini/commands/speckit.clarify.toml @@ -0,0 +1,185 @@ +description = "Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec." + +prompt = """ +--- +description: Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec. +handoffs: + - label: Build Technical Plan + agent: speckit.plan + prompt: Create a plan for the spec. I am building with... +--- + +## User Input + +```text +$ARGUMENTS +``` + +You **MUST** consider the user input before proceeding (if not empty). + +## Outline + +Goal: Detect and reduce ambiguity or missing decision points in the active feature specification and record the clarifications directly in the spec file. + +Note: This clarification workflow is expected to run (and be completed) BEFORE invoking `/speckit.plan`. If the user explicitly states they are skipping clarification (e.g., exploratory spike), you may proceed, but must warn that downstream rework risk increases. + +Execution steps: + +1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields: + - `FEATURE_DIR` + - `FEATURE_SPEC` + - (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.) + - If JSON parsing fails, abort and instruct user to re-run `/speckit.specify` or verify feature branch environment. + - For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\\''m Groot' (or double-quote if possible: "I'm Groot"). + +2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked). + + Functional Scope & Behavior: + - Core user goals & success criteria + - Explicit out-of-scope declarations + - User roles / personas differentiation + + Domain & Data Model: + - Entities, attributes, relationships + - Identity & uniqueness rules + - Lifecycle/state transitions + - Data volume / scale assumptions + + Interaction & UX Flow: + - Critical user journeys / sequences + - Error/empty/loading states + - Accessibility or localization notes + + Non-Functional Quality Attributes: + - Performance (latency, throughput targets) + - Scalability (horizontal/vertical, limits) + - Reliability & availability (uptime, recovery expectations) + - Observability (logging, metrics, tracing signals) + - Security & privacy (authN/Z, data protection, threat assumptions) + - Compliance / regulatory constraints (if any) + + Integration & External Dependencies: + - External services/APIs and failure modes + - Data import/export formats + - Protocol/versioning assumptions + + Edge Cases & Failure Handling: + - Negative scenarios + - Rate limiting / throttling + - Conflict resolution (e.g., concurrent edits) + + Constraints & Tradeoffs: + - Technical constraints (language, storage, hosting) + - Explicit tradeoffs or rejected alternatives + + Terminology & Consistency: + - Canonical glossary terms + - Avoided synonyms / deprecated terms + + Completion Signals: + - Acceptance criteria testability + - Measurable Definition of Done style indicators + + Misc / Placeholders: + - TODO markers / unresolved decisions + - Ambiguous adjectives ("robust", "intuitive") lacking quantification + + For each category with Partial or Missing status, add a candidate question opportunity unless: + - Clarification would not materially change implementation or validation strategy + - Information is better deferred to planning phase (note internally) + +3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints: + - Maximum of 10 total questions across the whole session. + - Each question must be answerable with EITHER: + - A short multiple‑choice selection (2–5 distinct, mutually exclusive options), OR + - A one-word / short‑phrase answer (explicitly constrain: "Answer in <=5 words"). + - Only include questions whose answers materially impact architecture, data modeling, task decomposition, test design, UX behavior, operational readiness, or compliance validation. + - Ensure category coverage balance: attempt to cover the highest impact unresolved categories first; avoid asking two low-impact questions when a single high-impact area (e.g., security posture) is unresolved. + - Exclude questions already answered, trivial stylistic preferences, or plan-level execution details (unless blocking correctness). + - Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests. + - If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic. + +4. Sequential questioning loop (interactive): + - Present EXACTLY ONE question at a time. + - For multiple‑choice questions: + - **Analyze all options** and determine the **most suitable option** based on: + - Best practices for the project type + - Common patterns in similar implementations + - Risk reduction (security, performance, maintainability) + - Alignment with any explicit project goals or constraints visible in the spec + - Present your **recommended option prominently** at the top with clear reasoning (1-2 sentences explaining why this is the best choice). + - Format as: `**Recommended:** Option [X] - ` + - Then render all options as a Markdown table: + + | Option | Description | + |--------|-------------| + | A |