diff --git a/STACK.md b/STACK.md index 46f24d8..3941a5a 100644 --- a/STACK.md +++ b/STACK.md @@ -1,3 +1,167 @@ -# Libraries to use +# SummerCMS Technology Stack +## Philosophy +**Direct-style Scala 3 on JDK 21 virtual threads.** No monadic effect systems (no ZIO, no Cats Effect). Virtual threads make blocking IO cheap, so you write normal imperative-looking code that scales. This is the simplest possible modern Scala stack. + +--- + +## Core Stack + +| Layer | Technology | Why | +|-------|-----------|-----| +| **Language** | Scala 3.3+ LTS | VirtusLab maintains the compiler. Scala 3 has cleaner syntax, given/using for DI, extension methods, enums, union types | +| **Runtime** | JDK 21+ with Project Loom | Virtual threads = millions of lightweight threads, no async/callback hell | +| **HTTP Server** | Tapir + JDK HttpServer | Tapir gives type-safe endpoint definitions with auto-generated OpenAPI docs. JDK HttpServer with `Executors.newVirtualThreadPerTaskExecutor()` is the lightest possible server | +| **Concurrency** | Ox | Structured concurrency, Go-like channels, error supervision, retries, rate limiting. Built on virtual threads | +| **Database** | Magnum | Scala 3 native, typesafe SQL interpolator, auto-generated CRUD, no dependencies, works with any JDBC database | +| **Migrations** | Flyway | Industry standard, JVM-native, works with any JDBC database | + +## Supporting Libraries + +| Concern | Library | Notes | +|---------|---------|-------| +| **JSON** | uPickle or Circe | Serialization/deserialization for API + config | +| **Config** | Typesafe Config (HOCON) | Industry standard JVM config, supports YAML-like nesting, env var substitution | +| **Logging** | SLF4J + Logback | Standard JVM logging | +| **Caching** | Caffeine (in-memory) + Jedis/Lettuce (Redis) | Caffeine is the fastest JVM cache; Redis for distributed | +| **Hashing** | jBCrypt + JDK crypto | Password hashing + general encryption | +| **Email** | Jakarta Mail | Standard JVM email | +| **Admin Frontend** | Vue.js 3 + TypeScript | SPA admin panel consuming Tapir API | +| **OpenAPI codegen** | Tapir -> OpenAPI -> openapi-typescript | Auto-generated TS types for Vue frontend | +| **Template Engine** | Scalate (Mustache/SSP) or Twirl | Server-rendered public-facing themes | +| **CLI** | Decline or Scopt | Console command parsing for scaffolding | +| **Testing** | MUnit or ScalaTest + Tapir test utils | Unit + integration testing | +| **Build (project)** | sbt | Multi-module build for the 20+ subprojects | +| **Build (scripts)** | scala-cli | Quick scripts, prototyping, dev tooling. VirtusLab maintains it | + +--- + +## Module Mapping: Laravel Illuminate -> SummerCMS + +Each module = separate sbt subproject, publishable independently (like Illuminate packages). + +| Illuminate Package | SummerCMS Module | Implementation Approach | +|-------------------|-----------------|------------------------| +| **Container** | `summer-container` | Scala 3 `given`/`using` for compile-time DI + lightweight runtime registry for plugins | +| **Contracts** | `summer-contracts` | Scala traits — all public APIs defined here | +| **Support** | `summer-support` | Extension methods, utility types, base classes | +| **Config** | `summer-config` | Typesafe Config wrapper, HOCON files | +| **Pipeline** | `summer-pipeline` | Function composition `(A => A)*` — trivial in Scala | +| **Events** | `summer-events` | Simple event bus with typed events + Ox channels for async | +| **Http** | `summer-http` | Tapir endpoint definitions, request/response wrappers | +| **Routing** | `summer-routing` | Tapir endpoints are already type-safe routes — combine with auto-discovery | +| **Database** | `summer-database` | Magnum repos + case class models + query builder | +| **Auth** | `summer-auth` | JWT tokens (for API) + session cookies (for admin), guards as traits | +| **Validation** | `summer-validation` | Compile-time via Scala types + runtime rules engine (inspired by fields.yaml) | +| **Cache** | `summer-cache` | Caffeine + Redis, driver-based via trait | +| **Queue** | `summer-queue` | Ox channels + virtual threads for workers, persistent queue via DB or Redis | +| **Mail** | `summer-mail` | Jakarta Mail wrapper with template support | +| **Console** | `summer-console` | CLI command framework for scaffolding (`summer create:plugin`, etc.) | +| **Session** | `summer-session` | Cookie/DB-backed sessions for admin panel | +| **Filesystem** | `summer-filesystem` | `java.nio.file` + S3 adapter | +| **Translation** | `summer-translation` | i18n with HOCON/JSON locale files | +| **View** | `summer-view` | Template engine for admin panel rendering | +| **Log** | `summer-log` | SLF4J facade, minimal wrapper | +| **Collections** | *(not needed)* | Scala stdlib collections are already excellent | +| **Pagination** | `summer-pagination` | Generic paginator for Magnum query results | + +--- + +## Plugin & Theme System + +### Plugins + +Each plugin = a directory with a `Plugin.scala` descriptor (same lifecycle as WinterCMS). + +- Descriptor declares: models, controllers, components, console commands, event listeners, navigation items +- Plugins discovered at boot via classpath scanning or manifest +- Plugins can extend other plugins' models via Scala 3 extension methods + event hooks +- Plugin lifecycle: `register()` -> `boot()` + +### Components + +- Components are defined in plugins and placed in theme templates (like WinterCMS) +- Each component = a class with `onRun()`, properties, and a partial template +- Components handle their own data fetching and expose variables to templates +- Registered via plugin descriptor, auto-discovered by the theme engine + +### Themes + +- Theme = directory of templates + assets + config +- Templates rendered server-side (Scalate/Twirl) or served as SPA shell +- Components (from plugins) can be placed in theme templates + +--- + +## Admin Backend + +- Tapir endpoints serve as the admin API +- **YAML/JSON-driven forms** — same concept as WinterCMS `fields.yaml` / `columns.yaml`: + - Plugin defines `fields.yaml` for model forms + - Backend returns form schema as JSON, Vue frontend renders it + - Field types: text, textarea, dropdown, relation, repeater, etc. +- **Admin frontend: Full SPA in Vue.js 3 + TypeScript** — consumes Tapir-generated typed API + - TypeScript types auto-generated from Tapir OpenAPI spec + - Vue components for form builder, list columns, relation managers, etc. + +--- + +## Frontend-Backend Communication + +- **Tapir-generated typed API** — all communication is via typed JSON endpoints +- OpenAPI spec auto-generated from Tapir endpoint definitions +- TypeScript client types generated from OpenAPI for the Vue admin SPA +- Public-facing sites can use the same API (headless mode) or server-rendered templates +- Headless mode: admin panel + API controllers serve as a superuser data presentation layer, frontend is fully decoupled + +--- + +## Scaffolding Commands + +``` +summer create:plugin vendor.pluginname +summer create:model vendor.pluginname ModelName +summer create:controller vendor.pluginname ControllerName +summer create:component vendor.pluginname ComponentName +summer create:command vendor.pluginname CommandName +summer create:job vendor.pluginname JobName +summer create:migration vendor.pluginname description +``` + +--- + +## Project Structure + +``` +summercms/ + build.sbt # Multi-project sbt build + modules/ + summer-container/ + summer-contracts/ + summer-support/ + summer-config/ + summer-pipeline/ + summer-events/ + summer-http/ # Tapir integration + summer-routing/ + summer-database/ # Magnum integration + summer-auth/ + summer-validation/ + summer-cache/ + summer-queue/ # Ox integration + summer-mail/ + summer-console/ + summer-session/ + summer-filesystem/ + summer-translation/ + summer-view/ + summer-log/ + summer-pagination/ + app/ # Full CMS application (depends on all modules) + summer-cms/ # Assembled CMS with admin panel + plugins/ # Example/core plugins + summer-plugin-user/ + summer-plugin-blog/ + summer-plugin-pages/ +```