docs(01): create phase 1 foundation plans
Phase 01: Foundation - 3 plans in 3 waves (sequential dependency) - Plan 01: Mill build + ZIO HTTP server - Plan 02: PostgreSQL + Quill + Flyway migrations - Plan 03: Repository pattern + Pulumi/Besom deployment Ready for execution
This commit is contained in:
208
.planning/phases/01-foundation/01-01-PLAN.md
Normal file
208
.planning/phases/01-foundation/01-01-PLAN.md
Normal file
@@ -0,0 +1,208 @@
|
||||
---
|
||||
phase: 01-foundation
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- build.mill
|
||||
- src/Main.scala
|
||||
- src/config/AppConfig.scala
|
||||
- src/api/Routes.scala
|
||||
- src/api/HealthRoutes.scala
|
||||
- resources/application.conf
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Developer can run `mill run` and server starts on port 8080"
|
||||
- "GET /health returns 200 with 'ok' body"
|
||||
- "Server reads configuration from application.conf"
|
||||
- "Environment variables override HOCON values"
|
||||
artifacts:
|
||||
- path: "build.mill"
|
||||
provides: "Mill build configuration with ZIO dependencies"
|
||||
contains: "zio-http"
|
||||
- path: "src/Main.scala"
|
||||
provides: "Application entry point extending ZIOAppDefault"
|
||||
exports: ["Main"]
|
||||
- path: "src/config/AppConfig.scala"
|
||||
provides: "Configuration case classes"
|
||||
exports: ["AppConfig", "ServerConfig", "DatabaseConfig"]
|
||||
- path: "src/api/Routes.scala"
|
||||
provides: "Route composition"
|
||||
exports: ["Routes"]
|
||||
- path: "src/api/HealthRoutes.scala"
|
||||
provides: "Health check endpoint"
|
||||
contains: "/health"
|
||||
- path: "resources/application.conf"
|
||||
provides: "HOCON configuration with env overrides"
|
||||
contains: "server.port"
|
||||
key_links:
|
||||
- from: "src/Main.scala"
|
||||
to: "src/api/Routes.scala"
|
||||
via: "Server.serve(routes)"
|
||||
pattern: "Server\\.serve"
|
||||
- from: "src/Main.scala"
|
||||
to: "resources/application.conf"
|
||||
via: "ConfigProvider.fromResourcePath"
|
||||
pattern: "ConfigProvider"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Set up the Mill build system and create a working ZIO HTTP server with health endpoints and HOCON configuration.
|
||||
|
||||
Purpose: Establish the foundational build infrastructure and prove the ZIO HTTP stack works before adding database complexity.
|
||||
Output: Running HTTP server accessible at localhost:8080 with /health endpoint.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/jin/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/jin/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/phases/01-foundation/01-CONTEXT.md
|
||||
@.planning/phases/01-foundation/01-RESEARCH.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create Mill build configuration</name>
|
||||
<files>build.mill</files>
|
||||
<action>
|
||||
Create Mill build file with Scala 3 and ZIO dependencies.
|
||||
|
||||
Use programmatic Mill config (build.mill not YAML) for assembly support:
|
||||
- Scala version: 3.3.4 (LTS, better library compatibility than 3.8.x)
|
||||
- Dependencies:
|
||||
- dev.zio::zio:2.1.14
|
||||
- dev.zio::zio-http:3.0.1 (stable release, not 3.8.x which is unreleased)
|
||||
- dev.zio::zio-config:4.0.2
|
||||
- dev.zio::zio-config-typesafe:4.0.2
|
||||
- dev.zio::zio-config-magnolia:4.0.2
|
||||
- io.getquill::quill-jdbc-zio:4.8.5
|
||||
- org.postgresql:postgresql:42.7.4
|
||||
- org.flywaydb:flyway-core:10.21.0
|
||||
- org.flywaydb:flyway-database-postgresql:10.21.0
|
||||
|
||||
Include assembly configuration for fat JAR with:
|
||||
- Service file merging for META-INF/services
|
||||
- Exclude signature files (*.SF, *.DSA, *.RSA)
|
||||
|
||||
Note: Research suggested newer versions but use stable releases that exist on Maven Central.
|
||||
</action>
|
||||
<verify>Run `mill resolve _` to verify Mill parses the build file correctly</verify>
|
||||
<done>build.mill exists and Mill can parse all dependencies</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Create project structure and configuration</name>
|
||||
<files>
|
||||
src/config/AppConfig.scala
|
||||
resources/application.conf
|
||||
</files>
|
||||
<action>
|
||||
Create configuration infrastructure:
|
||||
|
||||
1. src/config/AppConfig.scala:
|
||||
- Case class AppConfig with server and database nested configs
|
||||
- Case class ServerConfig(host: String, port: Int)
|
||||
- Case class DatabaseConfig(host: String, port: Int, database: String, user: String, password: String)
|
||||
- Use zio-config-magnolia for automatic derivation
|
||||
|
||||
2. resources/application.conf (HOCON):
|
||||
```hocon
|
||||
server {
|
||||
host = "0.0.0.0"
|
||||
host = ${?SERVER_HOST}
|
||||
port = 8080
|
||||
port = ${?SERVER_PORT}
|
||||
}
|
||||
|
||||
database {
|
||||
host = "localhost"
|
||||
host = ${?DB_HOST}
|
||||
port = 5432
|
||||
port = ${?DB_PORT}
|
||||
database = "summercms"
|
||||
database = ${?DB_NAME}
|
||||
user = "summercms"
|
||||
user = ${?DB_USER}
|
||||
password = "summercms"
|
||||
password = ${?DB_PASSWORD}
|
||||
}
|
||||
```
|
||||
|
||||
Pattern: Environment variables override defaults using HOCON substitution syntax.
|
||||
</action>
|
||||
<verify>Files exist at correct paths</verify>
|
||||
<done>AppConfig case classes defined, application.conf has all database and server settings with env overrides</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Create HTTP routes and Main entry point</name>
|
||||
<files>
|
||||
src/api/HealthRoutes.scala
|
||||
src/api/Routes.scala
|
||||
src/Main.scala
|
||||
</files>
|
||||
<action>
|
||||
Create the HTTP layer:
|
||||
|
||||
1. src/api/HealthRoutes.scala:
|
||||
- Object HealthRoutes with `routes` val returning Routes
|
||||
- GET /health -> Response.text("ok")
|
||||
- Keep simple for now; /ready endpoint added when database exists
|
||||
|
||||
2. src/api/Routes.scala:
|
||||
- Object Routes that composes all route modules
|
||||
- For now, just re-exports HealthRoutes.routes
|
||||
- This is the composition point for future route modules
|
||||
|
||||
3. src/Main.scala:
|
||||
- Object Main extends ZIOAppDefault
|
||||
- Override bootstrap to set ConfigProvider.fromResourcePath()
|
||||
- In run: Server.serve(Routes.routes).provide(Server.defaultWithPort(8080))
|
||||
- Print ASCII art banner on startup (SummerCMS with sun motif)
|
||||
|
||||
ASCII banner example:
|
||||
```
|
||||
\\ | //
|
||||
\\ | //
|
||||
___\\###//___
|
||||
/ SUMMER \\
|
||||
\\ CMS /
|
||||
\\__________/
|
||||
|
||||
Starting on port 8080...
|
||||
```
|
||||
</action>
|
||||
<verify>Run `mill run` and curl localhost:8080/health returns "ok"</verify>
|
||||
<done>Server starts, /health returns 200 with "ok" body, banner displays</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
1. `mill resolve _` succeeds (build file valid)
|
||||
2. `mill compile` succeeds (code compiles)
|
||||
3. `mill run` starts server (process runs)
|
||||
4. `curl http://localhost:8080/health` returns "ok" (endpoint works)
|
||||
5. Server logs show startup banner
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Mill build configuration exists with all ZIO dependencies
|
||||
- Server starts on port 8080 via `mill run`
|
||||
- GET /health returns 200 OK with "ok" body
|
||||
- Configuration loads from application.conf
|
||||
- ASCII SummerCMS banner displays on startup
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user