Skip to content

Instantly share code, notes, and snippets.

View giacope's full-sized avatar
🦙
Vibing

Giaco giacope

🦙
Vibing
View GitHub Profile
@giacope
giacope / 01_public_id_guide.md
Created April 14, 2026 06:42
Stripe-style Public IDs for Rails + Inertia.js — concern, migration, Alba serializers, RuboCop cop, and tests

Stripe-Style Public IDs for Rails + Inertia.js

A complete guide to implementing Stripe-style public IDs (po_a8Kx3mNp2qR1) in a Rails application. Public IDs replace raw database IDs in URLs, APIs, and frontend code — preventing enumeration attacks and leaking internal state.

Why Public IDs?

  • Security: Sequential integer IDs leak record counts and are trivially enumerable
  • Portability: Prefixed IDs (us_, po_, ch_) are self-describing across logs, support tickets, and APIs
  • Decoupling: Frontend and API consumers never depend on internal database IDs
@giacope
giacope / CLAUDE.md
Created April 14, 2026 02:15
Claude Code agent config for a Rails + Inertia.js + React app: hooks, rules, agents, skills, and commands

CLAUDE.md

Setup

mise install   # Install Ruby + Node versions from mise.toml
bin/setup      # Bundler, pnpm install, js:routes, db:prepare, clear tmp

Running

@giacope
giacope / postgresql-rls-rails.md
Created April 14, 2026 02:13
PostgreSQL Row Level Security (RLS) in Rails — a complete production-tested guide for multi-tenant apps

PostgreSQL Row Level Security (RLS) in Rails

A production-tested guide to implementing PostgreSQL RLS in a multi-tenant Rails application. Extracted from a real SaaS codebase serving thousands of workspaces.

Data is isolated at two levels:

  • Organization (billing, memberships, API keys)
  • Workspace (all operational data — posts, comments, files, etc.)

Adapt these to your tenancy model. Single-tenant apps can drop the organization layer entirely and use just tenant_id.

@giacope
giacope / .prettierignore
Created April 14, 2026 01:41
ESLint flat config, custom rules, Prettier, and TypeScript configs for a Rails + Inertia.js + React app
# Ignore artifacts:
build
coverage
app/frontend/routes
app/frontend/types/serializers
@giacope
giacope / .rubocop.yml
Created April 14, 2026 01:38
RuboCop config with custom cops (RESTful actions, no raw IDs, no render json)
require:
- ./lib/rubocop/cop/custom
inherit_from: .rubocop_todo.yml
inherit_mode:
merge:
- Exclude
# Omakase Ruby styling for Rails
inherit_gem: { rubocop-rails-omakase: rubocop.yml }
class ApplicationRecord < ActiveRecord::Base
around_save :uniq_validation
def uniq_validation
yield
rescue ActiveRecord::RecordNotUnique => e
columns = e.message[/Key \((.+)\)=/, 1]&.split(", ") || [:base]
columns.each { |column| errors.add(column, "must be unique") }
end
end
@giacope
giacope / cookies.rb
Created November 1, 2021 09:51
🍪 Rails Skip Cookies
class ApplicationController < ActionController::Base
after_action :skip_cookies
def skip_cookies
request.session_options[:skip] = true
end
end
@giacope
giacope / ahoy_cte.rb
Last active September 15, 2021 09:26
Ordered Funnel with Ahoy and ActiveRecord CTE
event_1 = 'Landed on product page'
event_2 = 'Added product to card'
event_3 = 'Went to checkout'
ActiveRecord::Base.connection.exec_query(
Ahoy::Event.with(
event_1: Ahoy::Event.select(:visit_id, 'MIN(time) AS step_time')
.where(name: event_1)
.group(1),
event_2: Ahoy::Event.select(:visit_id, 'MIN(time) AS step_time')