# Dokumentasi Folder `scripts/` ## Gambaran Umum Folder `scripts/` berisi utility scripts untuk development, testing, dan database management. Scripts ini membantu developer untuk verify functionality, seed data, dan debug issues. --- ## ๐Ÿ“ Struktur Direktori ``` scripts/ โ”œโ”€โ”€ check-links.ts # Check user-coach relationships โ”œโ”€โ”€ check_logs.ts # View recent activity logs โ”œโ”€โ”€ seed_log.ts # Create test activity log โ”œโ”€โ”€ test_har_core.ts # Test activity recognition system โ””โ”€โ”€ test_rehab_core.ts # Test exercise recognition system ``` **Total Files**: 5 TypeScript scripts --- ## ๐Ÿ“„ Database Management Scripts ### **1. `check-links.ts`** ๐Ÿ”— **Path**: `/scripts/check-links.ts` **Fungsi**: Menampilkan semua users dan coach-client relationships **Size**: ~466 bytes **Use Case**: - Verify seeding berhasil - Debug coach-client assignments - Quick database health check **Code**: ```typescript import "dotenv/config"; import { PrismaClient } from "../app/generated/client/client"; const prisma = new PrismaClient(); async function main() { const users = await prisma.users.findMany(); console.log("--- All Users ---"); users.forEach((u) => console.log(`${u.name} (${u.role}): ID=${u.id}, CoachID=${u.coach_id}`), ); } ``` **How to Run**: ```bash npx tsx scripts/check-links.ts ``` **Expected Output**: ``` --- All Users --- Coach One (COACH): ID=C00001, CoachID=null Coach Two (COACH): ID=C00002, CoachID=null Client One (CLIENT): ID=U00001, CoachID=C00001 Client Two (CLIENT): ID=U00002, CoachID=C00001 Client Three (CLIENT): ID=U00003, CoachID=C00002 ``` **Use Cases**: - โœ… Verify after running `prisma db seed` - โœ… Check migration success - โœ… Debug role assignments - โœ… List all registered users --- ### **2. `check_logs.ts`** ๐Ÿ“‹ **Path**: `/scripts/check_logs.ts` **Fungsi**: Menampilkan 10 activity logs terbaru dari database **Size**: ~887 bytes **Use Case**: - Monitor real-time activity tracking - Debug activity logging system - Verify fall detection alerts - Inspect log details (JSON) **Code**: ```typescript import { PrismaClient } from "../app/generated/client/client"; import * as dotenv from "dotenv"; dotenv.config(); const prisma = new PrismaClient(); async function main() { console.log("Checking Activity Logs..."); const logs = await prisma.activity_logs.findMany({ take: 10, orderBy: { timestamp: "desc" }, include: { user: { select: { name: true } }, }, }); if (logs.length === 0) { console.log("No logs found."); } else { console.log(`Found ${logs.length} logs:`); logs.forEach((log) => { console.log( `[${log.timestamp?.toISOString()}] ` + `User: ${log.user?.name || log.user_id} | ` + `Status: ${log.status} | ` + `Details: ${JSON.stringify(log.details)}`, ); }); } } ``` **How to Run**: ```bash npx tsx scripts/check_logs.ts ``` **Expected Output**: ``` Checking Activity Logs... Found 3 logs: [2025-12-28T10:30:00.000Z] User: Client One | Status: Standing | Details: {"exercise":"bicep_curl","reps":5} [2025-12-28T10:25:00.000Z] User: Client Two | Status: Sitting | Details: {} [2025-12-28T10:20:00.000Z] User: Client One | Status: Standing | Details: {} ``` **Features**: - โœ… Shows latest 10 logs (configurable via `take`) - โœ… Ordered by timestamp (newest first) - โœ… Includes user name via join - โœ… Pretty-prints JSON details **When to Use**: - After training session untuk verify logs created - Debug fall detection alerts - Monitor which users are active --- ### **3. `seed_log.ts`** ๐ŸŒฑ **Path**: `/scripts/seed_log.ts` **Fungsi**: Membuat test activity log untuk development **Size**: ~816 bytes **Use Case**: - Populate database dengan sample logs - Test log display UI - Verify logging system works **Code**: ```typescript import { PrismaClient } from "../app/generated/client/client"; import * as dotenv from "dotenv"; dotenv.config(); const prisma = new PrismaClient(); async function main() { console.log("Seeding Mock Log..."); // Get a client user const user = await prisma.users.findFirst({ where: { role: "CLIENT" }, }); if (!user) { console.error("No client user found to attach log to."); return; } const log = await prisma.activity_logs.create({ data: { user_id: user.id, timestamp: new Date(), status: "TEST_LOG", confidence: "1.0", details: { message: "Manual verification log" }, }, }); console.log("Created Log ID:", log.id); } ``` **How to Run**: ```bash npx tsx scripts/seed_log.ts ``` **Expected Output**: ``` Seeding Mock Log... Created Log ID: 1 ``` **Use Cases**: - โœ… Quick test untuk UI development - โœ… Verify database schema works - โœ… Populate logs tanpa perlu run full app **Customization**: ```typescript // Modify untuk create specific log data: { status: 'Fall Detected', // Test fall alert confidence: '0.95', details: { coordinates: { x: 100, y: 200 }, severity: 'HIGH' } } ``` --- ## ๐Ÿงช Testing Scripts ### **4. `test_har_core.ts`** ๐Ÿค– **Path**: `/scripts/test_har_core.ts` **Fungsi**: Unit test untuk `HARCore` activity recognition system **Size**: ~1 KB **Use Case**: - Test XGBoost model integration - Verify exercise detection logic - Debug HAR system issues - Ensure setExercise() mapping works **Code**: ```typescript import { HARCore } from "../lib/pose/HARCore"; import { Landmark } from "../lib/pose/ExerciseRules"; const har = new HARCore(); const mockLandmarks: Landmark[] = Array(33).fill({ x: 0.5, y: 0.5, z: 0, visibility: 1, }); console.log("Testing HARCore..."); const inputs = ["Bicep Curl", "Squats", "deadlift", "Unknown Exercise"]; inputs.forEach((input) => { har.setExercise(input); console.log(`Set to '${input}'. Invoking process...`); har .process(mockLandmarks) .then((res) => { console.log( `[PASS] '${input}' -> Result:`, res ? `Exercise: ${res.exercise}, Status: ${res.status}` : "NULL", ); }) .catch((e) => { console.error(`[FAIL] '${input}' -> Error:`, e); }); }); setTimeout(() => console.log("Done."), 2000); ``` **How to Run**: ```bash npx tsx scripts/test_har_core.ts ``` **Expected Output**: ``` Testing HARCore... Set to 'Bicep Curl'. Invoking process... Set to 'Squats'. Invoking process... Set to 'deadlift'. Invoking process... Set to 'Unknown Exercise'. Invoking process... [PASS] 'Bicep Curl' -> Result: Exercise: bicep_curl, Status: Standing [PASS] 'Squats' -> Result: Exercise: squat, Status: Standing [PASS] 'deadlift' -> Result: Exercise: deadlift, Status: Standing [PASS] 'Unknown Exercise' -> Result: Exercise: null, Status: Standing Done. ``` **What It Tests**: - โœ… Exercise name normalization (UI names โ†’ config keys) - โœ… Activity classification (Standing/Sitting/Fall) - โœ… Integration HARCore + RehabCore - โœ… Null handling untuk unknown exercises **Debug Use**: ```typescript // Add this untuk see feature extraction const features = har.extractFeatures(mockLandmarks); console.log("Extracted Features:", features.length); // Should be 141 ``` --- ### **5. `test_rehab_core.ts`** ๐Ÿ’ช **Path**: `/scripts/test_rehab_core.ts` **Fungsi**: Unit test untuk `RehabCore` exercise recognition system **Size**: ~1.1 KB **Use Case**: - Test all 7 exercise configs load correctly - Verify FSM initialization - Debug rep counting issues - Ensure config keys match **Code**: ```typescript import { RehabCore } from "../lib/pose/RehabCore"; import { Landmark } from "../lib/pose/ExerciseRules"; const core = new RehabCore(); const mockLandmarks: Landmark[] = Array(33).fill({ x: 0.5, y: 0.5, z: 0, visibility: 1, }); const exercises = [ "bicep_curls", "hammer_curls", "shoulder_press", "lateral_raises", "squats", "deadlifts", "lunges", ]; console.log("Testing RehabCore Config Loading..."); exercises.forEach((name) => { try { const result = core.process(name, mockLandmarks); if (result) { console.log(`[PASS] ${name} -> Processed successfully.`); } else { console.error(`[FAIL] ${name} -> Returned null (Config not found?).`); } } catch (e) { console.error(`[FAIL] ${name} -> Exception:`, e); } }); ``` **How to Run**: ```bash npx tsx scripts/test_rehab_core.ts ``` **Expected Output**: ``` Testing RehabCore Config Loading... [PASS] bicep_curls -> Processed successfully. [PASS] hammer_curls -> Processed successfully. [PASS] shoulder_press -> Processed successfully. [PASS] lateral_raises -> Processed successfully. [PASS] squats -> Processed successfully. [PASS] deadlifts -> Processed successfully. [PASS] lunges -> Processed successfully. ``` **What It Tests**: - โœ… Exercise name normalization - โœ… Config lookup dari `EXERCISE_CONFIGS` - โœ… FSM initialization (`COUNTER_MAP`) - โœ… Process loop doesn't crash **Common Failures**: ``` [FAIL] bicep_curls -> Returned null (Config not found?) ``` **Cause**: Typo in exercise name or config key **Fix**: Check `ExerciseRules.ts` dan `RehabCore.ts` COUNTER_MAP --- ## ๐Ÿ”ง How to Run Scripts ### **Prerequisites**: ```bash # Install tsx (TypeScript executor) npm install -g tsx # Or use npx (no global install) npx tsx scripts/[script-name].ts ``` ### **Environment Setup**: All scripts load `.env` file: ```bash # .env DATABASE_URL="postgresql://user:password@localhost:5432/dbname" ``` ### **Package Scripts** (Optional): Add to `package.json`: ```json { "scripts": { "check:links": "tsx scripts/check-links.ts", "check:logs": "tsx scripts/check_logs.ts", "seed:log": "tsx scripts/seed_log.ts", "test:har": "tsx scripts/test_har_core.ts", "test:rehab": "tsx scripts/test_rehab_core.ts" } } ``` Then run: ```bash npm run check:links npm run test:har ``` --- ## ๐Ÿ“Š Script Usage Matrix | Script | Purpose | When to Use | Dependencies | | -------------------- | -------------------------- | -------------------------------- | --------------------------- | | `check-links.ts` | List users & relationships | After seeding, debug assignments | Prisma, DB | | `check_logs.ts` | View recent activity logs | After training sessions | Prisma, DB | | `seed_log.ts` | Create test log | UI development, testing | Prisma, DB | | `test_har_core.ts` | Test activity recognition | After HAR changes, debug | HARCore, XGBoost model | | `test_rehab_core.ts` | Test exercise recognition | After config changes, debug | RehabCore, EXERCISE_CONFIGS | --- ## ๐ŸŽฏ Common Workflows ### **Workflow 1: Fresh Database Setup** ```bash # 1. Reset database npx prisma migrate reset # 2. Verify users created npx tsx scripts/check-links.ts # 3. Create test log npx tsx scripts/seed_log.ts # 4. Verify log saved npx tsx scripts/check_logs.ts ``` --- ### **Workflow 2: Debug Exercise Recognition** ```bash # 1. Test all exercises load npx tsx scripts/test_rehab_core.ts # 2. If FAIL, check config cat lib/pose/ExerciseRules.ts | grep -A 5 "bicep_curl" # 3. Fix and re-test npx tsx scripts/test_rehab_core.ts ``` --- ### **Workflow 3: Monitor Production Logs** ```bash # SSH to server ssh user@production-server # Check recent activity cd /path/to/app npx tsx scripts/check_logs.ts # If fall detected, investigate npx tsx scripts/check_logs.ts | grep "Fall Detected" ``` --- ## ๐Ÿ’ก Extending Scripts ### **Add New Test Script**: **Example**: `test_form_scoring.ts` ```typescript import { RehabCore } from "../lib/pose/RehabCore"; import { Landmark } from "../lib/pose/ExerciseRules"; const core = new RehabCore(); // Create realistic landmarks (proper squat form) const goodSquatLandmarks: Landmark[] = [ // ... 33 landmarks with correct squat angles ]; const result = core.process("squat", goodSquatLandmarks); console.log("Form Score:", result?.scores?.deviation_mae); // Expected: < 8 (Excellent) ``` --- ### **Add Data Export Script**: **Example**: `export_recaps.ts` ```typescript import { PrismaClient } from "../app/generated/client/client"; import fs from "fs"; const prisma = new PrismaClient(); async function main() { const recaps = await prisma.user_recaps.findMany({ include: { user: true, training_menus: true }, }); const csv = recaps.map((r) => ({ user: r.user?.name, menu: r.training_menus?.name, date: r.completed_at, // ... more fields })); fs.writeFileSync("export.json", JSON.stringify(csv, null, 2)); console.log("Exported to export.json"); } main(); ``` --- ## ๐Ÿ”’ Security Notes ### **Safe Scripts**: โœ… - `check-links.ts` - Read-only - `check_logs.ts` - Read-only - `test_har_core.ts` - No DB access - `test_rehab_core.ts` - No DB access ### **Destructive Scripts**: โš ๏ธ - `seed_log.ts` - **Writes** to database - Safe in dev, but be careful in production - Consider adding `--dry-run` flag ### **Best Practice**: ```typescript // Add environment check if (process.env.NODE_ENV === "production") { console.error("This script is not safe to run in production!"); process.exit(1); } ``` --- ## ๐Ÿš€ Advanced Usage ### **1. Continuous Testing**: ```bash # Watch mode for TDD npx tsx watch scripts/test_rehab_core.ts # Re-runs on file change ``` --- ### **2. Automated Checks**: ```bash # Add to CI/CD pipeline # .github/workflows/test.yml - name: Run Unit Tests run: | npx tsx scripts/test_har_core.ts npx tsx scripts/test_rehab_core.ts ``` --- ### **3. Data Migration**: ```typescript // scripts/migrate_old_logs.ts const oldLogs = await prisma.legacy_logs.findMany(); for (const log of oldLogs) { await prisma.activity_logs.create({ data: { user_id: log.userId, status: transformStatus(log.oldStatus), // ... transform logic }, }); } ``` --- ## ๐Ÿ› ๏ธ Troubleshooting ### **Issue**: `Cannot find module 'dotenv'` ```bash Error: Cannot find module 'dotenv' ``` **Solution**: ```bash npm install dotenv ``` --- ### **Issue**: `tsx: command not found` ```bash bash: tsx: command not found ``` **Solution**: ```bash # Use npx instead npx tsx scripts/check-links.ts # Or install globally npm install -g tsx ``` --- ### **Issue**: Prisma connection error ```bash Error: Can't reach database server ``` **Solution**: 1. Check PostgreSQL running 2. Verify `DATABASE_URL` in `.env` 3. Test connection: ```bash npx prisma db pull ``` --- ### **Issue**: Scripts hang (promises not resolving) ```typescript // Add timeout setTimeout(() => process.exit(0), 5000); ``` --- ## ๐Ÿ“š References **Tools Used**: - [tsx](https://github.com/esbuild-kit/tsx) - TypeScript executor - [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client) - Database ORM - [dotenv](https://github.com/motdotla/dotenv) - Environment variables **Related Docs**: - `/lib/pose/` - Core AI modules - `/prisma/` - Database schema - `package.json` - NPM scripts --- ## โœ… Summary **Total Scripts**: 5 **Categories**: - ๐Ÿ—„๏ธ **Database**: 3 scripts (check-links, check_logs, seed_log) - ๐Ÿงช **Testing**: 2 scripts (test_har_core, test_rehab_core) **When to Use**: - โœ… After database migrations - โœ… After modifying exercise configs - โœ… Debugging recognition issues - โœ… Verifying production data **Quick Commands**: ```bash # Database health check npx tsx scripts/check-links.ts # View recent activity npx tsx scripts/check_logs.ts # Test AI systems npx tsx scripts/test_har_core.ts npx tsx scripts/test_rehab_core.ts ``` Scripts ini adalah **development tools penting** untuk maintain code quality dan debug issues! ๐Ÿ› ๏ธ