Scaffold Rails + publicaciones estaticas (Fase 1) #5

Merged
ldraney merged 3 commits from 2-scaffold-rails into main 2026-06-12 03:39:38 +00:00
Owner

Summary

Scaffold completo de Rails 8.1 con docker-compose, controlador de paginas, vistas en espanol y tema oscuro que coincide con ereccion.html.

Changes

  • docker-compose.yml -- Copiado de rails-base, puerto 9999, PostgreSQL 17, imagen ruby-rails-build de Harbor
  • config/database.yml -- Configurado con variables de entorno (DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD) para desarrollo containerizado
  • app/controllers/pages_controller.rb -- Dos acciones: inicio y acerca
  • app/views/pages/inicio.html.erb -- Pagina principal con lista de publicaciones y enlace a ereccion.html
  • app/views/pages/acerca.html.erb -- Pagina "acerca de" describiendo el proyecto
  • app/views/layouts/application.html.erb -- Layout con tema oscuro (bg: #0a0a0f, text: #e8e4df, accent: #c45a3c), navegacion con enlaces a inicio/acerca/ereccion, favicon SVG
  • config/routes.rb -- root 'pages#inicio', get 'acerca', health check en /up
  • Archivos estaticos existentes (public/ereccion.html, public/favicon.svg) sin modificar

Test Plan

  • docker compose up inicia sin errores
  • GET / retorna 200 con contenido de inicio en espanol
  • GET /acerca retorna 200 con descripcion del proyecto
  • GET /ereccion.html retorna 200 (archivo estatico servido por Rails)
  • GET /up retorna 200 (health check)
  • Navegacion funciona entre todas las paginas

Review Checklist

  • Todos los textos visibles al usuario estan en espanol
  • Tema oscuro coincide con ereccion.html (colores, tipografia)
  • Archivos existentes en public/ no modificados
  • docker-compose.yml funcional con puerto 9999
  • database.yml usa variables de entorno
  • Rutas configuradas correctamente
  • No se comiten archivos sensibles (master.key excluido por .gitignore)

Ninguna nota de pal-e-docs relacionada.

Closes #2

## Summary Scaffold completo de Rails 8.1 con docker-compose, controlador de paginas, vistas en espanol y tema oscuro que coincide con ereccion.html. ## Changes - **docker-compose.yml** -- Copiado de rails-base, puerto 9999, PostgreSQL 17, imagen ruby-rails-build de Harbor - **config/database.yml** -- Configurado con variables de entorno (DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD) para desarrollo containerizado - **app/controllers/pages_controller.rb** -- Dos acciones: `inicio` y `acerca` - **app/views/pages/inicio.html.erb** -- Pagina principal con lista de publicaciones y enlace a ereccion.html - **app/views/pages/acerca.html.erb** -- Pagina "acerca de" describiendo el proyecto - **app/views/layouts/application.html.erb** -- Layout con tema oscuro (bg: #0a0a0f, text: #e8e4df, accent: #c45a3c), navegacion con enlaces a inicio/acerca/ereccion, favicon SVG - **config/routes.rb** -- `root 'pages#inicio'`, `get 'acerca'`, health check en `/up` - Archivos estaticos existentes (`public/ereccion.html`, `public/favicon.svg`) sin modificar ## Test Plan - `docker compose up` inicia sin errores - `GET /` retorna 200 con contenido de inicio en espanol - `GET /acerca` retorna 200 con descripcion del proyecto - `GET /ereccion.html` retorna 200 (archivo estatico servido por Rails) - `GET /up` retorna 200 (health check) - Navegacion funciona entre todas las paginas ## Review Checklist - [x] Todos los textos visibles al usuario estan en espanol - [x] Tema oscuro coincide con ereccion.html (colores, tipografia) - [x] Archivos existentes en public/ no modificados - [x] docker-compose.yml funcional con puerto 9999 - [x] database.yml usa variables de entorno - [x] Rutas configuradas correctamente - [x] No se comiten archivos sensibles (master.key excluido por .gitignore) ## Related Notes Ninguna nota de pal-e-docs relacionada. ## Related Closes #2
Agrega la estructura completa de Rails 8.1 con docker-compose,
PagesController (inicio/acerca), layout con tema oscuro que
coincide con ereccion.html, y database.yml configurado para
las variables de entorno de Docker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #5 Review

PR: Scaffold Rails + publicaciones estaticas (Fase 1)
Branch: 2-scaffold-rails -> main
Parent Issue: #2
Stats: 93 files changed, +2,435 / -22


DOMAIN REVIEW

Stack: Ruby on Rails 8.1.3, PostgreSQL 17, Docker Compose, Hotwire (Turbo/Stimulus), Propshaft

Rails architecture:

  • Controller is clean and minimal -- PagesController with two empty actions (inicio, acerca) that rely on convention-based view rendering. Correct pattern for static pages.
  • Routes are well-structured: root "pages#inicio", named acerca route, health check at /up. No unnecessary RESTful scaffolding for what are static pages.
  • database.yml correctly uses ENV.fetch() with sensible defaults for all connection params. Production config splits cache/queue/cable into separate databases per Rails 8 convention.
  • Gemfile is standard Rails 8.1 with good security tooling included (brakeman, bundler-audit, rubocop-rails-omakase).

Docker Compose:

  • Uses pre-built image from Harbor registry (harbor.tail5b443a.ts.net/library/ruby-rails-build:latest). No Dockerfile in the PR, which is fine -- image is built externally.
  • Port mapping 9999:9999 is consistent with the rails server -p 9999 command.
  • Development credentials (rails/rails) are appropriate for local dev docker-compose. These are not production secrets.
  • Volume mounts for app code and bundle cache are correct.

Frontend / HTML / CSS:

  • Layout uses lang="es" on the HTML element -- correct for a Spanish-language site.
  • CSS custom properties for theming (--bg, --text, --accent, --muted, --section-border, --nav-bg) are well-organized.
  • Responsive design: media query at 600px adjusts padding. Uses clamp() for fluid typography on hero text -- good pattern.
  • CSRF and CSP meta tags are included via Rails helpers.
  • Viewport meta tag present.
  • Favicon linked as SVG.

Content:

  • All user-facing text is in Spanish as specified by the issue.
  • Navigation links cover all three destinations: Inicio, Acerca, Ereccion (static file).
  • The static file link (/ereccion.html) correctly uses a plain <a> tag instead of link_to since it's not a Rails route.

BLOCKERS

1. No controller or integration tests (BLOCKER)

The test infrastructure exists (test_helper.rb, test environment config, Capybara/Selenium in Gemfile) but all test directories contain only .keep placeholder files. There are zero actual test files.

For a scaffold PR, at minimum the following should exist:

  • test/controllers/pages_controller_test.rb -- verify GET / returns 200, GET /acerca returns 200, response bodies contain expected content
  • An integration/system test verifying navigation between pages

The PR's own "Test Plan" section lists manual verification steps (GET / retorna 200, GET /acerca retorna 200, etc.) -- these are exactly the tests that should be automated.

Per review criteria: "New functionality with zero test coverage" is a BLOCKER.


NITS

1. Inline CSS in layout (minor)
All 140+ lines of CSS are inlined in <style> tags within application.html.erb. For a small project this works, but as the site grows this will become unwieldy. Consider moving to app/assets/stylesheets/application.css which Propshaft already serves. This would also benefit from cache headers on the CSS asset.

2. Missing accent marks in Spanish text (cosmetic)
The content consistently omits accent marks (tildes) -- "Espanol" instead of "Espanol" with tilde, "pagina" instead of "pagina" with accent, "reflexion" instead of "reflexion" with accent, etc. This appears intentional (matching the repo name and existing ereccion.html), but worth confirming it is a deliberate style choice rather than an oversight.

3. No aria-current or active-link highlighting
The nav links have a .activo CSS class defined but it is never applied dynamically. Consider adding class: ("activo" if current_page?(root_path)) to nav links for accessibility and visual feedback.

4. Footer year is hardcoded
lucas draney &middot; 2026 -- consider using <%= Date.current.year %> to avoid annual maintenance.

5. max_connections naming in database.yml
Line max_connections: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> -- the key max_connections was renamed to pool in standard Rails database.yml. While max_connections may work depending on the adapter version, pool is the canonical name. Verify this works with Rails 8.1.3 and pg adapter.


SOP COMPLIANCE

  • PR body has: Summary, Changes, Test Plan, Related (via Review Checklist)
  • No secrets or credentials committed (master.key excluded via .gitignore, credentials.yml.enc is properly encrypted, .env* ignored)
  • docker-compose uses dev-only credentials (rails/rails), not production secrets
  • Commit message is descriptive (branch name matches issue: 2-scaffold-rails)
  • No unnecessary file changes -- all 93 files are Rails scaffold + custom code
  • Tests exist and pass -- No tests written (see BLOCKER above)

PROCESS OBSERVATIONS

  • Deployment readiness: The docker-compose is dev-only. Production deployment (Fase 2, issue #3) will need a proper Dockerfile, k8s manifests, and CI/CD pipeline. This is correctly scoped out of this PR.
  • Change failure risk: Low. This is a greenfield scaffold with no existing production code to break. The risk is in missing test coverage that would catch regressions in future phases.
  • Documentation: The PR body is thorough with a clear checklist. The "Acerca" page itself serves as project documentation.
  • Scope: Well-contained to Fase 1 deliverables. No scope creep detected.

VERDICT: NOT APPROVED

Reason: Zero test coverage for new controller actions. Add at minimum test/controllers/pages_controller_test.rb with tests for GET / and GET /acerca (status 200, correct content rendered). The test infrastructure is already in place -- only the actual test file is missing.

## PR #5 Review **PR:** Scaffold Rails + publicaciones estaticas (Fase 1) **Branch:** 2-scaffold-rails -> main **Parent Issue:** #2 **Stats:** 93 files changed, +2,435 / -22 --- ### DOMAIN REVIEW **Stack:** Ruby on Rails 8.1.3, PostgreSQL 17, Docker Compose, Hotwire (Turbo/Stimulus), Propshaft **Rails architecture:** - Controller is clean and minimal -- `PagesController` with two empty actions (`inicio`, `acerca`) that rely on convention-based view rendering. Correct pattern for static pages. - Routes are well-structured: `root "pages#inicio"`, named `acerca` route, health check at `/up`. No unnecessary RESTful scaffolding for what are static pages. - `database.yml` correctly uses `ENV.fetch()` with sensible defaults for all connection params. Production config splits cache/queue/cable into separate databases per Rails 8 convention. - Gemfile is standard Rails 8.1 with good security tooling included (brakeman, bundler-audit, rubocop-rails-omakase). **Docker Compose:** - Uses pre-built image from Harbor registry (`harbor.tail5b443a.ts.net/library/ruby-rails-build:latest`). No Dockerfile in the PR, which is fine -- image is built externally. - Port mapping 9999:9999 is consistent with the `rails server -p 9999` command. - Development credentials (`rails`/`rails`) are appropriate for local dev docker-compose. These are not production secrets. - Volume mounts for app code and bundle cache are correct. **Frontend / HTML / CSS:** - Layout uses `lang="es"` on the HTML element -- correct for a Spanish-language site. - CSS custom properties for theming (`--bg`, `--text`, `--accent`, `--muted`, `--section-border`, `--nav-bg`) are well-organized. - Responsive design: media query at 600px adjusts padding. Uses `clamp()` for fluid typography on hero text -- good pattern. - CSRF and CSP meta tags are included via Rails helpers. - Viewport meta tag present. - Favicon linked as SVG. **Content:** - All user-facing text is in Spanish as specified by the issue. - Navigation links cover all three destinations: Inicio, Acerca, Ereccion (static file). - The static file link (`/ereccion.html`) correctly uses a plain `<a>` tag instead of `link_to` since it's not a Rails route. --- ### BLOCKERS **1. No controller or integration tests (BLOCKER)** The test infrastructure exists (test_helper.rb, test environment config, Capybara/Selenium in Gemfile) but all test directories contain only `.keep` placeholder files. There are zero actual test files. For a scaffold PR, at minimum the following should exist: - `test/controllers/pages_controller_test.rb` -- verify `GET /` returns 200, `GET /acerca` returns 200, response bodies contain expected content - An integration/system test verifying navigation between pages The PR's own "Test Plan" section lists manual verification steps (`GET /` retorna 200, `GET /acerca` retorna 200, etc.) -- these are exactly the tests that should be automated. Per review criteria: "New functionality with zero test coverage" is a BLOCKER. --- ### NITS **1. Inline CSS in layout (minor)** All 140+ lines of CSS are inlined in `<style>` tags within `application.html.erb`. For a small project this works, but as the site grows this will become unwieldy. Consider moving to `app/assets/stylesheets/application.css` which Propshaft already serves. This would also benefit from cache headers on the CSS asset. **2. Missing accent marks in Spanish text (cosmetic)** The content consistently omits accent marks (tildes) -- "Espanol" instead of "Espanol" with tilde, "pagina" instead of "pagina" with accent, "reflexion" instead of "reflexion" with accent, etc. This appears intentional (matching the repo name and existing `ereccion.html`), but worth confirming it is a deliberate style choice rather than an oversight. **3. No `aria-current` or active-link highlighting** The nav links have a `.activo` CSS class defined but it is never applied dynamically. Consider adding `class: ("activo" if current_page?(root_path))` to nav links for accessibility and visual feedback. **4. Footer year is hardcoded** `lucas draney &middot; 2026` -- consider using `<%= Date.current.year %>` to avoid annual maintenance. **5. `max_connections` naming in database.yml** Line `max_connections: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>` -- the key `max_connections` was renamed to `pool` in standard Rails database.yml. While `max_connections` may work depending on the adapter version, `pool` is the canonical name. Verify this works with Rails 8.1.3 and pg adapter. --- ### SOP COMPLIANCE - [x] PR body has: Summary, Changes, Test Plan, Related (via Review Checklist) - [x] No secrets or credentials committed (master.key excluded via .gitignore, credentials.yml.enc is properly encrypted, .env* ignored) - [x] docker-compose uses dev-only credentials (rails/rails), not production secrets - [x] Commit message is descriptive (branch name matches issue: `2-scaffold-rails`) - [x] No unnecessary file changes -- all 93 files are Rails scaffold + custom code - [ ] Tests exist and pass -- **No tests written** (see BLOCKER above) --- ### PROCESS OBSERVATIONS - **Deployment readiness:** The docker-compose is dev-only. Production deployment (Fase 2, issue #3) will need a proper Dockerfile, k8s manifests, and CI/CD pipeline. This is correctly scoped out of this PR. - **Change failure risk:** Low. This is a greenfield scaffold with no existing production code to break. The risk is in missing test coverage that would catch regressions in future phases. - **Documentation:** The PR body is thorough with a clear checklist. The "Acerca" page itself serves as project documentation. - **Scope:** Well-contained to Fase 1 deliverables. No scope creep detected. --- ### VERDICT: NOT APPROVED **Reason:** Zero test coverage for new controller actions. Add at minimum `test/controllers/pages_controller_test.rb` with tests for `GET /` and `GET /acerca` (status 200, correct content rendered). The test infrastructure is already in place -- only the actual test file is missing.
11 pruebas que verifican respuestas 200, contenido en español,
navegación, favicon SVG y atributo lang="es" en el layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

PR #5 Re-Review

Re-review after previous blocker (zero test coverage) was addressed with a new commit adding test/controllers/pages_controller_test.rb.

DOMAIN REVIEW

Stack: Ruby on Rails 8.1, PostgreSQL 17, Docker Compose, Minitest (ActionDispatch::IntegrationTest).

test/controllers/pages_controller_test.rb (NEW -- 65 lines, 11 tests)

The test file is well-structured and covers the right surface area for this phase:

  • Response codes: inicio (root) and acerca both return 200 -- good.
  • Content assertions: assert_select verifies <h1>, <h2>, navigation links, favicon <link> tag, and <html lang="es"> -- these are meaningful structural tests, not just status checks.
  • Navigation coverage: both pages tested for nav bar presence with expected link targets (/, /acerca, /ereccion.html).
  • Accessibility baseline: lang="es" attribute verified -- important for screen readers and search engines.
  • Favicon: verified via link[rel='icon'][type='image/svg+xml'][href='/favicon.svg'].

Test names are in Spanish, matching the project language -- consistent.

Missing but acceptable for Fase 1:

  • No test for GET /ereccion.html (static file served by Rails/Rack, not by PagesController -- testing this would be a system test concern, not a controller test concern).
  • No test for GET /up health check (Rails built-in, not custom code).
  • No negative/edge-case tests (e.g., POST to read-only routes returning 405) -- reasonable to defer since there are no write endpoints.

app/controllers/pages_controller.rb (7 lines)

Minimal controller with two empty actions relying on convention-over-configuration for view rendering. Correct for this scope. No logic to test beyond what the integration tests already cover.

app/views/layouts/application.html.erb (186 lines)

  • Inline <style> block: 140+ lines of CSS inlined in the layout. This works for Fase 1 but should move to a stylesheet file in a future phase. Nit, not a blocker.
  • CSS custom properties used consistently (--bg, --text, --accent, --muted, --section-border, --nav-bg) -- good for theming.
  • Responsive: media query at 600px -- covers mobile. No tablet breakpoint, acceptable for a text-centric site.
  • csrf_meta_tags and csp_meta_tag present -- good security baseline.
  • Hardcoded /ereccion.html link in nav: acceptable since it is a static file outside Rails routing. Could use a helper constant later.

app/views/pages/inicio.html.erb and acerca.html.erb

Clean ERB. Uses content_for(:title) for per-page titles. Uses link_to with named routes (acerca_path, root_path) -- correct. One hardcoded link (/ereccion.html) is appropriate for a static asset.

config/routes.rb (10 lines)

  • root "pages#inicio" -- correct.
  • get "acerca", to: "pages#acerca" -- correct.
  • Health check at /up -- standard Rails 8 pattern.
  • Comments in Spanish -- consistent.

config/database.yml (32 lines)

  • Uses ENV.fetch with sensible defaults -- good.
  • max_connections reads from RAILS_MAX_THREADS -- fine, but the key name is max_connections not pool (Rails 8.1 change). Confirmed this is the correct key for Rails 8.1+.
  • Production uses multi-database config (cache, queue, cable) -- standard Rails 8 solid_* gem setup.
  • Default password "rails" for dev/test is fine (not a secret -- local Docker only).

docker-compose.yml (32 lines)

  • POSTGRES_PASSWORD: rails in plaintext: acceptable for local dev. Not a production config.
  • Port 9999 matches the PR description.
  • harbor.tail5b443a.ts.net/library/ruby-rails-build:latest -- uses internal Harbor registry. The :latest tag is fine for dev but should be pinned for CI/prod (future phase concern).
  • Bundle volume mount avoids re-downloading gems on restart -- good.

Gemfile (60 lines)

  • Standard Rails 8.1 Gemfile. pg, puma, propshaft, Hotwire stack, solid_* gems.
  • Security tooling in dev/test group: bundler-audit and brakeman -- good.
  • rubocop-rails-omakase for linting -- good.
  • Test group has capybara and selenium-webdriver for future system tests.

BLOCKERS

None. The previous blocker (zero test coverage for PagesController) is resolved. The new test file provides 11 integration tests covering both controller actions, view content, navigation structure, favicon, and lang attribute. This is adequate coverage for the scope of Fase 1.

No secrets committed. No unvalidated user input (no user input paths exist -- read-only pages). No DRY violations in security paths. No credentials in code beyond local dev Docker defaults.

NITS

  1. Inline CSS in layout (application.html.erb lines 17-165): 140+ lines of CSS in an inline <style> block. Consider extracting to app/assets/stylesheets/ in a future phase for cacheability and maintainability.
  2. No alt text concern: Not applicable here (no <img> tags), but worth noting accessibility as a pattern for future phases with images.
  3. Missing accent marks in Spanish text: "Espanol" should be "Espanol" (without tilde is acceptable in code/URLs but the user-visible <h1> and nav text could use "Espanol" with tilde for proper Spanish). Similarly "Ereccion" in nav. Minor UX polish.

SOP COMPLIANCE

  • PR body has ## Summary, ## Changes, ## Test Plan, ## Related -- all present and filled
  • PR body includes Review Checklist -- thorough
  • Tests exist (11 tests, 30 assertions per previous run confirmation)
  • No secrets, .env files, or credentials committed (master.key excluded by .gitignore)
  • No unnecessary file changes -- 94 files is large but expected for a Rails scaffold; all custom files are in scope for issue #2
  • Closes #2 referenced in PR body

PROCESS OBSERVATIONS

  • Change size: 94 files / +2500 / -22 is a large PR, but this is a greenfield Rails scaffold where most files are generated boilerplate. The custom surface area is small (7 files, ~350 lines of handwritten code). Acceptable for an initial scaffold PR.
  • Deployment frequency: This is the first real feature PR. Merging unblocks Fase 2 (CI/CD pipeline) and Fase 3 (observability).
  • Change failure risk: Low. Read-only pages, no database writes, no user input processing. The Docker-first approach means local testing is straightforward.

VERDICT: APPROVED

## PR #5 Re-Review Re-review after previous blocker (zero test coverage) was addressed with a new commit adding `test/controllers/pages_controller_test.rb`. ### DOMAIN REVIEW **Stack:** Ruby on Rails 8.1, PostgreSQL 17, Docker Compose, Minitest (ActionDispatch::IntegrationTest). **test/controllers/pages_controller_test.rb (NEW -- 65 lines, 11 tests)** The test file is well-structured and covers the right surface area for this phase: - Response codes: `inicio` (root) and `acerca` both return 200 -- good. - Content assertions: `assert_select` verifies `<h1>`, `<h2>`, navigation links, favicon `<link>` tag, and `<html lang="es">` -- these are meaningful structural tests, not just status checks. - Navigation coverage: both pages tested for nav bar presence with expected link targets (`/`, `/acerca`, `/ereccion.html`). - Accessibility baseline: `lang="es"` attribute verified -- important for screen readers and search engines. - Favicon: verified via `link[rel='icon'][type='image/svg+xml'][href='/favicon.svg']`. Test names are in Spanish, matching the project language -- consistent. **Missing but acceptable for Fase 1:** - No test for `GET /ereccion.html` (static file served by Rails/Rack, not by PagesController -- testing this would be a system test concern, not a controller test concern). - No test for `GET /up` health check (Rails built-in, not custom code). - No negative/edge-case tests (e.g., POST to read-only routes returning 405) -- reasonable to defer since there are no write endpoints. **app/controllers/pages_controller.rb (7 lines)** Minimal controller with two empty actions relying on convention-over-configuration for view rendering. Correct for this scope. No logic to test beyond what the integration tests already cover. **app/views/layouts/application.html.erb (186 lines)** - Inline `<style>` block: 140+ lines of CSS inlined in the layout. This works for Fase 1 but should move to a stylesheet file in a future phase. **Nit, not a blocker.** - CSS custom properties used consistently (`--bg`, `--text`, `--accent`, `--muted`, `--section-border`, `--nav-bg`) -- good for theming. - Responsive: media query at 600px -- covers mobile. No tablet breakpoint, acceptable for a text-centric site. - `csrf_meta_tags` and `csp_meta_tag` present -- good security baseline. - Hardcoded `/ereccion.html` link in nav: acceptable since it is a static file outside Rails routing. Could use a helper constant later. **app/views/pages/inicio.html.erb and acerca.html.erb** Clean ERB. Uses `content_for(:title)` for per-page titles. Uses `link_to` with named routes (`acerca_path`, `root_path`) -- correct. One hardcoded link (`/ereccion.html`) is appropriate for a static asset. **config/routes.rb (10 lines)** - `root "pages#inicio"` -- correct. - `get "acerca", to: "pages#acerca"` -- correct. - Health check at `/up` -- standard Rails 8 pattern. - Comments in Spanish -- consistent. **config/database.yml (32 lines)** - Uses `ENV.fetch` with sensible defaults -- good. - `max_connections` reads from `RAILS_MAX_THREADS` -- fine, but the key name is `max_connections` not `pool` (Rails 8.1 change). Confirmed this is the correct key for Rails 8.1+. - Production uses multi-database config (cache, queue, cable) -- standard Rails 8 solid_* gem setup. - Default password `"rails"` for dev/test is fine (not a secret -- local Docker only). **docker-compose.yml (32 lines)** - `POSTGRES_PASSWORD: rails` in plaintext: acceptable for local dev. Not a production config. - Port 9999 matches the PR description. - `harbor.tail5b443a.ts.net/library/ruby-rails-build:latest` -- uses internal Harbor registry. The `:latest` tag is fine for dev but should be pinned for CI/prod (future phase concern). - Bundle volume mount avoids re-downloading gems on restart -- good. **Gemfile (60 lines)** - Standard Rails 8.1 Gemfile. `pg`, `puma`, `propshaft`, Hotwire stack, solid_* gems. - Security tooling in dev/test group: `bundler-audit` and `brakeman` -- good. - `rubocop-rails-omakase` for linting -- good. - Test group has `capybara` and `selenium-webdriver` for future system tests. ### BLOCKERS **None.** The previous blocker (zero test coverage for PagesController) is resolved. The new test file provides 11 integration tests covering both controller actions, view content, navigation structure, favicon, and lang attribute. This is adequate coverage for the scope of Fase 1. No secrets committed. No unvalidated user input (no user input paths exist -- read-only pages). No DRY violations in security paths. No credentials in code beyond local dev Docker defaults. ### NITS 1. **Inline CSS in layout** (application.html.erb lines 17-165): 140+ lines of CSS in an inline `<style>` block. Consider extracting to `app/assets/stylesheets/` in a future phase for cacheability and maintainability. 2. **No `alt` text concern**: Not applicable here (no `<img>` tags), but worth noting accessibility as a pattern for future phases with images. 3. **Missing accent marks in Spanish text**: "Espanol" should be "Espanol" (without tilde is acceptable in code/URLs but the user-visible `<h1>` and nav text could use "Espanol" with tilde for proper Spanish). Similarly "Ereccion" in nav. Minor UX polish. ### SOP COMPLIANCE - [x] PR body has ## Summary, ## Changes, ## Test Plan, ## Related -- all present and filled - [x] PR body includes Review Checklist -- thorough - [x] Tests exist (11 tests, 30 assertions per previous run confirmation) - [x] No secrets, .env files, or credentials committed (master.key excluded by .gitignore) - [x] No unnecessary file changes -- 94 files is large but expected for a Rails scaffold; all custom files are in scope for issue #2 - [x] Closes #2 referenced in PR body ### PROCESS OBSERVATIONS - **Change size**: 94 files / +2500 / -22 is a large PR, but this is a greenfield Rails scaffold where most files are generated boilerplate. The custom surface area is small (7 files, ~350 lines of handwritten code). Acceptable for an initial scaffold PR. - **Deployment frequency**: This is the first real feature PR. Merging unblocks Fase 2 (CI/CD pipeline) and Fase 3 (observability). - **Change failure risk**: Low. Read-only pages, no database writes, no user input processing. The Docker-first approach means local testing is straightforward. ### VERDICT: APPROVED
Author
Owner

PR #5 Review

DOMAIN REVIEW

Stack: Ruby on Rails 8.1.3, PostgreSQL 17, Docker Compose, Propshaft, Hotwire (Turbo + Stimulus), HTML/CSS.

Rails quality:

  • Controller is clean and minimal -- two empty actions relying on convention-based view rendering. Correct pattern for static pages.
  • Routes are well-structured: root, named acerca route, health check. Comments in Spanish match the project language.
  • database.yml properly uses ENV.fetch with fallback defaults for development. Production config correctly inherits and defines separate databases for cache/queue/cable (Solid Stack pattern).
  • config/application.rb uses config.load_defaults 8.1 -- matches the Gemfile's Rails version.
  • Gemfile includes brakeman and bundler-audit in dev/test -- good security posture out of the box.
  • credentials.yml.enc is committed (expected) and .gitignore excludes config/*.key -- master key is safe.

HTML/CSS quality:

  • Layout sets lang="es" -- correct for a Spanish-language site.
  • CSS uses custom properties (:root variables) for theming -- clean, maintainable approach.
  • Responsive breakpoint at 600px with sensible adjustments.
  • clamp() used for fluid typography -- good practice.
  • Navigation is semantic with flex layout and proper link structure.

Docker Compose:

  • Uses private Harbor registry image (harbor.tail5b443a.ts.net/library/ruby-rails-build:latest) -- appropriate for the platform.
  • PostgreSQL 17 Alpine is a solid choice.
  • Named volumes for pgdata and bundle prevent data loss across restarts.

Test coverage:

  • 11 integration tests in test/controllers/pages_controller_test.rb covering:
    • HTTP 200 responses for both routes
    • Content assertions (titles, links, navigation elements)
    • Favicon link tag presence
    • HTML lang attribute
  • This is solid coverage for a Fase 1 scaffold. Both happy-path and structural assertions are present.

BLOCKERS

None. No blocking issues found.

NITS

  1. Puma port mismatch (low risk): config/puma.rb defaults to port 3000 (ENV.fetch("PORT", 3000)) while docker-compose.yml runs the server explicitly on port 9999 via command: bundle exec rails server -b 0.0.0.0 -p 9999. This works because the command flag overrides Puma's config, but it creates a confusing discrepancy. Consider setting PORT=9999 in the docker-compose environment block so both agree, or changing the Puma default.

  2. README regression: The original README had project-specific content (description, quick-start, architecture links, related repos). This PR replaces it with the default Rails rails new boilerplate ("This README would normally document..."). The original README content was more informative and should be preserved or adapted rather than overwritten.

  3. All CSS is inline in the layout: The 150+ lines of CSS in app/views/layouts/application.html.erb should live in app/assets/stylesheets/application.css (which is currently empty aside from comments). Inline styles in the layout work but bypass the asset pipeline (no fingerprinting, no caching headers) and will become harder to maintain as the site grows.

  4. Hardcoded default passwords in database.yml: ENV.fetch("DATABASE_PASSWORD", "rails") provides a plaintext fallback. This is fine for local development, but if this default ever leaks into a production-like environment it could be a problem. Consider removing the fallback for DATABASE_PASSWORD so it fails loudly if unset: ENV.fetch("DATABASE_PASSWORD").

  5. .current-issue file: This tracking file is committed to the repo. It serves a workflow purpose but is not application code. Consider adding it to .gitignore if it is only used by the development tooling and should not be part of the deployed codebase.

  6. Missing accent marks in Spanish text: Several visible strings omit tildes/accents where standard Spanish requires them: "Espanol" should be "Espanol" (acceptable if the project intentionally avoids special characters in code), but the PR body and issue use accented forms. Minor consistency point.

  7. Content Security Policy disabled: config/initializers/content_security_policy.rb is entirely commented out. This is the Rails default, but since the app serves user-visible HTML with inline styles, consider enabling at least a basic CSP in Fase 2/3 when the CI/CD pipeline is established.

SOP COMPLIANCE

  • Branch named after issue (2-scaffold-rails references issue #2)
  • PR body has ## Summary
  • PR body has ## Changes
  • PR body has ## Test Plan
  • PR body has ## Review Checklist
  • PR body has Closes #2
  • Tests exist (test/controllers/pages_controller_test.rb -- 11 tests)
  • No secrets committed (config/*.key in .gitignore, .env* in .gitignore)
  • No unnecessary file changes -- 94 files is large but expected for a rails new scaffold; custom files align with issue scope
  • Commit messages -- single-purpose PR, scaffold scope is clear
  • Related Notes section says "Ninguna nota de pal-e-docs relacionada" -- no plan slug referenced (non-blocking for this project)

PROCESS OBSERVATIONS

  • This is a clean Fase 1 scaffold. The 94-file count is inherent to rails new and does not represent scope creep -- the custom work (controller, views, routes, layout, tests, docker-compose, database config) is well-scoped to issue #2.
  • Test coverage is good for a scaffold phase. The 11 tests verify both rendering correctness and structural elements (nav, favicon, lang attribute).
  • Deployment frequency: this PR establishes the application foundation. Once merged, Fase 2 (CI/CD pipeline) and Fase 3 (observability) can proceed.
  • Change failure risk: low. This is a greenfield scaffold with no existing production traffic.

VERDICT: APPROVED

## PR #5 Review ### DOMAIN REVIEW **Stack:** Ruby on Rails 8.1.3, PostgreSQL 17, Docker Compose, Propshaft, Hotwire (Turbo + Stimulus), HTML/CSS. **Rails quality:** - Controller is clean and minimal -- two empty actions relying on convention-based view rendering. Correct pattern for static pages. - Routes are well-structured: root, named `acerca` route, health check. Comments in Spanish match the project language. - `database.yml` properly uses `ENV.fetch` with fallback defaults for development. Production config correctly inherits and defines separate databases for cache/queue/cable (Solid Stack pattern). - `config/application.rb` uses `config.load_defaults 8.1` -- matches the Gemfile's Rails version. - Gemfile includes brakeman and bundler-audit in dev/test -- good security posture out of the box. - `credentials.yml.enc` is committed (expected) and `.gitignore` excludes `config/*.key` -- master key is safe. **HTML/CSS quality:** - Layout sets `lang="es"` -- correct for a Spanish-language site. - CSS uses custom properties (`:root` variables) for theming -- clean, maintainable approach. - Responsive breakpoint at 600px with sensible adjustments. - `clamp()` used for fluid typography -- good practice. - Navigation is semantic with flex layout and proper link structure. **Docker Compose:** - Uses private Harbor registry image (`harbor.tail5b443a.ts.net/library/ruby-rails-build:latest`) -- appropriate for the platform. - PostgreSQL 17 Alpine is a solid choice. - Named volumes for `pgdata` and `bundle` prevent data loss across restarts. **Test coverage:** - 11 integration tests in `test/controllers/pages_controller_test.rb` covering: - HTTP 200 responses for both routes - Content assertions (titles, links, navigation elements) - Favicon link tag presence - HTML lang attribute - This is solid coverage for a Fase 1 scaffold. Both happy-path and structural assertions are present. ### BLOCKERS None. No blocking issues found. ### NITS 1. **Puma port mismatch (low risk):** `config/puma.rb` defaults to port 3000 (`ENV.fetch("PORT", 3000)`) while `docker-compose.yml` runs the server explicitly on port 9999 via `command: bundle exec rails server -b 0.0.0.0 -p 9999`. This works because the command flag overrides Puma's config, but it creates a confusing discrepancy. Consider setting `PORT=9999` in the docker-compose environment block so both agree, or changing the Puma default. 2. **README regression:** The original README had project-specific content (description, quick-start, architecture links, related repos). This PR replaces it with the default Rails `rails new` boilerplate ("This README would normally document..."). The original README content was more informative and should be preserved or adapted rather than overwritten. 3. **All CSS is inline in the layout:** The 150+ lines of CSS in `app/views/layouts/application.html.erb` should live in `app/assets/stylesheets/application.css` (which is currently empty aside from comments). Inline styles in the layout work but bypass the asset pipeline (no fingerprinting, no caching headers) and will become harder to maintain as the site grows. 4. **Hardcoded default passwords in `database.yml`:** `ENV.fetch("DATABASE_PASSWORD", "rails")` provides a plaintext fallback. This is fine for local development, but if this default ever leaks into a production-like environment it could be a problem. Consider removing the fallback for `DATABASE_PASSWORD` so it fails loudly if unset: `ENV.fetch("DATABASE_PASSWORD")`. 5. **`.current-issue` file:** This tracking file is committed to the repo. It serves a workflow purpose but is not application code. Consider adding it to `.gitignore` if it is only used by the development tooling and should not be part of the deployed codebase. 6. **Missing accent marks in Spanish text:** Several visible strings omit tildes/accents where standard Spanish requires them: "Espanol" should be "Espanol" (acceptable if the project intentionally avoids special characters in code), but the PR body and issue use accented forms. Minor consistency point. 7. **Content Security Policy disabled:** `config/initializers/content_security_policy.rb` is entirely commented out. This is the Rails default, but since the app serves user-visible HTML with inline styles, consider enabling at least a basic CSP in Fase 2/3 when the CI/CD pipeline is established. ### SOP COMPLIANCE - [x] Branch named after issue (`2-scaffold-rails` references issue #2) - [x] PR body has ## Summary - [x] PR body has ## Changes - [x] PR body has ## Test Plan - [x] PR body has ## Review Checklist - [x] PR body has `Closes #2` - [x] Tests exist (`test/controllers/pages_controller_test.rb` -- 11 tests) - [x] No secrets committed (`config/*.key` in `.gitignore`, `.env*` in `.gitignore`) - [x] No unnecessary file changes -- 94 files is large but expected for a `rails new` scaffold; custom files align with issue scope - [x] Commit messages -- single-purpose PR, scaffold scope is clear - [ ] Related Notes section says "Ninguna nota de pal-e-docs relacionada" -- no plan slug referenced (non-blocking for this project) ### PROCESS OBSERVATIONS - This is a clean Fase 1 scaffold. The 94-file count is inherent to `rails new` and does not represent scope creep -- the custom work (controller, views, routes, layout, tests, docker-compose, database config) is well-scoped to issue #2. - Test coverage is good for a scaffold phase. The 11 tests verify both rendering correctness and structural elements (nav, favicon, lang attribute). - Deployment frequency: this PR establishes the application foundation. Once merged, Fase 2 (CI/CD pipeline) and Fase 3 (observability) can proceed. - Change failure risk: low. This is a greenfield scaffold with no existing production traffic. ### VERDICT: APPROVED
Español, Erección, Propósito, colección, páginas, aplicación,
navegación, reflexión, filosofía, diseño, estética, estático,
índice, nació, reúne — todos corregidos en layout, inicio,
acerca, y tests de controlador.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ldraney deleted branch 2-scaffold-rails 2026-06-12 03:39:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/html-poster-espanol!5
No description provided.