Skip to content

Modernization Phase 0 — Infrastructure & Backend Stabilisation - #48

Merged
HugoFara merged 15 commits into
mainfrom
phase0
Apr 10, 2026
Merged

Modernization Phase 0 — Infrastructure & Backend Stabilisation#48
HugoFara merged 15 commits into
mainfrom
phase0

Conversation

@HugoFara

Copy link
Copy Markdown

This PR delivers all items from the phase 0 estimate, plus some more fixes discovered along the way.

What's included

CD Pipeline — Automated deployment on push to main. A new GitHub Actions workflow runs tests, then SSHes into PythonAnywhere to pull code, run migrations, and reload the webapp. The existing tools/refresh_env.sh was cleaned up (removed makemigrations from production, added --noinput flags).

Python 3.10 — Pinned the Dockerfile from the vague python:3 to python:3.10, matching CI and the production target. The codebase was already 3.10-compatible.

Database hygiene — Migrations were gitignored and regenerated on every deploy. Now they're committed and version-controlled. Added tools/backup_db.sh for automated MySQL backups on PythonAnywhere (mysqldump + gzip, 30-day retention).

Admin interface fix — Admin search was broken: search_fields referenced a non-existent field (email instead of contact_email), a boolean (is_public), a display method (_created_by), and a date field (published_at). Fixed all four and added list_filter for better filtering.

Live client-side search — The profile search now filters instantly in the browser as you type, instead of doing a full page reload. A new /api/profiles/ endpoint serves all public profiles as JSON; vanilla JS handles the filtering (debounced, supports text + checkboxes). Server-side search remains as a no-JS fallback.

Signup 500 fix (closes #47) — Signup crashed with a 500 if the email backend failed, even though the user was already saved to the DB. Wrapped the email send in a try/except with logging and a user-facing error message.

Tests

Test count went from 17 → 61 (+44 new tests):

  • 11 admin tests (changelist + search for Profile, Publication, User)
  • 5 search API tests
  • 19 smoke tests (all major pages and endpoints)
  • 7 profile form tests (URL normalisation for ORCID, Twitter, GitHub, LinkedIn)
  • 2 signup tests (normal flow + email failure)

Manual actions needed after merge

  • Add GitHub secrets: PYTHONANYWHERE_SSH_KEY, PYTHONANYWHERE_USERNAME
  • Change PythonAnywhere Python version to 3.10 and recreate the virtualenv
  • Run python manage.py migrate --fake-initial on first deploy
  • Schedule tools/backup_db.sh as a daily task on PythonAnywhere
  • Verify email/SendGrid configuration (related to Error 500 on signup #47)

Add a deploy workflow that SSHes into PythonAnywhere and runs the
deploy script after tests pass on main. Clean up the test workflow
(add workflow_call trigger, bump checkout to v4, remove stale
commented-out deploy code). Fix refresh_env.sh: remove makemigrations
from prod, add --noinput flags, fix quoting.
The vague python:3 tag pulls latest 3.x, causing inconsistency with
CI and the production target (3.10).
Migrations were gitignored and regenerated on every deploy, making the
schema fragile and impossible to evolve safely. Now:
- Remove migration exclusion from .gitignore
- Commit the initial migration as a proper baseline
- Clean up refresh_db.sh to use committed migrations instead of
  deleting and regenerating them
- Add tools/backup_db.sh for automated MySQL backups on PythonAnywhere
  (mysqldump + gzip, 30-day retention)
search_fields referenced non-existent field ('email' instead of
'contact_email'), a boolean field ('is_public'), a display method
('_created_by'), and a date field ('published_at') — none of which
are searchable. Any search query caused a 500 error.

Fix search_fields to use correct text fields and add list_filter
for the fields that work better as filters. Add 11 admin tests.
Replace full-page-reload search with instant client-side filtering.
On page load, fetches all public profiles via a new /api/profiles/
endpoint, then filters in the browser as the user types (debounced).
Supports text search, under-represented country filter, and senior
position filter. Server-side search remains as no-JS fallback.

Adds ProfileSearchSerializer, ProfileSearchViewSet, and 5 API tests.
Smoke tests (19) verify all major pages render without errors:
home, repo list, search filters, profile detail, signup, login,
account, profile edit, recommend, FAQ, about, publications, and
all API endpoints. Form tests (7) verify URL normalization in
UserProfileForm.clean() for ORCID, Twitter, GitHub, LinkedIn.

Total test count: 17 → 59.
If the email backend fails (bad SMTP config, expired SendGrid key),
the signup crashed with a 500 even though the user was already saved.
Now catches the exception, logs it, and shows a user-facing error
message instead of crashing. Adds 2 tests.

Closes #47
@HugoFara
HugoFara requested a review from alpinho April 10, 2026 18:46
@HugoFara HugoFara assigned HugoFara and unassigned alpinho Apr 10, 2026
@HugoFara HugoFara added bug Something isn't working enhancement New feature or request labels Apr 10, 2026
@HugoFara
HugoFara marked this pull request as ready for review April 10, 2026 19:02
Replace hard-coded margin-left:170px with Bootstrap d-block mx-auto
classes so the button centers properly on all viewport sizes.
…oses #24)

ProfilesSitemap was querying all profiles including soft-deleted and
private ones, and Profile lacked get_absolute_url() which Django's
sitemap framework requires. Now only public profiles appear in the
sitemap.
Direct links like /faq/#heading-resources now auto-expand the target
accordion section and scroll to it. Uses Bootstrap's Collapse API on
DOMContentLoaded.
Use coverage run --source=profiles with --fail-under=50 threshold.
Remove makemigrations from CI — migrations are now committed to the
repo and should not be generated during test runs.
…kend

Remove duplicate email block that silently overrode values with empty
strings. Add section comments and use console email backend for local
development so emails are printed to stdout instead of failing silently.
README now includes venv setup, test instructions, Docker option, and
pre-created test accounts. CONTRIBUTING.md was empty — now covers
workflow, PR guidelines, and coding style.
HugoFara and others added 2 commits April 10, 2026 23:51
Production repo on PythonAnywhere is at ~/winrepo-prod, not ~/winrepo.
Phase 0 bonus - Bug fixes & developer experience

Ready for merging.
@HugoFara

Copy link
Copy Markdown
Author

Thanks to PR #49 , it will also fix the open issues #22, #24, #27, #34 and #48.

@HugoFara
HugoFara merged commit ef97243 into main Apr 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error 500 on signup

2 participants