@loop/shared
Single source of truth for Zod schemas, Drizzle ORM definitions, RBAC, SSO, types, errors, constants, and configuration loading. Used by virtually every other package.
Installation
pnpm add @loop/sharedZod Schemas
Validation schemas for all domain objects:
import { schemas } from '@loop/shared';
// Auth schemas
schemas.auth.loginSchema.parse({ email, password });
// User schemas
schemas.user.createUserSchema.parse({ email, firstName, lastName });
// Stack schemas
schemas.stack.createStackSchema.parse({ title, items });
// Health schemas
schemas.health.checkInSchema.parse({ painLevel: 3, mood: 8 });
// Commerce schemas
schemas.commerce.orderSchema.parse({ items, total });
// Patient Graph validation schemas
schemas.patientGraph.createCustomerProfileSchema.parse({ ... });
schemas.patientGraph.createLabResultSchema.parse({ ... });Drizzle ORM Schemas
Database schemas for Patient Graph and embeddings:
import { patientGraphSchema } from '@loop/shared/db';
// Tables
patientGraphSchema.customerProfiles
patientGraphSchema.labResults
patientGraphSchema.protocols
patientGraphSchema.patientEvents
patientGraphSchema.rbacLogs
patientGraphSchema.wearableData
// ... etc.RBAC
Role-based access control system:
import { PERMISSION_MATRIX, getPermission, checkAccess, persistAuditEntry, withAudit } from '@loop/shared/rbac';
// Check a permission
const perm = getPermission('customer', 'lab_results', 'read');
// 'ownOnly'
// Full access check
const decision = checkAccess({
role: 'staff',
resource: 'profile',
action: 'write',
actorId: 'user_123',
targetCustomerId: 'user_456',
});
// { allowed: true, reason: 'staff has full access to profile:write' }
// Persist audit entry
await persistAuditEntry(db, auditEntry);
// Wrap operation with audit
await withAudit(db, auditParams, async () => {
return await operation();
});SSO
SSO token generation and verification:
import { generateSSOToken, verifySSOToken, getTierDiscount } from '@loop/shared/sso';
const token = await generateSSOToken({
userId: 'user_123',
tier: 'pro',
});
const payload = await verifySSOToken(token);
// { sub: 'user_123', membership_tier: 'pro', discount_percent: 15 }
const discount = getTierDiscount('pro'); // 15Commerce
Discount calculation and display:
import { getDiscountPercent, calculateDiscount, formatDiscountDisplay, isEligibleForDiscount } from '@loop/shared/commerce';
getDiscountPercent('pro'); // 15
calculateDiscount(100, 'pro'); // 85
formatDiscountDisplay(15); // '15% off'
isEligibleForDiscount('free'); // falseError Classes
import { AppError, AuthError, NotFoundError, ValidationError, ForbiddenError } from '@loop/shared';
throw new NotFoundError('Profile', 'prof_123');
throw new AuthError('Invalid token');
throw new ValidationError('Email is required');Constants
import { ALLOWED_DOMAINS, SUBSCRIPTION_TIERS, STACK_CATEGORIES, JWT_CONFIG, RATE_LIMITS } from '@loop/shared';Config Loading
Environment-aware configuration:
import { loadConfig, requireEnvVars } from '@loop/shared';
const config = loadConfig(); // Validates and returns typed config
requireEnvVars(['DATABASE_URL', 'CLERK_SECRET_KEY']); // Throws if missingUtility Functions
import { generateCorrelationId, sleep, retry, omit, pick, isDefined, toISOString } from '@loop/shared';
const id = generateCorrelationId(); // 'corr_abc123...'
await sleep(1000); // Wait 1 second
const result = await retry(fn, 3); // Retry up to 3 times
const subset = pick(obj, ['a', 'b']); // Pick keys
const rest = omit(obj, ['secret']); // Omit keysUsed By
@loop/shared is used by most applications in the Loop Platform:
- @loop/admin — Zod schemas, types, and constants
- @loop/my-loop-health — Shared types, schemas, and config
- @loop/loop-health — Types and constants
- @loop/loop-health-mobile — Shared types and schemas
- @loop/call-booking — Types and validation schemas
- @loop/embeddings-api — Shared types and constants