[TERMINAL · SKILLS]
> mounting /skills...
> indexing 295 manifests...
> linking agents: claude · codex · gemini · cursor
> ready.
[░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
Terminal.skills
Use Cases/Build a Compliance Audit Checklist System

Build a Compliance Audit Checklist System

Build a compliance audit checklist with configurable frameworks (SOC 2, ISO 27001, GDPR), evidence collection, progress tracking, recurring audits, and exportable reports.

#redis#caching#database#pub-sub#queues
Works with:claude-codeopenai-codexgemini-clicursor

Skills stack · 5 skills

Avg quality 93/100·All SAFE
>

typescript

v

Not yet scored
View skill
>

redis

v1.0.0

Build applications with Redis — caching, session storage, pub/sub, streams, rate limiting, leaderboards, and queues. Use when tasks involve in-memory data storage, real-time messaging, distributed locking, or performance optimization with caching layers.

93/100 quality
1.81× impact
SAFE
View skill
>

postgresql

v1.0.0

Assists with designing schemas, writing performant queries, managing indexes, and operating PostgreSQL databases. Use when working with JSONB, full-text search, window functions, CTEs, row-level security, replication, or performance tuning. Trigger words: postgresql, postgres, sql, database, jsonb, rls, window functions, cte.

87/100 quality
1.53× impact
SAFE
View skill
>

hono

v1.0.0

You are an expert in Hono, the ultrafast web framework for the edge. You help developers build APIs and web applications that run on Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda, and Vercel Edge — with a tiny footprint (~14KB), middleware ecosystem, JSX support, RPC client, and Web Standards API compatibility that makes code truly portable across runtimes.

93/100 quality
3.00× impact
SAFE
View skill
>

zod

v1.0.0

You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.

100/100 quality
1.21× impact
SAFE
View skill
$

The Problem

Lena leads compliance at a 25-person SaaS undergoing SOC 2 Type II audit. The auditor sent a 200-item checklist. Evidence is scattered: some in Google Drive, some in Jira tickets, some in people's heads. Nobody knows which items are complete, in-progress, or blocked. When GDPR audit comes next quarter, they'll start from scratch. Annual recertification means doing it all again. They need a compliance system: configurable audit frameworks, evidence collection per item, progress tracking, recurring audits with carried-over evidence, and exportable reports.

Step 1: Build the Compliance Engine

typescript
import { pool } from "../db";
import { Redis } from "ioredis";
import { randomBytes } from "node:crypto";
const redis = new Redis(process.env.REDIS_URL!);

interface AuditFramework { id: string; name: string; version: string; sections: AuditSection[]; }
interface AuditSection { id: string; name: string; items: AuditItem[]; }
interface AuditItem { id: string; requirement: string; description: string; priority: "critical" | "high" | "medium" | "low"; }

interface AuditInstance {
  id: string;
  frameworkId: string;
  name: string;
  status: "in_progress" | "completed" | "expired";
  progress: { total: number; completed: number; percentage: number };
  dueDate: string;
  items: AuditItemStatus[];
  createdAt: string;
}

interface AuditItemStatus {
  itemId: string;
  status: "not_started" | "in_progress" | "completed" | "not_applicable";
  assignee: string | null;
  evidence: Array<{ name: string; url: string; uploadedAt: string; uploadedBy: string }>;
  notes: string;
  completedAt: string | null;
}

const FRAMEWORKS: Record<string, AuditFramework> = {
  soc2: {
    id: "soc2", name: "SOC 2 Type II", version: "2024",
    sections: [
      { id: "cc1", name: "Control Environment", items: [
        { id: "cc1.1", requirement: "Management philosophy and operating style", description: "Document management's commitment to integrity and ethical values", priority: "critical" },
        { id: "cc1.2", requirement: "Organizational structure", description: "Define organizational chart and reporting structure", priority: "high" },
        { id: "cc1.3", requirement: "HR policies", description: "Background checks, onboarding/offboarding procedures", priority: "high" },
      ]},
      { id: "cc6", name: "Logical and Physical Access", items: [
        { id: "cc6.1", requirement: "Access control policy", description: "Document access control policies and procedures", priority: "critical" },
        { id: "cc6.2", requirement: "Authentication mechanisms", description: "MFA, password policies, SSO configuration", priority: "critical" },
        { id: "cc6.3", requirement: "Access reviews", description: "Quarterly access reviews with evidence", priority: "high" },
      ]},
    ],
  },
  gdpr: {
    id: "gdpr", name: "GDPR Compliance", version: "2024",
    sections: [
      { id: "data", name: "Data Processing", items: [
        { id: "data.1", requirement: "Data processing register", description: "Maintain register of all processing activities (Art. 30)", priority: "critical" },
        { id: "data.2", requirement: "Legal basis documentation", description: "Document legal basis for each processing activity", priority: "critical" },
        { id: "data.3", requirement: "Data retention policy", description: "Define retention periods for each data category", priority: "high" },
      ]},
    ],
  },
};

export async function startAudit(frameworkId: string, name: string, dueDate: string): Promise<AuditInstance> {
  const framework = FRAMEWORKS[frameworkId];
  if (!framework) throw new Error("Framework not found");

  const id = `audit-${randomBytes(6).toString("hex")}`;
  const allItems = framework.sections.flatMap((s) => s.items);
  const items: AuditItemStatus[] = allItems.map((item) => ({ itemId: item.id, status: "not_started", assignee: null, evidence: [], notes: "", completedAt: null }));

  // Carry over evidence from previous audit of same framework
  const { rows: [prev] } = await pool.query(
    "SELECT items FROM audit_instances WHERE framework_id = $1 AND status = 'completed' ORDER BY created_at DESC LIMIT 1",
    [frameworkId]
  );
  if (prev) {
    const prevItems: AuditItemStatus[] = JSON.parse(prev.items);
    for (const item of items) {
      const prevItem = prevItems.find((p) => p.itemId === item.itemId);
      if (prevItem?.evidence.length) {
        item.evidence = prevItem.evidence;
        item.notes = prevItem.notes + "\n[Carried over from previous audit]";
      }
    }
  }

  const instance: AuditInstance = {
    id, frameworkId, name, status: "in_progress",
    progress: { total: items.length, completed: 0, percentage: 0 },
    dueDate, items, createdAt: new Date().toISOString(),
  };

  await pool.query(
    `INSERT INTO audit_instances (id, framework_id, name, status, due_date, items, created_at) VALUES ($1, $2, $3, 'in_progress', $4, $5, NOW())`,
    [id, frameworkId, name, dueDate, JSON.stringify(items)]
  );

  return instance;
}

export async function updateItemStatus(auditId: string, itemId: string, update: Partial<AuditItemStatus>): Promise<void> {
  const { rows: [audit] } = await pool.query("SELECT items FROM audit_instances WHERE id = $1", [auditId]);
  if (!audit) throw new Error("Audit not found");

  const items: AuditItemStatus[] = JSON.parse(audit.items);
  const item = items.find((i) => i.itemId === itemId);
  if (!item) throw new Error("Item not found");

  if (update.status) item.status = update.status;
  if (update.assignee !== undefined) item.assignee = update.assignee;
  if (update.notes !== undefined) item.notes = update.notes;
  if (update.evidence) item.evidence.push(...update.evidence);
  if (update.status === "completed") item.completedAt = new Date().toISOString();

  const completed = items.filter((i) => i.status === "completed" || i.status === "not_applicable").length;
  const progress = { total: items.length, completed, percentage: Math.round((completed / items.length) * 100) };

  await pool.query("UPDATE audit_instances SET items = $2, progress = $3 WHERE id = $1",
    [auditId, JSON.stringify(items), JSON.stringify(progress)]);
}

export async function generateReport(auditId: string): Promise<string> {
  const { rows: [audit] } = await pool.query("SELECT * FROM audit_instances WHERE id = $1", [auditId]);
  if (!audit) throw new Error("Audit not found");
  const framework = FRAMEWORKS[audit.framework_id];
  const items: AuditItemStatus[] = JSON.parse(audit.items);
  const progress = JSON.parse(audit.progress);

  let report = `# ${framework.name} Audit Report\n## ${audit.name}\n\n`;
  report += `**Status:** ${audit.status} | **Progress:** ${progress.percentage}% (${progress.completed}/${progress.total})\n`;
  report += `**Due:** ${audit.due_date} | **Generated:** ${new Date().toISOString().slice(0, 10)}\n\n`;

  for (const section of framework.sections) {
    report += `### ${section.name}\n\n`;
    for (const req of section.items) {
      const status = items.find((i) => i.itemId === req.id);
      const icon = status?.status === "completed" ? "✅" : status?.status === "in_progress" ? "🔄" : status?.status === "not_applicable" ? "➖" : "❌";
      report += `${icon} **${req.id}**: ${req.requirement}\n`;
      if (status?.evidence.length) report += `   Evidence: ${status.evidence.map((e) => e.name).join(", ")}\n`;
      if (status?.notes) report += `   Notes: ${status.notes}\n`;
      report += "\n";
    }
  }
  return report;
}

Results

  • Audit prep: 3 months → 3 weeks — checklist with clear ownership; evidence uploaded per item; no last-minute scramble; auditor gets organized package
  • Evidence carried over — annual SOC 2 recertification: 60% of evidence from last year still valid; team only updates what changed; effort halved
  • Progress visible — dashboard shows 72% complete, 5 critical items remaining; leadership knows exact status; no surprises before audit date
  • Multi-framework support — SOC 2 in Q1, GDPR in Q2, ISO 27001 in Q3; same system, different checklists; evidence shared across frameworks where applicable
  • Exportable reports — auditor receives markdown/PDF report with all items, evidence links, and notes; professional presentation; audit completed in 2 days instead of 2 weeks