/SKILL.md
Expert knowledge for developing, maintaining, and refactoring the SocioPulse V2 monorepo stack (multi-brand B2B platform).
npx skillsauth add tachfineamnay/sociopulsev1 Les EXTRAS V2Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides deep contextual knowledge and strict guidelines for working on the SocioPulse V2 project (formerly "Les Extras").
Multi-Brand Platform:
| Brand | Mode | Theme | Target |
|-------|------|-------|--------|
| SocioPulse | SOCIAL | Electric Teal (#14B8A6) / Deep Indigo (#4F46E5) | Éducateurs, travailleurs sociaux (MECS, IME, ITEP, Crèches, CCAS) |
| MedicoPulse | MEDICAL | Neon Rose (#F43F5E) / Electric Violet | Soignants (EHPAD, SSIAD, Cliniques, Hôpitaux, HAD) |
Strict Branding Rules:
socio-pulse.fr / medico-pulse.fr@sociopulse/*├── app/ # Next.js 14 App Router (Frontend)
│ ├── (auth)/ # Auth & onboarding routes (4 pages)
│ ├── (platform)/ # Protected routes (~65+ pages)
│ │ ├── dashboard/
│ │ │ ├── client/ # 18+ sub-routes (missions, bookings, vivier, finance, SOS...)
│ │ │ ├── talent/ # 16+ sub-routes (missions, applications, services, sociolive...)
│ │ │ ├── missions/[id]/ # Mission detail, contract, tracking
│ │ │ └── relief/ # SOS Relief form
│ │ ├── fil-pro/ # Professional social feed (Le Wall)
│ │ ├── services/ # Marketplace catalogue
│ │ ├── sos/ # SOS landing
│ │ ├── visio/ # LiveKit video rooms
│ │ └── ... # bookings, checkout, contracts, finance, messages, etc.
│ ├── (admin)/ # Admin backoffice (6+ pages: users, contracts, moderation, profiles, missions)
│ └── t/[slug]/ # Public SEO talent profiles
├── apps/api/ # NestJS 10 Backend (18 feature modules + 7 common)
│ └── src/
│ ├── auth/ # JWT auth, login/register
│ ├── admin/ # Admin backoffice
│ ├── matching-engine/ # Mission matching
│ ├── video-booking/ # Catalogue + LiveKit
│ ├── wall-feed/ # Social wall
│ ├── contracts/ # E-signatures
│ ├── messages/ # Messaging
│ ├── payments/ # Stripe Connect
│ ├── mission-hub/ # Active mission tracking
│ ├── notifications/ # WebSocket (Socket.IO gateway)
│ ├── availability/ # Talent availability slots
│ ├── finance/ # Financial reports
│ ├── talents/ # Talent profiles
│ ├── quotes/ # Commercial proposals (devis)
│ ├── dashboard/ # Dashboard stats endpoints
│ ├── pulse/ # Virtual currency (Pulse Economy)
│ ├── growth/ # Gamification + referrals
│ ├── health/ # Healthcheck for Coolify
│ └── common/ # Guards, decorators, filters, prisma, uploads, mailer, geocoding
├── components/ # React components (~230+ files, 30+ folders)
│ ├── dashboard/ # DashboardResolver + brand-specific dashboards + 19 widgets
│ ├── wall/ # WallResolver + 20+ polymorphic cards
│ ├── landing/ # 23+ landing page sections
│ ├── profile/ # 12 public profile components
│ ├── feed/ # Social feed (9 components)
│ ├── pulse/ # 8 Pulse economy components
│ ├── finance/ # 7 wallet/invoice components
│ ├── chat/ # 6 messaging components
│ ├── visio/ # 6 LiveKit video components
│ ├── mission/ # 6 mission tracking components
│ ├── vitrine/ # 6 marketplace components
│ ├── onboarding/ # 5 wizard components
│ ├── growth/ # 5 gamification components
│ ├── planning/ # 4 calendar components
│ ├── sociolive/ # 4 workshop/coaching components
│ ├── ui/ # 14 Radix/shadcn primitives
│ ├── providers/ # SocketProvider, ThemeProvider
│ └── ...
├── lib/ # Business logic & configuration (19+ files)
│ ├── auth.ts # Auth module (login, register, token management)
│ ├── useAuth.ts # React hook wrapping Zustand authStore
│ ├── brand.ts # Multi-brand config (BrandConfig, isMedical, isSocial)
│ ├── domain-config.ts # Feature flags, terminology, compliance rules, dashboard layouts
│ ├── config.ts # API URL resolution (getApiUrl) — browser/SSR/Docker
│ ├── dashboard-config.ts # Widget registry (16 widgets), Framer Motion animations
│ ├── nav-config.ts # Navigation items (360 lines, all roles)
│ ├── pricing-config.ts # Economic model (plans, commissions, cancellation rules)
│ ├── sos-config.ts # 50+ job definitions (1,071 lines)
│ ├── wall-config.ts # Polymorphic feed modes by role (314 lines)
│ ├── vitrine-config.ts # Marketplace homepage config (184 lines)
│ ├── hooks/ # useDashboardData, useClientStats, useTalentStats, usePulseWallet, useServices
│ ├── stores/authStore.ts # Zustand + persist (284 lines) — AuthUser type
│ ├── constants/jobTags.ts # Job tag constants
│ └── pricing/calculator.ts # Smart Rate Engine (323 lines)
├── packages/shared-types/ # Shared TypeScript DTOs
├── prisma/schema.prisma # Database schema (1,762 lines, 32 models, 34 enums)
├── seeds/ # 7 JSON talent category files
├── scripts/ # generate_seed_sociopulse.ts, health-check.ts, smoke-test.ts
└── tests/ # Playwright E2E (smoke.spec.ts)
| Layer | Technologies | |-------|-------------| | Frontend | Next.js 14, React 18, TypeScript 5, Tailwind CSS 3.4, Framer Motion 12, Radix UI, Zustand 5 | | Backend | NestJS 10.3, Prisma ~5.22 (pinned — v7 breaks!), PostgreSQL 15, Socket.IO 4.8, LiveKit 2.x | | Payments | Stripe Connect (marketplace) + Pulse Economy (1 Pulse = 5€ HT) | | Auth | JWT (jose), Cookie-based (SameSite=lax, 7 days), Role guards | | Testing | Playwright (E2E smoke tests) | | DevOps | Docker multi-stage (Node 20 Alpine), npm workspaces, Coolify-compatible healthchecks |
| File | Purpose | Lines |
|------|---------|-------|
| prisma/schema.prisma | Source of Truth — 32 models, 34 enums | 1,762 |
| lib/sos-config.ts | Job definitions (50+ métiers both brands) | 1,071 |
| app/globals.css | Theme CSS vars (:root + [data-theme="medical"]) | 1,380 |
| lib/dashboard-config.ts | Widget registry (16 widgets), animations | 522 |
| lib/nav-config.ts | Navigation items for all roles | 360 |
| lib/domain-config.ts | Feature flags, terminology, compliance rules | 350 |
| lib/pricing/calculator.ts | Smart Rate Engine (shift breakdown) | 323 |
| lib/wall-config.ts | Polymorphic feed config by role | 314 |
| lib/stores/authStore.ts | Zustand + persist (AuthUser type) | 284 |
| lib/pricing-config.ts | Economic model (plans, commissions, surcharges) | 269 |
| lib/brand.ts | Multi-brand config (BrandConfig interface) | 206 |
| lib/vitrine-config.ts | Marketplace homepage config | 184 |
| tailwind.config.ts | Custom theme (polymorphic colors, aurora glows) | 159 |
| middleware.ts | Route protection, role redirects, admin subdomain | 154 |
| lib/auth.ts | Auth module (login, register, token management) | 144 |
| apps/api/src/main.ts | NestJS bootstrap (CORS, Swagger, validation) | 108 |
lib/pricing-config.ts)enum PricingPlan {
BETA // 2% technical fees only (launch period — currently active)
STANDARD // 15% commission (private sector)
ENTERPRISE // 0% commission (SaaS subscription)
}
// Launch switch - Set to false to enable monetization
IS_LAUNCH_PERIOD: true
lib/pricing/calculator.ts)SURCHARGES: {
NIGHT_PERCENT: 25, // +25% (21h-06h)
SUNDAY_PERCENT: 50, // +50%
HOLIDAY_PERCENT: 100, // +100%
}
// Cumulative: Sunday night = +75%, Holiday night = +125%
Usage:
import { calculateShiftPrice, calculateFeePercentage, PricingPlan } from '@/lib/pricing';
// Calculate shift with surcharges
const pricing = calculateShiftPrice(startDate, endDate, baseRateCentimes);
// Get commission rate based on client plan
const feePercent = calculateFeePercentage(PricingPlan.STANDARD); // → 15 (or 2 if IS_LAUNCH_PERIOD)
apps/api/src/pulse/ with PulseGuard, @PulseCost() decorator, pulse-pricing.config.ts// ✅ CORRECT
import { isMedical, isSocial, currentBrand } from '@/lib/brand';
import { getTerm, isFeatureEnabled } from '@/lib/domain-config';
const title = getTerm('mission'); // "Vacation" (Medical) | "Mission" (Social)
const label = getTerm('talent'); // "Soignant" | "Intervenant"
if (isFeatureEnabled('enableWorkshops')) { /* Social only */ }
// ❌ WRONG
if (mode === 'MEDICAL') { ... } // Hardcoded check
className="bg-teal-500" // Brand-specific color
lib/domain-config.ts)| Flag | Social | Medical | Description |
|------|--------|---------|-------------|
| enableWorkshops | ✅ | ❌ | SocioLive workshops/ateliers |
| enableShiftView | ❌ | ✅ | Calendar-dense shift view |
| enablePortfolio | ✅ | ❌ | Talent portfolio showcase |
| enableJobTicker | ❌ | ✅ | Fast urgent shifts ticker |
| enableCriticalUrgency | ❌ | ✅ | CRITICAL urgency level |
| enableTeamVivier | ✅ | ✅ | TalentPool team management |
| enableProjects | ✅ | ❌ | Project-based mission grouping |
/* globals.css (1,380 lines) */
/* Social: Electric Teal (default) */
:root {
--primary-h: 174; --primary-s: 84%; --primary-l: 45%;
--radius-sm: 0.5rem; /* Soft, friendly */
--radius-full: 9999px; /* Pills allowed */
}
/* Medical: Neon Rose — sharp/clinical overrides */
[data-theme="medical"] {
--primary-h: 340; --primary-s: 85%; --primary-l: 55%;
--radius-sm: 0.25rem; /* Sharp, clinical */
--radius-full: 0.5rem; /* NO pills! */
}
// ✅ Use CSS variables
className="bg-[hsl(var(--primary))]"
className="text-primary-600" // Tailwind via CSS vars (50-900 scale)
className="shadow-theme-glow" // Brand-aware glow
className="rounded-[var(--radius-sm)]" // Brand-aware radius
// ❌ NEVER direct colors
className="bg-teal-500" // Breaks on Medical!
className="rounded-full" // Breaks on Medical! (no pills)
// Static cross-brand colors (always safe):
className="bg-brand-500" // Indigo — shared accent (#4F46E5)
className="bg-live-500" // Teal — SocioLive (#14B8A6)
className="bg-alert-500" // Rose — alerts/urgency (#F43F5E)
DashboardResolver dynamically loads brand+role dashboards:
| Brand | Client Layout | Talent Layout |
|-------|--------------|---------------|
| Social | project-hub (card-based) | portfolio-feed (skills + feed) |
| Medical | shift-planner (calendar-dense) | job-ticker (fast list) |
Widget system in lib/dashboard-config.ts:
featureFlag for brand filteringimport { JwtAuthGuard, RolesGuard } from '@/common/guards';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser, CurrentUserPayload } from '@/common/decorators/current-user.decorator';
@UseGuards(JwtAuthGuard, RolesGuard) // Order matters!
@Roles('CLIENT')
@Post('missions')
async create(@CurrentUser() user: CurrentUserPayload) {
// user.id, user.email, user.role, user.status
}
Guards Available:
| Guard | Purpose |
|-------|---------|
| JwtAuthGuard | Validates Bearer token |
| RolesGuard | Enforces @Roles() decorator |
| MissionAccessGuard | Mission-scoped data access |
| SeedInterceptionGuard | Prevents real actions on seed/demo data (isSeed: true) |
| PulseGuard | Checks Pulse wallet balance before debit actions |
API Architecture:
/api/v1http://localhost:4000/docsAllExceptionsFilter# Development (run both in parallel)
npm run dev # Frontend :3000
npm run api:dev # Backend :4000
# Database (ALWAYS run db:generate after schema changes!)
npm run db:generate # ⚠️ REQUIRED after schema.prisma edits
npm run db:push # Push to dev DB
npm run db:migrate # Create migration
npm run db:seed # Seed test data (tsx prisma/seed.ts)
npm run db:studio # Prisma Studio GUI
npm run db:seed:sociopulse # Generate + import SocioPulse seed data
# Testing
npm run test:smoke # Playwright smoke tests
# Production Build
docker build --build-arg NEXT_PUBLIC_APP_MODE=SOCIAL -t sociopulse .
docker build --build-arg NEXT_PUBLIC_APP_MODE=MEDICAL -t medicopulse .
docker build -f Dockerfile.api -t sociopulse-api .
import { getApiUrl } from '@/lib/config';
import { auth } from '@/lib/auth';
const res = await fetch(`${getApiUrl()}/endpoint`, {
headers: { Authorization: `Bearer ${auth.getToken()}` }
});
// getApiUrl() handles: browser (hostname detection), SSR (Docker INTERNAL_API_URL), production fallback
accessToken cookie (SameSite=lax, 7 days via js-cookie)lib/auth.ts → { login, register, setToken, getToken, logout, isAuthenticated, fetchMe }lib/useAuth.ts → React hook: { user, isLoading, isAuthenticated, error, refetch, logout } (50ms hydration delay)lib/stores/authStore.ts → Zustand + persist middleware, AuthUser type with full profile/establishmentmiddleware.ts → Route protection, role-based redirects, admin subdomain (dash.sociopulse.com)enableCrossBrand param)| Model | Purpose | Key Fields |
|-------|---------|------------|
| User | Account (CLIENT/TALENT/ADMIN) | role, status, clientType, allowedBrands[], walletBalance, stripeAccountId, isSeed |
| Profile | Talent professional profile | jobId, complianceStatus, slug, profileScore, hourlyRate, languages[], postureTags[] |
| Establishment | Client organization | pricingPlan, paymentMode, creditLimit, siret, isSocialActive, isMedicalActive |
| Service | Catalogue offering | type (WORKSHOP/COACHING_VIDEO), deliveryType, pricingOptions, ageGroups |
| ReliefMission | SOS urgent mission | jobId, urgencyLevel, missionType, specialtiesTags[], requiresCar/Night/Diploma |
| Booking | Reservation (polymorphic: Service OR ReliefMission) | appliedPlan, commissionRate, all surcharge snapshots, timesheet |
| Contract | E-signature | type (MISSION_SOS/SERVICE_BOOKING/FRAMEWORK), dual signatures |
| Quote | Commercial proposal (devis) | reference, lines[], status (DRAFT→SENT→ACCEPTED), revisions chain |
TalentPool, TalentPoolMember, AvailabilitySlot, MissionApplication (with rate negotiation), Post (OFFER/NEED/SOCIAL), Review, Transaction, Notification, Message, UserDocument, AdminNote, ExternalNews, AuditLog, Dispute (6 categories + resolution), Resource (document hub), AnalyticsEvent (pre-launch metrics)
MissionMessage (TEXT/SYSTEM), MissionInstruction (checklist with acknowledgment), MissionReport, MissionTimelineEvent (BRIEFING_READ, MISSION_STARTED, CHAT_MESSAGE, REPORT_SUBMITTED)
PulseWallet (balanceFree + balancePaid, FIFO, monthly stats, alert threshold), PulseTransaction (16 types, idempotency key, FIFO tracking)
UserRole (CLIENT/TALENT/ADMIN), UserStatus (6 states inc. PENDING_INVITE/INVITED), BookingStatus (12 states), ContractStatus (9 states), MissionUrgency (LOW→CRITICAL), PricingPlan (BETA/STANDARD/ENTERPRISE), PaymentMode (PREPAID/POSTPAID), DisputeCategory (6 types), QuoteStatus (7 states)
PENDING → AWAITING_CONTRACT → CONFIRMED → PAID → IN_PROGRESS → COMPLETED
↓
CANCELLED / REJECTED / EXPIRED / NO_SHOW / DISPUTED / REFUNDED
| Issue | Cause | Fix |
|-------|-------|-----|
| "Property X does not exist" | Schema changed | Run npm run db:generate |
| Wrong terminology | Hardcoded strings | Use getTerm('key') from domain-config |
| Colors wrong on one brand | Direct Tailwind | Use var(--primary) CSS vars |
| Border radius pills on Medical | rounded-full | Use rounded-[var(--radius-*)] |
| API 404 in production | Wrong URL | Use getApiUrl() helper |
| Guards not working | Wrong decorator order | @UseGuards(JwtAuthGuard, RolesGuard) before @Roles() |
| Commission wrong | Using old function | Use calculateFeePercentage(plan) |
| Prisma v7 breaks Docker | Upgrading past 5.x | Keep ~5.22.0 pinned in both package.json |
| Hydration mismatch | Auth state not ready | useAuth() hook has 50ms hydration delay |
| Seed data interactions | Users clicking demo data | SeedInterceptionGuard prevents actions on isSeed: true |
| Rate limiting errors | Exceeding API limits | 3 tiers: 10/1s, 50/10s, 200/60s |
| Stripe webhook fails | No raw body | rawBody: true set in main.ts bootstrap |
| Feature | Route(s) | API Module | Components |
|---------|----------|------------|------------|
| SOS Renfort | /sos, /dashboard/*/sos, /dashboard/relief | matching-engine | SOSMissionCard, UrgencyBadge, FlashRequestForm |
| Catalogue | /services/* | video-booking | SocioLiveCard, SlotManager, BookingFlow |
| Fil Pro (Wall) | /fil-pro | wall-feed | WallResolver, WallFeedClient, 20+ cards |
| Mission Hub | /dashboard/missions/[id]/* | mission-hub | MissionChatLive, MissionMonitor |
| Vivier | /vivier, /dashboard/client/vivier | — | TalentCRMCard, TalentImportModal |
| Finance | /finance, /dashboard/*/finance | finance, payments | WalletCard, InvoiceTable, BudgetOverview |
| Visio | /visio/[roomId], /live-session/[id] | video-booking | VideoRoom, ControlBar, PreJoinScreen |
| Pulse | /dashboard/client/finance/pulses | pulse | PulseWalletWidget, PulsePackGrid, PulseTransactionHistory |
| Growth | (embedded in dashboards) | growth | GamificationWidget, ReferralCard, TagSelector |
| Marketplace | / (platform root) | — | VitrineResolver, ClientVitrine, TalentVitrine |
| Public Profile | /t/[slug], /talent/[id] | talents | PublicTalentProfile, QRBusinessCard |
| Landing | / (unauthenticated) | — | 23+ sections (hero, bento grids, testimonials, trust) |
DashboardResolver dynamically loads brand+role specific dashboards:
├── SocialClientDashboard (project-hub layout — card-based)
│ └── Widgets: SOS launcher, upcoming missions, projects, SocioLive, finance, reviews
├── MedicalClientDashboard (shift-planner layout — calendar-dense)
│ └── Widgets: SOS launcher, upcoming missions, talent spotlight, team stability, finance, reviews
├── SocialTalentDashboard (portfolio-feed layout — skills showcase)
│ └── Widgets: profile hero, mission feed, bookings, savoir-être, sociolive, finance
└── MedicalTalentDashboard (job-ticker layout — fast list)
└── Widgets: profile hero, SOS ticker, bookings, mission feed, finance, reviews
node:20-alpine with libc6-compat, opensslNEXT_PUBLIC_APP_MODE (SOCIAL/MEDICAL), NEXT_PUBLIC_API_URLnextjs user, standalone output, port 3000@nestjs/cli global, builds shared-types first, then NestJSnestjs user, copies dist/, prisma/, seeds/, scripts/, port 4000prisma@5 and tsx installed globally (v7 has breaking changes)http://localhost:4000/docsnpm run db:studioTECHNICAL_AUDIT_2026-02-04.md.github/copilot-instructions.mdVersion 2.1.0 — Updated 2026-02-07
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.