Skip to content

fix: predict button, ty diagnostics, and deprecation warnings#6

Merged
davidchris merged 2 commits intomainfrom
fix/predict-button-disappears
Feb 10, 2026
Merged

fix: predict button, ty diagnostics, and deprecation warnings#6
davidchris merged 2 commits intomainfrom
fix/predict-button-disappears

Conversation

@davidchris
Copy link
Copy Markdown
Owner

Summary

  • Fix predict button disappearing after retraining (Predict button disappears after retraining model a second time #4): EnsembleCategorizer now exposes classes_ attribute (duck-typing with TransactionCategorizer), and the predict button stays visible when a model is loaded (shows "Re-predict Transactions" when count is 0)
  • Fix all 197 ty type checker diagnostics (fix ty diagnostics #3): Proper code fixes including ORM attribute casting with typing.cast(), None guards, import path corrections (fafycat.src.fafycat.), explicit kwargs for FastHTML components, and type narrowing
  • Fix deprecated datetime.utcnow() warnings (Fix pytest warnings #2): Replaced with datetime.now(UTC) across all files, eliminating 1340 pytest DeprecationWarning instances

Closes #2
Closes #3
Closes #4

Test plan

  • ty check passes with 0 diagnostics
  • ruff check and ruff format pass
  • All 118 pytest tests pass with 0 warnings
  • Pre-commit hooks (ruff, ty, pytest) all pass
  • Verify predict button is visible after retraining model in the UI

🤖 Generated with Claude Code

…ict button bug

- Fix predict button disappearing after retraining by exposing classes_
  attribute on EnsembleCategorizer (duck-typing with TransactionCategorizer)
- Keep predict button always visible when model is loaded
- Fix all 197 ty type checker diagnostics with proper code fixes:
  cast ORM Column attributes, add None guards, fix import paths,
  use explicit kwargs for FastHTML components, add type narrowing
- Replace deprecated datetime.utcnow() with datetime.now(UTC) everywhere,
  eliminating 1340 pytest DeprecationWarning instances
- Fix typo in pyproject.toml ty rule name (non-subscriptable -> not-subscriptable)

Closes #2
Closes #3
Closes #4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: bc57b8e07f

ℹ️ 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 +1301 to +1303
onclick="confirmAndPredictUnpredicted({unpredicted_count})"
class="inline-flex items-center px-3 py-2 text-sm font-medium text-blue-700 bg-blue-100 rounded-md hover:bg-blue-200"
title="Run ML predictions on all transactions that don't have predictions yet"
title="Run ML predictions on transactions without predictions"
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 Route re-predict button to an endpoint that reprocesses rows

This button now appears with the text “Re-predict Transactions” when unpredicted_count is zero, but it still calls confirmAndPredictUnpredicted(...), which posts to /api/ml/predict/batch-unpredicted; that API only handles transactions where predicted_category_id IS NULL (api/ml.py), so in the exact re-predict state it returns predictions_made: 0 and no existing predictions are refreshed after retraining.

Useful? React with 👍 / 👎.

api/services.py Outdated

def _to_datetime(value: Any) -> datetime:
"""Cast an ORM column value to datetime."""
return datetime(value.year, value.month, value.day, value.hour, value.minute, value.second)
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 Preserve timezone data when converting ORM datetimes

This conversion rebuilds a new datetime from date/time fields and discards timezone and sub-second precision, and it is now used across response payloads for created_at/updated_at; because this same commit also moved timestamp creation to datetime.now(UTC), UTC-aware values can be returned as naive timestamps, causing incorrect interpretation in timezone-aware clients.

Useful? React with 👍 / 👎.

The "Re-predict Transactions" button was a no-op after retraining because
it called the batch-unpredicted endpoint which only targets transactions
with predicted_category_id IS NULL. Add a dedicated /predict/batch-repredict
endpoint that targets unreviewed transactions with existing predictions,
and split the UI into separate Predict/Re-predict buttons with correct counts.

Also fix _to_datetime in services.py to use typing.cast instead of
reconstructing datetime objects, which was losing timezone and sub-second
precision.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@davidchris davidchris merged commit d17d3d2 into main Feb 10, 2026
1 check 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.

Predict button disappears after retraining model a second time fix ty diagnostics Fix pytest warnings

1 participant