--- name: jungle-studio-data-platform description: "Class-level patterns for Jungle Studio's Mariana Tek-backed data platform: sync pipelines, dashboard data quirks, future schedule hydration, and operational DB/API pitfalls across the shared apps." version: 1.0.0 author: Hermes Agent license: MIT metadata: hermes: tags: [jungle-studio, mariana-tek, postgres, sync, dashboard, mobile, data-quality] related_skills: [vps-app-deployment] --- # Jungle Studio Data Platform ## Overview Use this for the whole Jungle Studio data platform: Mariana Tek ingestion, shared Postgres behavior, dashboard/mobile API semantics, and the data-quality quirks that shape product logic. The maintainable unit is the platform, not separate micro-skills for one report or one admin screen bug. ## When to Use - Working on Mariana Tek sync pipelines - Debugging dashboard/mobile discrepancies driven by shared DB state - Investigating reservation counts, statuses, spots, future schedules, or instructor media - Making schema/data changes that affect both Jungle apps ## 1. Shared-platform mental model Two apps share one Postgres database: - jungle dashboard - jungle mobile Any schema or dedup change must be validated against both apps. Data fixes that look safe for one surface can silently break the other. ## 2. Mariana Tek sync lessons - real report volumes regularly exceed sync caps, so async/S3 export flows matter - chunked per-day backfills are safer than giant date ranges - never silently accept truncated 500-row results - preserve manual overrides when admin-edited statuses must win over later syncs - future schedule hydration may need both class-session creation and reservation sync to keep counts/spots accurate ## 3. Data semantics that drive the product - reservations often duplicate one customer across one class; count distinct customers, not raw rows - only certain statuses count as active reservations - date/time columns may be split or serialized in surprising ways; combine/normalize carefully before frontend display - reformer spot logic only makes sense for classes that actually use assigned spots ## 4. Operational/app-integration lessons - nginx `/api/` auth/proxy mistakes can make whole dashboards appear empty - build systems can leave stale dist output if TypeScript checks block downstream asset builds - instructor avatars do not appear just because files exist on disk; employee records must point to those URLs - direct DB remaps for image URLs often require no rebuild/restart because APIs read live from Postgres - after PM2 restarts, immediate public/local curls can briefly show `000`/`502` while `tsx server.ts` is booting; wait a few seconds and retry before treating it as a failed deploy ## 5. Instructor mobile test-user pattern See `references/instructor-mobile-test-user.md` for exact SQL and verification commands. ## 6. Jungle brand system (visual / styling work) For ANY Jungle UI restyling, brand alignment, mobile-app theming, or new partner-facing UIs, the canonical brand source is `Exxir/jungle-website` (Railway service `jungle-website` in exxir's Projects → Exxir App), NOT the mobile or dashboard apps. See `references/jungle-brand-system.md` for: color tokens, the three-family type system (Termina / Magnat Head / Queens), spacing/radii/shadows, the signature arch shape, component patterns observed on the live site, the Tailwind 4 `@theme` porting strategy, and the token-only vs per-screen-redesign decision split. Use the `railway-cli` skill to discover the right service and pull the source. When Alex asks for a test instructor user for the mobile app, create/update both layers in the shared Postgres DB: - `employees`: active row with `roles = ARRAY['Instructor']::text[]`; the mobile instructor APIs require `active = true AND 'Instructor' = ANY(roles)` - `app_users`: row linked by `employee_id`, with `role = 'instructor'`, `status = 'active'`, and a stable email/auth subject - Current instructor mobile view is route/API driven, not password-auth driven: `/instructor/:id` calls `GET /api/instructors/:id/mobile`, which sets the Zustand role via `setInstructorUser(...)` - Verify with local and public `GET /api/instructors/ID/mobile`, `GET /api/employees/instructors`, and the SPA route `https://jungle-mobile.apps.poofc.com/instructor/ID` - If the test instructor needs useful schedule cards, also assign future rows in `class_session_instructors`; an instructor with no assignments will still load but shows zero upcoming classes ## Common Pitfalls 1. Deleting/deduplicating class sessions without preserving FK relationships 2. Counting reservations with `COUNT(*)` when MT duplicates are common 3. Treating non-reformer zero-spot results as a bug 4. Forgetting that both apps share the same DB and expectations 5. Assuming uploaded instructor files automatically show up in client payloads ## Verification Checklist - [ ] Sync/backfill path handles row caps and async export behavior safely - [ ] Reservation counts use correct active-status + dedup rules - [ ] Future dates contain both hydrated class sessions and reservation rows when expected - [ ] Instructor payloads include the image URLs the frontend actually renders - [ ] Any DB/schema change was checked against both Jungle apps