Add representative dev seed data #21
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "19-dev-seed-data"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
db/seeds.rbwith 18 realistic links so local development has representative data instead of 3 placeholdersfind_or_create_bykeyed onurlfor idempotent seeding (safe to run repeatedly)Changes
db/seeds.rb: replaced boilerplate comments with 18 seed links spanning infrastructure/DevOps (ArgoCD, Harbor, Grafana, Woodpecker, Forgejo, Keycloak), development references (Ruby, Rails, PostgreSQL, Tailwind CSS), portfolio/projects (palinks, basketball-api, homelab, personal site), and personal/utility (brain.fm, calendar, email, GitHub). Includes a mix of favorited and non-favorited links, with and withoutforgejo_url, varied metadata tags, and staggered position values.Test Plan
ruby -c db/seeds.rbpasses syntax checkbin/rails db:seedin the dev container — should create 18 linksbin/rails db:seeda second time — count should remain 18 (idempotency)Link.tagged("infra")etc.Review Checklist
Related Notes
ldraney/palinks #19— the Forgejo issue this PR implementspalinks— personal link dashboard projectCloses #19
Review — PR #21
Scope: Single file change (
db/seeds.rb), 188 additions / 8 deletions.Correctness
find_or_create_by!(url:)is the correct idempotency pattern — keyed onurl, the natural unique identifierurlandtitle(both required by model validations)https://scheme, satisfying theURI::DEFAULT_PARSERformat validationmetadatahashes use{ tags: [...] }structure, compatible with thetaggedscope's@>JSONB operatorpositionvalues use logical grouping by category (1-6, 10-13, 20-23, 30-33), leaving room for insertionsfavoriteis boolean throughout, matching thedefault: false, null: falseschema constraintvisibilitycolumn referenced — correct, it does not exist in the current schemaData Coverage
forgejo_url, 15 withoutNo Issues Found
Clean implementation. No fixes needed.
VERDICT: APPROVED
PR #21 Review
DOMAIN REVIEW
Tech stack: Ruby on Rails 8.1, PostgreSQL, seed data (
db/seeds.rb).Schema alignment: All 7 attributes used in the seed hashes (
url,title,description,forgejo_url,metadata,position,favorite) match thelinkstable columns indb/schema.rb. No unknown or misspelled column names.Model validation compliance: Every seed entry provides both
url(with valid HTTPS format) andtitle(non-blank), satisfying thevalidates :url, presence: true, format: ...andvalidates :title, presence: trueconstraints inapp/models/link.rb. All 18 entries will pass validation.Idempotency:
find_or_create_by!(url:)is the correct pattern for seed idempotency. Note that thelinkstable has no unique index onurl-- idempotency relies on application-levelfind_or_create_by!rather than a DB constraint. This is acceptable for a single-process dev seed runner, but worth noting: ifdb:seedwere ever run concurrently, duplicates could occur. Not a blocker for dev seed data.Metadata structure: All
metadatavalues use{ tags: [...] }which is compatible with thetaggedscope (where("metadata @> ?", { tags: [tag] }.to_json)). The GIN index onmetadatawill support these queries.Position gaps: Positions use intentional gaps (1-6, 10-13, 20-23, 30-33) for category grouping. This is clean and allows future insertions without renumbering.
Favorite distribution: 8 of 18 links are favorited (
favorite: true), providing good coverage for the favorites filter tab.BLOCKERS
None.
This PR modifies only
db/seeds.rbwith static development data. There are no new endpoints, no controller changes, no model changes, and no new user-facing functionality. The BLOCKER criterion "new functionality with zero test coverage" does not apply -- seed data is not testable functionality, it is development tooling. No secrets or credentials are present. All URLs useexample.complaceholders for infrastructure services.NITS
No unique index on
url: Thefind_or_create_by!(url:)pattern assumes no concurrent seed runs, which is fine for dev. If the app later needs URL uniqueness (e.g., preventing duplicate links in production), a migration addingadd_index :links, :url, unique: truewould make idempotency bulletproof. Not needed now, but worth tracking.find_or_create_by!update semantics: If a link already exists with the same URL but different attributes (e.g., title changed),find_or_create_by!will NOT update the existing record -- the block only runs on create. This is the correct behavior for seeds (don't overwrite user edits), but worth documenting if anyone expects re-seeding to "reset" data. A comment in the file clarifying this would be helpful.Output message:
puts "Seeded #{seeds.size} links (#{Link.count} total in database)"is good for developer feedback. Consider usingRails.logger.infoinstead ofputsif seeds are ever run in a context where stdout is not visible, butputsis standard Rails seed convention.SOP COMPLIANCE
19-dev-seed-datafollows{issue-number}-{kebab-case-purpose}conventionldraney/palinks #19andCloses #19example.comdomaindb/seeds.rb), 1 changed file totalPROCESS OBSERVATIONS
db:seedis not part of the container entrypoint or any automated process.VERDICT: APPROVED
PR #21 Review
DOMAIN REVIEW
Tech stack: Ruby on Rails 8.1.3, PostgreSQL (JSONB), Hotwire/Turbo. Single-file change to
db/seeds.rb.Rails patterns:
find_or_initialize_by(url:)+assign_attributes+save!is the correct idempotent upsert pattern for seeds. Re-running updates existing records rather than silently skipping them. Well done.url,title,description,forgejo_url,metadata,position,favorite), which avoids reliance on DB defaults for clarity.save!(bang version) will raise on validation failure rather than silently returning false -- correct for seed scripts where failures should be loud.JSONB key handling: Seed data uses Ruby symbol keys (
{ tags: [...] }), while theLink.taggedscope queries with string keys ({ tags: [tag] }.to_json). This is safe because Rails JSONB serialization normalizes symbols to strings on write, but it is a minor readability inconsistency (see nits).Missing unique index on
url: Thefind_or_initialize_by(url:)pattern assumes at most one record per URL, butdb/schema.rbhas no unique index onlinks.url. For dev seed data this is low-risk, but if this pattern is relied upon for production data integrity, a unique index should be added. Out of scope for this PR.BLOCKERS
None.
This PR modifies only dev seed data (
db/seeds.rb). It introduces no new user-facing functionality, no new endpoints, no new model behavior, and no security-relevant changes. The BLOCKER criterion for "new functionality with zero test coverage" does not apply -- seed data is conventionally untested in Rails, and the underlyingLinkmodel validations and controller logic are already covered.NITS
PR body says
find_or_create_bybut code usesfind_or_initialize_by: The summary section states "Usesfind_or_create_bykeyed onurl" but the actual implementation usesfind_or_initialize_by+assign_attributes+save!. The code is actually better (allows updating changed attributes on re-seed), but the PR description should match what the code does.Symbol vs string keys in metadata hashes: The seed data uses
metadata: { tags: [...] }(symbol key), while the model'staggedscope and controller both use string keys ("tags"). Rails handles the conversion, but using string keys in the seed data (metadata: { "tags" => [...] }) would make the data format visually consistent with how it is queried and stored.Logger output could include counts of created vs updated: The final log line
"Seeded #{seeds.size} links"is helpful. A minor enhancement would be tracking how many were newly created vs updated, which aids debugging when seed data changes over time. Not blocking.SOP COMPLIANCE
19-dev-seed-datareferences issue #19)ldraney/palinks #19,Closes #19)example.comdomains)db/seeds.rb)PROCESS OBSERVATIONS
db:seedtwice, check UI). These are appropriate for seed data validation but are not automated. Consider whether a CI step to rundb:seedagainst a test database would catch seed breakage in the future.test/fixtures/links.yml) use minimal data (3 links). The new seeds and fixtures serve different purposes (dev environment vs test suite), which is the correct separation.VERDICT: APPROVED