- Chat as little as possible. Use short single-line sentences and be critical & strict.
- Do not try to unnecessarily please.
- Always use
./gradlew - Run app:
./gradlew :app:run - Run tests:
./gradlew :app:test - The app is a Kotlin/JVM Desktop app using Compose Multiplatform.
- Requires
OPENAI_API_KEYenvironment variable at runtime.
app/src/main/kotlin/org/example/project/
├── main.kt # Entry point, wires dependencies, launches windows
├── dependencies.kt # Manual DI: creates all services and injects them
├── AppColorScheme.kt # Material3 color scheme
├── chat/ # Chat UI + agent (ChatAgent, ChatViewModel, ChatScreen)
├── admin/ # Admin UI (products, orders, merchants, dashboard)
│ ├── app/AdminRoute.kt # Top-level admin navigation
│ ├── data/AdminDatabase.kt # DataSource / DB initialization
│ ├── products/, orders/, merchants/, shared/
├── domain/ # Business logic, services, repositories
│ ├── admin/ # Admin-specific services + repos
│ │ ├── dashboard/ # AdminDashboardService, AdminDashboardRepository
│ │ ├── merchants/ # AdminMerchantService
│ │ ├── orders/ # AdminOrderService, AdminOrderRepository, AdminOrderModels
│ │ └── products/ # (admin product service/repo)
│ ├── catalog/ # Product, Merchant, CatalogService
│ ├── order/ # Order, OrderService, OrderRepository, OrderStatus
│ ├── character/ # Character, CharacterService, CharacterRepository
│ ├── cart/ # Cart, CartService, CartRepository
│ ├── currency/ # Currency, CurrencyService
│ ├── review/ # Review, ReviewService
│ ├── shipping/ # Shipping, ShippingService
│ ├── wishlist/ # Wishlist, WishlistService
│ └── shared/ # Ids.kt (type aliases), Page.kt
├── db/ # SQLite setup, Exposed table definitions, demo seeder
└── koog/ # AI agent infrastructure (JdbcChatHistoryProvider, tools)
- Package:
org.jetbrains.exposed.v1.*(e.g.,org.jetbrains.exposed.v1.core.*,org.jetbrains.exposed.v1.jdbc.*) - DSL functions (
selectAll,update,insert,deleteWhere) are inorg.jetbrains.exposed.v1.jdbc - Wrap DB calls in
database.suspendTransaction { ... }(extension fromdb/SqliteDatabase.kt)
- Functions returning
nullas an absent-row signal must haveOrNullsuffix (e.g.,loadOrderDetailOrNull) - Type-safe ID aliases live in
domain/shared/Ids.kt
ChatAgentuses koog withsimpleOpenAIExecutor- Chat history persisted to SQLite via
JdbcChatHistoryProvider - Tools added to the agent live in
koog/(e.g.,AskQuestionTool)
- ViewModels use
androidx.lifecycle.viewmodel; factories created with companionfactory()functions - UI state is
StateFlowcollected viacollectAsState() - Admin UI components are in
admin/shared/ui/
- Tests live in
app/src/test/kotlin/org/example/project/ - Use JUnit 5 + coroutine test utilities