chore: initial hub repo structure
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
# PostgreSQL Migration Design
|
||||
**Date:** 2026-05-25
|
||||
**Scope:** Migrate elysia (Drizzle ORM + MySQL) and rust (SeaORM + MySQL) apps to PostgreSQL
|
||||
**Approach:** Direct cutover (Approach B)
|
||||
**Connection String:** `postgresql://asephs:hunterz@100.108.1.124:5432/hub`
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
|
||||
### Elysia App
|
||||
- **ORM:** Drizzle ORM v0.45.2
|
||||
- **Driver:** mysql2 v3.20.0
|
||||
- **Schema Location:** `apps/elysia/src/db/lib/schema.ts`
|
||||
- **Tables:** users, accounts, sessions, roles, permissions, userRoles, and related junction tables
|
||||
- **Database File:** `apps/elysia/src/db/lib/database.ts`
|
||||
|
||||
### Rust App
|
||||
- **ORM:** SeaORM v1.1.19
|
||||
- **Feature:** sqlx-mysql
|
||||
- **DB Setup:** `apps/rust/src/infra/db_setup.rs`
|
||||
- **Tables:** ImageCache (primary table managed by app)
|
||||
- **Config:** Environment-based connection string
|
||||
|
||||
### Apps NOT Migrating
|
||||
- 9router (uses SQLite runtime, excluded per requirements)
|
||||
- nextjs (frontend, minimal DB usage)
|
||||
- leptos, solidjs, rust-auth (frontends, no DB)
|
||||
|
||||
---
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### Phase 1: Pre-Migration (Preparation)
|
||||
1. **Backup MySQL**
|
||||
```bash
|
||||
mysqldump -u <user> -p <db> > mysql_backup.sql
|
||||
```
|
||||
2. **Convert MySQL dump to PostgreSQL**
|
||||
- Use `pgloader` or manual conversion for schema compatibility
|
||||
- Handle type conversions:
|
||||
- `INT` → `INTEGER`
|
||||
- `VARCHAR(n)` → `VARCHAR(n)` (PostgreSQL compatible)
|
||||
- `DATETIME` → `TIMESTAMP`
|
||||
- `AUTO_INCREMENT` → `SERIAL` or `BIGSERIAL`
|
||||
- Verify indexes and foreign keys convert correctly
|
||||
3. **Test import into target PostgreSQL**
|
||||
```bash
|
||||
psql postgresql://asephs:hunterz@100.108.1.124:5432/hub < converted.sql
|
||||
```
|
||||
4. **Validate data integrity**
|
||||
- Row counts match MySQL
|
||||
- Indexes exist
|
||||
- Foreign key constraints enforced
|
||||
|
||||
### Phase 2: Code Updates
|
||||
|
||||
#### Elysia App
|
||||
1. **Update `apps/elysia/src/db/lib/database.ts`**
|
||||
- Replace `mysql2` import with `postgres` driver
|
||||
- Change Drizzle dialect from `drizzle-orm/mysql2` to `drizzle-orm/postgres`
|
||||
- Update connection string format
|
||||
|
||||
2. **Update `apps/elysia/src/db/lib/schema.ts`**
|
||||
- Replace `drizzle-orm/mysql-core` imports with `drizzle-orm/postgres-core`
|
||||
- Change `mysqlTable` to `pgTable`
|
||||
- Adjust column types if needed (e.g., `int` → `integer`)
|
||||
|
||||
3. **Update `apps/elysia/package.json`**
|
||||
- Replace `mysql2` with `pg` (PostgreSQL driver)
|
||||
- Keep `drizzle-orm` and `drizzle-kit` versions
|
||||
|
||||
4. **Update environment/config**
|
||||
- Change `DATABASE_URL` to PostgreSQL connection string
|
||||
|
||||
#### Rust App
|
||||
1. **Update `apps/rust/Cargo.toml`**
|
||||
- Replace `sqlx-mysql` feature with `sqlx-postgres` in sea-orm dependency
|
||||
- Add `postgres` feature if needed
|
||||
|
||||
2. **Update `apps/rust/src/infra/db_setup.rs`**
|
||||
- Change `DbBackend::MySql` check to `DbBackend::Postgres`
|
||||
- Adjust SQL syntax for PostgreSQL (e.g., index creation)
|
||||
- Update error code handling (PostgreSQL uses different error codes)
|
||||
|
||||
3. **Update config/environment**
|
||||
- Change `DATABASE_URL` to PostgreSQL connection string
|
||||
|
||||
### Phase 3: Cutover (Execution)
|
||||
1. **Stop all apps**
|
||||
```bash
|
||||
# Stop elysia
|
||||
# Stop rust app
|
||||
```
|
||||
2. **Export MySQL data**
|
||||
```bash
|
||||
mysqldump -u <user> -p <db> > final_backup.sql
|
||||
```
|
||||
3. **Convert and import to PostgreSQL**
|
||||
```bash
|
||||
# Convert dump
|
||||
# Import to PostgreSQL
|
||||
psql postgresql://asephs:hunterz@100.108.1.124:5432/hub < converted.sql
|
||||
```
|
||||
4. **Deploy updated apps**
|
||||
- Deploy elysia with PostgreSQL driver
|
||||
- Deploy rust with PostgreSQL feature
|
||||
5. **Verify connectivity**
|
||||
- Test database queries from both apps
|
||||
- Check auth flow (users table)
|
||||
- Verify session management
|
||||
|
||||
### Phase 4: Validation
|
||||
1. **Smoke tests**
|
||||
- User login/logout
|
||||
- Session creation and retrieval
|
||||
- Role/permission queries
|
||||
- ImageCache operations (rust app)
|
||||
2. **Data integrity checks**
|
||||
- Row counts match pre-migration
|
||||
- No orphaned foreign keys
|
||||
- Indexes performing as expected
|
||||
3. **Performance baseline**
|
||||
- Compare query times MySQL vs PostgreSQL
|
||||
- Monitor connection pool usage
|
||||
|
||||
### Phase 5: Rollback Plan (if needed)
|
||||
1. **Stop apps**
|
||||
2. **Restore MySQL from backup**
|
||||
```bash
|
||||
mysql -u <user> -p <db> < mysql_backup.sql
|
||||
```
|
||||
3. **Revert connection strings in apps**
|
||||
4. **Redeploy with MySQL drivers**
|
||||
5. **Restart apps**
|
||||
|
||||
---
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Elysia Driver Change
|
||||
**Before:**
|
||||
```typescript
|
||||
import { drizzle } from 'drizzle-orm/mysql2'
|
||||
import { createPool } from 'mysql2/promise'
|
||||
```
|
||||
|
||||
**After:**
|
||||
```typescript
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import postgres from 'postgres'
|
||||
```
|
||||
|
||||
### Rust Feature Change
|
||||
**Before:**
|
||||
```toml
|
||||
sea-orm = { version = "1.1.19", features = ["sqlx-mysql", ...] }
|
||||
```
|
||||
|
||||
**After:**
|
||||
```toml
|
||||
sea-orm = { version = "1.1.19", features = ["sqlx-postgres", ...] }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|-----------|
|
||||
| Data loss during migration | Full MySQL backup before cutover; test import first |
|
||||
| App downtime | Cutover during low-traffic window; rollback plan ready |
|
||||
| Connection string misconfiguration | Test connection before deploying apps |
|
||||
| Schema incompatibilities | Pre-test conversion; validate indexes/constraints |
|
||||
| Performance regression | Baseline MySQL performance; monitor PostgreSQL after cutover |
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- ✅ All data migrated to PostgreSQL (row counts match)
|
||||
- ✅ Elysia app connects and queries work
|
||||
- ✅ Rust app connects and queries work
|
||||
- ✅ Auth flow functional (login/logout)
|
||||
- ✅ No orphaned foreign keys
|
||||
- ✅ Indexes present and performant
|
||||
- ✅ Rollback plan tested and documented
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
- **Pre-migration:** 30 min (backup, convert, test)
|
||||
- **Code updates:** 1-2 hours (driver changes, testing)
|
||||
- **Cutover:** 15-30 min (stop apps, migrate data, restart)
|
||||
- **Validation:** 30 min (smoke tests, data checks)
|
||||
- **Total:** ~3-4 hours (including buffer)
|
||||
Reference in New Issue
Block a user