Skip to content

About

A Multilingual Digital Informed Consent Application for Research Data Collection in Namibia.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ConsentLink

Offline-first, multilingual digital informed consent for field research in Namibia.

ConsentLink helps researchers turn a research proposal into a clear, approved consent form, then collect consent in the field. It works with no internet, in the participant's own language, and with read-aloud and voice answers. On-device AI drafts the form, and the researcher approves every section before anyone sees it.

ConsentLink 2.0 is a full rebuild of the original ConsentLink prototype (Ndamonako & Indongo, 2026), developed as a group prototype project for HCA820S – Human-Centred AI at the Namibia University of Science and Technology (NUST).


Features

For researchers

  • Upload a proposal (PDF, DOCX, ODT, TXT, scans), or describe your study by voice or text, and get a draft consent form
  • On-device AI drafting (no internet, proposal never leaves the phone), with source page, changes and confidence shown for every section
  • A rule checker for the 10 required consent elements (plus 4 more for studies with minors)
  • Section-by-section human approval: nothing reaches a participant unapproved
  • Google-Forms-style form builder: text, choice, date, signature, thumbprint, audio, photo and GPS fields
  • Analytics: recruitment progress, agreement rate, comprehension by language
  • Export to PDF, Word (.docx) and CSV

For participants

  • Large text, read-aloud on every screen, and voice or typed answers
  • Equal-weight Yes / No choices (no nudging)
  • Consent by signature, thumbprint or verbal recording, with a witness or interpreter
  • Minors: guardian consent plus the child's own assent; the child's "No" always stops participation
  • Optional feedback pop-up after completion (never shown to minors)

For institutions

  • Each institution's template, logo and colours apply automatically to its researchers
  • Admins upload a template; the app reads its fonts, spacing and margins and clips the logo from a PDF
  • Dynamic theming per institution (UNAM, NUST, IUM, Welwitchia and more), with ConsentLink green as the default

Languages: English, Afrikaans, Deutsch, Otjiherero, Khoekhoegowab, Rukwangali, Silozi and Oshiwambo. AI translations into local languages are always checked by a fluent human reviewer before use.

Uploads: executables, scripts and macro-enabled documents are blocked.


Human-centred AI principles

ConsentLink is designed around the two-dimensional HCAI framework: high automation and high human control.

Principle In ConsentLink
Human oversight AI drafts; researchers approve each section; fluent reviewers sign off translations
Transparency Every AI section shows its source page, what changed and its confidence
Accountability Append-only audit log of approvals, exports and withdrawals
Privacy & security On-device AI, encrypted local storage, row-level security per institution
Fairness Comprehension and completion compared across language groups
Autonomy Participants control language, pace, text size and audio, and can say no without penalty

Every screen must also pass our 11 design rules based on the UX laws (Hick, Fitts, Jakob, Miller, Peak-End, Aesthetic-Usability, hierarchy, consistency, accessibility, feedback, user control). See the Figma file.


Tech stack

Layer Technology
App (Android, iOS, desktop) Flutter, Riverpod, go_router
Local storage drift (SQLite) + SQLCipher
Sync PowerSync + Supabase
Backend Supabase: Auth (email confirmation), Postgres + RLS, Storage, Edge Functions
On-device AI llama.cpp with Gemma 4 E2B (fallback: Qwen 3.5 0.8B), GGUF format
Speech whisper.cpp (EN/AF/DE), flutter_tts, recorded native-speaker audio
Document service Python, FastAPI, PyMuPDF, python-docx, OpenCV, oletools, ClamAV
Export pdf + printing, docx_template, CSV
CI/CD GitHub Actions

Repository structure

