This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Frontier Forge is a streamlined voting platform for the Frontier Tower community to propose and prioritize building improvements. Ideas flow through submission → voting → approval → external tracking. Discussion happens in Telegram, project tracking happens in GitHub/Linear.
npm run dev # Start development server (http://localhost:5173)
npm run build # Build for production
npm run preview # Preview production build
npm run check # Type-check and validate Svelte components
npm run check:watch # Type-check in watch modenpm run db:generate # Generate Prisma client after schema changes
npm run db:push # Push schema to database (no migrations)
npm run db:studio # Open Prisma Studio GUI for database management
npm run db:seed # Seed database with test data (when implemented)- SvelteKit 5 with Svelte runes (
$state,$derived,$effect) for reactivity - Prisma ORM with PostgreSQL hosted on Supabase (shared pooler, no IPv4 addon)
- SSE (Server-Sent Events) via
sveltekit-ssefor real-time updates - Frontier Tower OAuth for authentication (JWT sessions)
- Frontier Tower Design System - Modern Professional Elegance with comprehensive component library
// State management with runes
let ideas = $state([]); // Reactive state
let filtered = $derived(ideas.filter(...)); // Computed values
$effect(() => { /* side effects */ }); // React to changesThe platform uses Server-Sent Events for one-way server→client updates:
- Server Broadcasting (
/api/sse/+server.ts): Maintains connections and emits events - Event Types:
new_idea,vote_update,idea_status_change - Client Store (
sse-updates.svelte.ts): Manages SSE connection and distributes updates - Broadcaster Utility (
sse-broadcaster.ts): Triggers broadcasts after database changes
Flow: Database change → sseBroadcaster.broadcast*() → SSE endpoint → Connected clients
Idea Lifecycle States:
OPEN→ Active for votingAPPROVED→ Approved for implementationPROJECT→ Implementation started (tracked externally)ARCHIVED→ Completed or rejected
- User clicks sign in → Redirects to
/auth/login - OAuth with Frontier Tower (test mode:
code=test-code) - Callback creates JWT token via
joselibrary - Token stored in httpOnly session cookie
getUserFromSession()validates on each request
// +page.server.ts
export const actions = {
default: async ({ request, cookies }) => {
const user = await getUserFromSession(cookies);
// Process form data
return { success: true };
}
};The VoteButton component demonstrates optimistic updates:
- Update UI immediately
- Send request to server
- Revert if request fails
- Broadcast SSE update on success
// +page.server.ts
export const load: PageServerLoad = async () => {
const ideas = await prisma.idea.findMany({
include: { votes: true, submitter: true }
});
return { ideas };
};- Homepage feed with Rising/Forged filters
- Idea submission form
- Upvoting with optimistic updates
- Top 5 ideas view (formerly assembly)
- SSE real-time updates for votes and new ideas
- JWT authentication with Frontier Tower OAuth
- Tailwind CSS styling with custom design system
- Simplified project model with external tracking links
- Idea detail pages (
/idea/[id]) - simplified without comments - User profiles
- Email notifications via Resend
- Search and filtering
- Admin approval workflow
Required environment variables (see .env.example):
DATABASE_URL- Supabase PostgreSQL with poolerDIRECT_URL- Direct connection for migrationsJWT_SECRET- At least 32 characters for session tokensFRONTIER_*- OAuth credentials (test mode available)RESEND_API_KEY- Email service (optional for now)
- Node.js 20.19+ required (SvelteKit 5 dependency)
- No migrations: Uses
db:pushfor schema changes - SSE Limitations: In-memory connection storage (needs Redis for multi-instance)
- Test Auth: Use
code=test-codefor development OAuth flow
Frontier Forge uses the Frontier Tower Design System implementing Modern Professional Elegance:
--surface-0: Background level (subtle warmth)
--surface-1: Cards, modals (elevated white)
--surface-2: Hover states (cooler contrast)
--surface-3: Active elements (highest contrast)/* Buttons */
.btn-primary # Frontier purple, primary actions
.btn-secondary # Neutral, secondary actions
.btn-destructive # Red, dangerous actions
.btn-ghost # Transparent, subtle actions
/* Cards */
.card # Standard elevation
.card-elevated # Higher elevation for modals
.card-modal # Highest elevation for overlays
/* Status Indicators */
.status-success # Green for positive states
.status-warning # Orange for warnings
.status-error # Red for errors
.status-info # Blue for informational
/* Form Elements */
.input # Standard input styling
.input-error # Error state styling
.textarea # Multi-line input
.label # Form labels
.label-required # Required field indicator (adds red *)- Primary: Frontier purple (
#6B46C1) for brand elements - Success: Green for positive actions and states
- Warning: Orange for cautions and warnings
- Destructive: Red for errors and dangerous actions
- Info: Blue for informational elements
The design system automatically adapts to dark mode via CSS custom properties and prefers-color-scheme.
- Add event type to
IdeaUpdateinterface - Create broadcast method in
sse-broadcaster.ts - Call broadcaster after database operation
- Handle event in client subscription
- Comments removed - discussion happens in Telegram
- Assembly model removed - just shows top 5 voted ideas
- Project tracking simplified - just links to external tools
- Focus on core voting and prioritization functionality
- Create route folder in
src/routes/ - Add
+page.sveltefor UI - Add
+page.server.tsfor data loading/actions - Use
getUserFromSession()for protected routes
- Update
prisma/schema.prisma - Run
npm run db:push - Run
npm run db:generate - Update affected server-side code