# ZAP Management Portal

Multi tenant school portal for staff, students, and parents: academics, CBT, results, finance, mail, and a WebView app.

## Stack

- **Language / Runtime**: PHP 8 on Apache (cPanel), timezone `Africa/Lagos`
- **Framework**: Custom PHP pages (no Composer app, no root npm app)
- **Key dependencies**: MySQL (`mysqli` plus PDO), jQuery, Bootstrap on desktop `admin/`, Material Design CSS at `app/admin/styles/zapapp.css`, Google Drive PHP client
- **Package manager**: none at repo root

## Build approach

Tracer Bullet (each slice is a real path through storage, server, and UI, just narrow).

## Commands

```bash
# Install
# None. Apache serves PHP on this host.

# Dev
# Edit files in place. Open the app at https://design-changes.zap.ng/app/admin/
# Desktop: /admin  Login: /private/login.php

# Build
# None. CSS and JS use ?v= filemtime via get_v().

# Test
# A few admin/includes/*_test.php scripts. Some open in the browser. Attendance engine tests run as php admin/includes/<name>_test.php. No CI.
```

## Specs

Stored in `docs/specs/`. Format: `docs/specs/NNNN-title.md`.

## Rules

- Most `app/admin` backend and AJAX lives in `admin/includes/` (`*_engine.php`, `*_ajax.php`, access helpers), shared with desktop. App pages include those files; they do not own a separate API. Engine functions take `mysqli` plus a `$ctx` array, return arrays, never echo, and never read `$_POST` or `$_GET`.
- Face matching is the exception: `admin/includes/staff_attendance_face_engine.php` (`saf_config`, `saf_detect`, `saf_verify`) takes `$ctx` only, with no `mysqli`.
- `request_is_same_domain` in `admin/includes/security.php` compares scheme, host, and port. Prefer `HTTP_REFERER`, then `HTTP_ORIGIN`. Do not read `X-Forwarded-Proto`.
- App pages boot from `app/admin/includes/init.php`. Desktop pages boot from `admin/includes/initialize.php`. Do not mix those bootstraps.
- School data is per tenant. `$_SESSION['db_name']` selects the school database. Do not hardcode a school DB.
- Work in `app/admin/`. Do not edit `app/public_html/` (gitignored deploy snapshot).
- Do not commit new secrets. Existing config already holds DB credentials; leave them, do not copy them into docs.
- App UI uses `app/admin/styles/zapapp.css`. Do not add React or npm MUI to these PHP pages.
- Display errors stay off in the app. Fatals become a retry screen.

## Agent skills

Declined: Agent Skills, MCP servers

## Context files

- [app/AGENTS.md](app/AGENTS.md): WebView school app in `app/admin` (main coding area)

_Drafted by /audit from the repo, worth a quick human pass. Edit freely: once a line stops matching this draft, later runs treat it as curated and will flag rather than overwrite it._
