TypeScript Patterns for Multiverse Campus
Express Route Pattern (with auth)
import { Router } from 'express';
import { requireAuth, requireAdmin } from '../middleware/auth';
const router = Router();
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 });
}
});
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 {
const { resourceId } = validatePayload(payload);
const result = await service.performAction(socket.userId, resourceId);
io.to(`resource:${resourceId}`).emit('resource:updated', result);
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');
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');
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)
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');
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable('students', table => {
table.dropColumn('last_login_at');
});
}
Error Handling Pattern
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');
}
}
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 },
});
}
console.error('Unhandled error:', err);
res.status(500).json({ success: false, error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' } });
}