# Setup and Development

## Overview

This project is a Kotlin Multiplatform repository with one included module, `:composeApp`. The active runtime is the desktop JVM application.

The repository currently assumes a desktop developer workflow with Gradle and local platform-native dependencies downloaded on demand.

## Prerequisites

Before running the app, make sure you have:

- Git
- a JDK compatible with the current Compose Multiplatform and Kotlin toolchain
- internet access for the first dependency resolution

Notes from the repository itself:

- the project uses the Foojay toolchain resolver in `settings.gradle.kts`
- `gradle.properties` contains a macOS note for Temurin JDK 25 in one build scenario
- the repository does not currently pin a single mandatory JDK version in Gradle configuration

## First-time setup

1. Clone the repository.
2. Open it in IntelliJ IDEA or Android Studio with Kotlin/Compose support.
3. Let Gradle sync and resolve dependencies.
4. Run a compile or test command once to download platform-specific artifacts, including JCEF natives for your OS and CPU architecture.

## Main commands

The repository convention is to use Windows commands by default.

### Run the desktop app

```powershell
.\gradlew.bat :composeApp:run
```

### Compile the JVM target

```powershell
.\gradlew.bat :composeApp:compileKotlinJvm
```

### Run all JVM tests

```powershell
.\gradlew.bat :composeApp:jvmTest
```

### Run one JVM test class

```powershell
.\gradlew.bat :composeApp:jvmTest --tests "*DailyFeedViewModelTest"
```

### Run common and JVM verification

```powershell
.\gradlew.bat :composeApp:check
```

## What happens on the first run

Expect a slower first run because Gradle may need to download:

- Compose Multiplatform artifacts
- Ktor, Koin, Coil, and Voyager dependencies
- JCEF Maven runtime artifacts
- the platform-specific JCEF native bundle selected by `composeApp/build.gradle.kts`

## Development map by area

Use this map to open the right part of the codebase quickly.

| Task area | Start here |
| --- | --- |
| App bootstrap and DI | `App.kt`, `di/AppModules.kt`, `presentation/root/AppRootScreenModel.kt` |
| Authentication and session | `presentation/auth`, `domain/session`, `data/session`, `jvmMain/data/auth` |
| Daily feed | `presentation/dailyfeed`, `domain/usecase/GetDailyFeedUseCase.kt`, `thulur_api/methods/daily_feed` |
| Thread history | `presentation/dailyfeed/thread_history`, `domain/usecase/GetThreadHistoryUseCase.kt` |
| Chat | `presentation/chat`, `domain/usecase/SendGeneralChatMessageUseCase.kt`, `domain/usecase/SendThreadChatMessageUseCase.kt`, `thulur_api/methods/chat` |
| Settings and feeds | `presentation/settings`, `thulur_api/methods/settings`, `thulur_api/methods/feeds` |
| Article reader | `presentation/dailyfeed/article_reader`, `jvmMain/presentation/dailyfeed/article_reader` |
| Theme | `presentation/theme`, `domain/theme`, `jvmMain/data/theme` |
| Backend contract changes | `thulur_api/dtos`, `thulur_api/methods`, `data/repository/RemoteThulurApiRepository.kt` |

## Expected workflow for code changes

### UI and feature work

1. Start from the relevant `presentation/*` feature folder.
2. Confirm which ViewModel owns the behavior.
3. Trace the ViewModel into domain use cases.
4. If backend data is involved, continue into `RemoteThulurApiRepository` and `thulur_api`.

### Backend contract work

1. Update or inspect the relevant method in `thulur_api/methods`.
2. Update DTOs in `thulur_api/dtos`.
3. Update repository mapping in `RemoteThulurApiRepository`.
4. Update domain models and UI code only if the shared shape changed.

### Navigation work

1. Update `presentation/router/AppRouter.kt`.
2. Update route key construction if needed.
3. Run the relevant `*RouteKeyTest.kt` files in `jvmTest`.

### Article reader work

Always inspect both shared and JVM code:

- shared screen and ViewModel behavior in `commonMain`
- JCEF runtime and web view implementation in `jvmMain`

## Runtime and local-data notes

- API base URL is hard-coded in `ThulurApiConfig` as `https://api.thulur.com`.
- Default request timeout is `15s`; chat uses `60s`.
- Theme preference is stored locally in JVM preferences.
- Token persistence prefers OS secure storage and falls back to in-memory storage.
- Read article state is in-memory only and is cleared with the session.

## Good places to orient a new developer

- `README.md`
- `docs/architecture.md`
- `docs/features-and-flows.md`
- `composeApp/src/commonMain/kotlin/com/example/thulur/di/AppModules.kt`
- `composeApp/src/commonMain/kotlin/com/example/thulur/presentation/router/AppRouter.kt`
