genesis-stack 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,188 @@
1
+ # Stack piece: rails
2
+
3
+ ## Description
4
+
5
+ Ruby on Rails application, Bundler, Active Record, Action Pack, assets, and
6
+ framework lifecycle conventions. Identified by `Gemfile.lock` listing `rails`,
7
+ `bin/rails`, `config/application.rb`, and `config/database.yml`.
8
+ Authoritative framework documentation: https://guides.rubyonrails.org/
9
+
10
+ ## Requires
11
+
12
+ - `ruby`
13
+
14
+ ## Guidance
15
+
16
+ - Use the Rails version locked in `Gemfile.lock` and its matching guides and
17
+ API documentation. Preserve Rails conventions (MVC, Active Record, concerns,
18
+ jobs, mailers, generators, `bin/rails` tasks) instead of adding parallel
19
+ framework plumbing.
20
+ - The development server binds the supplied host and port:
21
+ `bin/rails server -b <host> -p <port>`. Without `-p` Rails reads `PORT`;
22
+ it never reads `HOST` (only `BINDING`, and production defaults to
23
+ `0.0.0.0`), so pass `-b` explicitly. A server reachable only on loopback
24
+ is what makes trusting proxy headers safe.
25
+ - Behind a loopback development reverse proxy that rewrites `Host` and sends
26
+ `X-Forwarded-Host`, `X-Forwarded-Proto` and `X-Forwarded-Port`, Rails derives
27
+ `request.host`, `request.base_url` and generated URLs from those headers
28
+ natively (loopback is a trusted proxy by default). Do not hard-code
29
+ `default_url_options` hosts for development.
30
+ - Host authorization then sees the browser-facing host and answers "Blocked
31
+ hosts". In development, list that host (or `.parent.domain`) in
32
+ `RAILS_DEVELOPMENT_HOSTS`, or, when the server binds only loopback, add
33
+ `config.hosts.clear` to `config/environments/development.rb` only. In
34
+ production set `config.hosts` explicitly from the environment and exclude the
35
+ health route:
36
+ `config.host_authorization = { exclude: ->(request) { request.path == "/up" } }`.
37
+ - CSRF compares the `Origin` header with `request.base_url`. Some development
38
+ proxies rewrite a same-origin `Origin` to the upstream loopback address while
39
+ forwarding the browser host; form posts then fail with "HTTP Origin header
40
+ ... didn't match request.base_url". Only in that case, and only in
41
+ `development.rb`, set
42
+ `config.action_controller.forgery_protection_origin_check = false`; the
43
+ authenticity token still protects forms. Action Cable compares origins the
44
+ same way: allow the observed development origin in
45
+ `config.action_cable.allowed_request_origins` rather than disabling its
46
+ forgery protection.
47
+ - Rails sends `X-Frame-Options: SAMEORIGIN`, so a host that shows development
48
+ pages inside a frame on another origin gets a blank frame. Only in
49
+ `development.rb`, drop it with
50
+ `config.action_dispatch.default_headers.delete("X-Frame-Options")`;
51
+ production keeps the header.
52
+ - Secrets: development uses `tmp/local_secret.txt`. Production needs
53
+ `SECRET_KEY_BASE` (generate with `bin/rails secret`) or `RAILS_MASTER_KEY`
54
+ for `config/credentials.yml.enc`, supplied through the deployment
55
+ environment, never committed. `assets:precompile` in production also aborts
56
+ without it; a build that must not see the real secret can use
57
+ `SECRET_KEY_BASE_DUMMY=1`. When an
58
+ imported app lacks `config/master.key`, never run `bin/rails credentials:edit`
59
+ or delete the encrypted file to "fix" it: that destroys the existing values.
60
+ Ask for the key or move the needed values to environment variables.
61
+ - `bin/rails db:prepare` creates the database, loads the schema and runs
62
+ `db/seeds.rb` when it is new, and migrates it otherwise, so repeated setup is
63
+ safe. It seeds only a database without a `schema_migrations` table: one that
64
+ already has it (a development server's pending-migration check creates it on
65
+ the first request) is only migrated, so setup also runs `bin/rails db:seed`.
66
+ Seeds must therefore be idempotent (`find_or_create_by!`) and guard
67
+ development-only records with `Rails.env.development?`. In development every
68
+ request, including `/up`, fails with a pending-migration error until
69
+ `db:prepare` has run against the supplied database. Commit generated
70
+ migrations and `db/schema.rb`; never run `db:reset`, `db:setup`,
71
+ `db:schema:load`, `db:drop` or edit an applied migration as routine setup.
72
+ - `DATABASE_URL` overrides the connection of every environment, including
73
+ `test`. Keep it unset where tests run, and point `test` in
74
+ `config/database.yml` at its own disposable database (the database
75
+ integration's test database binding when it is supplied), never at the
76
+ development or production database. `bin/rails test` recreates the test
77
+ schema.
78
+ - Mode is set per environment: `RAILS_ENV=production` belongs in the
79
+ production environment and its commands, never in a project-wide default.
80
+ - Assets: never commit `public/assets`; a stale local `public/assets` shadows
81
+ development changes. Propshaft/Sprockets serve sources in development;
82
+ `tailwindcss-rails`, `cssbundling-rails` and `jsbundling-rails` need their
83
+ build or watcher (`bin/dev` runs them from `Procfile.dev`). When the Develop
84
+ command becomes `bin/dev`, confirm its web process still binds loopback and
85
+ the supplied `PORT`. Rails before 7.1 needs `RAILS_SERVE_STATIC_FILES=1` in
86
+ production without a front web server.
87
+ - Native gems need a C toolchain and headers: `psych` needs libyaml, `pg`
88
+ needs libpq, `mysql2` needs the MySQL client library, `sqlite3` usually ships
89
+ a precompiled gem. Dependency installation therefore also uses `cpp`.
90
+ `trilogy` avoids the MySQL client library. A `Gemfile.lock` resolved only on
91
+ another platform needs `bundle lock --add-platform x86_64-linux` (or the
92
+ deployment platform) before frozen deployment installs. `rails new` also
93
+ adds `image_processing`, which needs the libvips library for Active Storage
94
+ variants: provide libvips where variants are used, or remove the gem.
95
+ - Install gems into the project's `vendor/bundle` (the proposed Prepare sets
96
+ `bundle config set --local path vendor/bundle`), as deployment does: the
97
+ Ruby installation's own gem directory is often read-only (a system or
98
+ packaged Ruby), and `bundle install` then fails with
99
+ `Bundler::PermissionError`. Keep `/vendor/bundle` and `/.bundle` in
100
+ `.gitignore`.
101
+ - Production: `bin/rails server -e production` reads `PORT` but not `HOST`;
102
+ pass the supplied host with `-b`, as the proposed Serve does. Rails 7.1+
103
+ generates `force_ssl` and Rails 8 also `assume_ssl`; with `force_ssl` but no
104
+ `assume_ssl`, exclude `/up` from the redirect:
105
+ `config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }`.
106
+ Rails 8 runs Solid Queue jobs inside Puma only with `SOLID_QUEUE_IN_PUMA=1`
107
+ in the production environment; otherwise run `bin/jobs` as its own process.
108
+ - Keep the `/up` health route (`rails/health#show`, Rails 7.1+) unauthenticated.
109
+ Older apps add an equivalent route and update the Outputs and Deployment
110
+ readiness.
111
+ - Login: Rails 8 `bin/rails generate authentication`, Devise or the app's own
112
+ `has_secure_password`. Controllers generated after authentication require a
113
+ signed-in user, so their tests sign in first (`sign_in_as(users(:one))` from
114
+ the generated session test helper). Seed one administrator (an `admin` boolean or role)
115
+ and one ordinary user idempotently in `db/seeds.rb` for development only,
116
+ with passwords from the environment; never seed production credentials.
117
+ - The JavaScript dependency step assumes npm. A `yarn.lock` or `bun.lockb`
118
+ means that line uses the matching tool; importmap apps have no
119
+ `package.json` and skip it. The proposed Deployment assumes importmap: with
120
+ `jsbundling-rails`, `cssbundling-rails` or another `package.json` build, add
121
+ `nodejs` to its Runtimes and a Prepare `npm ci` step before
122
+ `assets:precompile`.
123
+
124
+ ## Adoption
125
+
126
+ - Read `Gemfile`, `Gemfile.lock` (Rails and Ruby versions, database adapter
127
+ gem, asset and JavaScript tooling), `config/database.yml`,
128
+ `config/environments/*.rb`, `config/puma.rb`, `Procfile.dev`/`bin/dev`,
129
+ `config/routes.rb` (health route) and whether `config/master.key` or
130
+ `config/credentials/*.key` exist before changing project contracts.
131
+ - Replace each proposed setup, Outputs, Verification and Deployment line that
132
+ does not match the app: RSpec apps verify with `bundle` `exec` `rspec`;
133
+ API-only apps have no `assets:precompile`; a different health route changes
134
+ both readiness lines; a different JavaScript package manager changes the
135
+ install step.
136
+ - Select the matching database integration (`rails-postgresql`,
137
+ `rails-mysql` or `rails-sqlite`) and align `config/database.yml` with its
138
+ environment names. Preserve existing data and the credentials file.
139
+
140
+ ## Workspace setup
141
+
142
+ - Prepare `Keep gems inside the project` with `ruby` when `Gemfile` exists: `bundle` `config` `set` `--local` `path` `vendor/bundle`
143
+ - Prepare `Install Ruby dependencies` with `ruby` `cpp` when `Gemfile` exists: `bundle` `install`
144
+ - Prepare `Install JavaScript dependencies` with `nodejs` if `package.json` exists: `npm` `install`
145
+ - Prepare `Prepare database` with `ruby` when `bin/rails` exists: `bin/rails` `db:prepare`
146
+ - Prepare `Seed development data` with `ruby` when `bin/rails` exists: `bin/rails` `db:seed`
147
+
148
+ ## Outputs
149
+
150
+ ### Target `app`: Run Rails app
151
+
152
+ - Default.
153
+ - Mode: `interactive`
154
+ - Runtimes: `ruby`
155
+ - Run `Develop`: `bin/rails` `server` `-b` `{host}` `-p` `{port}`
156
+
157
+ #### Presentation
158
+
159
+ - Kind: `web`
160
+ - Preferred port: `3000`
161
+ - URL path: `/`
162
+ - Ready when: `GET` `/up` returns `200`
163
+
164
+ ## Verification
165
+
166
+ - Verify `application`: `bin/rails` `test`
167
+
168
+ ## Deployment
169
+
170
+ - Runtimes: `ruby` `cpp`
171
+ - Recreate on restore: `vendor/bundle` `node_modules` `tmp` `log`
172
+ - Ready when: `GET` `/up` returns `200`
173
+ - Prepare `Use deployment bundle`: `bundle` `config` `set` `--local` `deployment` `true`
174
+ - Prepare `Exclude development gems`: `bundle` `config` `set` `--local` `without` `development test`
175
+ - Prepare `Install Ruby dependencies`: `bundle` `install`
176
+ - Build `Precompile assets`: `bin/rails` `assets:precompile` `RAILS_ENV=production`
177
+ - Migrate `Prepare database`: `bin/rails` `db:prepare` `RAILS_ENV=production`
178
+ - Serve `Start`: `sh` `-c` `exec bin/rails server -e production -b "$HOST" -p "$PORT"`
179
+
180
+ ## Deslop
181
+
182
+ - Preserve Rails conventions: models, concerns, controllers, callbacks,
183
+ validations, strong parameters, jobs, mailers and routes stay where Rails
184
+ expects them.
185
+ - Remove service objects, decorators or wrappers that only forward to Active
186
+ Record or Action Pack without protecting a real application seam.
187
+ - Preserve migration history, `db/schema.rb`, credentials and seed
188
+ idempotence; cleanup is not permission for destructive schema changes.
@@ -45,10 +45,7 @@ Ruby module, class, callable, dependency, lifecycle, and test conventions.
45
45
  only git sources. Verify that each spec loads from its source root.
46
46
  - Running a web process: bind the supplied listen host and port, trust forwarded
47
47
  headers only from a loopback proxy, and read secrets from the environment.
48
- Rails: allow the served host and the proxy's loopback host in `config.hosts`
49
- (Rails honours `X-Forwarded-Host`), read `SECRET_KEY_BASE` from the
50
- environment (generate it with `bin/rails secret`), and use
51
- `bin/rails db:prepare` for setup.
48
+ For Rails select `rails`; its piece owns the framework traps.
52
49
 
53
50
  ## Connected development
54
51
 
@@ -0,0 +1,74 @@
1
+ # Stack piece: spring-boot-mysql
2
+
3
+ ## Description
4
+
5
+ Spring Boot MySQL or MariaDB datasource, JDBC driver, Flyway, JPA, and database
6
+ environment conventions.
7
+
8
+ ## Requires
9
+
10
+ - `spring-boot`
11
+ - `mysql`
12
+
13
+ ## Conflicts
14
+
15
+ - `spring-boot-postgresql`
16
+
17
+ ## Environment defaults
18
+
19
+ - Default `DB_HOST`: `127.0.0.1`
20
+ - Default `DB_PORT`: `3306`
21
+ - Default `DB_NAME`: `spring`
22
+ - Default `DB_USERNAME`: `root`
23
+
24
+ ## Resources
25
+
26
+ ```json genesis-resource
27
+ {
28
+ "id": "database",
29
+ "kind": "mysql",
30
+ "environmentAlternatives": [
31
+ {
32
+ "bindings": {
33
+ "database": "DB_NAME",
34
+ "host": "DB_HOST",
35
+ "password": "DB_PASSWORD",
36
+ "port": "DB_PORT",
37
+ "username": "DB_USERNAME"
38
+ },
39
+ "allowEmpty": ["password"],
40
+ "preferred": true
41
+ }
42
+ ],
43
+ "optionalBindings": {
44
+ "testDatabase": "TEST_DB_NAME"
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Guidance
50
+
51
+ - Compose the JDBC URL from the individual names in `application.properties`:
52
+ `spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}`,
53
+ `spring.datasource.username=${DB_USERNAME}` and
54
+ `spring.datasource.password=${DB_PASSWORD:}`. A `mysql://` connection URL is
55
+ not a JDBC URL; do not feed one to `spring.datasource.url`.
56
+ - Match the driver to the server: check `SELECT VERSION()`. MySQL uses the
57
+ `com.mysql:mysql-connector-j` runtime driver. A MariaDB server needs
58
+ `org.mariadb.jdbc:mariadb-java-client` with a `jdbc:mariadb://` URL;
59
+ `mysql-connector-j` can fail against current MariaDB while Hibernate reads
60
+ connection metadata ("Unable to determine Dialect"). Flyway 10 and later
61
+ also need `org.flywaydb:flyway-mysql`, which covers both servers.
62
+ - Create databases with `utf8mb4`.
63
+ - When `TEST_DB_NAME` is supplied, the `test` profile's
64
+ `src/test/resources/application-test.properties` sets
65
+ `spring.datasource.url` to the same JDBC URL with `${TEST_DB_NAME}` in place
66
+ of `${DB_NAME}`. Flyway migrates that existing database; the database user
67
+ may lack permission to create databases. Never point tests at `DB_NAME`.
68
+
69
+ ## Adoption
70
+
71
+ - Confirm the server (MySQL or MariaDB), the datasource properties, the
72
+ environment names they read, the driver and Flyway or Liquibase modules, and
73
+ every profile's overrides from source before declaring readiness or
74
+ connecting to the database.
@@ -0,0 +1,68 @@
1
+ # Stack piece: spring-boot-postgresql
2
+
3
+ ## Description
4
+
5
+ Spring Boot PostgreSQL datasource, JDBC driver, Flyway, JPA, and database
6
+ environment conventions.
7
+
8
+ ## Requires
9
+
10
+ - `spring-boot`
11
+ - `postgresql`
12
+
13
+ ## Conflicts
14
+
15
+ - `spring-boot-mysql`
16
+
17
+ ## Environment defaults
18
+
19
+ - Default `DB_HOST`: `127.0.0.1`
20
+ - Default `DB_PORT`: `5432`
21
+ - Default `DB_NAME`: `spring`
22
+ - Default `DB_USERNAME`: `postgres`
23
+
24
+ ## Resources
25
+
26
+ ```json genesis-resource
27
+ {
28
+ "id": "database",
29
+ "kind": "postgresql",
30
+ "environmentAlternatives": [
31
+ {
32
+ "bindings": {
33
+ "database": "DB_NAME",
34
+ "host": "DB_HOST",
35
+ "password": "DB_PASSWORD",
36
+ "port": "DB_PORT",
37
+ "username": "DB_USERNAME"
38
+ },
39
+ "allowEmpty": ["password"],
40
+ "preferred": true
41
+ }
42
+ ],
43
+ "optionalBindings": {
44
+ "testDatabase": "TEST_DB_NAME"
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Guidance
50
+
51
+ - Compose the JDBC URL from the individual names in `application.properties`:
52
+ `spring.datasource.url=jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}`,
53
+ `spring.datasource.username=${DB_USERNAME}` and
54
+ `spring.datasource.password=${DB_PASSWORD:}`. A `postgres://` connection URL
55
+ is not a JDBC URL; do not feed one to `spring.datasource.url`.
56
+ - Use the `org.postgresql:postgresql` runtime driver. Flyway 10 and later also
57
+ need `org.flywaydb:flyway-database-postgresql` next to the Flyway starter.
58
+ - When `TEST_DB_NAME` is supplied, the `test` profile's
59
+ `src/test/resources/application-test.properties` sets
60
+ `spring.datasource.url` to the same JDBC URL with `${TEST_DB_NAME}` in place
61
+ of `${DB_NAME}`. Flyway migrates that existing database; the database role
62
+ may lack permission to create databases. Never point tests at `DB_NAME`.
63
+
64
+ ## Adoption
65
+
66
+ - Confirm the datasource properties, the environment names they read, the
67
+ driver and Flyway or Liquibase modules, and every profile's overrides from
68
+ source before declaring readiness or connecting to the database.
@@ -0,0 +1,154 @@
1
+ # Stack piece: spring-boot
2
+
3
+ ## Description
4
+
5
+ Spring Boot web application, Spring MVC, Spring Security, Actuator, profiles,
6
+ Maven or Gradle wrapper, and schema-migration conventions. Identified by a
7
+ `pom.xml` or `build.gradle(.kts)` using the Spring Boot parent or plugin and an
8
+ `@SpringBootApplication` class. Authoritative framework documentation:
9
+ https://docs.spring.io/spring-boot/
10
+
11
+ ## Requires
12
+
13
+ - `java`
14
+
15
+ ## Guidance
16
+
17
+ - Use the Spring Boot version selected by the build and follow its matching
18
+ official documentation. Boot 4 splits auto-configuration into per-technology
19
+ starters (`spring-boot-starter-webmvc`, `spring-boot-starter-flyway`, ...):
20
+ a bare `flyway-core` dependency no longer runs migrations, so add the
21
+ matching starter instead of hand-written configuration. Preserve Spring's
22
+ dependency injection, configuration properties, Spring Data repositories,
23
+ Spring Security and Actuator instead of adding parallel plumbing.
24
+ - Building and running need a full JDK (`javac`), not only a Java runtime.
25
+ Keep the Maven wrapper (`mvnw`, `.mvn/wrapper`) committed and executable;
26
+ the proposed operations call `./mvnw`.
27
+ - Bind the listen address and port from the environment in
28
+ `application.properties`: `server.address=${HOST:127.0.0.1}` and
29
+ `server.port=${PORT:8080}`. Spring reads `SERVER_PORT`, not `PORT`, by
30
+ itself. The proposed development run also passes both as
31
+ `--server.address`/`--server.port` application arguments.
32
+ - Behind a development or production reverse proxy on the same machine that
33
+ rewrites `Host` and sends `X-Forwarded-Host`, `X-Forwarded-Proto` and
34
+ `X-Forwarded-Port`, set `server.forward-headers-strategy=native`,
35
+ `server.tomcat.remoteip.host-header=X-Forwarded-Host` and
36
+ `server.tomcat.remoteip.port-header=X-Forwarded-Port`. Embedded Tomcat then
37
+ trusts those headers only from loopback and private internal proxies, so
38
+ login redirects, `ServletUriComponentsBuilder` URLs and the `Secure` session
39
+ cookie use the browser-facing origin. Without it, Spring Security redirects
40
+ to the loopback address. Use `framework` only for a non-Tomcat server, and
41
+ only while the server is reachable solely through that proxy.
42
+ - Also set `server.tomcat.use-relative-redirects=true`. A proxy may send a
43
+ same-origin form post with the forwarded host and port removed and `Origin`
44
+ rewritten to the loopback address, so Tomcat would turn the redirect after
45
+ login or after any POST into `https://127.0.0.1/...`; a relative `Location`
46
+ lets the browser resolve it against its own origin.
47
+ - Spring Security's CSRF protection is token based (`_csrf`) and works behind
48
+ such a proxy. A proxy may present same-origin requests with an `Origin`
49
+ rewritten to the loopback address; keep CORS configuration for genuine
50
+ cross-origin clients rather than comparing `Origin` with the request host.
51
+ - Spring Security answers `X-Frame-Options: DENY`, so a development tool that
52
+ shows the application inside a frame stays blank. When that is needed,
53
+ disable frame options only through a property set in the `dev` profile
54
+ (for example `app.allow-framing=true`, read by the security configuration
55
+ before `http.headers(h -> h.frameOptions(f -> f.disable()))`); production
56
+ keeps `DENY`.
57
+ - Add `spring-boot-starter-actuator`, expose
58
+ `management.endpoints.web.exposure.include=health`, and let Spring Security
59
+ `permitAll` `/actuator/health`; the proposed readiness checks use it. Its
60
+ status includes the datasource, so readiness also proves the database
61
+ connection. An application that must not expose Actuator replaces both
62
+ readiness lines with another unauthenticated route.
63
+ - Select profiles with `SPRING_PROFILES_ACTIVE` set separately in each
64
+ environment (for example `dev` locally); never make a development profile
65
+ the project-wide default, because defaults also reach deployment. Keep
66
+ profile-specific values in `application-<profile>.properties`.
67
+ - Read credentials from the environment through property placeholders; never
68
+ commit passwords or tokens in `application*.properties`. Spring Boot has no
69
+ framework secret key of its own; application secrets, such as a token
70
+ signing key, are generated with `openssl rand -base64 32` and supplied
71
+ through the environment.
72
+ - Flyway or Liquibase owns the schema and runs at application startup, so the
73
+ proposed deployment has no separate migration step. Add new migrations;
74
+ never edit an applied one (its checksum is validated). Use
75
+ `spring.jpa.hibernate.ddl-auto=validate` and never `create`, `create-drop`
76
+ or `update` against supplied data; set `spring.jpa.open-in-view=false`.
77
+ Seeds are idempotent: repeatable migrations or a startup runner that checks
78
+ before inserting.
79
+ - Keep tests off development data: a `test` profile
80
+ (`src/test/resources/application-test.properties`, activated with
81
+ `@ActiveProfiles("test")` or Surefire's `spring.profiles.active`) points the
82
+ datasource at a disposable test database supplied by the environment
83
+ (`TEST_DB_NAME` with the database integrations below). Do not
84
+ add `src/test/resources/application.properties`, which replaces the main file
85
+ on the test classpath. Testcontainers needs a container runtime the
86
+ environment may not provide.
87
+ - Deployment serves the executable jar. Set `<finalName>app</finalName>` in the
88
+ Maven `<build>` so the proposed Serve step finds `target/app.jar`; the jar
89
+ reads `HOST` and `PORT` through the properties above.
90
+ - When the app has login, use Spring Security users with `ADMIN` and `USER`
91
+ roles and a delegating `PasswordEncoder`. Seed one administrator and one
92
+ ordinary user for development from a `dev`-profile runner or seed migration
93
+ that reads the password from the environment and creates each user only
94
+ when absent. Never use `{noop}` passwords or seeded credentials outside
95
+ development.
96
+ - A Gradle project replaces the proposals with the wrapper equivalents:
97
+ `./gradlew` `bootRun` `--args=--server.address={host} --server.port={port}`,
98
+ `./gradlew` `test`, and `./gradlew` `bootJar` with
99
+ `bootJar { archiveFileName = 'app.jar' }` serving `build/libs/app.jar`.
100
+
101
+ ## Adoption
102
+
103
+ - Inspect `pom.xml` or `build.gradle(.kts)`, the wrapper, the Spring Boot and
104
+ Java versions, `application.properties`/`application.yml` and every profile
105
+ file, the security configuration, the embedded server, the packaging (`jar`
106
+ or `war`) and the migration tool before changing project contracts. Preserve
107
+ the build tool and Boot major version.
108
+ - Replace any proposed setup, run, readiness, verification or deployment line
109
+ that does not match the application before claiming readiness, including
110
+ the jar name, the health route and the address/port properties.
111
+ - When the app uses PostgreSQL or MySQL, select the matching Spring Boot
112
+ database integration so its datasource environment names become explicit.
113
+
114
+ ## Workspace setup
115
+
116
+ - Prepare `Compile application` with `java` when `pom.xml` exists: `./mvnw` `-B` `-DskipTests` `compile`
117
+
118
+ ## Outputs
119
+
120
+ ### Target `app`: Run Spring Boot app
121
+
122
+ - Default.
123
+ - Mode: `interactive`
124
+ - Runtimes: `java`
125
+ - Run `Develop`: `./mvnw` `-B` `spring-boot:run` `-Dspring-boot.run.arguments=--server.address={host} --server.port={port}`
126
+
127
+ #### Presentation
128
+
129
+ - Kind: `web`
130
+ - Preferred port: `8080`
131
+ - URL path: `/`
132
+ - Ready when: `GET` `/actuator/health` returns `200`
133
+
134
+ ## Verification
135
+
136
+ - Verify `application`: `./mvnw` `-B` `test`
137
+
138
+ ## Deployment
139
+
140
+ - Runtimes: `java`
141
+ - Ready when: `GET` `/actuator/health` returns `200`
142
+ - Build `Package`: `./mvnw` `-B` `-DskipTests` `package`
143
+ - Serve `Start`: `java` `-jar` `target/app.jar`
144
+
145
+ ## Deslop
146
+
147
+ - Preserve Spring's constructor injection, configuration properties,
148
+ component boundaries, Spring Data repositories, transaction boundaries and
149
+ security configuration.
150
+ - Keep `@Transactional` at service boundaries and validation at controller or
151
+ configuration-properties boundaries. Remove service, mapper or DTO layers only
152
+ when they duplicate framework behavior without protecting a real seam.
153
+ - Preserve migration history and entity mappings; cleanup is not permission to
154
+ edit applied migrations or loosen `ddl-auto`.
@@ -21,6 +21,12 @@ SQLite file-backed persistence, migrations, and backup conventions.
21
21
  persistent database filename through the `database` resource semantic and
22
22
  the environment name the application actually reads. A driver selector such
23
23
  as `DB_CONNECTION=sqlite` is configuration, not a database filename.
24
+ - When no framework database component declares that resource (an Express,
25
+ Next.js or plain Node.js app, for example), the project Stack declares it
26
+ under `## Resources` as one fenced `json genesis-resource` block, such as
27
+ `{"id": "database", "kind": "sqlite", "environmentAlternatives": [{"bindings": {"database": "DB_DATABASE"}, "preferred": true}]}`.
28
+ The application opens the filename in that variable; a gitignored
29
+ repository-relative file is only a fallback for a checkout without it.
24
30
  - Keep durable database files outside disposable build and release directories.
25
31
  A host may supply a persistent filename; do not replace that value with a
26
32
  repository-relative default or recreate an existing database during setup.