TafTaf Docs

Product documentation

TafTaf

Premium real estate, transacted in taps. TafTaf connects property owners and clients across Kenya — Airbnb stays, apartments, houses, plots and commercial space — with verified listings, M-Pesa-native payments, and tools for owners to manage tenants and rent from their pocket.

Flutter · Android & iOS Firebase Auth · Firestore · Storage M-Pesa Daraja API ZegoCloud voice calling Package ke.co.taftaf.app
5
Property types
2
Account roles
KES 50
Unlock fee, one-time
1.0.1
Current version
“Home is not a place. It’s a feeling.” — from the TafTaf onboarding carousel

What TafTaf is

TafTaf is a two-sided marketplace app. Clients browse verified listings, unlock full property details with a single M-Pesa payment, message owners directly, and book stays. Owners list properties across five categories, track views and saves, and run day-to-day rent operations for their buildings through a dedicated Tenant Manager — down to bulk-importing tenants from a spreadsheet and printing PDF receipts.

Product

Features

Everything below ships in the current build — pulled directly from the app’s feature set, not a roadmap.

Verified Listings

Airbnb stays, apartments, houses, plots/land and commercial space, each with a verified badge, rating, and live availability status.

🔒

Pay-Per-Unlock

Full property details — owner contact, exact location, amenities — stay behind a one-time KES 50 charge. Pay once, unlock forever.

M-Pesa Native

STK Push checkout straight against the Safaricom Daraja API, with status polling and graceful failure handling.

In-App Messaging

Direct chat between clients and owners once a conversation is started from a listing.

Voice Calling

Real-time voice calls powered by ZegoCloud — no phone minutes required on either side.

Tenant Manager

Owners create apartments, assign tenants to rooms, and track rent and due dates from a single screen.

Bulk Tenant Import

Onboard a whole building at once via an Excel template, parsed on-device.

PDF Receipts

Generate, print, and share rent receipts and statements directly from the phone.

Location-Aware Search

Filter by price range and property type, or tap “Near Me” for live geolocation results.

Dual Roles, One Codebase

The same app renders a Client shell (browse & book) or an Owner shell (list & manage), decided by the account’s role.

Product · Client role

Client Experience

From sign-up to booking: the flow a person renting or buying moves through. Screenshots below are captured from a real build running on an Android emulator, not mockups.

Product · Owner role

Owner Dashboard

Owners get a management console instead of a browse feed: listing performance at a glance, a fast path to add inventory, and a rent-collection tool most listing apps don’t bother building.


Why a Tenant Manager exists

Most listing marketplaces stop at the booking. TafTaf’s owner side keeps going after move-in: rooms get assigned to tenants with a rent amount and due date, a whole building can be imported from a spreadsheet in one pass, and receipts get generated as PDFs the owner can print or share — no separate landlord software required.

Engineering

Architecture

One Flutter codebase, Firebase as the backend of record, and three external services doing the jobs Firebase doesn’t: payments, voice, and maps.

Client
  • Flutter 3.44 / Dart 3.12
  • flutter_riverpod — state
  • go_router — navigation
  • Material 3 — component base
  • Poppins — typeface
Backend
  • Firebase Auth — email/password + Google
  • Cloud Firestore — users, properties, chats
  • Firebase Storage — listing photos
Integrations
  • Safaricom Daraja — M-Pesa STK Push
  • ZegoCloud — voice calling
  • Google Maps + Geolocator — location
  • pdf / printing / excel — documents
Flutter App
Firebase Auth
Cloud Firestore
Firebase Storage
Flutter App
Daraja OAuth
STK Push
Status Poll

Account documents live in two Firestore collections: users/{uid} holds the profile, and usernames/{usernameLower} is a lookup index that enforces username uniqueness and resolves username → email at login.

Engineering

Code Reference

Three excerpts, taken directly from the codebase, that show how the core mechanics actually work.

Property price formatting

From lib/core/models/property_model.dart — collapses raw KES values into the K/M shorthand shown throughout the app.

property_model.dart
enum PropertyType { airbnb, apartment, house, plot, commercial }
enum PriceType { daily, monthly, fixed }

String get priceFormatted {
  if (price >= 1000000) {
    return 'KES ${(price / 1000000).toStringAsFixed(1)}M';
  } else if (price >= 1000) {
    final k = price / 1000;
    final s = k == k.truncateToDouble()
        ? k.toInt().toString()
        : k.toStringAsFixed(1);
    return 'KES ${s}K';
  }
  return 'KES ${price.toStringAsFixed(0)}';
}

Signup — username uniqueness

From lib/core/services/auth_service.dart — a username reservation doc is written alongside the Firebase Auth account so logins can resolve username → email.

auth_service.dart
Future<UserModel> signup(String username, String email,
    String phone, UserRole role, String password) async {
  final usernameLower = username.trim().toLowerCase();
  final existing = await _usernames.doc(usernameLower).get();
  if (existing.exists) throw Exception('Username or email already taken');

  final cred = await _auth.createUserWithEmailAndPassword(
      email: email.trim(), password: password);
  final uid = cred.user!.uid;

  final newUser = UserModel(id: uid, username: username.trim(),
      email: email.trim(), phone: phone.trim(), role: role,
      createdAt: DateTime.now());

  await _users.doc(uid).set(newUser.toJson());
  await _usernames.doc(usernameLower)
      .set({'uid': uid, 'email': email.trim().toLowerCase()});
  return newUser;
}

