Skip to content

feat(server): redesign registration, isolation, and maintenance - #194

Merged
YaoYinYing merged 21 commits into
mainfrom
codex/registration-profile-fields
Jul 28, 2026
Merged

feat(server): redesign registration, isolation, and maintenance#194
YaoYinYing merged 21 commits into
mainfrom
codex/registration-profile-fields

Conversation

@YaoYinYing

@YaoYinYing YaoYinYing commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • require and display research-profile details during registration, including name, affiliation, academic position, and PI name
  • keep existing SQLite user and task databases upgrade-compatible, with a verified auth-database migration workflow that includes WAL data
  • isolate Celery from the user database and web secrets by extracting a dedicated task runtime
  • replace web-process daemon loops with an APScheduler maintenance service and self-configuring periodic tasks
  • add optional fractional-day result retention, scheduled task/user database backups, registration digest delivery, and persistent maintenance logs
  • remove the unsafe public-dashboard mode and always enforce owner/admin task isolation
  • add explicit dev/prod restart modes while preserving host UID/GID local builds and the published 1000:1000 image contract
  • move server test ownership into server/Makefile and update the server GitHub Actions workflow accordingly
  • reorganize environment documentation and update the changelog

Why

The previous server mixed web, Celery, authentication storage, and periodic work in one runtime boundary. It also lacked the required registration metadata, made deployment modes ambiguous, and left periodic cleanup/notification behavior spread across daemon loops. This redesign gives each process only the storage and settings it needs while keeping existing SQLite deployments upgradeable.

Operational impact

  • existing SQLite databases are upgraded in place; auth storage can be migrated with restart_pssm_flask.sh migrate-auth-db
  • Celery starts without access to users.sqlite3
  • maintenance jobs are opt-in through their environment settings
  • RESULT_RETENTION_DAYS accepts fractions such as 0.1 (2.4 hours); unset or zero disables cleanup
  • database backups use BACKUP_DB_CRON, BACKUP_DB_PATH, and optional MAX_DB_BACKUP
  • maintenance output is written to ${LOG_DIR}/maintenance.log and remains visible in container logs
  • restart --mode=dev builds local images; restart --mode=prod pulls configured images and requires UID/GID 1000:1000

Validation

  • make -C server test — 207 passed
  • focused maintenance, backup, migration, registration, isolation, and restart-mode regression tests
  • Python byte-compilation for changed server modules
  • bash -n server/run/restart_pssm_flask.sh
  • Docker Compose configuration validation with the production environment
  • git diff --check

Summary by CodeRabbit

  • New Features
    • Added required research profile fields during registration and expanded profile information in account and admin views.
    • Added optional scheduled database backups with retention controls.
    • Added automatic cleanup of expired task results, including fractional-day retention settings.
  • Bug Fixes
    • Improved database upgrades and migrations with safer backups, rollback support, and WAL data preservation.
    • Restricted task visibility and access to owners and administrators.
  • Documentation
    • Updated deployment, configuration, security, authentication migration, and testing guidance.
  • Chores
    • Improved service isolation and streamlined server test commands.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@YaoYinYing, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ce197e6e-b51f-45cb-96a4-ec730575a122

📥 Commits

Reviewing files that changed from the base of the PR and between fd53614 and 3e5f070.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • docs/dev-guide/server.md
  • server/README.md
  • server/pssm_gremlin_server/config.py
  • server/pssm_gremlin_server/db.py
  • server/pssm_gremlin_server/maintenance/tasks/result_cleanup.py
  • server/pssm_gremlin_server/pssm_gremlin.py
  • server/pssm_gremlin_server/routes.py
  • server/pssm_gremlin_server/static/js/dashboard.js
  • server/pssm_gremlin_server/task_runtime.py
  • server/run/restart_pssm_flask.sh
  • server/tests/test_config.py
  • server/tests/test_process_isolation.py
  • server/tests/test_tasks.py
📝 Walkthrough

Walkthrough

The server was refactored around centralized configuration, isolated task execution, APScheduler maintenance jobs, separated authentication storage, expanded registration profiles, updated Docker deployment controls, and server-local test commands with corresponding documentation and validation coverage.

Changes

GREMLIN server modernization

Layer / File(s) Summary
Configuration and user profile contracts
server/pssm_gremlin_server/config.py, auth.py, schemas.py, routes.py, templates/*, static/*
Runtime environment parsing was centralized, user profile fields were added to storage and API schemas, and registration, profile, and admin interfaces were updated.
Task runtime extraction and access boundaries
server/pssm_gremlin_server/task_runtime.py, pssm_gremlin.py, routes.py, docker-compose.yml, server/tests/test_docker.py
Celery and Docker execution moved into task_runtime; task access is owner/admin scoped, and Docker socket and authentication storage mounts are separated by service.
Scheduled maintenance jobs
server/pssm_gremlin_server/maintenance/*, server/tests/test_maintenance_manager.py, server/tests/test_database_backup.py
A standalone APScheduler service now registers optional admin digest, result cleanup, and SQLite backup jobs with configurable scheduling and retention.
Authentication migration and deployment operations
server/pssm_gremlin_server/migrate_auth_db.py, server/run/restart_pssm_flask.sh, server/docker-compose.yml, server/.env.example
Authentication database migration uses verified SQLite backups, while restart modes, auth storage validation, service startup, and production runner identity are enforced by deployment tooling.
Validation, packaging, and documentation
server/Makefile, .github/workflows/*, server/tests/*, docs/dev-guide/*, server/README.md, pyproject.toml
Server test commands and coverage configuration moved to server-local tooling, dependencies and CI were updated, and operational documentation and regression tests were expanded.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Web as web service
  participant Maintenance as maintenance service
  participant SQLite
  participant Files as result files
  Client->>Web: submit or view task
  Web->>SQLite: persist task and user state
  Maintenance->>SQLite: find expired terminal tasks
  Maintenance->>Files: delete validated result artifacts
  Maintenance->>SQLite: mark cleaned tasks as deleted
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main server changes: registration, process isolation, and maintenance redesign.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/registration-profile-fields

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@deepsource-io

deepsource-io Bot commented Jul 28, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 569bf39...3e5f070 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
Python Jul 28, 2026 9:17a.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@codacy-production

codacy-production Bot commented Jul 28, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 11 high · 7 medium · 4 minor

Alerts:
⚠ 22 issues (≤ 0 issues of at least minor severity)

Results:
22 new issues

Category Results
UnusedCode 1 medium
Documentation 4 minor
ErrorProne 1 high
Security 10 high
Complexity 6 medium

View in Codacy

🟢 Metrics 216 complexity · 14 duplication

Metric Results
Complexity 216
Duplication 14

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@YaoYinYing
YaoYinYing marked this pull request as ready for review July 28, 2026 08:43
@YaoYinYing YaoYinYing changed the title Redesign GREMLIN server registration, isolation, and maintenance feat(server): redesign registration, isolation, and maintenance Jul 28, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd53614291

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +85 to +86
delete_task_artifacts(task, results_folder)
task_store.update_task(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Claim expired tasks before deleting artifacts

If a user resubmits the same FASTA from an expired failed or cancelled task while this cleanup pass is running, list_tasks() can hold the old terminal row while the upload route replaces it with a new pending run. This code then deletes the new run's result directory and unconditionally changes its row to a deleted status, because deleted-status updates bypass TaskDatabase.update_task()'s terminal guard. Atomically claim the row only while its status and finished_at still match the expired record before removing artifacts.

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.14%. Comparing base (39f29a1) to head (fd53614).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #194      +/-   ##
==========================================
+ Coverage   73.55%   74.14%   +0.58%     
==========================================
  Files         122      122              
  Lines       15221    15592     +371     
==========================================
+ Hits        11196    11560     +364     
- Misses       4025     4032       +7     

see 16 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/tests/test_auth.py (1)

1044-1069: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Split test_auth.py — file now exceeds the 1000-line guideline.

Content in this file runs past line 1069. This PR keeps adding new test classes/functions (DB-upgrade tests, profile-field tests) to an already-oversized file.

As per coding guidelines, **/test*.py: "Keep each test file under 1000 lines and split tests by concern when necessary."

Consider splitting into concern-focused modules (e.g. test_auth_profile.py, test_auth_db_migration.py, test_auth_schemas.py) going forward.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/tests/test_auth.py` around lines 1044 - 1069, Split the oversized
test_auth.py into concern-focused test modules, moving schema tests such as
test_schema_user_response_excludes_password_hash into a suitable schemas module
and grouping profile-field and database-upgrade tests similarly. Preserve all
test behavior, fixtures, imports, and coverage while keeping each resulting test
file under 1000 lines.

Source: Coding guidelines

🧹 Nitpick comments (8)
server/pssm_gremlin_server/schemas.py (1)

110-113: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

affiliation lacks the length constraint applied to its siblings.

full_name/pi_name are capped at 128 and RegisterRequest.affiliation at 256, but the admin create/update paths accept unbounded affiliation strings.

♻️ Proposed constraint
-    affiliation: str | None = None
+    affiliation: str | None = Field(default=None, max_length=256)

(apply in both AdminCreateUserRequest and AdminUpdateUserRequest)

Also applies to: 134-137

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/schemas.py` around lines 110 - 113, Add a
max_length=256 constraint to the affiliation fields in both
AdminCreateUserRequest and AdminUpdateUserRequest, matching the existing
RegisterRequest.affiliation limit while preserving their optional defaults.
server/pssm_gremlin_server/static/js/user-control.js (1)

353-356: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Normalize empty affiliation like the sibling fields.

full_name, position, and pi_name collapse empty input to null, but affiliation submits "", persisting an empty string instead of an unset value.

♻️ Proposed change
-      affiliation: document.getElementById("newAffiliation").value.trim(),
+      affiliation: document.getElementById("newAffiliation").value.trim() || null,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/static/js/user-control.js` around lines 353 - 356,
Normalize the affiliation value in the user creation payload alongside full_name
and pi_name: trim newAffiliation and convert an empty result to null. Keep
non-empty affiliation values unchanged.
server/pssm_gremlin_server/pssm_gremlin.py (1)

362-375: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Compat aliases snapshot values at import time.

Rebinding e.g. pssm_gremlin.run_pssm_gremlin_in_docker (a pattern tests and legacy callers use) has no effect on the runtime path, since task_runtime.run_gremlin_task resolves its own module globals. A module __getattr__ delegating to task_runtime would keep the aliases live.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/pssm_gremlin.py` around lines 362 - 375, Replace
the import-time compatibility aliases in the web module with a module-level
__getattr__ that delegates requested symbols to task_runtime, so rebinding
task_runtime attributes is reflected dynamically. Preserve the existing
compatibility names, including run_pssm_gremlin_in_docker and run_gremlin_task,
and raise AttributeError for unknown names.
server/pssm_gremlin_server/routes.py (1)

1172-1179: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Inconsistent clear semantics across profile fields.

position honors an explicit null via model_fields_set, while full_name, affiliation, and pi_name silently ignore null, so admins can clear position but not the other profile fields. Consider using model_fields_set uniformly.

♻️ Proposed change
-    if req.affiliation is not None:
+    if "affiliation" in req.model_fields_set:
         update_fields["affiliation"] = req.affiliation
-    if req.full_name is not None:
+    if "full_name" in req.model_fields_set:
         update_fields["full_name"] = req.full_name
     if "position" in req.model_fields_set:
         update_fields["position"] = req.position
-    if req.pi_name is not None:
+    if "pi_name" in req.model_fields_set:
         update_fields["pi_name"] = req.pi_name
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/routes.py` around lines 1172 - 1179, Update the
profile update logic around the request fields so affiliation, full_name, and
pi_name use req.model_fields_set like position, allowing explicitly provided
null values to clear those fields while still ignoring omitted fields.
server/pssm_gremlin_server/maintenance/tasks/result_cleanup.py (1)

68-92: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Full table scan per pass.

list_tasks() materializes every task row on each cleanup run. If the task table grows, a filtered query on status/finished_at (with an index) would scale better.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/maintenance/tasks/result_cleanup.py` around lines
68 - 92, Update cleanup_expired_task_artifacts to use a task_store query that
filters terminal statuses and finished_at values at the database level before
iterating, rather than materializing every task via list_tasks(). Add or reuse
an indexed query method on TaskDatabase, and preserve the existing artifact
deletion, status update, and cleaned count behavior.
server/pssm_gremlin_server/task_runtime.py (2)

259-285: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

SIGINT handler is installed globally and never restored; also unsafe outside the main thread.

signal.signal raises ValueError when the task executes on a non-main thread (e.g. Celery --pool=threads/gevent), and the handler keeps referencing a dead container after the run completes.

♻️ Proposed hardening
+    previous_sigint = None
     try:
-        signal.signal(signal.SIGINT, lambda unused_sig, unused_frame: container.kill())
+        try:
+            previous_sigint = signal.signal(
+                signal.SIGINT, lambda unused_sig, unused_frame: container.kill()
+            )
+        except ValueError:  # not running in the main thread
+            previous_sigint = None
         for line in container.logs(stream=True):
@@
     finally:
