fix: add project_manager migration + add migration step to full-deploy.sh
- New migration updates MongoDB users collection validator to accept project_manager role and pm_client_ids field - full-deploy.sh was missing the run_migrations step entirely; added it after rebuild_containers so new role/field validators apply on every deploy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bbd324e3c7
commit
723bbbc695
2 changed files with 160 additions and 0 deletions
|
|
@ -0,0 +1,142 @@
|
|||
"""Add project_manager role to user collection schema validator."""
|
||||
|
||||
from app.migrations.migrator import Migration
|
||||
|
||||
|
||||
class Migration(Migration):
|
||||
"""Update MongoDB schema validator to support project_manager role."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.version = "2026-04-27-000000"
|
||||
self.description = "Add project_manager role to user schema validator"
|
||||
|
||||
async def up(self) -> None:
|
||||
"""Update the users collection validator."""
|
||||
|
||||
validator = {
|
||||
"$jsonSchema": {
|
||||
"bsonType": "object",
|
||||
"required": ["email", "full_name", "role", "auth_provider", "is_active"],
|
||||
"properties": {
|
||||
"email": {
|
||||
"bsonType": "string",
|
||||
"pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"description": "Must be a valid email address"
|
||||
},
|
||||
"hashed_password": {
|
||||
"bsonType": ["string", "null"],
|
||||
"description": "Hashed password (null for Microsoft users)"
|
||||
},
|
||||
"full_name": {
|
||||
"bsonType": "string",
|
||||
"minLength": 1,
|
||||
"description": "User's full name"
|
||||
},
|
||||
"role": {
|
||||
"enum": ["client", "reviewer", "linguist", "production", "project_manager", "admin"],
|
||||
"description": "User role"
|
||||
},
|
||||
"auth_provider": {
|
||||
"enum": ["local", "microsoft"],
|
||||
"description": "Authentication provider"
|
||||
},
|
||||
"is_active": {
|
||||
"bsonType": "bool",
|
||||
"description": "Whether user account is active"
|
||||
},
|
||||
"pm_client_ids": {
|
||||
"bsonType": ["array"],
|
||||
"items": {"bsonType": "string"},
|
||||
"description": "Client IDs where user is assigned as Project Manager"
|
||||
},
|
||||
"created_at": {
|
||||
"bsonType": "date",
|
||||
"description": "Account creation timestamp"
|
||||
},
|
||||
"updated_at": {
|
||||
"bsonType": "date",
|
||||
"description": "Last update timestamp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
await self.db.command({
|
||||
"collMod": "users",
|
||||
"validator": validator,
|
||||
"validationLevel": "moderate",
|
||||
"validationAction": "error"
|
||||
})
|
||||
print(f"✅ Updated users collection validator")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not update validator: {e}")
|
||||
try:
|
||||
await self.db.create_collection(
|
||||
"users",
|
||||
validator=validator,
|
||||
validationLevel="moderate",
|
||||
validationAction="error"
|
||||
)
|
||||
print(f"✅ Created users collection with validator")
|
||||
except Exception as e2:
|
||||
print(f"⚠️ Could not create collection: {e2}")
|
||||
|
||||
print(f"✅ Applied migration {self.version}: {self.description}")
|
||||
|
||||
async def down(self) -> None:
|
||||
"""Revert to validator without project_manager role."""
|
||||
|
||||
validator = {
|
||||
"$jsonSchema": {
|
||||
"bsonType": "object",
|
||||
"required": ["email", "full_name", "role", "auth_provider", "is_active"],
|
||||
"properties": {
|
||||
"email": {
|
||||
"bsonType": "string",
|
||||
"pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
"description": "Must be a valid email address"
|
||||
},
|
||||
"hashed_password": {
|
||||
"bsonType": ["string", "null"],
|
||||
"description": "Hashed password (null for Microsoft users)"
|
||||
},
|
||||
"full_name": {
|
||||
"bsonType": "string",
|
||||
"minLength": 1,
|
||||
"description": "User's full name"
|
||||
},
|
||||
"role": {
|
||||
"enum": ["client", "reviewer", "linguist", "production", "admin"],
|
||||
"description": "User role"
|
||||
},
|
||||
"auth_provider": {
|
||||
"enum": ["local", "microsoft"],
|
||||
"description": "Authentication provider"
|
||||
},
|
||||
"is_active": {
|
||||
"bsonType": "bool",
|
||||
"description": "Whether user account is active"
|
||||
},
|
||||
"created_at": {
|
||||
"bsonType": "date",
|
||||
"description": "Account creation timestamp"
|
||||
},
|
||||
"updated_at": {
|
||||
"bsonType": "date",
|
||||
"description": "Last update timestamp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await self.db.command({
|
||||
"collMod": "users",
|
||||
"validator": validator,
|
||||
"validationLevel": "moderate",
|
||||
"validationAction": "error"
|
||||
})
|
||||
|
||||
print(f"⚠️ Rolled back migration {self.version}: {self.description}")
|
||||
print(f"⚠️ WARNING: project_manager role users will fail validation!")
|
||||
|
|
@ -246,6 +246,23 @@ build_and_deploy_frontend() {
|
|||
echo ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Run Database Migrations
|
||||
# =============================================================================
|
||||
|
||||
run_migrations() {
|
||||
print_header "Running Database Migrations"
|
||||
|
||||
print_info "Checking migration status..."
|
||||
docker compose $COMPOSE_FILES exec -T api python migrate.py status
|
||||
|
||||
print_info "Applying pending migrations..."
|
||||
docker compose $COMPOSE_FILES exec -T api python migrate.py up
|
||||
print_success "Migrations completed"
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Display Deployment Summary
|
||||
# =============================================================================
|
||||
|
|
@ -335,6 +352,7 @@ main() {
|
|||
preflight_checks
|
||||
verify_code_updated
|
||||
rebuild_containers
|
||||
run_migrations
|
||||
build_and_deploy_frontend
|
||||
display_summary
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue