• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

akvo / akvo-mis / #1339
90%

Build:
DEFAULT BRANCH: main
Ran 05 Oct 2026 04:45AM UTC
Jobs 1
Files 147
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

05 Oct 2026 04:33AM UTC coverage: 90.417% (+0.02%) from 90.397%
#1339

push

coveralls-python

web-flow
[#507] Purge workspaces that never finished signing up (#509)

* [#507] Bind the activation link's lifetime to a new purge window setting

Introduces `TENANT_PURGE_AFTER_HOURS`, defaulting to 48, which the
purge job in the next commit will measure against. The activation
link's lifetime now derives from it instead of being a hardcoded
week.

The trade-off is that activation links get much shorter — a week to
48 hours. That is deliberate rather than incidental: once an
unconfigured workspace is deleted after 48 hours, a link that stayed
valid for five more days would verify an account whose tenant no
longer existed. One setting cannot disagree with itself; two numbers
could.

Validation lives in `utils/purge_window.py` rather than inline in
`settings.py` so that it can be tested. A guard inside `settings.py`
is only reachable by re-importing a module Django has already cached,
which means in practice it could not be tested at all. A non-positive
window is refused at boot because its symptoms — every workspace
purged on sight, every link dead on arrival — would look like a bug
anywhere except at the setting that caused them.

* [#507] Purge workspaces that never finished signing up

Sign-up phase 1 claims a subdomain so that nobody can take the name
during the email round-trip, and nothing ever gave the claim back. An
abandoned sign-up held the name forever, on a free tier where signing
up costs nothing. This gives it back.

"Never finished" reuses `tenant_is_configured` rather than asking the
question again in SQL. That predicate is already shared with the
configuration gate and the bulk-upload gate, and a second spelling of
it inside a destructive job is exactly where two definitions drift
apart.

The safety guard is the database, not a pre-flight check. Every FK to
`Tenant` is PROTECT, so a workspace that still owns anything makes
the delete raise before a row is touched, and the exception names
what held it. An enumerated check would be a second lis... (continued)

8189 of 9303 branches covered (88.03%)

Branch coverage included in aggregate %.

15256 of 16627 relevant lines covered (91.75%)

0.92 hits per line

Coverage Regressions

Lines Coverage ∆ File
22
91.41
-0.01% api/v1/v1_users/views.py
13
81.87
0.0% utils/email_helper.py
1
96.67
-2.14% mis/settings.py
1
95.17
0.0% utils/custom_generator.py
Jobs
ID Job ID Ran Files Coverage
1 #1339.1 05 Oct 2026 04:45AM UTC 147
90.42
Source Files on build #1339
  • Tree
  • List 147
  • Changed 4
  • Source Changed 0
  • Coverage Changed 4
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • 9e8cc2e3 on github
  • Prev Build on main
  • Next Build on main
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc