4.4 KiB
4.4 KiB
Copilot Instructions for Ionian
Project Overview
Ionian is a full-stack content file management system focused on comic/media files. It's a pnpm monorepo with 3 packages: server
(Elysia.js API), client
(React+Vite SPA), and dbtype
(shared TypeScript types).
Architecture & Key Patterns
Monorepo Structure
- Uses pnpm workspaces with
packages/*
configuration dbtype
package provides shared types between client/server- Server builds to
dist/
directory which client proxies to via Vite dev server
Server Architecture (Elysia.js + SQLite)
- Framework: Elysia.js with TypeScript, uses Kysely for type-safe SQL queries
- Database: SQLite with custom migration system in
migrations/
directory - Core Pattern: Document-centric with content types (
comic
,video
, etc.) - File Watching:
DiffManager
+ content watchers monitor filesystem changes insrc/diff/
- Permissions: Role-based system in
src/permission/permission.ts
- Routes: Organized by domain (
/api/doc/*
,/api/user/*
,/api/diff/*
)
Client Architecture (React + State Management)
- Router: Uses
wouter
(not React Router) for client-side routing - State: Jotai atoms for global state (
src/lib/atom.ts
re-exports jotai) - API: SWR for data fetching with custom hooks in
src/hook/
- UI: shadcn/ui components with Tailwind CSS, dark mode support
- Build Info: Vite injects git hash/build time via
__BUILD_*__
constants
Critical File Watching System
The diff system monitors content directories:
DiffManager
orchestrates multiple content watchersContentDiffHandler
processes filesystem changes- Watchers register via
await diffManager.register(type, watcher)
- Content changes queue in waiting lists before manual commit
Development Workflows
Build Commands
# Full deployment build (run from root)
pnpm run app:build # Builds both client and server
# Individual package builds
pnpm run compile # Server build
pnpm run build # Client build (from packages/client)
# Development
cd packages/server && pnpm run dev # tsx watch mode
cd packages/client && pnpm run dev # Vite dev server
Database Migrations
cd packages/server && pnpm run migrate
Migrations live in migrations/YYYY-MM-DD.ts
with manual version tracking.
Testing
cd packages/server && pnpm test # Vitest unit tests
cd packages/server && pnpm test:watch # Watch mode
Key Conventions
Import Patterns
- Server: Use
.ts
extensions in imports (./module.ts
) - Client: Use
@/
alias forsrc/
directory - Cross-package imports:
import { Type } from "dbtype/mod.ts"
API Design
- RESTful routes under
/api/
prefix - Elysia schema validation with
t.Object()
patterns - Permission decorators:
beforeHandle: createPermissionCheck(Permission.QueryContent)
- Error handling via
sendError()
helper and global error handler
Component Patterns
- Page components in
src/page/
directory - Reusable components in
src/components/
with ui/ subdirectory - Custom hooks in
src/hook/
for API operations - State atoms in
src/lib/atom.ts
Database Patterns
- Models in
src/model/
define interfaces - Controllers in
src/db/
implement database operations - Use Kysely query builder, not raw SQL
- Document-centric design with tag relationships
Project-Specific Context
Content Types
System supports multiple content types (comic
, video
) with extensible architecture. Comic content has special thumbnail/page rendering support.
Permission System
Three-tier permissions: Admin, User, Guest. Check src/permission/permission.ts
for available permissions.
Client-Server Communication
- Client proxies
/api/*
to server during development - Production serves client from server's static middleware
- Authentication via HTTP-only cookies with JWT refresh pattern
Common Tasks
Adding New Content Type
- Create watcher in
src/diff/watcher/
- Register in
create_server()
- Add route handler in
src/route/
- Update
dbtype
if new fields needed
Adding New API Endpoint
- Create route in appropriate
src/route/*.ts
file - Add to main router in
src/server.ts
- Define types in
dbtype
package if needed - Create client hook in
packages/client/src/hook/
UI Component Development
- Use shadcn/ui patterns in
src/components/ui/
- Use Jotai atoms for component state sharing
- Follow existing page structure patterns