M-Pesa STK Push

From lib/core/services/mpesa_service.dart — the request that pops the payment prompt on the payer’s phone.

mpesa_service.dart
Future<StkPushResult> initiateStkPush({
  required String phoneNumber,
  required int amount,
  required String accountReference,
  required String transactionDescription,
}) async {
  final token = await _getAccessToken(); // Daraja OAuth, cached
  final password = base64Encode(utf8.encode(
      '${ApiKeys.mpesaBusinessShortCode}${ApiKeys.mpesaPasskey}$ts'));

  final res = await http.post(
    Uri.parse('$_baseUrl/mpesa/stkpush/v1/processrequest'),
    headers: {'Authorization': 'Bearer $token'},
    body: jsonEncode({
      'BusinessShortCode': ApiKeys.mpesaBusinessShortCode,
      'TransactionType': 'CustomerPayBillOnline',
      'Amount': amount,
      'PartyA': phone, 'PhoneNumber': phone,
      'AccountReference': accountReference,
    }),
  );
  // ResponseCode '0' => success, checkout ID returned for polling
}

Engineering

Design System

Pulled directly from app_colors.dart and app_theme.dart. Neon lime on near-black, in the same register as the Apple Fitness palette, plus a matching light theme.

Brand accent

Primary
#BEFF0A
Light
#D5FF5C
Deep
#8CBB00
Surface
#1C2800
Background
#000000

Semantic

Success
#30D158
Warning / Star
#FFD60A
Error
#E05A00
Card (dark)
#2C2C2E
Text secondary
#8E8E93

Type scale — Poppins

displayLargeAa34 / 800 / -0.5
headlineLargeAa24 / 700
titleLargeAa18 / 600
bodyLargeAa14 / 400
labelLargeAa14 / 700

Components

● All Airbnb Apartments

Buttons use a 30px pill radius; cards and inputs use 14–16px radii — consistent across both themes.

Engineering

Getting Started

Local setup for anyone picking up the codebase.

Clone & install dependencies

Standard Flutter workflow — SDK ^3.12.0.

git clone <repo>
cd taftaf
flutter pub get

Add Firebase config

Drop in the platform config files from your Firebase project (taftaf-app-b0167 for the reference build).

android/app/google-services.json
ios/Runner/GoogleService-Info.plist

Add local API keys

Copy the example file and fill in Maps, M-Pesa Daraja, ZegoCloud and EmailJS keys. This file is gitignored on purpose.

cp lib/core/constants/api_keys.example.dart \
   lib/core/constants/api_keys.dart

Run it

Pick a target device and launch in debug mode.

flutter devices
flutter run -d <device-id>
Build note: zego_express_engine pins an old compileSdkVersion in its own Gradle file, which can conflict with newer Android Gradle Plugin versions. If a build fails on the Zego module, that plugin’s android/build.gradle in the pub cache is the first place to check.

Contact

Developer

TafTaf is designed, built, and maintained end-to-end by a single fullstack engineer.

Sharks Muli

Sharks Muli

Fullstack Engineer · Founder, LM-Graphics
Nakuru, Kenya

Building TafTaf end-to-end — the Flutter app, the Firebase backend, and the M-Pesa integration behind the pay-per-unlock model documented on this site. Software Engineering undergraduate at Kisii University, focused on API design, database architecture, and system integration. Also runs LM-Graphics, a technical & digital solutions studio.


Skills

Toolbox

Languages
DartPythonJavaScript
Frameworks
FlutterSpring BootReact
Backend
REST API designServer-side developmentApplication logic
Data
FirestoreMongoDBSQL
Architecture
MicroservicesModular system design
Practice
GitStructured workflowsAgile teamwork

Experience

Projects & roles

TafTaf

Founder & Fullstack Engineer
  • Designed and built the entire product documented on this site — Flutter client, Firebase backend, M-Pesa payments, ZegoCloud calling.
  • Owns the data model, the owner/client dual-role architecture, and the Tenant Manager rent-collection tools.

Medical Management System

  • Designed and developed a backend-driven system to manage patient records and appointment scheduling.
  • Implemented structured data storage and retrieval logic for secure record handling.
  • Designed REST-style endpoints to support frontend integration.

Haki-Record Digital OB System

Team project
  • Co-developed a digital Occurrence Book system to improve record accessibility and data security.
  • Contributed backend logic for secure data handling and structured workflows.

LM-Graphics

Founder — technical & digital solutions
  • Leads client-based digital solution projects, from system design through implementation.
  • Leads graphic design projects and delivery.

Local Service Hub

Operations Assistant
  • Coordinates daily service requests and matches clients with appropriate local providers.
  • Maintains accurate records of transactions, service delivery, and client feedback.

Education

Kisii University
BSc. Software Engineering
2022 – 2027
Mango Secondary School
Kenya Certificate of Secondary Education
2017 – 2021

Résumé

Résumé preview

Meshack Muli Kikuvi — Full CV

One-page résumé: professional summary, full project & work history, skills and education. PDF, ready to download or open in a new tab.

TafTaf wordmark
TafTaf — premium real estate platform for Kenya. Built with Flutter, Firebase, and M-Pesa.