Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
package main
import (
"context"
"database/sql"
"log"
"github.com/jackc/pgx/v5/pgxpool"
)
// applyPlatformAdmins maps legacy admin_users → users.is_platform_admin.
// Matching prefers remapped Clerk/legacy user_id, then email. Never creates orphan admin rows.
// Company-admin memberships (member→admin) are a separate post-load step:
// see runMembershipRoleRepair (-list-member-memberships / -promote-company-admins).
func applyPlatformAdmins(
ctx context.Context,
mysqlDB *sql.DB,
pg *pgxpool.Pool,
userMap map[string]string,
report map[string]int,
dryRun bool,
) {
if !mysqlTableExists(ctx, mysqlDB, "admin_users") {
log.Printf("admin_users skipped: table missing")
return
}
// Legacy shape: user_id (Clerk text) + email. Column presence varies by dump age.
hasUserID := mysqlColumnExists(ctx, mysqlDB, "admin_users", "user_id")
hasEmail := mysqlColumnExists(ctx, mysqlDB, "admin_users", "email")
if !hasUserID && !hasEmail {
log.Printf("admin_users skipped: no user_id/email columns")
return
}
q := `SELECT `
switch {
case hasUserID && hasEmail:
q += `COALESCE(user_id, ''), COALESCE(email, '') FROM admin_users`
case hasUserID:
q += `user_id, '' FROM admin_users`
default:
q += `'', email FROM admin_users`
}
rows, err := mysqlDB.QueryContext(ctx, q)
if err != nil {
log.Printf("admin_users skipped: %v", err)
return
}
defer rows.Close()
for rows.Next() {
var legacyUserID, email string
if err := rows.Scan(&legacyUserID, &email); err != nil {
report["admin_users_skipped"]++
continue
}
pgUserID, ok := userMap[legacyUserID]
if !ok && email != "" {
// Resolve via email already loaded into Postgres (or dry-run map miss).
if dryRun {
report["admin_users_unmatched"]++
continue
}
var id string
err := pg.QueryRow(ctx, `SELECT id::text FROM users WHERE lower(email) = lower($1)`, email).Scan(&id)
if err != nil {
report["admin_users_unmatched"]++
continue
}
pgUserID = id
}
if pgUserID == "" {
report["admin_users_unmatched"]++
continue
}
if dryRun {
report["admin_users"]++
continue
}
tag, err := pg.Exec(ctx, `
UPDATE users
SET is_platform_admin = true,
staff_role = COALESCE(staff_role, 'admin'),
updated_at = now()
WHERE id = $1::uuid`, pgUserID)
if err != nil {
log.Printf("admin_users update %s: %v", legacyUserID, err)
report["admin_users_skipped"]++
continue
}
if tag.RowsAffected() == 0 {
report["admin_users_unmatched"]++
continue
}
report["admin_users"]++
}
}