add-training

star 0

Map and implement all Musix Studio touchpoints required to add a complete training module. Use when adding a new training, training page, practice module, metric service, Supabase training data, leaderboard, gamification, daily goals, daily challenges, achievements, feature card, route, menu, or metrics/ranking integration.

gleisonkz By gleisonkz schedule Updated 6/7/2026

name: add-training description: Map and implement all Musix Studio touchpoints required to add a complete training module. Use when adding a new training, training page, practice module, metric service, Supabase training data, leaderboard, gamification, daily goals, daily challenges, achievements, feature card, route, menu, or metrics/ranking integration.

Add Training

Use this skill before creating or wiring a new Musix Studio training. Goal: avoid a half-added module that appears in UI but misses Supabase, metrics, ranking, goals, challenges, achievements, XP, or round completions.

Hard rule: do not call a training "complete" until the local validator passes for its module id and metric table. If Supabase persistence is involved, also verify the live database or apply a migration before reporting done.

First Pass

  1. Run Nx workspace discovery first:
    • npx nx show projects
    • npx nx show project musix-studio --json
  2. Search existing modules before editing:
    • rg -n "TrainingRoundModule|RoundCompleteEvent|AnswerEvent|recordRound|recordAnswer|onRoundComplete|recordProgress|fetchLeaderboard|getSummary|hydrateFromRemote" src/app/domain/musix-studio
    • rg -n "training_round_completions|metric_entries|leaderboard|daily_challenges|achievements|daily_goals|xp|module" supabase/migrations
  3. Pick a stable module id and use it everywhere. Existing ids:
    • major_scale
    • cipher_notation
    • fretboard
    • harmonic_field
    • triades
    • intervalos
    • perception
    • key_training

Ask before implementation if the user did not provide: training name, route slug, module id, question/answer shape, scoring rule, modes, whether it needs Supabase persistence, and which rankings/achievements should count it.

Required Guardrail

Before final response, run:

.\.agents\skills\add-training\scripts\validate-training-module.ps1 -ModuleId <module_id> -MetricTable <metric_table>

Examples:

.\.agents\skills\add-training\scripts\validate-training-module.ps1 -ModuleId key_training -MetricTable key_training_answers
.\.agents\skills\add-training\scripts\validate-training-module.ps1 -ModuleId intervalos -MetricTable interval_metric_entries

If the validator fails, fix the missing touchpoints instead of explaining the checklist. Use -SkipMetricTable only when a training intentionally has no persisted answer metrics; still validate round completions and gamification.

UI Entry Points

Update these when the new training should be discoverable:

  • src/app/domain/musix-studio/feature-cards.constant.ts
    • Add FEATURE_CARDS entry with category: 'training'.
    • Confirm TRAINING_CARDS should include it automatically.
  • src/app/domain/musix-studio/musix-studio.routes.ts
    • Add authenticated route under MUSIX_STUDIO_ROUTES children.
  • src/app/shared/constants/menus.ts
    • Usually no per-training menu item; trainings live under /trainings.
    • Only add menu entry when product explicitly wants direct sidebar access.
  • src/app/domain/musix-studio/pages/training-hub/*
    • Verify hub renders TRAINING_CARDS; adjust only if filtering/sorting/category rules hide the new card.
  • src/app/domain/musix-studio/pages/landing-page/*
    • Verify public landing shows desired cards and auth redirect behavior still holds.

Training Page Contract

Use existing training pages as templates. Prefer closest behavior:

  • pages/major-scale-training/*: mode/scale-heavy flow, leaderboard snapshot, full metrics.
  • pages/cipher-notation/*: compact answer training with mode filters.
  • pages/fretboard-training/*: fast answer loop, per-string metrics.
  • pages/harmonic-field-training/*: scale/mode details and richer summaries.
  • pages/triades-training/*: multi-mode music theory training.
  • pages/interval-training/*: recent simple full integration.
  • pages/perception-training/*: audio/perception flow and daily challenge direct call.
  • pages/key-training/*: key-by-ear flow.

Wire shared components when useful:

  • components/training-flow-header/*
  • components/training-answer-feedback/*
  • components/training-round-summary/*
  • components/leaderboard-row/*
  • training-flow.types.ts
  • training-practice-focus.ts
  • training-round-share.ts
  • share-card.ts

At answer time, call the module metric service recordAnswer(...). For gamification, call GamificationService.onAnswer(...) unless the page has a deliberate special path. At round end, call both TrainingRoundCompletionsService.recordRound(...) and GamificationService.onRoundComplete(...).

Supabase Checklist

Create or update migrations under supabase/migrations.

For a complete persisted training, add:

  • <module>_metric_entries table or equivalent:
    • id, user_id default auth.uid(), answered_at default now()
    • mode_id
    • prompt/answer columns needed for metrics
    • correct
    • response_time_ms when speed/ranking/XP should use speed
    • indexes on (user_id, answered_at desc) and key filters
    • RLS enabled
    • select/insert policies scoped to auth.uid()
    • grants for authenticated
  • leaderboard RPC:
    • returns rank, user id, display name, avatar url when UI needs it
    • uses SECURITY DEFINER only when cross-user aggregation requires it
    • revokes public and grants execute to authenticated
  • speed leaderboard RPC if the metrics page has speed rankings.
  • training_round_completions constraint:
    • drop and recreate training_round_completions_module_check
    • include the new module id and every existing module id
  • training_rounds_leaderboard RPC:
    • include new module id in accepted p_module list
    • keep return contract aligned with TrainingRoundsLeaderboardRow

Important drift class to prevent: TypeScript may know a module while Supabase still rejects it. Always verify:

  • answer table inserts can infer user_id through default auth.uid()
  • answer table has answered_at default now()
  • answer table RLS has select/insert policies scoped to auth.uid() = user_id
  • training_round_completions_module_check includes the module id
  • training_rounds_leaderboard accepts the module id instead of falling back to another module
  • the live DB has the migration applied when working against hosted Supabase

Metrics Service

Create src/app/domain/musix-studio/services/<module>-metrics.service.ts or extend an existing service if the training shares data.

Match existing service surface:

  • recordAnswer(input): void | Promise<void>
  • getSummary()
  • hydrateFromRemote()
  • fetchLeaderboard(...)
  • optional fetchLeaderboardSpeed(...)
  • local signal cache plus Supabase persistence
  • graceful behavior when Supabase client/session is unavailable

Add imports to gamification only when summary data is needed for achievements/cross-module checks.

Gamification

Update all module id unions:

  • src/app/domain/musix-studio/services/training-round-completions.service.ts
    • TrainingRoundModule
  • src/app/domain/musix-studio/services/gamification/gamification.service.ts
    • AnswerEvent.module
    • RoundCompleteEvent.module

Update XP and activity:

  • services/gamification/xp-levels.service.ts
    • resolveXpWeight(module, modeId) if weight differs from default
    • labels/activity metadata only if needed by UI
  • pages/gamification/gamification.page.ts
    • moduleTrainingPath(...)
    • moduleLabel(...)
    • any module-specific challenge labels/icons

Update daily goals and challenges:

  • services/gamification/daily-goal.service.ts
    • Usually answer count is module-agnostic; verify no module filter blocks the new training.
  • services/gamification/daily-challenges.service.ts
    • Add module id to DailyChallengeDefinition.module union.
    • Add challenge definitions for the new training if product wants it in daily rotation.
    • Update cross-module lists (CROSS_MODULES) if the new training should count toward cross-module challenges.

Update achievements:

  • services/gamification/achievements.service.ts
    • Add module-specific ACHIEVEMENTS entries when needed.
    • Extend ExtendedMasteryContext with summary/round fields.
    • Add checks in checkExtendedMastery(...).
    • Update cross-module achievements if new training changes "all modules" semantics.
  • services/gamification/gamification.service.ts
    • Inject new metrics service if achievements need summaries.
    • Hydrate it in hydrateAll().
    • Include round counts in daily rounds, totals, and cross-module booleans.

Metrics And Ranking Page

Update src/app/domain/musix-studio/pages/major-scale-metrics/* even though the name says major-scale; it is the app-wide metrics/ranking page.

Check:

  • services injected in .ts
  • leaderboard fetch methods
  • round-completion leaderboards:
    • add this.roundCompletions.fetchLeaderboard({ module: '<module_id>', ... })
  • template sections for accuracy, speed, rounds, and skeleton states
  • labels and units
  • SCSS only if layout needs another section/column

If adding a dedicated per-training leaderboard snapshot, mirror existing training page pattern with TrainingRoundSummaryComponent and LeaderboardRowComponent.

Validation

Prefer Nx commands:

  • npx nx build musix-studio
  • npx nx lint musix-studio only if requested or needed; repo has known pre-existing lint errors.
  • npx nx test musix-studio only if requested or after fixing known Jest setup issue; repo has known pre-existing Jest setup path problem.

For Supabase migrations, inspect SQL carefully:

  • no unsafe RLS
  • no raw user rows exposed by leaderboard RPC
  • all module ids preserved in constraints and RPC allowlists
  • frontend type unions match DB allowlists

Run the bundled validator:

.\.agents\skills\add-training\scripts\validate-training-module.ps1 -ModuleId <module_id> -MetricTable <metric_table>

For hosted Supabase, also inspect or apply the live migration. Minimal SQL checks:

select column_default
from information_schema.columns
where table_schema = 'public'
  and table_name = '<metric_table>'
  and column_name in ('user_id', 'answered_at');

select pg_get_constraintdef(oid)
from pg_constraint
where conrelid = 'public.training_round_completions'::regclass
  and conname = 'training_round_completions_module_check';

select public.training_rounds_leaderboard('<module_id>', 30, 1, 1);

Manual smoke path:

  1. Public landing shows card if expected.
  2. Card click redirects/login-gates correctly.
  3. Authenticated route loads.
  4. Answer records metric.
  5. Round complete records training_round_completions.
  6. XP/daily goal/challenge update.
  7. Achievements unlock when thresholds are met.
  8. Metrics/ranking page shows accuracy/speed/round data or intentionally omits unsupported sections.

Commit Message

After code changes, suggest:

feat(<module>): add <training name> training

Use another type only when the work is not a feature.

Install via CLI
npx skills add https://github.com/gleisonkz/musix-studio --skill add-training
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator