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.
@@ -32,6 +32,15 @@ https://mobily-enterprises.github.io/jskit-ai/
32
32
  `AUTH_LOCAL_SESSION_SECRET` as a required environment name in the project's
33
33
  established environment contract and committed environment example. Never
34
34
  commit or invent its value.
35
+ - An application with accounts always has the host's browser-preview login,
36
+ without waiting to be asked: when adding authentication, add the
37
+ `auth/auth-surface` pattern's executable `tools/preview-identity` and copy its
38
+ exact `#### Preview identity` block (Command `tools/preview-identity`,
39
+ Protocol `vibe64.preview-identity.command.v1`, Identity types `email`
40
+ `user-id`, Enabled environment `AUTH_DEV_BYPASS_ENABLED`, Secret environment
41
+ `AUTH_DEV_BYPASS_SECRET`, Runtimes `nodejs`) under the web `Outputs` target.
42
+ Which existing accounts the preview uses stays the person's choice; never
43
+ create users for it.
35
44
  - Before creating or modifying JSKIT Vue/Vuetify UI, read the Material 3
36
45
  contract at
37
46
  `https://mobily-enterprises.github.io/jskit-ai/guide/framework/material-3`
@@ -77,6 +86,25 @@ https://mobily-enterprises.github.io/jskit-ai/
77
86
  input fields never grant administrator access. Verify the requested provider
78
87
  outcomes and denied access with controlled fixtures. Genesis transports
79
88
  guidance and opaque declarations; it does not execute integrations or payments.
89
+ - Shipping the app to phones ("install on my phone"): the host-owned
90
+ `## Packaging` section is written only when the person adds a mobile target.
91
+ It declares a separate `web-bundle` package whose Build produces the bundled
92
+ client (Output its build folder) with the absolute HTTPS API base the client
93
+ calls, then a `capacitor` package with `Content: package <that id>`,
94
+ `Platforms: android`, a permanent reverse-DNS `Id`, `Name`, a committed
95
+ 1024x1024 PNG `Icon` without transparency, `Version from: package.json` and
96
+ one `Permission` line, with a plain reason, per native capability. The host
97
+ generates and discards the native project on every build: never commit
98
+ `android/`, `ios/`, `capacitor.config.*`, Gradle files, build numbers or
99
+ signing keys. Native plugins are ordinary client dependencies at the exact
100
+ versions in `package-lock.json`, and the host's shell is Capacitor 8; it
101
+ blocks a lockfile mismatch or another major. `@jskit-ai/mobile-capacitor` is
102
+ still on Capacitor 7, so propose mobile packaging for a JSKIT client only
103
+ once its Capacitor dependencies are 8.x. A deep-link scheme and app-link
104
+ domains live once in `## Environment defaults` (for example `APP_URL_SCHEME`,
105
+ `APP_LINK_DOMAINS`) and Packaging names them with `Deep link scheme from` and
106
+ `App link domains from`; the server's CORS and OAuth callbacks must accept
107
+ the app's origin and scheme.
80
108
 
81
109
  ## Adoption
82
110
 
@@ -96,7 +124,9 @@ https://mobily-enterprises.github.io/jskit-ai/
96
124
  component when the script or preparation file does not exist.
97
125
  - When the project declares an application-owned identity exchange for a host's
98
126
  browser preview, preserve its command, selectors, protocol, environment names,
99
- runtime and timeout in the project's existing section.
127
+ runtime and timeout in the project's existing section. When an application
128
+ with JSKIT accounts lacks it, add it from the `auth/auth-surface` pattern as
129
+ in Guidance.
100
130
  A host-saved identity name/value is not a substitute for this application
101
131
  contract.
102
132
  - Treat generator descriptors, receipts, sync commands, legacy service
@@ -0,0 +1,181 @@
1
+ # Stack piece: nextjs
2
+
3
+ ## Description
4
+
5
+ Next.js React application conventions: App Router or Pages Router, the
6
+ `next` CLI, Server Actions, middleware, environment variables, builds and
7
+ production serving. A Next.js application has `next` in `package.json`
8
+ dependencies and usually a `next.config.js`, `next.config.mjs` or
9
+ `next.config.ts` file and an `app/` or `pages/` directory. Authoritative
10
+ framework documentation: https://nextjs.org/docs
11
+
12
+ ## Requires
13
+
14
+ - `nodejs`
15
+
16
+ ## Conflicts
17
+
18
+ - `express`
19
+
20
+ ## Guidance
21
+
22
+ - Match the installed Next.js major version and the router the application
23
+ already uses (`app/` App Router or `pages/` Pages Router). Recent releases
24
+ ship version-matched documentation in `node_modules/next/dist/docs/`; read
25
+ the relevant guide there before relying on remembered APIs. `next dev` may
26
+ write a framework-owned agent-rules block into `AGENTS.md`; commit it rather
27
+ than repeatedly removing it.
28
+ - Bind the development server to the host and port it is given:
29
+ `next dev --hostname <host> --port <port>` (the proposed Run passes them
30
+ through `npm run dev --`). Without `--hostname`, `next dev` and `next start`
31
+ listen on every interface. Never hard-code a port in `package.json` scripts.
32
+ - Behind a development reverse proxy on loopback that rewrites `Host` and sends
33
+ `X-Forwarded-Host`, `X-Forwarded-Proto` and `X-Forwarded-Port`, Next.js
34
+ builds request URLs from the forwarded headers. The development server blocks
35
+ requests for its own development resources (the `/_next/hmr` WebSocket and
36
+ other `/_next/*` dev endpoints) whose `Origin` hostname is not `localhost`,
37
+ the hostname it was started with, or an `allowedDevOrigins` entry. A proxy
38
+ that rewrites the browser's `Origin` to the loopback address needs no entry;
39
+ otherwise add the browser-facing hostname pattern to `allowedDevOrigins`,
40
+ read from an environment variable rather than hard-coded. The HMR client
41
+ connects through the page's own origin; do not hard-code an asset prefix or
42
+ WebSocket host for the proxy.
43
+ - Server Actions reject a POST whose `Origin` host differs from
44
+ `X-Forwarded-Host` (or `Host` without it) with "Invalid Server Actions
45
+ request". A proxy that forwards both unchanged, or presents a same-origin
46
+ request entirely on the loopback origin (loopback `Origin` and `Host`, no
47
+ forwarded host), needs no setting. Add an exact host to
48
+ `experimental.serverActions.allowedOrigins` only for a real reported
49
+ mismatch, in development only (ports cannot be wildcarded); the list also
50
+ applies in production, so never admit arbitrary origins.
51
+ - Redirect with relative paths. A Server Action's redirect travels in a
52
+ framework response header, not `Location`, so a proxy does not rewrite it,
53
+ and Auth.js `signIn`/`signOut` with `redirectTo` build an absolute URL from
54
+ the request's host headers, which a proxy may present as the loopback
55
+ address. Call them with `redirect: false`, then `redirect("/path")`.
56
+ `request.nextUrl` in `proxy`/middleware names the server's own host, so an
57
+ Auth.js `callbackUrl` may be a loopback URL: use only its path.
58
+ - `NEXT_PUBLIC_*` variables are inlined into client bundles at build time:
59
+ never put secrets in them, and their production values must exist when
60
+ `next build` runs, not only at start. Server-only values are read from
61
+ `process.env` at request time. Next.js reads `.env*` files but the
62
+ environment wins; keep real values out of committed `.env*` files.
63
+ - With Auth.js (`next-auth` v5), supply `AUTH_SECRET` through the environment
64
+ (generate with `openssl rand -base64 33`; `npx auth secret` writes it into a
65
+ file instead) and set `AUTH_TRUST_HOST=true` when the app is served behind a
66
+ trusted reverse proxy, so callback and redirect URLs use the forwarded
67
+ origin. Other auth libraries need their equivalent trusted-host setting.
68
+ - With `cacheComponents` enabled (the recent `create-next-app` default),
69
+ pages that read the session must render at request time: call
70
+ `await connection()` before `auth()`, wrap the read in `<Suspense>`, or
71
+ export `instant = false`; otherwise `next build` fails. Gate protected
72
+ routes in `proxy`/middleware (Auth.js `authorized` callback), not only with
73
+ `redirect()` during render: the client router can replay a cached
74
+ render-time redirect to the login page after sign-in.
75
+ - Readiness and health probes must reach a public route: middleware (or
76
+ `proxy`) that redirects `/` to a login page makes a `GET /` probe fail.
77
+ Exclude the probe path from the auth matcher, or add a small public route
78
+ handler (for example `app/health/route.ts`) and point the Outputs and
79
+ Deployment readiness checks at it.
80
+ - Database access goes through the application's ORM (Prisma, Drizzle, Kysely
81
+ or another). Its schema migrations are application-owned: deployment runs the
82
+ non-interactive apply command (for example `prisma migrate deploy`), never
83
+ `prisma migrate dev` or `prisma db push` against supplied data. Seed scripts
84
+ must be idempotent. Tests use a disposable database supplied for them, never
85
+ the development or production database. Declare the database Resources in
86
+ the project Stack; this piece does not choose a database.
87
+ - Production: `next build` then `next start`. `next start` reads `PORT` but not
88
+ `HOST`; bind it explicitly (`next start --hostname <host>`), as the proposed
89
+ Serve does. Set `NODE_ENV=production` only through the production
90
+ environment, never as a project-wide default; `next build` and `next start`
91
+ set it themselves. `output: "standalone"` changes the start command to
92
+ `node .next/standalone/server.js` (which reads `HOSTNAME` and `PORT`) and
93
+ requires copying `public/` and `.next/static/`; update Deployment if the
94
+ application uses it. `output: "export"` produces static files with no server.
95
+ - Do not run `next build` into the same `.next` directory a running `next dev`
96
+ uses unless the installed major isolates development output (Next.js 16 and
97
+ later write development output to `.next/dev`); with older majors stop the
98
+ development server first or build into a separate `distDir`.
99
+ - When the application has login, seed one administrator and one ordinary user
100
+ for development through an idempotent seed script with credentials from the
101
+ environment, and keep role checks on the server (Server Components, route
102
+ handlers, Server Actions), not only in client components.
103
+ - Shipping the app to phones ("install on my phone") needs a static client:
104
+ `output: "export"` (no Server Actions, route handlers, middleware or
105
+ request-time rendering in that build), with API calls going to an absolute
106
+ HTTPS base read from a `NEXT_PUBLIC_*` variable. The host-owned
107
+ `## Packaging` section, written only when the person adds a mobile target,
108
+ declares a `web-bundle` package (Build `npm` `run` `build`, Output `out`)
109
+ and a `capacitor` package with `Content: package <that id>`,
110
+ `Platforms: android`, a permanent reverse-DNS `Id`, `Name`, a committed
111
+ 1024x1024 PNG `Icon` without transparency, `Version from: package.json` and
112
+ one `Permission` line per native capability. Native plugins are ordinary
113
+ dependencies at exact `package-lock.json` versions on Capacitor 8; the host
114
+ generates and discards the native project, so never commit `android/`,
115
+ `capacitor.config.*` or signing keys. A server-rendered app is not yet
116
+ supported as a phone app: it needs a separate static client first.
117
+
118
+ ## Adoption
119
+
120
+ - Inventory the real files before changing project contracts: the installed
121
+ `next` version in the lockfile, `app/` or `pages/`, `next.config.*` (`output`,
122
+ `basePath`, `distDir`, `experimental`), `middleware.*`/`proxy.*`, the auth
123
+ library and its environment names, the ORM and its migration commands, and
124
+ the real `dev`, `build`, `start`, `lint` and `test` scripts.
125
+ - Identify the package manager from the lockfile and replace every proposed
126
+ `npm` line when the project uses pnpm, Yarn or Bun. Next.js 16 removed
127
+ `next lint`; if the `lint` script is missing, remove that Verification line
128
+ instead of inventing one, and add the project's real test command when it
129
+ has one.
130
+ - Replace the readiness path when `/` is not publicly reachable, a `basePath`
131
+ is set, or a dedicated health route exists. Replace the Serve line for
132
+ `output: "standalone"`, a custom server, or `output: "export"`.
133
+ - A custom Next.js server built on Express is a project-owned decision: keep
134
+ this piece and describe that server's real commands in the project's own
135
+ sections.
136
+
137
+ ## Workspace setup
138
+
139
+ - Prepare `Install dependencies` with `nodejs` when `package.json` exists: `npm` `install`
140
+
141
+ ## Outputs
142
+
143
+ ### Target `app`: Run Next.js app
144
+
145
+ - Default.
146
+ - Mode: `interactive`
147
+ - Runtimes: `nodejs`
148
+ - Run `Develop`: `npm` `run` `dev` `--` `--hostname` `{host}` `--port` `{port}`
149
+
150
+ #### Presentation
151
+
152
+ - Kind: `web`
153
+ - Preferred port: `3000`
154
+ - URL path: `/`
155
+ - Ready when: `GET` `/` returns `200`
156
+
157
+ ## Verification
158
+
159
+ - Verify `lint`: `npm` `run` `lint`
160
+ - Verify `build`: `npm` `run` `build`
161
+
162
+ ## Deployment
163
+
164
+ - Runtimes: `nodejs`
165
+ - Recreate on restore: `node_modules` `.next/cache`
166
+ - Ready when: `GET` `/` returns `200`
167
+ - Prepare `Install dependencies`: `npm` `ci`
168
+ - Build `Build`: `npm` `run` `build`
169
+ - Serve `Start`: `sh` `-c` `exec npm start -- --hostname "$HOST"`
170
+
171
+ ## Deslop
172
+
173
+ - Keep data fetching in Server Components, route handlers and Server Actions
174
+ where the router supports it; remove client-side fetch wrappers that only
175
+ duplicate a server read.
176
+ - Keep `"use client"` boundaries as low in the tree as possible and do not mark
177
+ whole layouts as client components to reach one interactive widget.
178
+ - Use the framework's `Link`, `Image`, `Script`, metadata and font facilities
179
+ instead of hand-written equivalents.
180
+ - Remove abandoned starter content, unused route segments and duplicate
181
+ environment readers only when routes, redirects and tests stay unchanged.
@@ -41,9 +41,21 @@ Node.js package, command, module, dependency, and test conventions.
41
41
  `package.json` and `package-lock.json` stay unchanged; Verify resolves each
42
42
  package from the application root and fails unless it resolves to its
43
43
  connected source root. An ordinary `npm ci` restores the published packages.
44
+ - Publishing a library to npm: the host-owned `## Packaging` section declares
45
+ the package (`npm` packer, its Workdir, `Version from: package.json`) only
46
+ when a publishing target is added; the host builds with `npm pack` from the
47
+ saved commit and owns tags, credentials and uploads. Keep `name`, `version`,
48
+ `license`, `files` (or `.npmignore`) and an `exports`/`main` entry correct in
49
+ `package.json`; never commit tarballs, tokens or `.npmrc` credentials, and
50
+ remove `"private": true` only for a package that is really published. A
51
+ build step before packing (TypeScript, bundling) is a declared Build command
52
+ such as `npm run build`, not a `prepublishOnly` script. A project using
53
+ Changesets or release-please keeps that tool and declares
54
+ `Version from: external`.
44
55
  - Long-running web processes accept their listen host and port from arguments
45
56
  or the environment rather than hard-coding them, and fail if the port is
46
- taken instead of silently choosing another.
57
+ taken instead of silently choosing another. For Express or Next.js select
58
+ `express` or `nextjs`; that piece owns the framework traps.
47
59
 
48
60
  ## Adoption
49
61
 
@@ -42,13 +42,26 @@ Python package, module, callable, dependency, and test conventions.
42
42
  PEP 610 `direct_url.json` is editable with the source root's `file:` URL and
