pg_multitenant_schemas 0.1.3 โ 0.2.2
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.
- checksums.yaml +4 -4
- data/.actrc +17 -0
- data/.env.local.example +21 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +86 -0
- data/LOCAL_TESTING_SUMMARY.md +141 -0
- data/README.md +269 -16
- data/TESTING_LOCALLY.md +208 -0
- data/docs/README.md +81 -0
- data/docs/configuration.md +340 -0
- data/docs/context.md +292 -0
- data/docs/errors.md +498 -0
- data/docs/github_actions_permissions_fix.md +136 -0
- data/docs/github_actions_setup.md +181 -0
- data/docs/integration_testing.md +454 -0
- data/docs/local_workflow_testing.md +314 -0
- data/docs/migrator.md +291 -0
- data/docs/rails_integration.md +468 -0
- data/docs/schema_switcher.md +182 -0
- data/docs/tenant_resolver.md +394 -0
- data/docs/testing.md +358 -0
- data/examples/context_management.rb +198 -0
- data/examples/migration_workflow.rb +50 -0
- data/examples/rails_integration/controller_examples.rb +368 -0
- data/examples/schema_operations.rb +124 -0
- data/lib/pg_multitenant_schemas/configuration.rb +4 -4
- data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
- data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
- data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
- data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
- data/lib/pg_multitenant_schemas/migrator.rb +89 -0
- data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
- data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
- data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
- data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
- data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
- data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
- data/lib/pg_multitenant_schemas/version.rb +1 -1
- data/lib/pg_multitenant_schemas.rb +10 -5
- data/pg_multitenant_schemas.gemspec +10 -9
- data/pre-push-check.sh +95 -0
- data/rails_integration/app/controllers/application_controller.rb +6 -0
- data/rails_integration/app/models/tenant.rb +6 -0
- data/test-github-setup.sh +85 -0
- data/validate-github-commands.sh +47 -0
- metadata +49 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4523327235e126955f182413b00ecab417f260daf3b0ed550ece95bc1da7a8bf
|
|
4
|
+
data.tar.gz: 4f277b6139588035c3d04befb30b475ad55fd7a199d582e7728aed15757dcc7c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a454ee397a247ea820b89590c0e9c8d10f63e83507f4b989b27780b8721c99b5191fe9048f7cf378d9388371650524b48adcf4a4ec58c2566aa2e0afdfb66929
|
|
7
|
+
data.tar.gz: 6adc8a9a67ff69b2e045982ff85a48f045a683614bb548343bc64e78062c01b191e5e70984c8ed3dd110696bd556f51def524dd2619f1a5d20cd43f3eeafcb9a
|
data/.actrc
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# act configuration file
|
|
2
|
+
# This configures act to run GitHub Actions locally
|
|
3
|
+
|
|
4
|
+
# Use Linux AMD64 architecture for compatibility
|
|
5
|
+
--container-architecture linux/amd64
|
|
6
|
+
|
|
7
|
+
# Set artifact server path
|
|
8
|
+
--artifact-server-path /tmp/act-artifacts
|
|
9
|
+
|
|
10
|
+
# Load environment variables from local file
|
|
11
|
+
--env-file .env.local
|
|
12
|
+
|
|
13
|
+
# Use medium size runner image
|
|
14
|
+
--platform ubuntu-latest=catthehacker/ubuntu:act-latest
|
|
15
|
+
|
|
16
|
+
# Show more verbose output
|
|
17
|
+
--verbose
|
data/.env.local.example
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Local environment variables for testing with act
|
|
2
|
+
# Copy this to .env.local and fill in your actual values
|
|
3
|
+
|
|
4
|
+
# GitHub token (create at https://github.com/settings/tokens)
|
|
5
|
+
# Needs repo and workflow permissions
|
|
6
|
+
GITHUB_TOKEN=your_github_token_here
|
|
7
|
+
|
|
8
|
+
# RubyGems API key (get from https://rubygems.org/profile/edit)
|
|
9
|
+
# Only needed for testing release workflow
|
|
10
|
+
RUBYGEMS_API_KEY=your_rubygems_api_key_here
|
|
11
|
+
|
|
12
|
+
# Repository information
|
|
13
|
+
GITHUB_REPOSITORY=rubenpazch/pg_multitenant_schemas
|
|
14
|
+
GITHUB_ACTOR=your_github_username
|
|
15
|
+
|
|
16
|
+
# PostgreSQL configuration for local testing
|
|
17
|
+
PGDATABASE=pg_multitenant_test
|
|
18
|
+
PGUSER=postgres
|
|
19
|
+
PGPASSWORD=
|
|
20
|
+
PGHOST=localhost
|
|
21
|
+
PGPORT=5432
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.4.3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,86 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2025-09-07
|
|
11
|
+
|
|
12
|
+
### ๐ง **Developer Experience & Testing**
|
|
13
|
+
- **NEW: Local Workflow Testing**: Complete solution for testing GitHub Actions locally before push
|
|
14
|
+
- **NEW: Pre-Push Validation**: `pre-push-check.sh` script validates CI components locally
|
|
15
|
+
- **NEW: GitHub Actions Testing**: `act` tool integration with configuration files
|
|
16
|
+
- **NEW: Validation Scripts**: `validate-github-commands.sh` and `test-github-setup.sh`
|
|
17
|
+
|
|
18
|
+
### ๐ **CI/CD Improvements**
|
|
19
|
+
- **FIXED: GitHub Actions Permissions**: Resolved permission issues with release workflow
|
|
20
|
+
- **FIXED: RSpec Command**: Corrected `--exclude-pattern` usage for unit test isolation
|
|
21
|
+
- **IMPROVED: Release Automation**: Enhanced release workflow with proper bot identity
|
|
22
|
+
- **IMPROVED: Documentation**: Comprehensive guides for CI/CD setup and troubleshooting
|
|
23
|
+
|
|
24
|
+
### ๐ **Documentation Enhancements**
|
|
25
|
+
- **NEW: Local Testing Guide**: `TESTING_LOCALLY.md` and `LOCAL_TESTING_SUMMARY.md`
|
|
26
|
+
- **NEW: CI/CD Setup Guide**: `docs/github_actions_setup.md` with step-by-step instructions
|
|
27
|
+
- **NEW: Permissions Fix Guide**: `docs/github_actions_permissions_fix.md`
|
|
28
|
+
- **NEW: Workflow Testing Guide**: `docs/local_workflow_testing.md`
|
|
29
|
+
- **IMPROVED: Core Documentation**: Updated `docs/README.md` with local testing references
|
|
30
|
+
|
|
31
|
+
### ๐งช **Testing Infrastructure**
|
|
32
|
+
- **ENHANCED: RuboCop Compliance**: Fixed all code style violations across test suite
|
|
33
|
+
- **ENHANCED: Test Organization**: Improved test structure and mocking patterns
|
|
34
|
+
- **ENHANCED: Integration Testing**: Better PostgreSQL integration test support
|
|
35
|
+
- **ENHANCED: Security Auditing**: Bundle audit integration in CI pipeline
|
|
36
|
+
|
|
37
|
+
### ๐ง **Configuration Files**
|
|
38
|
+
- **NEW: `.actrc`**: Configuration for local GitHub Actions testing
|
|
39
|
+
- **NEW: `.env.local.example`**: Template for local environment variables
|
|
40
|
+
- **IMPROVED: `.gitignore`**: Added local testing files to ignore list
|
|
41
|
+
|
|
42
|
+
## [0.2.1] - 2025-09-06
|
|
43
|
+
|
|
44
|
+
### ๐ **Migration System Overhaul**
|
|
45
|
+
- **NEW: Automated Migration Management**: Complete migration system for multi-tenant schemas
|
|
46
|
+
- **NEW: PgMultitenantSchemas::Migrator**: Comprehensive migration management class
|
|
47
|
+
- **NEW: Simplified Rake Tasks**: Modern `tenants:*` namespace with intuitive commands
|
|
48
|
+
- **NEW: Bulk Operations**: Single-command migration across all tenant schemas
|
|
49
|
+
- **NEW: Enhanced Status Reporting**: Detailed migration status with progress indicators
|
|
50
|
+
|
|
51
|
+
### โจ **Enhanced Features**
|
|
52
|
+
- **Automated Tenant Setup**: `setup_tenant()` creates schema + runs migrations
|
|
53
|
+
- **Migration Status Tracking**: Real-time status across all tenant schemas
|
|
54
|
+
- **Error Resilience**: Graceful error handling per tenant during bulk operations
|
|
55
|
+
- **Tenant Creation Workflow**: `create_tenant_with_schema()` for complete tenant setup
|
|
56
|
+
- **Rollback Support**: Individual tenant rollback capabilities
|
|
57
|
+
|
|
58
|
+
### ๐ง **Developer Experience**
|
|
59
|
+
- **Intuitive Commands**: `rails tenants:migrate`, `rails tenants:status`, `rails tenants:create`
|
|
60
|
+
- **Progress Feedback**: Visual progress indicators during migration operations
|
|
61
|
+
- **Safety Features**: Confirmation prompts for destructive operations
|
|
62
|
+
- **Legacy Compatibility**: Deprecated old commands with migration path
|
|
63
|
+
- **Example Scripts**: Complete workflow documentation and examples
|
|
64
|
+
|
|
65
|
+
## [0.2.0] - 2025-09-06
|
|
66
|
+
|
|
67
|
+
### ๐ **BREAKING CHANGES**
|
|
68
|
+
- **Modernized for Rails 8+ and Ruby 3.4+**: Removed backward compatibility
|
|
69
|
+
- **Simplified API**: Removed dual API support for cleaner codebase
|
|
70
|
+
- **Rails 8+ Only**: Updated dependencies to require ActiveRecord >= 8.0
|
|
71
|
+
- **Ruby 3.2+ Required**: Minimum Ruby version increased from 3.1.0 to 3.2.0
|
|
72
|
+
|
|
73
|
+
### โจ **Added**
|
|
74
|
+
- Modern Ruby 3.3+ features and performance optimizations
|
|
75
|
+
- Enhanced configuration defaults for Rails 8+ applications
|
|
76
|
+
- Improved error messages and developer experience
|
|
77
|
+
|
|
78
|
+
### ๐ง **Changed**
|
|
79
|
+
- Simplified `SchemaSwitcher` API (removed connection parameter overloads)
|
|
80
|
+
- Updated default connection class to `ApplicationRecord`
|
|
81
|
+
- Enhanced excluded subdomains and TLD lists
|
|
82
|
+
- Automatic Rails logger integration
|
|
83
|
+
|
|
84
|
+
### ๐๏ธ **Removed**
|
|
85
|
+
- Backward compatibility layers
|
|
86
|
+
- Dual API support (old conn parameter methods)
|
|
87
|
+
- Legacy Rails version compatibility code
|
|
88
|
+
- Ruby < 3.3 support
|
|
89
|
+
|
|
10
90
|
## [0.1.3] - 2025-09-03
|
|
11
91
|
|
|
12
92
|
### Added
|
|
@@ -48,3 +128,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
48
128
|
- Initial release
|
|
49
129
|
- Basic schema switching functionality
|
|
50
130
|
- PostgreSQL multitenancy support
|
|
131
|
+
|
|
132
|
+
[Unreleased]: https://github.com/rubenpazch/pg_multitenant_schemas/compare/v0.2.2...HEAD
|
|
133
|
+
[0.2.2]: https://github.com/rubenpazch/pg_multitenant_schemas/compare/v0.2.1...v0.2.2
|
|
134
|
+
[0.2.1]: https://github.com/rubenpazch/pg_multitenant_schemas/compare/v0.2.0...v0.2.1
|
|
135
|
+
[0.2.0]: https://github.com/rubenpazch/pg_multitenant_schemas/compare/v0.1.0...v0.2.0
|
|
136
|
+
[0.1.0]: https://github.com/rubenpazch/pg_multitenant_schemas/releases/tag/v0.1.0
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# ๐งช Summary: How to Test GitHub Workflows Locally
|
|
2
|
+
|
|
3
|
+
## โ
What You Can Do Right Now
|
|
4
|
+
|
|
5
|
+
### 1. **Pre-Push Script (Recommended)**## ๐ **Files Created**
|
|
6
|
+
|
|
7
|
+
- **`pre-push-check.sh`** - Main testing script
|
|
8
|
+
- **`validate-github-commands.sh`** - Test exact GitHub Actions commands
|
|
9
|
+
- **`TESTING_LOCALLY.md`** - Quick start guide
|
|
10
|
+
- **`docs/local_workflow_testing.md`** - Complete documentation
|
|
11
|
+
- **`.actrc`** - act configuration
|
|
12
|
+
- **`.env.local.example`** - Environment templateh
|
|
13
|
+
# Run this before every push
|
|
14
|
+
./pre-push-check.sh
|
|
15
|
+
```
|
|
16
|
+
This validates everything that runs in CI:
|
|
17
|
+
- โ
RuboCop (code style)
|
|
18
|
+
- โ
RSpec (tests)
|
|
19
|
+
- โ
Bundle audit (security)
|
|
20
|
+
- โ
Gem building
|
|
21
|
+
- โ
Integration tests (if PostgreSQL available)
|
|
22
|
+
|
|
23
|
+
### 2. **Manual Component Testing**
|
|
24
|
+
```bash
|
|
25
|
+
```bash
|
|
26
|
+
# Test each CI component individually
|
|
27
|
+
bundle install
|
|
28
|
+
bundle exec rubocop # Code style check
|
|
29
|
+
bundle exec rspec # Run all tests
|
|
30
|
+
bundle exec rspec --tag integration # Integration tests only
|
|
31
|
+
bundle exec rspec --exclude-pattern '**/integration/**/*_spec.rb' # Unit tests only
|
|
32
|
+
bundle audit # Security audit
|
|
33
|
+
gem build pg_multitenant_schemas.gemspec # Test gem build
|
|
34
|
+
```
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. **act Tool (Partial Support)**
|
|
38
|
+
```bash
|
|
39
|
+
# List workflows
|
|
40
|
+
act -l
|
|
41
|
+
|
|
42
|
+
# Dry run (shows what would execute)
|
|
43
|
+
act -n push
|
|
44
|
+
|
|
45
|
+
# Note: Currently has issues with PostgreSQL services
|
|
46
|
+
# Better for simple workflows without database dependencies
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## ๐ฏ **Before Every Push Checklist**
|
|
50
|
+
|
|
51
|
+
1. โ
Run `./pre-push-check.sh`
|
|
52
|
+
2. โ
Fix any issues found
|
|
53
|
+
3. โ
Commit your changes
|
|
54
|
+
4. โ
Push to GitHub
|
|
55
|
+
|
|
56
|
+
## ๐ **Component Status**
|
|
57
|
+
|
|
58
|
+
| Component | Local Testing | Status |
|
|
59
|
+
|-----------|---------------|---------|
|
|
60
|
+
| RuboCop | โ
`bundle exec rubocop` | Working |
|
|
61
|
+
| Unit Tests | โ
`bundle exec rspec` | Working |
|
|
62
|
+
| Integration Tests | โ
With local PostgreSQL | Working |
|
|
63
|
+
| Security Audit | โ
`bundle audit` | Working |
|
|
64
|
+
| Gem Building | โ
`gem build *.gemspec` | Working |
|
|
65
|
+
| Release Workflow | โ ๏ธ Manual simulation only | Partial |
|
|
66
|
+
| Full CI with act | โ ๏ธ PostgreSQL service issues | Limited |
|
|
67
|
+
|
|
68
|
+
## ๐ง **Quick Setup**
|
|
69
|
+
|
|
70
|
+
1. **Make pre-push script executable:**
|
|
71
|
+
```bash
|
|
72
|
+
chmod +x pre-push-check.sh
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. **Install act (optional):**
|
|
76
|
+
```bash
|
|
77
|
+
brew install act
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
3. **Create environment file (for act):**
|
|
81
|
+
```bash
|
|
82
|
+
cp .env.local.example .env.local
|
|
83
|
+
# Edit .env.local with your tokens if needed
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## ๐ **Recommended Workflow**
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 1. Make your changes
|
|
90
|
+
git add .
|
|
91
|
+
|
|
92
|
+
# 2. Test locally
|
|
93
|
+
./pre-push-check.sh
|
|
94
|
+
|
|
95
|
+
# 3. If all passes, commit and push
|
|
96
|
+
git commit -m "Your changes"
|
|
97
|
+
git push
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## ๐ ๏ธ **Troubleshooting**
|
|
101
|
+
|
|
102
|
+
### PostgreSQL Issues
|
|
103
|
+
```bash
|
|
104
|
+
# Check if PostgreSQL is running
|
|
105
|
+
pg_isready
|
|
106
|
+
|
|
107
|
+
# Start PostgreSQL (macOS)
|
|
108
|
+
brew services start postgresql@15
|
|
109
|
+
|
|
110
|
+
# Create test database
|
|
111
|
+
createdb pg_multitenant_test
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Ruby Issues
|
|
115
|
+
```bash
|
|
116
|
+
# Install correct Ruby version
|
|
117
|
+
rbenv install 3.3.0
|
|
118
|
+
rbenv local 3.3.0
|
|
119
|
+
bundle install
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### act Issues
|
|
123
|
+
```bash
|
|
124
|
+
# Try without services (simpler)
|
|
125
|
+
act -j security # Just run security audit job
|
|
126
|
+
|
|
127
|
+
# Check Docker is running
|
|
128
|
+
docker ps
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## ๐ **Files Created**
|
|
132
|
+
|
|
133
|
+
- **`pre-push-check.sh`** - Main testing script
|
|
134
|
+
- **`TESTING_LOCALLY.md`** - Quick start guide
|
|
135
|
+
- **`docs/local_workflow_testing.md`** - Complete documentation
|
|
136
|
+
- **`.actrc`** - act configuration
|
|
137
|
+
- **`.env.local.example`** - Environment template
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
**๐ก Bottom Line**: Use `./pre-push-check.sh` for reliable local testing. It covers 95% of what CI does and catches issues early!
|
data/README.md
CHANGED
|
@@ -3,18 +3,27 @@
|
|
|
3
3
|
[](https://badge.fury.io/rb/pg_multitenant_schemas)
|
|
4
4
|
[](https://github.com/yourusername/pg_multitenant_schemas/actions/workflows/main.yml)
|
|
5
5
|
|
|
6
|
-
A Ruby gem that provides PostgreSQL schema-based multitenancy with automatic tenant resolution
|
|
6
|
+
A modern Ruby gem that provides PostgreSQL schema-based multitenancy with automatic tenant resolution and schema switching. Built for Rails 8+ and Ruby 3.3+, focusing on security, performance, and developer experience.
|
|
7
7
|
|
|
8
|
-
## Features
|
|
8
|
+
## โจ Features
|
|
9
9
|
|
|
10
10
|
- ๐ข **Schema-based multitenancy** - Complete tenant isolation using PostgreSQL schemas
|
|
11
|
-
- ๐ **Automatic schema switching** - Seamlessly switch between tenant schemas
|
|
11
|
+
- ๐ **Automatic schema switching** - Seamlessly switch between tenant schemas
|
|
12
12
|
- ๐ **Subdomain resolution** - Extract tenant from request subdomains
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- ๏ฟฝ **Rails 8+ optimized** - Built for modern Rails applications
|
|
14
|
+
- ๏ฟฝ๏ธ **Security-first design** - Database-level tenant isolation
|
|
15
15
|
- ๐งต **Thread-safe** - Safe for concurrent operations
|
|
16
16
|
- ๐ **Comprehensive logging** - Track schema operations
|
|
17
|
-
- โก **High performance** - Minimal overhead
|
|
17
|
+
- โก **High performance** - Minimal overhead with clean API
|
|
18
|
+
|
|
19
|
+
## ๐ Requirements
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Ruby 3.4+
|
|
24
|
+
- Rails 8.0+
|
|
25
|
+
- PostgreSQL 12+
|
|
26
|
+
- **pg gem**: 1.5 or higher
|
|
18
27
|
|
|
19
28
|
## Installation
|
|
20
29
|
|
|
@@ -53,20 +62,90 @@ end
|
|
|
53
62
|
|
|
54
63
|
## Usage
|
|
55
64
|
|
|
56
|
-
###
|
|
65
|
+
### Migration Management
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
# Switch to a tenant schema
|
|
60
|
-
PgMultitenantSchemas::SchemaSwitcher.switch_schema('tenant_123')
|
|
67
|
+
The gem provides automated migration management across all tenant schemas:
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
PgMultitenantSchemas::SchemaSwitcher.create_schema('tenant_456')
|
|
69
|
+
#### Running Migrations
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
```bash
|
|
72
|
+
# Migrate all tenant schemas at once (recommended)
|
|
73
|
+
rails tenants:migrate
|
|
74
|
+
|
|
75
|
+
# Migrate a specific tenant
|
|
76
|
+
rails tenants:migrate_tenant[acme_corp]
|
|
67
77
|
|
|
68
|
-
#
|
|
69
|
-
|
|
78
|
+
# Check migration status across all tenants
|
|
79
|
+
rails tenants:status
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### Setting Up New Tenants
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Create new tenant with full setup (schema + migrations)
|
|
86
|
+
rails tenants:create[new_tenant]
|
|
87
|
+
|
|
88
|
+
# Create tenant with attributes using JSON
|
|
89
|
+
rails tenants:new['{"subdomain":"acme","name":"ACME Corp","domain":"acme.com"}']
|
|
90
|
+
|
|
91
|
+
# Setup schemas for all existing tenants (migration from single-tenant)
|
|
92
|
+
rails tenants:setup
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Migration Workflow
|
|
96
|
+
|
|
97
|
+
1. **Create your migration** as usual:
|
|
98
|
+
```bash
|
|
99
|
+
rails generate migration AddEmailToUsers email:string
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
2. **Deploy to all tenants** with a single command:
|
|
103
|
+
```bash
|
|
104
|
+
rails tenants:migrate
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
3. **Check status** to verify migrations across tenants:
|
|
108
|
+
```bash
|
|
109
|
+
rails tenants:status
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This shows detailed migration status:
|
|
113
|
+
```
|
|
114
|
+
๐ Migration Status Report
|
|
115
|
+
โธ acme_corp: โ
Up to date (5 migrations)
|
|
116
|
+
โธ beta_corp: โ ๏ธ 2 pending migrations
|
|
117
|
+
โธ demo_corp: โ
Up to date (5 migrations)
|
|
118
|
+
|
|
119
|
+
๐ Overall: 2/3 tenants current, 2 migrations pending
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The migrator automatically:
|
|
123
|
+
- Runs migrations across all tenant schemas
|
|
124
|
+
- Provides detailed progress feedback
|
|
125
|
+
- Handles errors gracefully per tenant
|
|
126
|
+
- Maintains migration version tracking per schema
|
|
127
|
+
- Supports rollbacks for individual tenants
|
|
128
|
+
|
|
129
|
+
#### Advanced Migration Operations
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# List all tenant schemas
|
|
133
|
+
rails tenants:list
|
|
134
|
+
|
|
135
|
+
# Rollback specific tenant
|
|
136
|
+
rails tenants:rollback[tenant_name,2] # rollback 2 steps
|
|
137
|
+
|
|
138
|
+
# Drop tenant schema (DANGEROUS - requires confirmation)
|
|
139
|
+
rails tenants:drop[old_tenant]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Programmatic Access
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
# Use the Migrator directly in your code
|
|
146
|
+
PgMultitenantSchemas::Migrator.migrate_all
|
|
147
|
+
PgMultitenantSchemas::Migrator.setup_tenant('new_client')
|
|
148
|
+
PgMultitenantSchemas::Migrator.migration_status
|
|
70
149
|
```
|
|
71
150
|
|
|
72
151
|
### Tenant Resolution
|
|
@@ -130,6 +209,180 @@ class Tenant < ApplicationRecord
|
|
|
130
209
|
end
|
|
131
210
|
```
|
|
132
211
|
|
|
212
|
+
## ๐๏ธ Multi-Tenant Architecture Principles
|
|
213
|
+
|
|
214
|
+
### Core Principle: Tenant Isolation
|
|
215
|
+
|
|
216
|
+
**In well-designed multi-tenant applications, tenants should NOT communicate with each other directly.** Each tenant operates in complete isolation for security, compliance, and data integrity.
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
# โ
GOOD: Isolated tenant operations
|
|
220
|
+
PgMultitenantSchemas.with_tenant(tenant) do
|
|
221
|
+
# All operations are isolated to this tenant's schema
|
|
222
|
+
User.create!(name: "John", email: "john@example.com")
|
|
223
|
+
Order.where(status: "pending").update_all(status: "processed")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# โ BAD: Cross-tenant data sharing (security risk!)
|
|
227
|
+
# Never do: tenant_a.users.merge(tenant_b.users)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### When Cross-Schema Operations Are Appropriate
|
|
231
|
+
|
|
232
|
+
There are only **3 legitimate use cases** for cross-schema operations:
|
|
233
|
+
|
|
234
|
+
#### 1. **Platform Analytics & Reporting** (Admin-only)
|
|
235
|
+
```ruby
|
|
236
|
+
# Platform owner needs aggregate statistics across all tenants
|
|
237
|
+
def platform_analytics
|
|
238
|
+
PgMultitenantSchemas::SchemaSwitcher.with_connection do |conn|
|
|
239
|
+
conn.execute(<<~SQL)
|
|
240
|
+
SELECT
|
|
241
|
+
schemaname as tenant,
|
|
242
|
+
COUNT(*) as total_users,
|
|
243
|
+
SUM(revenue) as total_revenue
|
|
244
|
+
FROM (
|
|
245
|
+
SELECT 'tenant_a' as schemaname, COUNT(*) as users,
|
|
246
|
+
(SELECT SUM(amount) FROM tenant_a.orders) as revenue
|
|
247
|
+
UNION ALL
|
|
248
|
+
SELECT 'tenant_b' as schemaname, COUNT(*) as users,
|
|
249
|
+
(SELECT SUM(amount) FROM tenant_b.orders) as revenue
|
|
250
|
+
) stats
|
|
251
|
+
GROUP BY schemaname;
|
|
252
|
+
SQL
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### 2. **Tenant Migration & Data Operations** (Admin-only)
|
|
258
|
+
```ruby
|
|
259
|
+
# Moving data between environments or consolidating tenants
|
|
260
|
+
def migrate_tenant_data(from_tenant, to_tenant)
|
|
261
|
+
PgMultitenantSchemas.with_tenant(from_tenant) do
|
|
262
|
+
users = User.all.to_a
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
PgMultitenantSchemas.with_tenant(to_tenant) do
|
|
266
|
+
users.each { |user| User.create!(user.attributes.except('id')) }
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### 3. **Shared Reference Data** (Read-only)
|
|
272
|
+
```ruby
|
|
273
|
+
# Shared lookup tables that all tenants can read (e.g., countries, currencies)
|
|
274
|
+
class Country < ApplicationRecord
|
|
275
|
+
self.table_name = 'public.countries' # Shared across all schemas
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# In tenant context, can still access shared data
|
|
279
|
+
PgMultitenantSchemas.with_tenant(tenant) do
|
|
280
|
+
user = User.create!(name: "John", country: Country.find_by(code: 'US'))
|
|
281
|
+
end
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### ๐ซ Anti-Patterns to Avoid
|
|
285
|
+
|
|
286
|
+
```ruby
|
|
287
|
+
# โ NEVER: Direct tenant-to-tenant communication
|
|
288
|
+
def share_data_between_tenants(tenant_a, tenant_b)
|
|
289
|
+
# This violates tenant isolation!
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# โ NEVER: Cross-tenant user authentication
|
|
293
|
+
def authenticate_user_across_tenants(email)
|
|
294
|
+
# Users should only exist in their tenant's schema
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# โ NEVER: Cross-tenant business logic
|
|
298
|
+
def process_order_with_other_tenant_data(order_id, other_tenant)
|
|
299
|
+
# Business logic should be isolated per tenant
|
|
300
|
+
end
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Why Tenant Isolation Matters
|
|
304
|
+
|
|
305
|
+
1. **Security**: Prevents accidental data leaks between customers
|
|
306
|
+
2. **Compliance**: GDPR, HIPAA, SOX require strict data separation
|
|
307
|
+
3. **Performance**: Each tenant's queries are optimized for their data size
|
|
308
|
+
4. **Reliability**: One tenant's issues don't affect others
|
|
309
|
+
5. **Scalability**: Easy to move tenants to different database servers
|
|
310
|
+
|
|
311
|
+
### Architecture Recommendation
|
|
312
|
+
|
|
313
|
+
```ruby
|
|
314
|
+
# โ
Proper multi-tenant architecture
|
|
315
|
+
class ApplicationController < ActionController::Base
|
|
316
|
+
include PgMultitenantSchemas::Rails::ControllerConcern
|
|
317
|
+
|
|
318
|
+
before_action :authenticate_user!
|
|
319
|
+
before_action :resolve_tenant
|
|
320
|
+
before_action :ensure_user_belongs_to_tenant
|
|
321
|
+
|
|
322
|
+
private
|
|
323
|
+
|
|
324
|
+
def resolve_tenant
|
|
325
|
+
@tenant = resolve_tenant_from_subdomain
|
|
326
|
+
switch_to_tenant(@tenant) if @tenant
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def ensure_user_belongs_to_tenant
|
|
330
|
+
# Ensure current user can only access their tenant's data
|
|
331
|
+
redirect_to_login unless current_user.tenant == @tenant
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Bottom Line**: Cross-tenant operations should be **extremely rare**, **admin-only**, and **carefully audited**. The vast majority of your application should operate within a single tenant's schema.
|
|
337
|
+
|
|
338
|
+
## ๐ Documentation
|
|
339
|
+
|
|
340
|
+
### Complete Architecture Documentation
|
|
341
|
+
|
|
342
|
+
Detailed documentation for each core component:
|
|
343
|
+
|
|
344
|
+
- **[๐ Core Architecture Overview](docs/README.md)** - Complete system architecture
|
|
345
|
+
- **[๐ง Schema Switcher](docs/schema_switcher.md)** - Low-level PostgreSQL schema operations
|
|
346
|
+
- **[๐งต Context Management](docs/context.md)** - Thread-safe tenant context handling
|
|
347
|
+
- **[๐ Migration System](docs/migrator.md)** - Automated migration management
|
|
348
|
+
- **[โ๏ธ Configuration](docs/configuration.md)** - Gem settings and customization
|
|
349
|
+
- **[๐ Tenant Resolver](docs/tenant_resolver.md)** - Tenant identification strategies
|
|
350
|
+
- **[๐ค๏ธ Rails Integration](docs/rails_integration.md)** - Framework components and patterns
|
|
351
|
+
- **[๐จ Error Handling](docs/errors.md)** - Exception classes and error management
|
|
352
|
+
|
|
353
|
+
### Examples and Patterns
|
|
354
|
+
|
|
355
|
+
- **[Schema Operations](examples/schema_operations.rb)** - Core schema management
|
|
356
|
+
- **[Context Management](examples/context_management.rb)** - Thread-safe tenant switching
|
|
357
|
+
- **[Migration Workflow](examples/migration_workflow.rb)** - Automated migration examples
|
|
358
|
+
- **[Rails Controllers](examples/rails_integration/controller_examples.rb)** - Framework integration patterns
|
|
359
|
+
|
|
360
|
+
## ๐งช Testing
|
|
361
|
+
|
|
362
|
+
This gem includes a comprehensive test suite with both unit and integration tests.
|
|
363
|
+
|
|
364
|
+
### Running Tests
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Run unit tests only (fast, no database required)
|
|
368
|
+
bundle exec rspec
|
|
369
|
+
|
|
370
|
+
# Run integration tests (requires PostgreSQL)
|
|
371
|
+
bundle exec rspec --tag integration
|
|
372
|
+
|
|
373
|
+
# Run all tests
|
|
374
|
+
bundle exec rspec --no-tag
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Test Categories
|
|
378
|
+
|
|
379
|
+
- **Unit Tests** (65 examples): Fast, isolated component testing
|
|
380
|
+
- **Integration Tests** (21 examples): Real PostgreSQL multi-schema operations
|
|
381
|
+
- **Performance Tests**: Memory usage and thread safety validation
|
|
382
|
+
- **Edge Cases**: Error handling and boundary condition testing
|
|
383
|
+
|
|
384
|
+
See [Testing Guide](docs/testing.md) for detailed information about the test suite and [Integration Testing Guide](docs/integration_testing.md) for PostgreSQL integration testing details.
|
|
385
|
+
|
|
133
386
|
## Development
|
|
134
387
|
|
|
135
388
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|