+        if previous_sigint is not None:
+            try:
+                signal.signal(signal.SIGINT, previous_sigint)
+            except ValueError:
+                pass
         try:
             container.remove(force=True)
         except docker.errors.DockerException:
             pass
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/task_runtime.py` around lines 259 - 285, Update
the container execution flow around the SIGINT setup to install the handler only
when running in the main thread, preserving the existing behavior for
interrupting the active container. Capture the previous SIGINT handler and
restore it in the finally block after cleanup, ensuring no handler remains bound
to the completed container and non-main-thread execution does not call
signal.signal.

261-272: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No wall-clock bound on the container run.

container.logs(stream=True) and container.wait() block indefinitely; a hung GREMLIN run occupies a Celery slot forever. Consider a wait(timeout=...) plus a Celery time_limit/soft_time_limit on the task so stuck runs are reaped.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/pssm_gremlin_server/task_runtime.py` around lines 261 - 272, Add a
wall-clock timeout to the container execution flow around
container.logs(stream=True) and container.wait(), ensuring hung runs are
terminated and reported rather than blocking indefinitely. Configure appropriate
Celery time_limit and soft_time_limit settings on the task, and preserve
existing log/stage processing for runs that complete normally.
server/tests/test_process_isolation.py (1)

154-183: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fragile string-splitting to inspect docker-compose.yml.

This test slices the compose file by substring markers ("x-task-env:", " web:", etc.) instead of parsing YAML. Any reordering, re-indentation, or added comment line in docker-compose.yml can silently shift the slice boundaries and make assertions pass/fail for the wrong reason, without the test failing loudly.

Consider yaml.safe_load and walking the parsed structure (e.g. services.web.environment, x-task-env, service volume lists) for a more robust, format-independent check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/tests/test_process_isolation.py` around lines 154 - 183, Replace the
substring-based extraction in
test_compose_isolates_worker_auth_and_web_docker_socket with yaml.safe_load and
inspect the parsed top-level extension sections and services.web,
services.maintenance, and services.worker structures directly. Normalize
environment and volume representations as needed, then preserve the existing
assertions for secrets, settings, service commands, auth paths, ports, and
Docker socket access without relying on ordering or indentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/pssm_gremlin_server/config.py`:
- Around line 66-67: Update env_csv to treat an explicitly empty environment
value as unset, matching env_bool, env_str, env_int, and env_float. Select
default when the retrieved value is empty before splitting and stripping
entries, while preserving the existing CSV parsing behavior for non-empty
values.

In `@server/pssm_gremlin_server/task_runtime.py`:
- Around line 246-256: Update run_pssm_gremlin_in_docker’s client.containers.run
invocation to pass CONFIG.docker_user as the container user, ensuring the runner
writes mounted output artifacts with the validated non-root identity.

In `@server/run/restart_pssm_flask.sh`:
- Around line 318-324: Replace the cp-based backup in the user-DB backup block
of restart_pssm_flask.sh with SQLite’s consistent backup API, matching the
approach used by migrate_auth_db.py. Ensure the backup captures committed WAL
data and preserves the existing success and warning messages around the
generated _backup destination.

In `@server/tests/test_tasks.py`:
- Around line 351-415: Replace the misspelled completed-deletion status
“deleted:finshed” with “deleted:finished” across deleted_status_from_task(),
db.py, routes.py, task_runtime.py, and pssm_gremlin.py, including route response
fields and JSON status checks. Update all corresponding test expectations and
fixtures, including
test_cleanup_expired_task_artifacts_only_removes_old_terminal_results, while
preserving other deleted statuses such as “deleted:cancel”.

---

Outside diff comments:
In `@server/tests/test_auth.py`:
- Around line 1044-1069: Split the oversized test_auth.py into concern-focused
test modules, moving schema tests such as
test_schema_user_response_excludes_password_hash into a suitable schemas module
and grouping profile-field and database-upgrade tests similarly. Preserve all
test behavior, fixtures, imports, and coverage while keeping each resulting test
file under 1000 lines.

---

Nitpick comments:
In `@server/pssm_gremlin_server/maintenance/tasks/result_cleanup.py`:
- Around line 68-92: Update cleanup_expired_task_artifacts to use a task_store
query that filters terminal statuses and finished_at values at the database
level before iterating, rather than materializing every task via list_tasks().
Add or reuse an indexed query method on TaskDatabase, and preserve the existing
artifact deletion, status update, and cleaned count behavior.

In `@server/pssm_gremlin_server/pssm_gremlin.py`:
- Around line 362-375: Replace the import-time compatibility aliases in the web
module with a module-level __getattr__ that delegates requested symbols to
task_runtime, so rebinding task_runtime attributes is reflected dynamically.
Preserve the existing compatibility names, including run_pssm_gremlin_in_docker
and run_gremlin_task, and raise AttributeError for unknown names.

In `@server/pssm_gremlin_server/routes.py`:
- Around line 1172-1179: Update the profile update logic around the request
fields so affiliation, full_name, and pi_name use req.model_fields_set like
position, allowing explicitly provided null values to clear those fields while
still ignoring omitted fields.

In `@server/pssm_gremlin_server/schemas.py`:
- Around line 110-113: Add a max_length=256 constraint to the affiliation fields
in both AdminCreateUserRequest and AdminUpdateUserRequest, matching the existing
RegisterRequest.affiliation limit while preserving their optional defaults.

In `@server/pssm_gremlin_server/static/js/user-control.js`:
- Around line 353-356: Normalize the affiliation value in the user creation
payload alongside full_name and pi_name: trim newAffiliation and convert an
empty result to null. Keep non-empty affiliation values unchanged.

In `@server/pssm_gremlin_server/task_runtime.py`:
- Around line 259-285: Update the container execution flow around the SIGINT
setup to install the handler only when running in the main thread, preserving
the existing behavior for interrupting the active container. Capture the
previous SIGINT handler and restore it in the finally block after cleanup,
ensuring no handler remains bound to the completed container and non-main-thread
execution does not call signal.signal.
- Around line 261-272: Add a wall-clock timeout to the container execution flow
around container.logs(stream=True) and container.wait(), ensuring hung runs are
terminated and reported rather than blocking indefinitely. Configure appropriate
Celery time_limit and soft_time_limit settings on the task, and preserve
existing log/stage processing for runs that complete normally.

In `@server/tests/test_process_isolation.py`:
- Around line 154-183: Replace the substring-based extraction in
test_compose_isolates_worker_auth_and_web_docker_socket with yaml.safe_load and
inspect the parsed top-level extension sections and services.web,
services.maintenance, and services.worker structures directly. Normalize
environment and volume representations as needed, then preserve the existing
assertions for secrets, settings, service commands, auth paths, ports, and
Docker socket access without relying on ordering or indentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fa2ec06e-6a52-4a19-a73b-7977a9f734b1

📥 Commits

Reviewing files that changed from the base of the PR and between 569bf39 and fd53614.

📒 Files selected for processing (47)
  • .github/workflows/server-test.yml
  • .gitignore
  • CHANGELOG.md
  • Makefile
  • docs/dev-guide/makefile-reference.md
  • docs/dev-guide/server.md
  • pyproject.toml
  • server/.coveragerc
  • server/.env.example
  • server/Makefile
  • server/README.md
  • server/docker-compose.yml
  • server/pssm_gremlin_server/auth.py
  • server/pssm_gremlin_server/config.py
  • server/pssm_gremlin_server/db.py
  • server/pssm_gremlin_server/maintenance/__init__.py
  • server/pssm_gremlin_server/maintenance/manager.py
  • server/pssm_gremlin_server/maintenance/model.py
  • server/pssm_gremlin_server/maintenance/tasks/__init__.py
  • server/pssm_gremlin_server/maintenance/tasks/admin_digest.py
  • server/pssm_gremlin_server/maintenance/tasks/database_backup.py
  • server/pssm_gremlin_server/maintenance/tasks/result_cleanup.py
  • server/pssm_gremlin_server/migrate_auth_db.py
  • server/pssm_gremlin_server/pssm_gremlin.py
  • server/pssm_gremlin_server/routes.py
  • server/pssm_gremlin_server/schemas.py
  • server/pssm_gremlin_server/static/css/profile.css
  • server/pssm_gremlin_server/static/js/profile.js
  • server/pssm_gremlin_server/static/js/register.js
  • server/pssm_gremlin_server/static/js/user-control.js
  • server/pssm_gremlin_server/task_runtime.py
  • server/pssm_gremlin_server/templates/profile.html
  • server/pssm_gremlin_server/templates/register.html
  • server/pssm_gremlin_server/templates/user_control.html
  • server/pyproject.toml
  • server/run/restart_pssm_flask.sh
  • server/tests/conftest.py
  • server/tests/test_admin.py
  • server/tests/test_auth.py
  • server/tests/test_config.py
  • server/tests/test_database_backup.py
  • server/tests/test_docker.py
  • server/tests/test_maintenance_manager.py
  • server/tests/test_process_isolation.py
  • server/tests/test_security.py
  • server/tests/test_security_advanced.py
  • server/tests/test_tasks.py
💤 Files with no reviewable changes (2)
  • pyproject.toml
  • Makefile

Comment thread server/pssm_gremlin_server/config.py Outdated
Comment thread server/pssm_gremlin_server/task_runtime.py
Comment thread server/run/restart_pssm_flask.sh
Comment thread server/tests/test_tasks.py
@YaoYinYing
YaoYinYing merged commit 0e69433 into main Jul 28, 2026
6 of 13 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