用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill mindtickle-sdk-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Implement user sign-up and sign-in flows with Clerk. Use when building authentication UI, customizing sign-in experience, or implementing OAuth social login. Trigger with phrases like "clerk sign-in", "clerk sign-up", "clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk. Use when managing user sessions, configuring route protection, or implementing token refresh and custom JWT templates. Trigger with phrases like "clerk session", "clerk middleware", "clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management. Use when implementing SSO integration, configuring role-based permissions, or setting up organization-level controls. Trigger with phrases like "clerk SSO", "clerk RBAC", "clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
基于 SOC 职业分类
正在显示 SKILL.md
| name | mindtickle-sdk-patterns |
| description | Sdk Patterns for MindTickle. Trigger: "mindtickle sdk patterns". |
| allowed-tools | Read, Write, Edit |
| version | 1.7.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","mindtickle","sales"] |
| compatibility | Designed for Claude Code |
MindTickle's REST API serves sales enablement workflows including course management, quiz administration, user progress tracking, SCIM user provisioning, and coaching analytics. A structured SDK client is critical because MindTickle uses compound API keys with org-scoped tokens, returns progress data as nested completion trees with module-level granularity, and enforces strict SCIM schema compliance for user sync. These patterns provide org-aware authentication, typed models for training content hierarchies, progress query builders, and mock factories for sales readiness test scenarios.
MINDTICKLE_API_KEY environment variable (generated in Admin > Integrations > API Keys)MINDTICKLE_ORG_ID for multi-org deploymentsaxios or node-fetch for HTTP transportinterface MindTickleConfig {
apiKey: string;
orgId: string;
baseUrl?: string;
timeout?: number;
}
let client: MindTickleClient | null = null;
export function getMindTickleClient(overrides?: Partial<MindTickleConfig>): MindTickleClient {
if (!client) {
const config: MindTickleConfig = {
apiKey: process.env.MINDTICKLE_API_KEY ?? '',
orgId: process.env.MINDTICKLE_ORG_ID ?? '',
baseUrl: 'https://api.mindtickle.com/v2',
timeout: 15_000,
...overrides,
};
if (!config.apiKey || !config.orgId) throw new Error('MINDTICKLE_API_KEY and MINDTICKLE_ORG_ID are required');
client = new MindTickleClient(config);
}
return client;
}
interface MindTickleError { statusCode: number; errorType: string; description: string; requestId: string; }
async function safeMindTickle<T>(fn: () => Promise<T>): Promise<T> {
try { return await fn(); }
catch (err: any) {
const parsed: MindTickleError = {
statusCode: err.response?.status ?? 500,
errorType: err.response?.data?.error?.type ?? 'INTERNAL_ERROR',
description: err.response?.data?.error?.description ?? err.message,
requestId: err.response?.headers?.['x-request-id'] ?? 'unknown',
};
if (parsed.statusCode === 429) {
const retryMs = parseInt(err.response?.?.[] ?? , );
( (r, retryMs));
();
}
(parsed. === ) ();
(parsed. === ) ();
();
}
}
class ProgressQueryBuilder {
private params: Record<string, string> = {};
forUser(userId: string) { this.params.user_id = userId; return this; }
inCourse(courseId: string) { this.params.series_id = courseId; return this; }
completedAfter(date: string) { this.params.completed_after = date; return this; }
status(s: 'not_started' | 'in_progress' | 'completed') { this.params.status = s; return this; }
page(n: number) { this.params.page = String(n); return ; }
() { .. = (.(n, )); ; }
(): { (.); }
}
interface Course { id: string; title: string; moduleCount: number; status: 'draft' | 'published' | 'archived'; createdAt: string; }
interface QuizResult { quizId: string; userId: string; score: number; passingScore: number; passed: boolean; attemptNumber: number; completedAt: string; }
interface UserProgress { userId: string; courseId: string; completedModules: number; totalModules: number; percentComplete: number; lastActivityAt: string; }
interface ScimUser { id: string; userName: string; displayName: string; emails: { value: string; : }[]; : ; : []; }
type Middleware = (req: RequestInit, next: () => Promise<Response>) => Promise<Response>;
const orgScopeMiddleware = (orgId: string): Middleware => (req, next) => {
req.headers = { ...req.headers as Record<string, string>, 'X-MindTickle-Org': orgId, Authorization: `Bearer ${process.env.MINDTICKLE_API_KEY}` };
return next();
};
const metricsMiddleware: Middleware = async (req, next) => {
const start = Date.now();
const res = await next();
const endpoint = new URL(req.url as string).pathname;
console.log(`[mindtickle] ${req.method} ${endpoint} ${res.status} ms`);
res;
};
function mockCourse(overrides?: Partial<Course>): Course {
return { id: 'series_abc', title: 'Q3 Product Training', moduleCount: 8, status: 'published', createdAt: '2025-07-01T00:00:00Z', ...overrides };
}
function mockProgress(userId: string, courseId: string): UserProgress {
return { userId, courseId, completedModules: 5, totalModules: 8, percentComplete: 62.5, lastActivityAt: '2025-07-15T14:30:00Z' };
}
function mockScimUser(overrides?: Partial<ScimUser>): ScimUser {
return { id: 'usr_test_001', userName: 'jsmith@acme.com', displayName: 'Jane Smith', emails: [{ value: 'jsmith@acme.com', primary: true }], : , : [], ...overrides };
}
| Pattern | When to Use | Example |
|---|---|---|
| Retry with header delay | 429 on progress or analytics endpoints | Parse Retry-After-Ms header, wait exact duration, retry once |
| SCIM conflict resolution | 409 when provisioning existing user | Fetch existing user by email, update instead of create |
| Org scope validation | 403 on cross-org resource access | Verify MINDTICKLE_ORG_ID matches target course owner |
| Completion tree unwrap | Nested module progress with null leaves | Flatten tree, filter nulls, compute rollup percentage |
| Bulk operation chunking | Enrolling 500+ users in a course | Batch into groups of 50, sequential with rate limit pauses |
Apply in mindtickle-core-workflow-a.