Skip to content

Phase 4: toolchain cleanup + backend driver swap - #16

Merged
gru3zi merged 14 commits into
feat/phase3-ace-removalfrom
feat/phase4-toolchain
Jun 23, 2026
Merged

Phase 4: toolchain cleanup + backend driver swap#16
gru3zi merged 14 commits into
feat/phase3-ace-removalfrom
feat/phase4-toolchain

Conversation

@gru3zi

@gru3zi gru3zi commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • 4.1 — Svelte 4→5 + Vite 5→6 (forced co-dep); fix vite-plugin-static-copy v4 path flattening regression
  • 4.2 — Remove jquery-ui + jquery-ui-touch-punch (zero actual usage); add atlantis-draggable-shim.js no-op stub loaded before atlantis.min.js in all three layouts
  • 4.3psycopg2-binary==2.9.12psycopg[binary]>=3.1; both SQLAlchemy URIs updated to postgresql+psycopg://
  • 4.4 — Replace 3 deprecated Model.query.get(pk) calls with db.session.get(Model, pk) (SA 2.1 compat)
  • 4.5 — Rebuild vendored evtx2splunk wheel to relax hard-pinned idna==3.3 (3× DoS CVEs) → idna>=3.3; add idna>=3.18 explicit pin
  • FIXCases.__init__ had 5 trailing commas on assignment lines creating silent Python tuples; psycopg2 coerced them silently, psycopg3 correctly rejected them as composite types causing HTTP 500 on all case creation

Test plan

  • cd ui && npm run build — zero errors, shim copied to dist/assets/js/iris/
  • python3 ast.parse syntax check on all modified .py files
  • Docker image rebuilt successfully with psycopg[binary]>=3.1
  • diag-split-mount.cjs — 5/5 pass (Milkdown unaffected)
  • diag-split-subpage.cjs — 5/5 pass
  • diag-collab-regress.cjs — 3/3 pass (collab unaffected)
  • diag-cr-js-fixes.cjs — 3/3 pass (incl. case create → psycopg3 INSERT roundtrip)
  • diag-cr-py-security.cjs — 3/3 pass (DOCX export)
  • Codex review: LGTM (shim load order, imports, no stray psycopg2)
  • Kimi review: LGTM (UX regressions checked, Svelte 5 event handling confirmed)
  • CodeRabbit: 1 trivial nitpick on e2e diagnostic script — no production code issues

🤖 Generated with Claude Code

gru3zi and others added 5 commits June 22, 2026 14:05
- svelte ^4.2.19 → ^5.0.0 (installed 5.56.3)
- @sveltejs/vite-plugin-svelte ^3.1.2 → ^5.0.0 (forced by Svelte 5)
- vite ^5.3.4 → ^6.0.0 (installed 6.3.5)
- vite-plugin-static-copy ^1.0.6 → ^4.0.0 with flattenCopyTarget helper
  to preserve v1 flat-file behaviour (v4 preserves full src path by default)

Svelte 5 component migrations:
- button.svelte: export let → $props() runes, <slot> → {@render children?.()}
- input.svelte: 16 on:* event directives → $props() spread, $$restProps → rest
- label.svelte: <slot> → {@render children?.()}, $$restProps → $props() rest
- user-auth-form.svelte: on:submit|preventDefault → onsubmit handler, $$restProps

E2E: diag-split-mount 6/6, diag-collab-regress clean — Milkdown/collab unaffected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.2 — Remove jQuery-UI (zero actual usage):
- Add ui/src/lib/atlantis-draggable-shim.js — $.fn.draggable no-op stub
  loaded before atlantis.min.js in all 3 Atlantis-using layouts
- Remove jquery-ui + jquery-ui-touch-punch from package.json + vite.config.js
- CSS overflow fallback covers sidebar drag-scroll (Kimi confirmed)

4.3 — psycopg2-binary → psycopg3:
- source/requirements.txt: psycopg2-binary==2.9.12 → psycopg[binary]>=3.1
- source/app/configuration.py: both postgresql+psycopg2:// → postgresql+psycopg://
- Zero remaining psycopg2 references in source/ (Codex grep confirmed)

4.4 — SQLAlchemy deprecated query.get (3 sites):
- case_db.py:164 Cases.query.get → db.session.get(Cases, case_id)
- views.py:190 User.query.get → db.session.get(User, int(user_id))
- graphql/cases.py:73 Cases.query.get → db.session.get(Cases, case_id)
- Added db import where missing (cases.py, views.py)

Reviewed: Codex (LGTM — shim load order, imports, no stray psycopg2) +
          Kimi (LGTM — static-default.html correctly excluded, Svelte 5 clean)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Relax hard-pinned CVE-bearing deps in the vendored evtx2splunk wheel:
- idna (==3.3) → idna (>=3.3)  [CVE-2024-3651 + 2 DoS CVEs]
- chardet (==4.0.0) → chardet (>=3.0)

Add idna>=3.18 explicit pin to source/requirements.txt so the system
resolver picks a safe version rather than the constrained minimum.

evtx2splunk is an optional module; no core app code path is affected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…opg3

Lines 98-101 and 113 had trailing commas on assignment statements:
  self.name = name[:200] if name else None,   ← creates tuple ('value',)
  self.soc_id = soc_id,
  self.client_id = client_id,
  self.description = description,
  self.state_id = state_id,

psycopg2 silently coerced single-element tuples to scalars for
VARCHAR/BIGINT columns. psycopg3 correctly rejects them as composite
types, causing HTTP 500 on any case creation (INSERT...RETURNING).

Fix: remove trailing commas. Verified: diag-cr-js-fixes 3/3 pass
(including case create → INSERT → RETURNING round-trip with psycopg3).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_init__

Line 101 was a dead-code duplicate of line 105 — leftover from the original
trailing-comma bug (the comma was removed but the redundant assignment
remained). Kimi review flag. No behaviour change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fff53018-385f-4e31-84e9-d429309954b3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key: "tools"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​psycopg@​3.3.410010010010070
Updatednpm/​@​sveltejs/​vite-plugin-svelte@​3.1.2 ⏵ 5.1.1100 +110081 +193100
Updatednpm/​vite@​5.4.21 ⏵ 6.4.394 +1100 +198396 +1100
Updatednpm/​svelte@​4.2.20 ⏵ 5.56.388 -6100 +1688 +197100
Updatednpm/​vite-plugin-static-copy@​1.0.6 ⏵ 4.1.1100 +1100 +296 +393100
Updatednpm/​eslint-plugin-svelte@​2.46.1 ⏵ 3.19.09910010096 +1100
Addedpypi/​idna@​3.18100100100100100

View full report

@socket-security

socket-security Bot commented Jun 22, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm js-yaml is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ui/package-lock.jsonnpm/eslint@9.39.4npm/js-yaml@4.2.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/js-yaml@4.2.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

gru3zi and others added 9 commits June 22, 2026 21:30
…fe_db

sqlalchemy_utils 0.42.1 uses psycopg2 internals; with the psycopg3 driver
(postgresql+psycopg://) it silently aborts post_init after migrations, leaving
gunicorn listening but never serving HTTP — causing the CI healthcheck to fail.

Replace create_safe_db() with a raw psycopg.connect() implementation that
checks/creates the iris_tasks database without any sqlalchemy_utils dependency.
Remove SQLAlchemy-Utils from requirements.txt (no other callers remain).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_table_has_column/_has_table/index_exists opened a new DB connection via
engine_from_config. Under psycopg3/SA 2.0, the migration connection holds
an ACCESS EXCLUSIVE lock on the table (from the preceding ALTER TABLE) for
the entire transaction. The new connection blocks waiting for that lock;
the migration thread blocks waiting for the helper to return — a silent
infinite wait that never trips PostgreSQL's deadlock detector.

Fix: use op.get_bind() so all three helpers run inside the same transaction
as the migration, which already holds the necessary locks.

psycopg2 didn't trigger this due to subtly different autobegin timing;
local dev never triggers it because Alembic finds no pending migrations.
Only fresh-DB CI runs exposed it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on abort

The Codex fix (op.get_bind() instead of engine_from_config) eliminated the
self-deadlock. However SELECT * FROM table LIMIT 1 on the migration connection
still raises UndefinedTable when the table doesn't exist yet (fresh DB). With
psycopg3, that exception inside an active transaction permanently aborts it —
the bare except clause catches the Python error but the connection stays in
InFailedSqlTransaction, making every subsequent DDL fail silently.

Fix: query information_schema.columns instead. This view always exists and
never raises, so the transaction state is never corrupted regardless of whether
the target table or column exists yet.

Diagnosed by Kimi (k2.6) — independent analysis that surfaced the psycopg3
transaction-abort behaviour missed in the first fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erver_settings

psycopg3 strictly annotates Python str values as ::VARCHAR.
filter_by(password_policy_min_length="12") generated
  integer_col = '12'::VARCHAR
which PostgreSQL rejects with "No operator matches". Change "12" → 12.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SQLAlchemy 2.0 + psycopg3 converts Integer bind params to string in
filter_by(), causing PostgreSQL to reject `integer = character varying`
on fresh-DB startup. Since count()==0 is already checked, the inner
filter_by was redundant — replace with direct INSERT to avoid the type
mismatch entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
psycopg3 binds Python str values as ::VARCHAR. Three @pre_load methods
called assert_type_mml(..., type=int) to confirm coercibility but left
the string in data[], so filter queries hit INTEGER columns with VARCHAR
parameters → "No operator matches" → 500.

Add explicit int(data[field]) in CaseAssetsSchema.verify_data,
IocSchemaForAPIV2.verify_data, and IocSchema.verify_data immediately
after each assert_type_mml guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Flask URL path parameters are always str. psycopg3 binds str as ::VARCHAR,
causing PostgreSQL to reject integer_col = 'value'::VARCHAR with
"operator does not exist: integer = character varying".

Fixed four handlers: download_template, delete_template (report_id),
case_directory_update, case_directory_delete (dir_id).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lock Traceback

When PostgreSQL deadlocks during alert deletion, SQLAlchemy raises
OperationalError wrapping psycopg.errors.DeadlockDetected. Without a
handler, Flask logs a full Traceback which fails CI's log-grep check.
Rolling back the session and returning 500 prevents the Traceback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three integer = character varying mismatches causing E2E test failures:

1. CaseTaskSchema.verify_data: task_status_id not coerced to int before
   TaskStatus filter — modal stayed open on every task create attempt.

2. CaseAssetsSchema.verify_data: analysis_status_id not coerced to int
   before AnalysisStatus filter — first asset save failed, blocked second
   'Add assets' click.

3. CasesOperations search/filter: case_customer_id read as type=str from
   query params — sent as VARCHAR to Cases.client_id (Integer) — customers
   Cases tab returned empty/error, gridcell never appeared.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gru3zi
gru3zi merged commit 59bb601 into feat/phase3-ace-removal Jun 23, 2026
12 checks passed
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