43
43
  that its modules import from there. Do not use `uv sync`, which needs tracked
44
44
  `[tool.uv.sources]` and lockfile changes.
45
+ - Publishing a library to PyPI: the host-owned `## Packaging` section declares
46
+ the package (`python-dist` packer, `Runtimes: python`, its `dist` Output,
47
+ `Version from: pyproject.toml`) only when a publishing target is added; the
48
+ host builds the sdist and wheel from the saved commit and owns tags,
49
+ credentials and uploads. The build runs in a clean copy where `build` is
50
+ not installed, and managed Pythons refuse a bare `pip install` (PEP 668), so
51
+ a plain `python3 -m build` fails. The package installs its own throwaway
52
+ tools: Prepare `python3 -m venv .build-tools`, Prepare
53
+ `.build-tools/bin/python -m pip install --quiet build`, Build
54
+ `.build-tools/bin/python -m build`; add `.build-tools/` to `.gitignore`. Keep a PEP 621
55
+ `[project]` table with a static `version`, `readme`, `license` and
56
+ `requires-python` so `twine check --strict` passes; versions use PEP 440
57
+ (`1.5.0rc1`). Never commit `dist/`, tokens or `.pypirc`. A project with a
58
+ dynamic version (setuptools-scm, hatch-vcs) declares
59
+ `Version from: external`.
45
60
  - Running a web process: bind the supplied listen host and port, trust forwarded
46
61
  headers only from a loopback proxy, and read secrets from the environment.
47
- Django: set `ALLOWED_HOSTS` and `CSRF_TRUSTED_ORIGINS` for the served origin
48
- (`ALLOWED_HOSTS` also lists the loopback host the proxy connects to),
49
- `SECURE_PROXY_SSL_HEADER` and `USE_X_FORWARDED_HOST` only behind that trusted
50
- proxy, and read `SECRET_KEY` from the environment. Flask uses Werkzeug's
51
- `ProxyFix`; Uvicorn uses `--proxy-headers --forwarded-allow-ips 127.0.0.1`.
62
+ For Django select `django`; its piece owns the framework traps. Flask uses
63
+ Werkzeug's `ProxyFix`; Uvicorn uses `--proxy-headers --forwarded-allow-ips
64
+ 127.0.0.1`.
52
65
 
53
66
  ## Connected development
54
67
 
@@ -0,0 +1,81 @@
1
+ # Stack piece: rails-mysql
2
+
3
+ ## Description
4
+
5
+ Rails MySQL connection, Active Record migration, and database environment conventions.
6
+
7
+ ## Requires
8
+
9
+ - `rails`
10
+ - `mysql`
11
+
12
+ ## Conflicts
13
+
14
+ - `rails-postgresql`
15
+ - `rails-sqlite`
16
+
17
+ ## Environment defaults
18
+
19
+ - Default `DB_HOST`: `127.0.0.1`
20
+ - Default `DB_PORT`: `3306`
21
+ - Default `DB_DATABASE`: `rails`
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_DATABASE",
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
+ - `rails new -d mysql` (adapter `mysql2`) or `-d trilogy` hard-codes database
52
+ names. Make `config/database.yml` read the resource names: under `default`,
53
+ `host: <%= ENV.fetch("DB_HOST", "127.0.0.1") %>`,
54
+ `port: <%= ENV.fetch("DB_PORT", 3306) %>`,
55
+ `username: <%= ENV["DB_USERNAME"] %>`, `password: <%= ENV["DB_PASSWORD"] %>`;
56
+ and `database: <%= ENV["DB_DATABASE"] %>` for development and the
57
+ production primary. Point `test` at
58
+ `<%= ENV.fetch("TEST_DB_NAME", "<app>_test") %>`, never at the development
59
+ or production database.
60
+ - Keep `encoding: utf8mb4`. `mysql2` compiles against the MySQL client
61
+ library; `trilogy` (Rails 7.1+) is pure Ruby and avoids it. Do not switch an
62
+ existing app's adapter without testing it.
63
+ - `bin/rails test` purges the test database whenever its schema is out of
64
+ date by dropping and recreating it, so the user needs `CREATE` and `DROP`
65
+ on that database name even when `TEST_DB_NAME` names it.
66
+ - Rails 8 production declares separate `cache`, `queue` and `cable`
67
+ databases. When only one database is supplied, follow the Solid Cache, Solid
68
+ Queue and Solid Cable single-database instructions (their schemas become
69
+ ordinary migrations and their `connects_to` settings are removed) instead of
70
+ inventing extra database names.
71
+ - Use the inherited Rails migration and seed guidance. Keep connection,
72
+ integration and payment records in this database through Active Record
73
+ migrations and transactions; test uniqueness and concurrent updates on MySQL
74
+ itself.
75
+
76
+ ## Adoption
77
+
78
+ - Confirm the adapter, every environment's database, username, password, host
79
+ and port expressions in `config/database.yml`, and whether `DATABASE_URL` is
80
+ read, before declaring readiness or connecting. Align the project Resource
81
+ bindings with the names the file actually reads.
@@ -0,0 +1,86 @@
1
+ # Stack piece: rails-postgresql
2
+
3
+ ## Description
4
+
5
+ Rails PostgreSQL connection, Active Record migration, and database environment conventions.
6
+
7
+ ## Requires
8
+
9
+ - `rails`
10
+ - `postgresql`
11
+
12
+ ## Conflicts
13
+
14
+ - `rails-mysql`
15
+ - `rails-sqlite`
16
+
17
+ ## Environment defaults
18
+
19
+ - Default `DB_HOST`: `127.0.0.1`
20
+ - Default `DB_PORT`: `5432`
21
+ - Default `DB_DATABASE`: `rails`
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_DATABASE",
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
+ - `rails new -d postgresql` hard-codes database names and reads only a
52
+ production password variable. Make `config/database.yml` read the resource
53
+ names: under `default`, `host: <%= ENV.fetch("DB_HOST", "127.0.0.1") %>`,
54
+ `port: <%= ENV.fetch("DB_PORT", 5432) %>`,
55
+ `username: <%= ENV["DB_USERNAME"] %>`, `password: <%= ENV["DB_PASSWORD"] %>`;
56
+ and `database: <%= ENV["DB_DATABASE"] %>` for development and the
57
+ production primary. Point `test` at
58
+ `<%= ENV.fetch("TEST_DB_NAME", "<app>_test") %>`, never at the development
59
+ or production database.
60
+ - `bin/rails test` purges the test database whenever its schema is out of
61
+ date by dropping and recreating it, so the role needs `CREATEDB` (and must
62
+ own the database) even when `TEST_DB_NAME` names it.
63
+ - After loading fixtures, Rails checks their foreign keys
64
+ (`verify_foreign_keys_for_fixtures`, on by default) by updating
65
+ `pg_catalog.pg_constraint`, which only a superuser may do. With an ordinary
66
+ `CREATEDB` role every fixture test fails with `permission denied for table
67
+ pg_constraint`; set `config.active_record.verify_foreign_keys_for_fixtures =
68
+ false` in `config/environments/test.rb` rather than granting superuser.
69
+ - Rails 8 production declares separate `cache`, `queue` and `cable`
70
+ databases. When only one database is supplied, follow the Solid Cache, Solid
71
+ Queue and Solid Cable single-database instructions (their schemas become
72
+ ordinary migrations and their `connects_to` settings are removed) instead of
73
+ inventing extra database names.
74
+ - The `pg` gem compiles against libpq unless the locked version ships a
75
+ precompiled gem for the platform.
76
+ - Use the inherited Rails migration and seed guidance. Keep connection,
77
+ integration and payment records in this database through Active Record
78
+ migrations and transactions; test uniqueness and concurrent updates on
79
+ PostgreSQL itself.
80
+
81
+ ## Adoption
82
+
83
+ - Confirm the adapter, every environment's database, username, password, host
84
+ and port expressions in `config/database.yml`, and whether `DATABASE_URL` is
85
+ read, before declaring readiness or connecting. Align the project Resource
86
+ bindings with the names the file actually reads.
@@ -0,0 +1,60 @@
1
+ # Stack piece: rails-sqlite
2
+
3
+ ## Description
4
+
5
+ Rails SQLite connection, Active Record migration, and database filename conventions.
6
+
7
+ ## Requires
8
+
9
+ - `rails`
10
+ - `sqlite`
11
+
12
+ ## Conflicts
13
+
14
+ - `rails-mysql`
15
+ - `rails-postgresql`
16
+
17
+ ## Resources
18
+
19
+ ```json genesis-resource
20
+ {
21
+ "id": "database",
22
+ "kind": "sqlite",
23
+ "environmentAlternatives": [
24
+ {
25
+ "bindings": {
26
+ "database": "DB_DATABASE"
27
+ },
28
+ "preferred": true
29
+ }
30
+ ]
31
+ }
32
+ ```
33
+
34
+ ## Guidance
35
+
36
+ - `rails new` (SQLite is the default) writes repository-relative files under
37
+ `storage/`, and Rails 8.1 leaves the production files unset. Make the
38
+ development and production primary read the supplied filename with the
39
+ generated name as fallback, for example
40
+ `database: <%= ENV.fetch("DB_DATABASE", "storage/development.sqlite3") %>`.
41
+ A bare `ENV.fetch("DB_DATABASE")` raises while `database.yml` loads and
42
+ breaks generators and asset builds that run without the variable. Keep `test`
43
+ on its own file such as `storage/test.sqlite3`.
44
+ - Rails 8 production also declares `cache`, `queue` and `cable` SQLite
45
+ databases. Keep them next to the primary file, for example
46
+ `<%= File.join(File.dirname(ENV.fetch("DB_DATABASE", "storage/production.sqlite3")), "production_cache.sqlite3") %>`,
47
+ so they persist with it; never leave them in a disposable release directory.
48
+ - Do not replace a supplied filename with a repository-relative default or
49
+ delete an existing file. `bin/rails db:prepare` creates a missing file and
50
+ its schema and migrates an existing one.
51
+ - The `sqlite3` gem normally installs a precompiled native gem; a source build
52
+ needs the SQLite headers. Use the inherited Rails migration and seed
53
+ guidance and test concurrent writes on SQLite itself.
54
+
55
+ ## Adoption
56
+
57
+ - Read `config/database.yml` for every environment's filename, including the
58
+ Rails 8 cache, queue and cable files, and preserve existing data: snapshot
59
+ it before moving to a supplied filename. Do not switch an existing app to an
60
+ empty database.