The grand plan
How we take Dumo from a clickable prototype to an Android app in the hands of 100 South African creators: one gated process, six paid milestones, and every milestone accepted on the client's own phone.
Summary
A TikTok-style vertical video app for South African creators: post short videos, grow a following, and watch a test-money wallet fill up from views and gifts. Real payouts, iOS, LIVE and the Shop come in later phases.
Our process
Each stage has an owner and a gate. Nothing moves forward until the gate is passed in writing, so we don't build the wrong thing.
Discovery
We send our questions and design assumptions. The client answers on the Questions page.
Owner: Solution architect + PMUX & UI design
A clickable prototype of every pilot screen, plus the admin dashboard. The client pins comments, and we do 2 review rounds.
Owner: Senior designerBuild M1–M6
Flutter app, API and admin. Every milestone ends with "done when" tests on the client's phone.
Owner: Tech lead + Flutter devsPilot release
Google Play closed testing under Dumo's account. 100 creators are invited, and we hand everything over.
Owner: PM + QAHypercare
2 weeks of fast bug fixes and monitoring while the pilot runs live.
Owner: Tech leadWho does what
R = does the work · A = accountable, signs off · C = consulted · I = kept informed.
| Activity | Client (BP Mhlanga) | Solution architect | Senior designer | PM | Flutter devs | QA |
|---|---|---|---|---|---|---|
| Discovery questions & answers | A | R | C | R | I | I |
| UX flows & UI design | A | C | R | C | C | I |
| Technical plan, stack, cost estimate | A | R | I | C | C | I |
| Accounts in the company's name | A | R | – | R | I | – |
| App & API build | I | A | C | I | R | C |
| Admin dashboard build | I | A | C | I | R | C |
| Milestone testing & acceptance | A | C | C | R | C | R |
| Status updates (Mon/Thu) & demos | I | C | I | A | C | C |
| Change requests | A | C | C | R | I | I |
| Play release & handover | A | R | I | R | R | R |
Proposed stack
Our recommendation keeps data and compute in Johannesburg wherever possible, for speed and POPIA. Every library is MIT, Apache 2.0 or BSD and will be listed in the README.
| Area | Recommended | Why | Alternative |
|---|---|---|---|
| App | Rec.Flutter (Dart), Android 9+ (API 28) | One codebase, so iOS follows later. Smooth video on low-end Android. Strong tooling for paged feeds. | React Native (Expo) |
| Video player | Rec.video_player / ExoPlayer (Media3) with HLS | Adaptive bitrate. We preload the next 1–2 videos and cap resolution when Data Saver is on. | better_player_plus |
| Cloud & region | Rec.Google Cloud africa-south1 (Johannesburg) | A full cloud region inside South Africa, close to users, which keeps POPIA simple. | Supabase. It is fast to build on, but it has no South African region at the time of writing, so data would sit in the EU. This is a trade-off for the client to decide. |
| Auth | Rec.Firebase Authentication (phone OTP) | Ready-made SMS OTP for cellphone sign-up, with abuse protection (Play Integrity, rate limits). The auth service itself is global. | Own OTP flow over Clickatell (SA SMS provider) |
| API | Rec.Cloud Run, TypeScript/Node (Fastify) | Scales to zero and is cheap for a pilot. One documented REST API serves both the app and the admin dashboard. | Supabase Edge Functions |
| Database | Rec.Cloud SQL for PostgreSQL (africa-south1) | Relational data suits the wallet ledger, follows and reports. SQL makes auditing easy. | Firestore (harder for ledger and reports) |
| Files | Rec.Cloud Storage (africa-south1) | Profile photos and thumbnails. Signed URLs for upload. | Supabase Storage |
| Video | Rec.Mux Video | Adaptive HLS, a low-bitrate rendition for Data Saver, a 60 s cap enforced on upload, and webhooks when a video is ready. Residency note: stored in US/EU and delivered via a global CDN. This needs a POPIA s72 cross-border clause. | Cloudflare Stream |
| Admin dashboard | Rec.Next.js (React) on Cloud Run | Web dashboard for users, videos, reports, removals, suspensions and the rand-per-1,000-views setting. Admin roles are checked on the server. | Firebase Hosting + React SPA |
| Crashes & analytics | Rec.Firebase Crashlytics + minimal analytics | Proves the "15 min with no crashes" test. We only collect the events we need. | Sentry (self-hosted) |
| CI/CD | Rec.GitHub Actions → Play internal testing | Every merge to main builds a signed AAB. Secrets are stored in GitHub/Cloud Secret Manager. | Codemagic |
| Languages | Rec.Flutter intl with ARB files | All app text lives in one app_en.arb, ready for isiZulu, isiXhosa, Afrikaans and other languages later. | – |
Architecture
The app never talks to the database directly. Every request goes through the API, which checks auth and roles. Video goes straight from the phone to the video service and plays back from a CDN.
Solid lines are API calls. Dashed lines are video traffic. On a phone, scroll the diagram sideways.
Data model sketch
Postgres with foreign keys and soft-delete flags. Deleting an account removes the user's videos from Mux and storage through a background job (POPIA right to erasure).
id, phone_e164 (unique), dob, role (user|admin), status (active|suspended|deleted), created_atuser_id, handle (unique), display_name, bio, location, avatar_url, languages[], founding_creator, data_saverid, creator_id, mux_asset_id, playback_id, caption, language, hashtags[], duration_s, earn_enabled, status (processing|live|removed), like_count, comment_count, created_atfollower_id, creator_id, created_at · PK(follower, creator)user_id, video_id, created_at · PK(user, video)id, video_id, user_id, body, status, created_atid, video_id, viewer_id, watched_ms, qualified (bool), created_at · index(viewer, video, created_at)id, video_id, sender_id, creator_id, gift_type, coin_value, creator_share_zar (70%), created_at · test coins onlyid, account (creator|platform|test_coin_pool), user_id, entry_type (views|gift|subscription), amount_cents, ref_id, created_at · double-entry, test moneyid, reporter_id, target_type (video|user|comment), target_id, reason, note, status (open|actioned|dismissed), handled_by, handled_atblocker_id, blocked_id, created_atkey, value, updated_by, updated_at · e.g. zar_per_1000_views, gift_creator_shareid, actor_id, action, target, before, after, created_at · every admin actionBusiness rules
These rules drive both the wallet and the spreadsheet check in Milestone 4. Values marked "assumption" need the client's confirmation (see Questions).
Watched for at least 3 s, by someone who is not the creator, and not the same viewer on the same video within 30 minutes.
Assumption · confirm(qualified views ÷ 1,000) × the admin's rand rate, rounded to the cent and credited to the ledger daily.
Rate set in adminViewers send gifts with free test coins. The creator's wallet shows 70% of the gift's rand value, and 30% goes to the platform ledger.
From briefDate of birth at sign-up. Under 13 cannot join. Ages 13–17 can watch and post, but their wallet is locked with an "Earn from 18" message.
From briefNo payment SDK in the build. Cash out shows "Coming soon", and every rand amount is labelled test money.
From briefscore = likes × 2 + comments × 3 + qualified views ÷ 10, decayed by age (half-life 24 h). Videos from blocked users are never shown.
Assumption · confirmMilestones
The scope and "done when" tests are copied from the brief. Payment is released only when every test passes on the client's phone.
| # | Milestone | Budget | Weeks | Scope | Done when | Designed screens |
|---|---|---|---|---|---|---|
| 1 | Foundation | 10% | 2 |
|
|
Welcome Phone OTP |
| 2 | Video feed | 20% | 3 |
|
|
Feed Post Comments |
| 3 | Profiles and following | 15% | 2 |
|
|
Creator Discover My profile |
| 4 | Creator wallet (test money) | 15% | 2 |
|
|
Wallet Gift Admin settings |
| 5 | Safety and admin | 15% | 2 |
|
|
Report Age check Admin |
| 6 | Pilot release and handover | 25% | 2 |
|
|
Handover list |
Timeline
Kickoff Monday 12 October 2026. M1 setup (repo, accounts, auth) runs alongside design, because it doesn't depend on visual sign-off. We pause over the December holidays, and each 5-day acceptance window overlaps the start of the next milestone.
| Phase | Start | End | Demo & acceptance |
|---|
Monthly running costs (estimate)
Pilot assumptions: 100 creators, about 2,000 viewers, 3,000 videos stored (about 30 s average), 500,000 minutes watched a month, 1,500 OTP SMS a month. Prices are list prices converted at about R18/$. We confirm them with real quotes in Milestone 1.
| Item | USD / month | ZAR / month | Notes |
|---|---|---|---|
| Video: encode, store, stream (Mux) | $150 – $450 | R2,700 – R8,100 | Delivery is the biggest cost. Data Saver and a 720p cap pull it toward the lower end. |
| API (Cloud Run) | $0 – $25 | R0 – R450 | Scales to zero, and the free tier covers most of the pilot |
| Database (Cloud SQL Postgres, small) | $30 – $70 | R540 – R1,260 | Includes daily backups |
| Storage + egress (photos, thumbnails) | $5 – $20 | R90 – R360 | |
| SMS OTP | $40 – $120 | R720 – R2,160 | Per-SMS rates to SA numbers vary. Clickatell may be cheaper locally. |
| Admin dashboard hosting | $0 – $10 | R0 – R180 | Cloud Run |
| Crash reporting & monitoring | $0 – $10 | R0 – R180 | Crashlytics is free, plus Cloud Monitoring |
| Domain & company email | $8 – $20 | R144 – R360 | If not already owned |
| Total per month | $233 – $725 | R4,200 – R13,000 |
One-off: Google Play developer registration $25 (about R450). An organisation account needs a D-U-N-S number, which is free but can take up to 30 days, so we start it in week 1. Real-money features (PayShap, coin purchases) add payment-provider fees in a later phase.
Risks & mitigations
| Risk | Level | Mitigation |
|---|---|---|
| Video streaming costs grow faster than expected | High | Cap at 720p, use a low-bitrate default on cellular, preload only 1–2 videos, set budget alerts at 50/80/100%, review the cost dashboard weekly. |
| OTP SMS delivery or cost problems in SA | Medium | Test on Vodacom, MTN, Cell C and Telkom in M1. Rate-limit OTP requests. Keep Clickatell as a fallback. Allow a "resend code" after 30 s. |
| POPIA compliance and data leaving SA | Medium | Data and compute in Johannesburg. Collect only what we need. Sign a data processing agreement with the video provider (s72). Account deletion really deletes. Privacy policy agreed with the client. |
| Minors' safety (13–17 year olds) | High | Age gate at sign-up, earning locked under 18, reporting and blocking everywhere, admin removal in under a minute, community guidelines accepted at sign-up. |
| Slow performance on low-end Android | Medium | Test on budget devices weekly, use HLS with a small first segment, cache thumbnails, profile in release mode, set a 2 s start budget in QA. |
| Scope creep from features the prototype shows (PayShap, Subscribe, LIVE, Go Global, cross-posting) | High | These are marked "Coming soon" or hidden in the pilot design and listed as decisions in Questions. Any change needs a written change request with price and time. |
| Google Play policy for user-generated content apps | Medium | Policy requires in-app reporting, blocking, moderation and a published content policy, all built in M5. We complete the data safety form and content rating questionnaire early. |
| Slow client acceptance holds up payments and the schedule | Low | Test scripts sent with every build, 15-min demo calls, a 5-working-day window, and acceptance overlapping the next milestone. |
| Company accounts not ready (Play, cloud billing, D-U-N-S) | Medium | Account checklist in week 1. The client owns every account, and we are invited with access only. |
Cadence, quality and Definition of Done
Communication
- Written update every Monday and Thursday: done, next, blockers
- 15-minute demo call at the end of each milestone
- Feature questions go to BP Mhlanga before we guess
- Code pushed to the company's GitHub at least twice a week
Acceptance
- The client has 5 working days to test each milestone
- Bugs found are fixed before payment
- Payment is released through Fiverr milestones once every "done when" test passes
- Scope changes are agreed in writing, with price and time, before work starts
Definition of Done
- Matches the signed-off design
- Strings are in the ARB file, with no hard-coded text
- No secrets in code, and CI is green
- Tested on the device matrix and on throttled 4G
- README updated, libraries listed with their licences
Test devices
- Samsung Galaxy A05 (entry level, Android 13/14)
- Samsung Galaxy A15 (mid-range, our 2 s benchmark)
- Xiaomi Redmi 12
- Hisense or Infinix (low-end)
- One Android 9 device (minimum version)
QA checks per milestone
- Throttled 4G profile: video start ≤ 2 s on the A15
- 15-minute swipe, like and comment session with no crashes (Crashlytics)
- Wallet results match the client's spreadsheet to the cent (M4)
- Report, then remove in under 60 s, timed (M5)
- Data use measured with Data Saver on and off (M3)
Final handover checklist
- All code in the company GitHub, latest version pushed
- README covers setup, running locally, releasing and costs
- Every account and service listed, owned by the company, your access removed
- Recorded code walkthrough delivered
- Signed confirmation that all work belongs to Dumo The Fame (Pty) Ltd
Security & ownership
Dumo The Fame (Pty) Ltd owns everything: code, designs, databases and accounts. Google Play, Google Cloud, Mux, the SMS provider and GitHub are opened in the company's name and paid by the company, and the team only gets access. No passwords, API keys or secrets in the repository: they live in Secret Manager and GitHub Actions secrets. Admin actions are written to an audit log. Only open-source libraries with commercial-friendly licences (MIT, Apache 2.0, BSD) are used.