All work
MS-03 · Client project · Al-Majmaah, Saudi Arabia

Operations system

Da’wa, Guidance and Community Awareness Association, Al-Majmaah

An internal system built around the association’s operational plan. Each department logs its work on its own page, and management sees targets against results in one dashboard, with finance, donors, official letters and an evidence archive alongside.

Specifications
Front end
React 19 · Vite · Tailwind 4 · PWA
Server
Google Apps Script with a single endpoint
Data
Google Sheets, with evidence files on Google Drive
Hosting
Firebase Hosting with strict security headers
Protection
ChaCha20 encryption and PBKDF2 hashing, written without libraries
My role
The whole system, solo
6departments
66programs in the plan
33KPIs
7staff roles
8encrypted data collections

01The problem

Six departments work on one yearly plan. Each needs to log its work without seeing or changing anyone else’s, and management needs one picture that compares targets with results.

The board and donors need limited, read-only access without full accounts.

02How it fits together

The interface sends only what changed, and the server decides who can read and write before anything is saved.

React appArabic PWA17 screens
Sync enginesends only changes150 items per batch
Board & donor portalsigned, read-only link
Apps Script25 API actionsper-department permissionsencryption and signing
Google Sheets6 sheetsincluding the audit log

03What it runs

  • Plan and operationsThe quarterly plan, each department’s operations, and an executive dashboard of targets against results.
  • FinanceInvoices, payment orders, receipt vouchers, bank accounts and a chart of accounts.
  • DonorsDonor management and proposals, plus a portal where each donor sees only their projects.
  • CorrespondenceLetters with an approval and official-stamp workflow, circulars, announcements with read receipts, and chat.
  • Preachers and recordsA dossier per preacher with residency-expiry tracking, and encrypted records.
  • Evidence and reportsAn evidence archive on Drive, and executive reports exported to multi-sheet Excel.

04Three engineering decisions

A

A department stays inside its lane

Permissions are checked on the server on every write: staff write only in their own department and can’t move an item to another one. Once a letter is approved its department can no longer edit it, and only the director or a delegate can stamp it.

backend/Policy.gs — excerpt
if (!isWholeOrg_(ctx)) {
  if (oldItem && !ownsDept_(ctx, p.depts(oldItem))) return 'OUT_OF_SCOPE';
  if (newItem && !ownsDept_(ctx, p.depts(newItem))) return 'OUT_OF_SCOPE';
  // ⁨لا يجوز نقل عنصر إلى قسم آخر⁩
  if (oldItem && newItem &&
      JSON.stringify(p.depts(oldItem)) !== JSON.stringify(p.depts(newItem)))
    return 'OUT_OF_SCOPE';
}
B

Never overwrite another department’s item

If a new item arrives with an ID that’s already taken, or that belongs to an item the user can’t see, the server renames it instead of writing over it, and tells the interface the new ID.

backend/Data.gs — excerpt
if (existing && (isNew || !oldItem || !canReadItem_(ctx, collection, oldItem))) {
  var oldId = item.id;
  do { item.id = oldId + '-' + hex_(randomBytes_(2)); }
  while (dataGet_(collection, item.id));
  result.renamed.push({ from: oldId, to: item.id });
}
C

Encryption without libraries

Apps Script has no complete crypto library, so I wrote ChaCha20 and PBKDF2 by hand and tested the cipher against the official RFC 8439 vectors. Sign-in takes the same time whether a number is registered or not, so timing doesn’t reveal accounts.

backend/Crypto.gs — excerpt
function pbkdf2_(passwordBytes, saltBytes, iterations) {
  var u = hmac_(passwordBytes, saltBytes.concat([0, 0, 0, 1]));
  var t = u.slice();
  for (var i = 1; i < iterations; i++) {
    u = hmac_(passwordBytes, u);
    for (var j = 0; j < t.length; j++) t[j] ^= u[j];
  }
  return t;
}

05Quality

Q-0119 server tests run against a local Apps Script emulator, across 6 test files.
Q-02Every write is logged to the audit sheet, with a screen to browse the log.
Q-03Security headers on hosting: HSTS, a strict CSP, and no framing.

06Known limits

L-01When two people edit the same item at the same moment, the last save wins. Next step: compare versions and warn the user.
© 2026 · Cairo, Egypt