- Files:
kebab-casefor utility files; Vue SFCs usePascalCase.vue - Components:
PascalCase(DashboardView,TalkReviewCard) - Composables:
use-prefix for future Vue composables - API routes: Active APIs live in
server/app.tsorserver/routes/*; legacy Next APIs remain underapp/api - Types:
PascalCaseinterfaces,camelCaseproperties (QuizSession,event_date) - DB helpers:
verb + entitypattern (getAllEvents,getEventById,createEvent,updateEvent) - Constants:
SCREAMING_SNAKE_CASE(POLL_INTERVAL_MS,REVEALING_DURATION_MS)
src/— active Vue app shell, routes, views, stores, and future composablessrc/components/ui/— active Vue shared primitives mounted or reused across views, such as the global Sonner toastersrc/lib/— browser-side app helpers such asnotify, alongside legacy-compatible shared modulesserver/— active Hono API and Bun production entrypointapp/(public)/— legacy Next public routes kept as migration referenceapp/(admin)/admin/— legacy Next admin routes kept as migration referenceapp/api/— legacy Next API routes kept as migration referencecomponents/— legacy React components split by domain (admin/,archive/,slides/) +ui/lib/mock-db/— one file per entity, all exported functions are asynchooks/— legacy React hooks only; future Vue state should use Pinia stores/composables undersrc/
Active Vue views call Hono APIs with same-origin fetch:
const response = await fetch('/api/overview');
const overview = await response.json();Use Hono context responses from active API handlers:
app.get('/api/events', async (c) => c.json(await getAllEvents()));Always use typed entity helpers from lib/mock-db/ — never call readData/writeData directly from routes:
import { getAllEvents, createEvent } from '@/lib/mock-db/events';
const events = await getAllEvents();Keep quiz state reads and phase changes separate:
await fetch('/api/quiz/state/advance', { method: 'POST', body: JSON.stringify({ session_id }) });
const state = await fetch(`/api/quiz/state?sessionId=${session_id}`);GET /api/quiz/state should stay read-only. Hide correct_index from current_question; reveal player-specific correctness through player_result.correct_index only after a player has answered.
Auth and role checks have not been migrated yet. Add them in the Hono server first so the Vue app can rely on same-origin session cookies.
Use dc-* Tailwind classes for all brand colors. For programmatic style generation (e.g. status badges), use getStatusBadge(status) from lib/design-system.ts:
const { className, label } = getStatusBadge(talk.status);The next rebrand should align public app surfaces with the devcongress.org light theme rather than preserving the dark companion palette:
- Background:
#F5F2E8 - Ink/text:
#111111 - Brand yellow:
#F5E642 - Brand pink:
#E8117F - Subtle border:
#E0DDD4 - Mid text:
#555555 - Muted text:
#888888
Keep tailwind.config.ts, src/styles.css, and lib/design-system.ts synchronized when applying the theme.
Use notify from src/lib/notify.ts for app notifications so all messages target the globally mounted AppToaster and inherit the editorial/ops Sonner theme. Do not import toast from vue-sonner directly inside views unless a feature needs a deliberate separate toaster.
- Seed script at
data/seed.tsserves as the manual data setup mechanism. - Run with:
pnpm seed - Run tests with:
pnpm test
- No auth middleware — active Hono APIs do not have server-side access control yet. Add session/role checks before exposing admin mutations.
- Simulated delay in API routes —
SIMULATED_DELAY_MSsetTimeoutin every route. Remove before production.