Project-Rivet / context /packs /typescript_patterns.md
HumboldtJoker's picture
Upload folder using huggingface_hub
4554903 verified
|
Raw
History Blame Contribute Delete
4.7 kB

TypeScript Patterns for Multiverse Campus

Express Route Pattern (with auth)

import { Router } from 'express';
import { requireAuth, requireAdmin } from '../middleware/auth';

const router = Router();

// All routes require auth unless explicitly public
router.use(requireAuth);

router.get('/resource', async (req, res) => {
  try {
    const result = await service.getResource(req.user.studentId);
    res.json({ success: true, data: result });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

// Admin routes
router.put('/resource/:id', requireAdmin, async (req, res) => { ... });

Zustand Store Pattern

import { create } from 'zustand';

interface ResourceStore {
  items: Resource[];
  loading: boolean;
  error: string | null;
  fetch: () => Promise<void>;
  update: (id: string, data: Partial<Resource>) => void;
}

export const useResourceStore = create<ResourceStore>((set, get) => ({
  items: [],
  loading: false,
  error: null,
  fetch: async () => {
    set({ loading: true, error: null });
    try {
      const res = await api.get('/resource');
      set({ items: res.data, loading: false });
    } catch (err) {
      set({ error: err.message, loading: false });
    }
  },
  update: (id, data) => {
    set(state => ({
      items: state.items.map(item =>
        item.id === id ? { ...item, ...data } : item
      ),
    }));
  },
}));

Socket.IO Handler Pattern (server, PM2 cluster-safe)

export function registerHandlers(io: Server, socket: AuthenticatedSocket) {
  socket.on('resource:action', async (payload, callback) => {
    try {
      // Validate payload
      const { resourceId } = validatePayload(payload);
      
      // Perform action
      const result = await service.performAction(socket.userId, resourceId);
      
      // Broadcast to room (Redis adapter handles cross-process)
      io.to(`resource:${resourceId}`).emit('resource:updated', result);
      
      // Acknowledge to sender
      callback({ success: true, data: result });
    } catch (err) {
      callback({ success: false, error: err.message });
    }
  });
}

Database Transaction Pattern (pg-boss safe)

import { getPool } from '../db';

async function transferGems(fromId: string, toId: string, amount: number) {
  const pool = getPool();
  const client = await pool.connect();
  
  try {
    await client.query('BEGIN');
    
    // Debit
    const debit = await client.query(
      'UPDATE students SET gems = gems - $1 WHERE id = $2 AND gems >= $1 RETURNING gems',
      [amount, fromId]
    );
    if (debit.rowCount === 0) throw new Error('Insufficient gems');
    
    // Credit
    await client.query(
      'UPDATE students SET gems = gems + $1 WHERE id = $2',
      [amount, toId]
    );
    
    await client.query('COMMIT');
  } catch (err) {
    await client.query('ROLLBACK');
    throw err;
  } finally {
    client.release();
  }
}

Migration Pattern (additive only)

// migrations/YYYYMMDDHHMMSS_add_feature_column.ts
import { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
  await knex.schema.alterTable('students', table => {
    table.timestamp('last_login_at').nullable().defaultTo(null);
    table.index('last_login_at'); // Only if frequently queried
  });
}

export async function down(knex: Knex): Promise<void> {
  await knex.schema.alterTable('students', table => {
    table.dropColumn('last_login_at');
  });
}
// NOTE: down() exists for dev rollback only.
// In production, prefer a NEW migration that deprecates rather than drops.

Error Handling Pattern

// Custom error classes for typed error handling
class AppError extends Error {
  constructor(
    message: string,
    public statusCode: number = 500,
    public code: string = 'INTERNAL_ERROR'
  ) {
    super(message);
  }
}

class NotFoundError extends AppError {
  constructor(resource: string, id: string) {
    super(`${resource} ${id} not found`, 404, 'NOT_FOUND');
  }
}

class AuthorizationError extends AppError {
  constructor(action: string) {
    super(`Not authorized to ${action}`, 403, 'FORBIDDEN');
  }
}

// Express error middleware
function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) {
  if (err instanceof AppError) {
    return res.status(err.statusCode).json({
      success: false,
      error: { code: err.code, message: err.message },
    });
  }
  // Unknown errors — log and return generic
  console.error('Unhandled error:', err);
  res.status(500).json({ success: false, error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' } });
}