Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The project is structured into distinct, decoupled framework modules. **Do not v
- **`cache`**: Two-level caching engine (`Cache`), L1 LRU memory cache (`L1Cache`), L2 Valkey client (`ValkeyWrapper`), CBOR binary serialization (`BinaryCodec`), bucket versioning, and single-flight loader deduplication (`SingleFlight`).
- **`exposed`**: Database connection management (`DatabaseWrapper`), Exposed ORM integration, Liquibase migrations, `@Transactional` annotations & proxying (`TransactionalProxy`), and repository base classes (`AbstractRepository`).
- **`validator`**: Reflection-based validation engine (`Validator`), constraints (`@RequireAtLeastOneValid`, `@NotNull`, `@NotBlank`, `@NotEmpty`), and `ObjectNotValidException`.
- **`ktor`**: Ktor web integrations, route annotation binding (`@RestController`, `@GetMapping`, `@PostMapping`, `@PatchMapping`), request parameter resolvers (`@QueryParam`, `@PathParam`, `@RequestBody`), automatic `@Valid` validation integration, `ResponseEntity` wrapper, `MessageDto` error response standardization, and OpenAPI metadata (`@Operation`, `@ApiResponses`, `@ApiResponse`).
- **`ktor`**: Ktor (server and client) integrations, route annotation binding (`@RestController`, `@GetMapping`, `@PostMapping`, `@PatchMapping`), request parameter resolvers (`@QueryParam`, `@PathParam`, `@RequestBody`), automatic `@Valid` validation integration, `ResponseEntity` wrapper, `MessageDto` error response standardization, OpenAPI metadata (`@Operation`, `@ApiResponses`, `@ApiResponse`), and a preconfigured HTTP client (`createHttpClient`).

For detailed architectural principles, read the [Architecture Guide](guidelines/ARCHITECTURE.md).

Expand Down
6 changes: 5 additions & 1 deletion guidelines/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ core (base logging & core utils)
- **`cache`**: Provides a two-level caching facade (`Cache`), combining an in-memory L1 LRU cache (`L1Cache`) with a distributed L2 Valkey/Redis store (`ValkeyWrapper`), CBOR binary encoding (`BinaryCodec`), bucket versioning, and concurrent loader deduplication (`SingleFlight`).
- **`exposed`**: Coordinates database connections via `DatabaseWrapper` (HikariCP + Exposed + Liquibase), provides `TransactionalProxy` dynamic proxies for `@Transactional` methods, and supplies `AbstractRepository` with an upsert DSL (`ifExists`, `newIfNotExists`, `applyFlush`).
- **`validator`**: Provides a runtime reflection-based validation engine (`Validator`) and validation annotations (`@RequireAtLeastOneValid`, `@NotNull`, `@NotBlank`, `@NotEmpty`).
- **`ktor`**: Bridges Ktor web server with framework annotations. Discovers `@RestController` endpoints, binds routes (`@GetMapping`, `@PostMapping`, `@PatchMapping`), resolves parameter arguments (`@QueryParam`, `@PathParam`, `@RequestBody`), executes automatic validation via `@Valid`, packages responses with `ResponseEntity`, generates OpenAPI metadata (`@Operation`, `@ApiResponses`), and handles error formatting via `MessageDto`.
- **`ktor`**: Bridges Ktor (server **and client**) with framework conventions. Discovers `@RestController` endpoints, binds routes (`@GetMapping`, `@PostMapping`, `@PatchMapping`), resolves parameter arguments (`@QueryParam`, `@PathParam`, `@RequestBody`), executes automatic validation via `@Valid`, packages responses with `ResponseEntity`, generates OpenAPI metadata (`@Operation`, `@ApiResponses`), handles error formatting via `MessageDto`, and exposes a preconfigured HTTP client (`createHttpClient`).

## Dependency Sharing

The framework extends itself to consuming services: **module dependencies are exposed with `api(...)`** so that projects building on the framework can use them to their full potential (e.g. `api(libs.bundles.ktorServerEcosystem)`, `api(libs.bundles.ktorClientEcosystem)`). Use `implementation` only for dependencies that are genuinely internal to a module.

## Technical Stack

Expand Down
14 changes: 14 additions & 0 deletions guidelines/CODE_STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
- **Format code consistently** adhering to Kotlin standard style guidelines.
- **Reuse existing project patterns** (e.g. factory patterns, annotations, proxy handlers).

## Imports

- **Always import symbols directly** (`import kotlinx.serialization.ExperimentalSerializationApi`); never reference a type by its fully-qualified name inline (e.g. `kotlinx.serialization.ExperimentalSerializationApi::class`). This keeps the code short and readable.

## Expression Bodies

- For expression-body functions, put the `=` at the end of the signature line and the body expression on the **next line**, indented one level:

```kotlin
@GetMapping("/ok")
fun ok(): ResponseEntity<Book> =
ResponseEntity.ok(Book(1, "Dune"))
```

## Comments & Intent

When adding internal framework handlers or reflection logic, document the technical rationale:
Expand Down
9 changes: 9 additions & 0 deletions guidelines/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ class MyComponentTest {
// ... tests
}
```

## 6. Test Every Public Framework API

The framework is **consumed by other projects**: every public API it ships (server controllers, the preconfigured `HttpClient`, argument resolvers, response wrappers, etc.) must be covered by tests. This makes dependency upgrades explicit: a **Ktor** (or other framework dependency) bump that changes behavior — or a version that drifts — immediately breaks a framework test, instead of silently shipping a broken version to consuming projects.

- **Server side**: use Ktor's test host (`io.ktor:ktor-server-test-host`) to start routes/controllers in-process and exercise them without a real network server.
- **Client side**: use `io.ktor:ktor-client-mock` (MockEngine) to test the `HttpClient` deterministically (request building, content negotiation/serialization, timeouts) with no network, asserting on request/response fixtures.
- **A public API change without a corresponding test is an incomplete change.**
- Run the full suite with `./gradlew test` before submitting.
2 changes: 1 addition & 1 deletion ktor/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This file contains specific rules for the `ktor` submodule. All agents working within this submodule must strictly adhere to these guidelines in addition to the root [`AGENTS.md`](../AGENTS.md).

## Module Purpose & Scope
The `ktor` module provides web framework integration for Ktor Server. It handles `@RestController` discovery, route mapping (`@GetMapping`, `@PostMapping`, `@PatchMapping`), request argument resolution (`@QueryParam`, `@PathParam`, `@RequestBody`), automatic `@Valid` validation, `ResponseEntity` packaging, `MessageDto` response serialization, and OpenAPI documentation generation.
The `ktor` module provides web framework integration for Ktor (server **and client**). It handles `@RestController` discovery, route mapping (`@GetMapping`, `@PostMapping`, `@PatchMapping`), request argument resolution (`@QueryParam`, `@PathParam`, `@RequestBody`), automatic `@Valid` validation, `ResponseEntity` packaging, `MessageDto` response serialization, and OpenAPI documentation generation, as well as framework-aware HTTP clients (e.g. a preconfigured `HttpClient`).

## Submodule-Specific Rules (Règles du sous-module)

Expand Down
Loading