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

akvo / akvo-mis / #778
89%
main: 89%

Build:
Build:
LAST BUILD BRANCH: feature/273-two-phase-registration
DEFAULT BRANCH: main
Ran 31 Jul 2026 09:45AM UTC
Jobs 1
Files 113
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

31 Jul 2026 09:36AM UTC coverage: 88.879%. First build
#778

Pull #285

coveralls-python

zuhdil
[#273] Scope approval batches, and make role names unique per tenant

Two gaps the read-isolation iteration left behind, found while checking
the role endpoint.

**Batches were readable across workspaces by guessing an id.** Five
endpoints — the batch's data, its comments, its summary, its attachments
— each fetched `DataBatch` by the id in the URL without asking whose it
was. Those ids are sequential, so any authenticated submitter or approver
in any workspace could walk another's pending submissions. Queryset-level
filtering could never have caught this: the lookup does not go through a
list.

`DataBatch` now carries the tenant path the read-isolation spec already
assigned it but which was never implemented, and one `batch_for` helper
asks the ownership question so a sixth endpoint cannot forget to.

**Role names were globally unique**, so the second workspace to want a
"Data Entry" role could not have one — an integrity error with no
sensible message. Uniqueness is now per tenant.

That needs the tenant stored on the role rather than derived through its
level, because a unique constraint cannot span a join. The column is
denormalised, so `save` sets it from `administration_level.tenant` and
nothing else can: it is not an input. `TENANT_PATH` follows it to the
direct column. The migration backfills from each role's level before the
constraint is added — leaving the column NULL would make every existing
role look like it belonged to one tenant-less workspace, and two legacy
roles sharing a name would collide.

The isolation tests pair each refusal with the same request against the
caller's own batch, because a route that does not exist also answers 404.

Still unaddressed, and deliberately: `RoleAccess`, `RoleFeatureAccess`
and `QuestionOptions` were also given paths by that spec and still lack
them. Each is only reachable through a parent that is scoped, so none is
currently exposed.
Pull Request #285: [#273] Verify the email before the workspace exists

5772 of 6671 branches covered (86.52%)

Branch coverage included in aggregate %.

10996 of 12195 relevant lines covered (90.17%)

0.9 hits per line

Jobs
ID Job ID Ran Files Coverage
1 #778.1 31 Jul 2026 09:45AM UTC 113
88.88
Source Files on build #778
  • Tree
  • List 113
  • Changed 0
  • Source Changed 0
  • Coverage Changed 0
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Pull Request #285
  • Next Build on feature/273-two-phase-registration
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