ConsentLink/
├─ app/                Flutter app
│  ├─ lib/
│  │  ├─ core/         theme, router, feature flags, l10n      (P1)
│  │  ├─ contracts/    interfaces + models                     (ALL)
│  │  ├─ fakes/        fake implementations of each contract
│  │  ├─ features/     screens                                 (P1)
│  │  ├─ data/         database, repositories, sync, export    (P2)
│  │  ├─ ai/           model runtime, prompts, rules, speech   (P3)
│  │  ├─ main_dev.dart     runs on fakes
│  │  └─ main_demo.dart    runs on real implementations
│  ├─ l10n/            translations (.arb)
│  └─ test/
├─ service/            Python FastAPI document service         (P4)
├─ supabase/           migrations, seed data, RLS, functions   (P2)
├─ schemas/            shared JSON schemas                     (ALL)
├─ notebooks/          SUS + fairness analysis                 (P4)
├─ docs/               decisions, API notes, model card
└─ .github/            workflows, CODEOWNERS, PR template      (P2)

Getting started

Prerequisites

  • Flutter (stable channel) and Android Studio or Xcode
  • Python 3.12+
  • Supabase CLI (optional; Docker is needed only for a local Supabase)
  • A physical Android phone with 6 GB+ RAM for testing on-device AI

1. Clone and configure

git clone https://github.com/DrGitman/ConsentLink.git
cd ConsentLink
cp .env.example .env        # fill in values from the team (never commit .env)

2. Run the app on fakes (no backend needed)

cd app
flutter pub get
dart run build_runner build --delete-conflicting-outputs
flutter run -t lib/main_dev.dart

3. Run the app with real services

flutter run -t lib/main_demo.dart \
  --dart-define=USE_REAL_AI=true \
  --dart-define=USE_REAL_SYNC=true \
  --dart-define=USE_REAL_TEMPLATES=true

Any service can be switched back to its fake by setting its flag to false.

The template upload screen can be pointed at the Python service with --dart-define=TEMPLATE_SERVICE_URL=http://10.0.2.2:8000 for the Android emulator (use a reachable host address on a physical device). Upload also requires an authenticated user's Supabase access token through templateAccessTokenProvider; this build leaves that provider unconfigured until the P2 auth integration is connected. Do not pass bearer tokens or service-role keys with --dart-define.

4. Run the Python service

cd service
py -m venv .venv
.venv\Scripts\python.exe -m pip install -e ".[dev]"
$env:SUPABASE_JWT_SECRET = "<local signing secret provided by P2>"
$env:SUPABASE_URL = "<your Supabase project URL>"
$env:SUPABASE_ANON_KEY = "<your Supabase anon key>"
$env:SUPABASE_TEMPLATE_BUCKET = "<private template bucket with caller upload permission>"
.venv\Scripts\python.exe -m uvicorn app.main:app --reload

The service uses SUPABASE_JWT_SECRET to verify bearer tokens and SUPABASE_URL plus SUPABASE_ANON_KEY to access private Supabase Storage with the caller's JWT. SUPABASE_TEMPLATE_BUCKET must name a private bucket whose Storage policies allow the signed-in caller to upload. Never use a service-role key in client requests.

All four variables are required for the complete service. Keep their values in the deployment platform's secret/environment configuration; do not commit them or include them in support logs. For local development, set them in the current PowerShell session as shown above. The development command uses --reload; for deployment, run Uvicorn without reload, bind to the platform-provided port, and terminate it through the platform's normal process manager.

POST /v1/files/scan accepts one multipart file up to 25 MB. It checks PDF, DOCX, ODT, TXT and PNG/JPEG/TIFF signatures, rejecting unsupported types, executables, scripts and macro-enabled documents. Files are checked in memory and not saved.

This endpoint is for templates (they are uploaded to Storage anyway). Research proposals are never uploaded: the app only checks their type and size on the phone before on-device drafting.

POST /v1/templates/upload accepts one multipart PDF or DOCX file up to 25 MB. It scans and analyzes the file before uploading it to the configured bucket with the caller's JWT, then returns its storage_path, detected style properties, confidence values, PDF logo candidates, and detected text sections (sections, each with title and text). POST /v1/templates/analyse returns the same analysis fields, including sections, for an existing object and accepts JSON with storage_path in bucket/object/path format. Section extraction uses document headings and typography, so it is best-effort; documents without detectable headings return an empty list. The service does not identify or enforce the ten required consent elements or determine whether wording is official; the app must retain those safeguards. Unsafe, unsupported, or invalid uploads are rejected without being stored. Pass the returned storage_path to POST /v1/logos/extract with a 1-based PDF page and optional crop array of four page coordinates; the extracted PNG is written to the same bucket under logos/. All Storage operations use the caller's JWT.

PDF and DOCX style extraction is supported. Logo candidate detection and extraction currently require PDF input. The 1–60 page limit applies only to consent-form templates sent to this service for style analysis or logo extraction; research proposals, theses, and mini-theses are not uploaded to this template service. DOCX pagination is renderer-dependent, so DOCX templates are limited by the shared 25 MB upload cap instead. Password-protected PDFs, malformed templates, and documents without extractable PDF text return validation errors. Supabase Storage operations have a 20-second timeout. Open http://localhost:8000/health to check the service or http://localhost:8000/docs for API documentation. Run the service tests from service/ with:

.venv\Scripts\python.exe -m pytest

Deployment health checks should use GET /health (or the versioned GET /v1/health) and require HTTP 200. Service error logs are JSON records with stable event names and limited diagnostic fields; they intentionally omit request bodies, filenames, storage paths, tokens, upstream response bodies, and exception messages. Treat application and platform logs as operational data and restrict access through the deployment provider.

5. Local Supabase (optional)

supabase start
supabase db reset                  # applies migrations + seed data

AI model

Model files are not stored in Git. The app downloads the model after sign-in, on Wi-Fi (about 1.3 GB). For development, put the GGUF file path in .env (see .env.example).


Working on this repo

We use trunk-based development: main is the only long-lived branch. Each member works on short-lived task branches under their own prefix:

Member Prefix Example
P1 · UI & accessibility ui-dev/ ui-dev/7-onboarding-screens
P2 · Data, sync & export data-dev/ data-dev/9-powersync-setup
P3 · On-device AI & speech ai-dev/ ai-dev/12-rule-checker
P4 · Python service & HCI py-dev/ py-dev/15-template-style-api

Read CONTRIBUTING.md before your first branch.


Team

Role Member GitHub
P1 · UI & accessibility Orilio Naobeb @DrGitman
P2 · Data, sync & export Erastus Shingenge @erastusshingenge-maker
P3 · On-device AI & speech Amaury Cansa @1Cansa
P4 · Python service & HCI Kristofina Shipalanga @Tuilika

Lecturer: Mr Naftali N. Indongo, HCA820S, NUST.


Design

All screens, the design system, diagrams, HCI roadmap and task plan are in the ConsentLink Figma file: add link.

Figma page What's there
App Identity Logo, design system, the 11 design rules
Screen Artboards All screens, numbered (e.g. 04.3)
Development Diagrams Architecture, contracts, work packages, sequences, integration plan
Design Diagrams User flows and information architecture
HCI Roadmap Course concepts applied, UX laws, personas, stakeholder session
Task Distribution and Planning Roles, day-by-day plan, version control
Wireframes / Animations Low-fi screens, motion specs

Refer to screens by their number in issues and pull requests.


Roadmap

Date Milestone
Sun 4 – Mon 5 Oct Contracts + fakes merged, AI model spike
Tue 6 Oct Stakeholder engagement session
Fri 9 Oct Integration day
Sun 11 Oct v0.1.0 internal demo
Mon 12 Oct Usability test round 1
Fri 16 Oct Usability test round 2 (SUS + fairness check)
Sun 18 Oct v1.0.0 release

Ethics and data

  • Use test data only in development and shared environments. Never commit real participant data.
  • Real data may only be collected under an approved ethics clearance.
  • Studies with minors require ethics approval that covers minors, guardian consent and child assent.

Acknowledgements

Builds on ConsentLink: A Multilingual Digital Informed Consent Application for Research Data Collection in Namibia (Ndamonako & Indongo, 2026, NUST).

AI assistance was used to help resolve conflicts in the repository.

License

To be decided by the team.

About

A Multilingual Digital Informed Consent Application for Research Data Collection in Namibia.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages