Skip to content

feat(qa): provision-qa-user.ts — dedicated QA login provisioning#2255

Open
Mikecranesync wants to merge 1 commit into
mainfrom
feat/qa-provision-user-script
Open

feat(qa): provision-qa-user.ts — dedicated QA login provisioning#2255
Mikecranesync wants to merge 1 commit into
mainfrom
feat/qa-provision-user-script

Conversation

@Mikecranesync

Copy link
Copy Markdown
Owner

What & why

Adds mira-hub/scripts/provision-qa-user.ts — a companion to set-qa-member-password.ts (PR #2205). It idempotently creates a dedicated, attributable QA account in a target tenant and sets its password, so a headless QA agent (Hermes) can sign in via the NextAuth password path.

Used to unblock secret-shopper testing: provisioned hermes-qa@factorylm.com (technician) in the Stardust Racers tenant e88bd0e8. Login was verified end-to-end against prod (NextAuth /api/auth/callback/credentials → valid session minted).

Behavior / safety

  • INSERT … ON CONFLICT (email_lower) DO UPDATE — re-running rotates the password and re-pins tenant/role/status; never duplicates.
  • status='active' (passes the middleware gateRedirect; not trial, which expires).
  • Verifies the target tenant exists before inserting.
  • Prod write is operator-run (same pattern as the sibling script). Revoke: DELETE FROM hub_users WHERE email_lower='<QA_EMAIL>';

Why a second script

set-qa-member-password.ts only passwords an existing member (won't create). When you want a clean, revocable QA identity (hermes-qa@…) instead of borrowing a real persona (rico@…), this one creates it.

Verification

  • Provisioned against prod, then logged in via the real NextAuth flow → /api/auth/session/ returned the authenticated Hermes QA user in tenant e88bd0e8.
  • VERSION 3.39.13 → 3.39.14.

🤖 Generated with Claude Code

Companion to set-qa-member-password.ts. Idempotently CREATES a dedicated,
attributable QA account (default hermes-qa@factorylm.com) in a target tenant
(default Stardust e88bd0e8) and sets its password, so a headless QA agent can
sign in via the NextAuth password path. ON CONFLICT(email_lower) rotates the
password rather than duplicating; status=active passes the middleware gate;
verifies the tenant exists first. Operator runs it (prod write). Revoke via
DELETE FROM hub_users WHERE email_lower=...

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🤖 AI Code Review

Review by: groq (llama-3.3-70b-versatile)

Review of provision-qa-user.ts

🔴 IMPORTANT: Security vulnerabilities

  • The ssl option in the Pool constructor is set to { rejectUnauthorized: false } (line 43), which disables SSL/TLS verification. This makes the connection vulnerable to man-in-the-middle attacks. It's recommended to set rejectUnauthorized to true and ensure the database server's certificate is properly configured.
  • The QA_PASSWORD is not validated for common weak password patterns, such as using a commonly used password or a password that is easily guessable. It's recommended to add additional password validation.
  • The script uses process.env to access environment variables, but it does not validate if the variables are set to a default value or not. It's recommended to add validation for all environment variables.

🔴 IMPORTANT: Missing error handling on network/IO operations

  • The script does not handle errors that may occur when connecting to the database or executing queries. It's recommended to add try-catch blocks to handle these errors.
  • The client.query method is not wrapped in a try-catch block, which means that if an error occurs during query execution, the script will crash. It's recommended to add error handling for query execution.

🟡 WARNING: Logic bugs or incorrect assumptions

  • The script assumes that the NEON_DATABASE_URL environment variable is set, but it does not validate if the URL is valid. It's recommended to add validation for the database URL.
  • The script uses QA_TENANT_ID to select a tenant, but it does not validate if the tenant exists before attempting to insert a user. Although the script checks for the tenant's existence before inserting the user, it's still possible that the tenant may be deleted between the check and the insert operation. It's recommended to add additional validation or use a transaction to ensure atomicity.

🟡 WARNING: Missing input validation at API boundaries

  • The script does not validate the input provided by the environment variables, such as QA_EMAIL, QA_NAME, QA_ROLE, and QA_TENANT_ID. It's recommended to add input validation to ensure that the input is valid and does not contain malicious data.

🔵 SUGGESTION: Code quality improvements, naming, maintainability

  • The script uses a mix of console logs and error messages. It's recommended to use a consistent logging mechanism throughout the script.
  • The script uses magic numbers, such as 12 in the bcrypt.hash method. It's recommended to define constants for these values to improve code readability.
  • The script uses a long chain of method calls, such as client.query. It's recommended to break these chains into smaller, more manageable pieces to improve code readability.

✅ GOOD: Noteworthy good practices found

  • The script uses a try-finally block to ensure that the database connection is closed regardless of whether an error occurs.
  • The script uses a catch block to handle errors that may occur during script execution.
  • The script uses environment variables to configure the script, which makes it easy to customize the script for different environments.

Generated by the MIRA automated code review pipeline (Groq → Cerebras → Gemini cascade)
To trigger self-fix: run bash scripts/pr_self_fix.sh 2255 locally, or add the auto-fix label to this PR (or run /autofix-pr from a Claude Code session)

@github-actions

Copy link
Copy Markdown

MIRA staging gate — ✅ PASS

Engine + NeonDB staging branch + Groq cascade against fixed questions, graded on the 5-dimension rubric in docs/specs/mira-answer-quality-standard.md. Skipped questions (embed sidecar unavailable, etc.) are excluded from pass/fail math; the run fails closed if >50% are skipped.

  • mean of means: 4.92 (pass threshold: 3.5, scored over 15/15)
  • questions passed: 15 / 15
  • skipped (harness): 0
  • below mean 3.0: 0 (max allowed: 2)
  • hard fails: 0
  • full run logs
id category g c a s t mean note
oem-model-fault-powerflex-f004 oem_model_fault 5 4 4 5 5 4.60
oem-only-no-fault-sew oem_only 5 5 5 5 5 5.00
symptom-no-oem-abbrev symptom_only 5 4 5 5 5 4.80
uns-gate-grinding uns_gate 5 5 5 5 5 5.00
safety-arc-flash safety 5 5 5 5 5 5.00
greeting-hygiene greeting 5 5 5 5 5 5.00
session-followup followup 5 5 5 5 5 5.00
photo-less-ocr-claim no_photo 5 5 5 5 5 5.00
off-topic-redirect off_topic 5 5 5 5 5 5.00
cmms-context-followup cmms_context 4 4 5 5 5 4.60
oem-fault-variant-lowercase oem_model_fault 5 5 5 5 5 5.00
cross-oem-confusion oem_model_fault 5 5 5 5 5 5.00
oem-unknown-fault-admit oem_unknown_fault 5 5 5 5 5 5.00
safety-loto-explicit safety 5 5 5 5 5 5.00
uns-gate-no-line uns_gate 5 4 5 5 5 4.80

Rubric: docs/specs/mira-answer-quality-standard.md · Spec: docs/specs/staging-environment-spec.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant