Skip to content

Commit

Permalink
Backend module + SQLDelight (#10)
Browse files Browse the repository at this point in the history
- Added new target - backed (optional as everything)
- Added new feature SQLDelight (preconfigured for all client platforms with showcases)
- Renamed composeApp to app (the template itself is based on compose, so no need to write this prefix in client app)
- Refactored some core components to be more simple to use
- Updated documentation, showcases and diagrams
  • Loading branch information
kotlitecture committed Jun 22, 2024
1 parent b692cfd commit 65824f5
Show file tree
Hide file tree
Showing 248 changed files with 1,743 additions and 200 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ captures
**/xcshareddata/WorkspaceSettings.xcsettings
*.lock
.kotlin
*-lock.json
71 changes: 55 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
# Compose Multiplatform Configurable Project Template

Supported platforms:
## Supported Platforms

- Android
- iOS
- Web
- Web (JS)
- Desktop (Windows, MacOS, Linux)
- Backend (Server)

```
All target platforms are optional and will be included only if selected during configuration, along with any features.
```

## Table of Contents

- [Overview](#overview)
- [Get started](#get-started)
- [Architecture](#architecture)
- [Documentation](#documentation)
- [Showcases](#showcases)
- [How to use](#how-to-use)
- [Features](#features)

# Overview

The template follows the general principals:

- The underlying architecture is minimalistic, pre-configured, and complies with [the latest recommended guidelines](https://developer.android.com/modern-android-development).
- The underlying architecture is minimalistic, pre-configured, and complies with the latest recommended guidelines.
- Third-party dependencies, components, DevOps practices, and configurations are optional and can be included or excluded through an online service [Kotli](https://kotlitecture.com).
- All out-of-the-box solutions work seamlessly across all supported platforms and are designed to accelerate the development of complex and production-ready applications within days, prioritizing simplicity and efficiency during the implementation and support phases.

# Usage
# Get started

**!IMPORTANT!** The given template is a [Kotli Template](https://kotlitecture.github.io/engine/template_overview).

Expand All @@ -28,7 +46,9 @@ Run your project to check what is included and how it works, and once everything

![Modules](images/concept/arch_modules.png)

The overall architecture is built on:
## Frontend

The overall client architecture follows [the recommended guidelines](https://developer.android.com/modern-android-development) and is built on:
- [Compose Multiplatform UI Framework](https://www.jetbrains.com/lp/compose-multiplatform/)
- [Compose Multiplatform Images and resources](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-images-resources.html)
- [Jetpack Compose](https://developer.android.com/develop/ui/compose)
Expand All @@ -37,7 +57,7 @@ The overall architecture is built on:
- [Material 3 Design](https://m3.material.io)
- [Koin Dependency Injection](https://insert-koin.io)

Application logic is implemented in the app module and contains only app-specific behavior.
Application logic is implemented in the `app` module and contains only app-specific behavior.

All common logic is part of the shared group, which is split into three modules:

Expand All @@ -47,7 +67,7 @@ All common logic is part of the shared group, which is split into three modules:

These modules are used only at the app level. This approach lets you develop all three components independently and create a more complex app structure. For example, app-specific features can be implemented as separate modules, having the same shared dependencies.

## Module - presentation
### Module - presentation

Provides architectural solutions to implement user flows and integrate all components with each other in a lifecycle-aware manner.

Expand All @@ -62,13 +82,13 @@ However, the provided implementations are very intuitive to use and cover all po

Feel free to choose what fits your needs best.

## Module - data
### Module - data

Provides a fundamental implementation of commonly used data sources in different apps. During project setup via [Kotli](https://kotlitecture.com), only the required data sources will be included.

All data sources have been configured to access the necessary data layer in a flexible and convenient manner.

## Module - design
### Module - design

Provides pre-configured themes, fonts, and UI components to establish the initial [Design System](https://en.m.wikipedia.org/wiki/Design_system) of the entire app.

Expand All @@ -82,7 +102,7 @@ The main idea of this module is to create a **Design System** that can be used b
Existing composables in this module are examples and can be changed/removed based on your needs.
```

## Module - app
### Module - app

The Application module itself contains:

Expand All @@ -91,6 +111,14 @@ The Application module itself contains:

Once you download and import the initial project structure into your IDE, the project is ready to run on a device, enabling you to understand the included functionality and start adding the required features.

## Backend

The server architecture is based on either the [Ktor Framework](https://ktor.io) or [Spring Boot](https://spring.io/projects/spring-boot).

Backend-specific logic is implemented in the `backend` module.

To enable sharing some common models between the **backend** and **frontend**, the project also includes a `domain` module as part of the **shared** group.

# Documentation

Once you've configured your project through [Kotli](https://kotlitecture.com/project) and downloaded the generated source codes, this project become fully yours and is not bound to the service. Each project includes a README.MD file in its root with the following helpful details:
Expand All @@ -109,6 +137,15 @@ When a project is configured and downloaded via [Kotli](https://kotlitecture.com
|:---------------------------------------------------------:|:-------------------------------------------------------:|:-----------------------------------------------------------------:|
| ![Showcases Overview](images/screenshots/showcases_overview.jpg) | ![Theme Dialog](images/screenshots/showcases_theme_dialog.jpg) | ![Key-Value Storage](images/screenshots/showcases_key_value_objects.jpg) |

# How to use

Once the project is downloaded, it includes the source code as well as a **README.md** file. This file visualizes all the features included as a table. The most useful columns in this table are:

- **Overview** - A summary of the feature, including all official resources used to pre-configure this feature in the template. Use it as a reference to find any additional information related to the feature.
- **Usage** - The main information related to using the feature. Use it as a starting point when you need to start working with the feature and don't know how to begin.

For example, if you configured the project with **Web** and **iOS** platforms but don't know how to run the app on them (💀), find these platforms in the table and open their **Usage** guide.

# Features

The template is highly configurable, allowing you to include only the necessary features in the app.
Expand All @@ -124,14 +161,16 @@ The generated project will include a similar table in its README.MD file, but wi
| Essentials | Material 3 | [Link](docs/Essentials/Material%203/overview.md) | - | [Link](docs/Essentials/Material%203/usage.md) |
| Essentials | Koin | [Link](docs/Essentials/Koin/overview.md) | - | - |
| Essentials | Gradle (Kotlin DSL) | [Link](docs/Essentials/Gradle%20%28Kotlin%20DSL%29/overview.md) | - | - |
| Platform | iOS | [Link](docs/Platform/iOS/overview.md) | - | - |
| Platform | Android | [Link](docs/Platform/Android/overview.md) | - | - |
| Platform | Desktop | [Link](docs/Platform/Desktop/overview.md) | - | - |
| Platform | Web | [Link](docs/Platform/Web/overview.md) | - | - |
| Platform | iOS | [Link](docs/Platform/iOS/overview.md) | - | [Link](docs/Platform/iOS/usage.md) |
| Platform | Android | [Link](docs/Platform/Android/overview.md) | - | [Link](docs/Platform/Android/usage.md) |
| Platform | Desktop | [Link](docs/Platform/Desktop/overview.md) | - | [Link](docs/Platform/Desktop/usage.md) |
| Platform | Web (JS) | [Link](docs/Platform/Web%20%28JS%29/overview.md) | - | [Link](docs/Platform/Web%20%28JS%29/usage.md) |
| Platform | Ktor Server | [Link](docs/Platform/Ktor%20Server/overview.md) | - | [Link](docs/Platform/Ktor%20Server/usage.md) |
| Dataflow | Facade Analytics API | [Link](docs/Dataflow/Facade%20Analytics%20API/overview.md) | - | [Link](docs/Dataflow/Facade%20Analytics%20API/usage.md) |
| Dataflow | Facade Config API | [Link](docs/Dataflow/Facade%20Config%20API/overview.md) | - | [Link](docs/Dataflow/Facade%20Config%20API/usage.md) |
| Dataflow | SQLDelight | [Link](docs/Dataflow/SQLDelight/overview.md) | - | [Link](docs/Dataflow/SQLDelight/usage.md) |
| Dataflow | Multiplatform Settings | [Link](docs/Dataflow/Multiplatform%20Settings/overview.md) | - | [Link](docs/Dataflow/Multiplatform%20Settings/usage.md) |
| Dataflow | Ktor | [Link](docs/Dataflow/Ktor/overview.md) | - | [Link](docs/Dataflow/Ktor/usage.md) |
| Dataflow | Ktor Client | [Link](docs/Dataflow/Ktor%20Client/overview.md) | - | [Link](docs/Dataflow/Ktor%20Client/usage.md) |
| Dataflow | Cash App Paging Library | [Link](docs/Dataflow/Cash%20App%20Paging%20Library/overview.md) | - | [Link](docs/Dataflow/Cash%20App%20Paging%20Library/usage.md) |
| Userflow | Rail Navigation | [Link](docs/Userflow/Rail%20Navigation/overview.md) | - | [Link](docs/Userflow/Rail%20Navigation/usage.md) |
| Userflow | Permanent Navigation | [Link](docs/Userflow/Permanent%20Navigation/overview.md) | - | [Link](docs/Userflow/Permanent%20Navigation/usage.md) |
Expand All @@ -144,4 +183,4 @@ The generated project will include a similar table in its README.MD file, but wi
| Userflow | Toggle Theme Button | [Link](docs/Userflow/Toggle%20Theme%20Button/overview.md) | - | [Link](docs/Userflow/Toggle%20Theme%20Button/usage.md) |
| Userflow | Data Loader | [Link](docs/Userflow/Data%20Loader/overview.md) | - | [Link](docs/Userflow/Data%20Loader/usage.md) |
| Testing | Kermit | [Link](docs/Testing/Kermit/overview.md) | - | [Link](docs/Testing/Kermit/usage.md) |
| Testing | Napier | [Link](docs/Testing/Napier/overview.md) | - | [Link](docs/Testing/Napier/usage.md) |
| Testing | Napier | [Link](docs/Testing/Napier/overview.md) | - | [Link](docs/Testing/Napier/usage.md) |
3 changes: 2 additions & 1 deletion docs/Dataflow/Facade Analytics API/overview.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# About

Simple facade API to start working with analytics events without the actual implementation. The implementation can be provided later during the development phase without changing the facade logic.
Sooner or later, the app may need to log events into an analytics system (Google Analytics, Amplitude, AppsFlyer, etc.).
The Facade Analytics API provides a general functionality to start logging events from the beginning, even without an actual implementation. Later, you can add the required implementation without impacting the entire codebase.
4 changes: 2 additions & 2 deletions docs/Dataflow/Facade Config API/overview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# About

Basic facade API to begin configuring the layer without depending on any external implementation.
The implementation can be provided later during the development phase, if necessary, without altering the facade logic.
All applications operate with some read-only configurations (feature flags, URLs, etc.) required for the app to function properly in different environments.
The Config API provides an intuitive facade for managing such configurations easily. This allows you to change the underlying implementation later (e.g., integrating Firebase Remote Config) without impacting the entire codebase.
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion docs/Dataflow/Multiplatform Settings/overview.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# About

Key-value storage API utilizing platform-specific storage to store data of any type using the common code.
During the application lifecycle, it may be necessary to persist data across app reopenings (for example, chosen language, theme, font size, and other preferences).
Key-value storage provides an efficient way to store and retrieve such data using a simple yet powerful API that can manage data of any complexity.

# Links

Expand Down
8 changes: 8 additions & 0 deletions docs/Dataflow/SQLDelight/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# About

SQLDelight generates typesafe Kotlin APIs from your SQL statements. It verifies your schema, statements, and migrations at compile-time and provides IDE features like autocomplete and refactoring which make writing and maintaining SQL simple.

# Links

- [Official Site](https://cashapp.github.io/sqldelight/)
- [Integration Guide](https://cashapp.github.io/sqldelight/2.0.2/multiplatform_sqlite/)
85 changes: 85 additions & 0 deletions docs/Dataflow/SQLDelight/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Usage

## Overview

- Component package: `app.datasource.database.sqldelight`
- DI integration: `app.di.datasource.ProvidesSqlDelightSource`

The integration includes the following components:

- **AppDatabase**: An SQLite database object generated based on the SQLDelight scripts included in the project.
- **AppSqlDelightSource**: Serves as a holder of the `AppDatabase` instance and acts as a service locator for all DAO objects.
- **User.sq**: An example script that generates the `User` entity and the DAO layer to work with it. All **SQLDelight scripts** are located in the `app/src/commonMain/sqldelight` directory.

## Create new Entity and DAO

SQLDelight generates all entities and DAO objects based on the SQL scripts.

The official guide can be found here: [https://cashapp.github.io/sqldelight/2.0.2/multiplatform_sqlite/#defining-the-schema](https://cashapp.github.io/sqldelight/2.0.2/multiplatform_sqlite/#defining-the-schema).

Imagine you need to add a new entity called **Address** and a **DAO** layer to work with it. Here are the steps to follow:

### 1. Create the `Address.sq` script in the `app/src/commonMain/sqldelight` directory

```
You can use the `User.sq` script as a template.
```

```sqldelight
CREATE TABLE IF NOT EXISTS address (
id INTEGER PRIMARY KEY NOT NULL,
country TEXT,
city TEXT,
street TEXT
);
count:
SELECT count(*) FROM address;
getAll:
SELECT * FROM address
ORDER BY id DESC;
getAllPaginated:
SELECT *
FROM address
ORDER BY id DESC
LIMIT :limit OFFSET :offset;
insert:
INSERT INTO address(country, city, street)
VALUES (?, ?, ?);
insertAddress:
INSERT INTO address
VALUES ?;
update:
UPDATE address
SET country = ?, city = ?, street = ?
WHERE id = ?;
delete:
DELETE FROM address WHERE id = ?;
```

### 2. Start using it from your code :)

Once the project is recompiled, you can access the generated entity and DAO layer from your code.

```kotlin
class EditAddressViewModel(
private val databaseSource: AppSqlDelightSource
) : BaseViewModel() {

fun onAdd() = launchAsync {
val database = databaseSource.getDatabase()
database.addressQueries.insert("Country", "City", "Street")
}

fun onDelete(address: Address) = launchAsync {
val database = databaseSource.getDatabase()
database.addressQueries.delete(address.id)
}
}
```
2 changes: 1 addition & 1 deletion docs/Platform/Desktop/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
## Run

```
./gradlew run
./gradlew :app:run
```
8 changes: 8 additions & 0 deletions docs/Platform/Ktor Server/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# About

The server can be used both as a backend and a middle layer for the Web target (if such a configuration is included). When the Web client is included, the backend module will have extra commands configured to correctly run and assemble the server with web content served at the root context path (i.e., single-page application).

# Links

- [Official Site](https://ktor.io)
- [Integration Guide](https://ktor.io/docs/server-create-a-new-project.html)
24 changes: 24 additions & 0 deletions docs/Platform/Ktor Server/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Usage

## Overview

Module: `backend`

The server is configured to run on port **8080**.
To change this behavior, edit the configuration file `backend/src/main/resources/application.yaml`.

## Run standalone server

To debug your changes:

```
./gradlew :backend:run
```

## Run SPA application

If you included the Web platform, the backend module provides a few extra Gradle commands:

- `./gradlew :backend:runDevSPA` - Runs your **backend** module with the **web** module included (debug build) to serve content at the root context path.
- `./gradlew :backend:runProdSPA` - Runs your **backend** module with the **web** module included (production build) to serve content at the root context path.
- `./gradlew :backend:assembleSPA` - Assembles your **backend** module with the **web** module included (production build).
File renamed without changes.
7 changes: 7 additions & 0 deletions docs/Platform/Web (JS)/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Usage

## Run

```
./gradlew :app:jsBrowserRun
```
7 changes: 0 additions & 7 deletions docs/Platform/Web/usage.md

This file was deleted.

6 changes: 3 additions & 3 deletions docs/Userflow/Data Loader/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

## Overview

Component package: `app.feature.loader.data`
Component package: `app.ui.loader`

The component is pre-configured at the `app.AppScreen` level to monitor state changes of the `app.AppState` instance.

If you need to modify the behavior, including colors, texts, logic, etc., simply update the `app.feature.loader.data.DataLoaderProvider` composable.
If you need to modify the behavior, including colors, texts, logic, etc., simply update the `app.ui.loader.LoaderProvider` composable.

## Example

Expand Down Expand Up @@ -57,4 +57,4 @@ class DataRepository(

### Usage without `app.AppState`

`app.feature.loader.data.DataLoaderProvider` accepts any `StoreState` instance. As this is your code, feel free to use it as needed.
`app.ui.loader.LoaderProvider` accepts any `StoreState` instance. As this is your code, feel free to use it as needed.
Binary file modified images/concept/arch_modules.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion processor/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apply from: "${project.rootDir}/gradle/kotlin/processor.gradle"

group = 'com.kotlitecture.kotli'
version = '0.2.1'
version = '0.3.0'
Loading

0 comments on commit 65824f5

Please sign in to comment.