<!-- markdownlint-disable MD013 -->

# ZumaX Enterprises Admin and Client-Enquiry Platform Blueprint

**Version:** 1.0  
**Date:** 2 August 2026  
**Status:** Proposed implementation specification  
**Prepared for:** ZumaX Enterprises, Mbeya, Tanzania

---

## 1. Executive decision

ZumaX Enterprises should evolve the current homepage into a database-backed business platform while preserving the existing public design and its two-step email-verification experience.

The recommended target is one **Laravel 13 + MySQL application** with two clearly separated surfaces:

1. **Public website** — homepage, contact form, email verification, Privacy Policy and Terms of Service.
2. **Private office** — a protected administration area at `/office` for enquiries, clients, follow-ups, quotations, packages, documents, templates, users, reports and audit history.

The current file-based system is suitable as a safe staging implementation, but it should not become the permanent business record. Its protected JSON records should be replaced by transactional database records before the new administration platform becomes the production source of truth.

### Recommended defaults

| Decision | Recommended default |
| --- | --- |
| Application structure | One Laravel application for the public site and private office |
| Database | MySQL using migrations, foreign keys and indexed status fields |
| Admin URL | `https://zumaxenterprises.com/office` initially |
| Initial users | ZumaX owner account only; public registration disabled |
| Public design | Preserve the current homepage design and branding |
| Public languages | English and Kiswahili |
| Office language | English initially |
| Currency | TZS, with currency stored on every quotation |
| Pricing | Quote-based by default; public prices optional later |
| Email | Authenticated domain SMTP; delivery webhooks optional later |
| Payments | Not part of the first release |
| Client accounts | Not part of the first release |
| Deployment | Staging first, then controlled production cutover |

---

## 2. Objectives

The platform should provide ZumaX with a dependable record of each business enquiry from first submission through conversion or closure.

### Primary objectives

- Store verified enquiries in a searchable database.
- Preserve the rule that nothing reaches the business inbox before client confirmation.
- Distinguish pending, verified, expired, failed and repeated verification attempts.
- Prevent duplicate forwarding when a verification request is repeated.
- Give administrators a complete enquiry timeline.
- Organise prospects, clients, notes, assignments and follow-up tasks.
- Prepare professional, versioned quotations and PDF copies.
- Manage services and optional packages from the office.
- Draft, review and publish versioned legal and public documents.
- Record important administrative and security activity.
- Apply defined data-retention and deletion procedures.
- Remain practical for cPanel hosting and a small team.

### Non-goals for the first release

- Full accounting or tax management.
- Online payments.
- Customer self-registration and client dashboards.
- Full project-management boards.
- Employee payroll or human-resource management.
- Marketing automation or bulk promotional email.
- Artificial-intelligence generation of legal documents without human review.

These may be added later only when a real operational need exists.

---

## 3. Target architecture

```mermaid
flowchart TD
    A["Visitor browser"] --> B["Public Laravel routes"]
    B --> C["Application services"]
    C --> D["MySQL database"]
    C --> E["Mail and queue"]
    C --> F["Private file storage"]
    G["ZumaX office user"] --> H["Protected /office routes"]
    H --> C
```

### Application layers

| Layer | Responsibility |
| --- | --- |
| Blade views and current assets | Public pages and responsive office interface |
| Controllers and form requests | Request validation, routing and response handling |
| Domain services | Verification, enquiry progression, quotation calculations and publication |
| Policies and middleware | Authentication, permissions, throttling and session protection |
| Models and repositories | Database persistence and relationships |
| Jobs and notifications | Email sending, PDF generation, reminders and scheduled cleanup |
| Private storage | Quote PDFs and future approved attachments |
| Scheduler | Token expiry, retention, reminders, backups and queue maintenance |

### Important architecture rules

- The public form and office must use the same business rules and database.
- Controllers should remain thin; important actions belong in dedicated services.
- Email sending must be idempotent: repeating a request must not forward the same enquiry twice.
- Published legal versions and sent quotation versions must be immutable.
- Files must not be publicly addressable by their storage path.
- SMTP, database and API secrets must remain in environment configuration, never in an editable settings screen.

---

## 4. Business workflow

### 4.1 Enquiry and verification flow

```mermaid
flowchart TD
    A["Form submitted"] --> B["Pending verification"]
    B -->|"24 hours pass"| C["Expired"]
    B -->|"Link opened"| D["Review page"]
    D -->|"Confirm button"| E["Verified enquiry"]
    E --> F["Office inbox"]
    F --> G["Contacted and qualified"]
    G --> H["Quoted, won, lost or archived"]
```

1. Validate the form, CSRF token, honeypot and rate limit.
2. Create an enquiry with `verification_status = pending`.
3. Store only a cryptographic hash of the verification token.
4. Send the client a verification link.
5. The link opens a review page but does not forward the enquiry automatically.
6. The client presses **Verify Email and Send Enquiry**.
7. A database transaction marks the token used and the enquiry verified.
8. A unique delivery key prevents a second business notification.
9. The verified enquiry appears in the office inbox and is sent to `info@zumaxenterprises.com`.
10. Reusing the link displays **Already Verified**; an expired link displays **Verification Link Expired**.

### 4.2 Separate status dimensions

One status column should not represent the entire lifecycle.

#### Verification status

- `pending`
- `verified`
- `expired`
- `failed`
- `cancelled`

#### Business pipeline status

- `new`
- `assigned`
- `contacted`
- `qualified`
- `quote_draft`
- `quote_sent`
- `won`
- `lost`
- `spam`
- `archived`

This separation prevents an enquiry from becoming logically confusing. For example, an enquiry can be both `verified` and `quote_sent`.

### 4.3 Quotation workflow

```mermaid
flowchart TD
    A["Draft quote"] --> B["Internal review"]
    B --> C["Version locked"]
    C --> D["Sent to client"]
    D --> E["Accepted, declined or expired"]
    E -->|"Changes required"| A
```

Quotation statuses:

- `draft`
- `under_review`
- `approved`
- `sent`
- `accepted`
- `declined`
- `expired`
- `superseded`
- `cancelled`

A sent quote must remain unchanged. Changes create a new version while retaining the exact earlier version.

### 4.4 Legal-document workflow

- `draft`
- `in_review`
- `approved`
- `published`
- `retired`

Only an authorised user may publish. Each enquiry should record the Privacy Policy version shown when the form was submitted.

---

## 5. Office information architecture

### 5.1 Main navigation

1. Dashboard
2. Enquiries
3. Clients
4. Follow-ups
5. Quotations
6. Services and Packages
7. Documents
8. Templates
9. Reports
10. Activity Log
11. Users and Roles
12. Settings

### 5.2 Dashboard

The first dashboard should show useful operational information rather than decorative statistics.

#### Summary cards

- New verified enquiries.
- Pending email verifications.
- Overdue follow-ups.
- Quotations awaiting a response.
- Email failures requiring attention.
- Won quotation value for the selected period.

#### Main panels

- Recent verified enquiries.
- Follow-ups due today and this week.
- Quotation pipeline.
- Recent security and administrative alerts.
- Enquiry sources and service interest.

### 5.3 Enquiry list

Required filters:

- Verification status.
- Pipeline status.
- Service.
- Assigned user.
- Submission date.
- Follow-up due date.
- Email-delivery state.
- Tag.

Required actions:

- Open details.
- Assign.
- Change pipeline status.
- Add a note.
- Create a follow-up.
- Convert to client.
- Create quotation.
- Mark spam.
- Archive.
- Export only when the user has export permission.

### 5.4 Enquiry detail

The detail screen should contain:

- Client-supplied information.
- Verification and email status.
- Current pipeline stage and assignee.
- Chronological timeline.
- Internal notes.
- Follow-up tasks.
- Related client.
- Related quotations.
- Data-retention date.
- Restricted administrative actions.

### 5.5 Quotation builder

The quotation builder should support:

- Automatic quote number.
- Client and enquiry selection.
- Reusable service/package items.
- Custom line items.
- Quantity, unit, unit price and discount.
- Configurable tax fields without assuming tax registration.
- TZS currency by default.
- Payment terms.
- Project assumptions and exclusions.
- Delivery estimate.
- Quote validity date.
- Internal notes not shown to the client.
- Preview before sending.
- Versioned PDF generation.
- Secure client acceptance link in a later milestone.

### 5.6 Documents

Initial managed documents:

- Privacy Policy.
- Terms of Service / Terms of Use.
- Quotation terms.
- Service descriptions.
- Frequently Asked Questions.

Legal documents should use plain text or a restricted rich-text editor. Arbitrary scripts, embedded frames and unsafe HTML must not be accepted.

---

## 6. Roles and permissions

Public registration must be disabled. The first production account should be created through a secure deployment command or controlled setup process.

| Capability | Owner | Administrator | Sales | Support | Content Editor | Auditor |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| View dashboard | Yes | Yes | Yes | Yes | Limited | Yes |
| View enquiries | Yes | Yes | Assigned/all | Assigned | No | Read-only |
| Edit enquiry status | Yes | Yes | Yes | Limited | No | No |
| View client contacts | Yes | Yes | Yes | Limited | No | Read-only |
| Create quotations | Yes | Yes | Yes | No | No | No |
| Approve/send quotations | Yes | Yes | Optional | No | No | No |
| Manage services/packages | Yes | Yes | Read | Read | Draft/edit | Read-only |
| Draft documents | Yes | Yes | No | No | Yes | Read-only |
| Publish legal documents | Yes | Optional | No | No | No | No |
| Export personal data | Yes | Optional | No | No | No | No |
| View activity log | Yes | Yes | Own events | Own events | Own events | Yes |
| Manage users and roles | Yes | Limited | No | No | No | No |
| Manage security settings | Yes | No | No | No | No | No |
| Permanently delete records | Yes | No | No | No | No | No |

### Role design principles

- Begin with the Owner role only, but design permissions for future staff.
- Authorisation must be enforced on the server, not only by hiding buttons.
- Sensitive exports, permanent deletion and legal publication should require password confirmation.
- The final active Owner account must not be deactivated accidentally.
- Every role and permission change must create an audit event.

---

## 7. Proposed database schema

Use Laravel migrations, foreign keys, transactions and UTC timestamps in storage. Display dates using `Africa/Dar_es_Salaam`.

ULIDs are recommended for business-facing entities because they are sortable and difficult to enumerate. Numeric IDs may still be used for small reference tables.

### 7.1 Identity and access

#### `users`

- `id` ULID primary key.
- `name`.
- `email` unique.
- `password` hash.
- `is_active`.
- `email_verified_at`.
- `last_login_at`.
- `last_login_ip_hash` nullable.
- Two-factor fields encrypted at application level.
- `remember_token`.
- Timestamps and soft-delete timestamp.

#### `roles`

- `id`.
- `key` unique, such as `owner` or `sales`.
- `name`.
- `description`.
- `is_system`.

#### `permissions`

- `id`.
- `key` unique, such as `quotes.send`.
- `description`.

#### `role_user`

- `role_id`.
- `user_id`.
- Unique composite index.

#### `permission_role`

- `permission_id`.
- `role_id`.
- Unique composite index.

### 7.2 Enquiries and verification

#### `enquiries`

- `id` ULID primary key.
- `reference` unique, human-friendly value such as `ENQ-2026-000123`.
- `client_id` nullable.
- `service_id` nullable.
- `assigned_to` nullable user ID.
- `name`.
- `email`.
- `email_hash` indexed for safe deduplication and matching.
- `phone`.
- `message` text.
- `language`, such as `en` or `sw`.
- `source`, default `website`.
- `verification_status` indexed.
- `pipeline_status` indexed.
- `submitted_at`.
- `verified_at` nullable.
- `last_activity_at` indexed.
- `privacy_document_version_id` nullable.
- `retention_review_at` nullable and indexed.
- `deleted_reason` nullable.
- Timestamps and soft-delete timestamp.

Sensitive fields may use encrypted casts where operational searching is not required. Backups containing personal information must be encrypted.

#### `enquiry_verifications`

- `id` ULID primary key.
- `enquiry_id` foreign key.
- `token_hash` unique; never store the raw token.
- `status` indexed.
- `expires_at` indexed.
- `first_opened_at` nullable.
- `verified_at` nullable.
- `used_at` nullable.
- `attempt_count` default zero.
- Timestamps.

#### `enquiry_deliveries`

- `id` ULID primary key.
- `enquiry_id` foreign key.
- `delivery_type`, such as `verification`, `business_forward` or `client_confirmation`.
- `idempotency_key` unique.
- `email_message_id` nullable.
- `completed_at` nullable.
- `failed_at` nullable.
- `failure_code` nullable.
- Timestamps.

The unique `idempotency_key` is the final database protection against duplicate forwarding.

#### `enquiry_events`

- `id` ULID primary key.
- `enquiry_id` foreign key.
- `actor_type`: `system`, `client` or `user`.
- `actor_user_id` nullable.
- `event_type` indexed.
- `from_status` nullable.
- `to_status` nullable.
- `summary`.
- `metadata` sanitised JSON nullable.
- `occurred_at` indexed.

Events are append-only. Corrections should create a new event rather than silently rewriting history.

#### `enquiry_notes`

- `id` ULID primary key.
- `enquiry_id` foreign key.
- `user_id` foreign key.
- `body` text, optionally encrypted.
- `visibility`, initially `internal` only.
- Timestamps and soft-delete timestamp.

### 7.3 Clients and contacts

#### `clients`

- `id` ULID primary key.
- `reference` unique, such as `CLI-2026-000045`.
- `type`: `individual` or `business`.
- `business_name` nullable.
- `status`: `prospect`, `active`, `inactive` or `archived`.
- `owner_user_id` nullable.
- `source_enquiry_id` nullable.
- `address` nullable.
- `city` nullable.
- `region` nullable.
- `country_code` default `TZ`.
- `retention_review_at` nullable.
- Timestamps and soft-delete timestamp.

#### `client_contacts`

- `id` ULID primary key.
- `client_id` foreign key.
- `name`.
- `email` nullable.
- `email_hash` nullable and indexed.
- `phone` nullable.
- `position` nullable.
- `is_primary`.
- Timestamps and soft-delete timestamp.

### 7.4 Follow-ups and organisation

#### `tasks`

- `id` ULID primary key.
- `taskable_type` and `taskable_id` for enquiry, client or quote.
- `assigned_to`.
- `created_by`.
- `title`.
- `description` nullable.
- `priority`: `low`, `normal`, `high` or `urgent`.
- `status`: `open`, `completed` or `cancelled`.
- `due_at` indexed.
- `completed_at` nullable.
- Timestamps.

#### `tags`

- `id`.
- `name` unique.
- `colour`.
- `description` nullable.

#### `taggables`

- `tag_id`.
- `taggable_type`.
- `taggable_id`.
- Unique composite index.

### 7.5 Services and packages

#### `services`

- `id` ULID primary key.
- `code` unique.
- `name_en` and `name_sw`.
- `summary_en` and `summary_sw`.
- `description_en` and `description_sw` nullable.
- `is_active`.
- `is_public`.
- `sort_order`.
- Timestamps and soft-delete timestamp.

#### `packages`

- `id` ULID primary key.
- `service_id` foreign key.
- `code` unique.
- `name_en` and `name_sw`.
- `summary_en` and `summary_sw`.
- `pricing_mode`: `fixed`, `starting_from` or `quote_only`.
- `base_price` nullable decimal.
- `currency` default `TZS`.
- `estimated_days_min` nullable.
- `estimated_days_max` nullable.
- `included_revisions` nullable.
- `support_days` nullable.
- `is_active`.
- `is_public`.
- `sort_order`.
- Timestamps and soft-delete timestamp.

#### `package_features`

- `id` ULID primary key.
- `package_id` foreign key.
- `feature_en` and `feature_sw`.
- `is_highlighted`.
- `sort_order`.

### 7.6 Quotations

#### `quotes`

- `id` ULID primary key.
- `quote_number` unique, such as `ZX-Q-2026-0001`.
- `client_id` foreign key.
- `enquiry_id` nullable.
- `status` indexed.
- `current_version_id` nullable.
- `created_by`.
- `assigned_to` nullable.
- `valid_until` nullable and indexed.
- `sent_at`, `accepted_at`, `declined_at` nullable.
- Timestamps and soft-delete timestamp.

#### `quote_versions`

- `id` ULID primary key.
- `quote_id` foreign key.
- `version_number`.
- `currency`.
- `subtotal`, `discount_total`, `tax_total` and `grand_total` decimals.
- `title`.
- `introduction` nullable.
- `scope` nullable.
- `assumptions` nullable.
- `exclusions` nullable.
- `payment_terms` nullable.
- `delivery_terms` nullable.
- `client_note` nullable.
- `internal_note` nullable and restricted.
- `pdf_path` nullable private path.
- `content_checksum`.
- `locked_at` nullable.
- `created_by`.
- Timestamps.
- Unique index on `quote_id` and `version_number`.

#### `quote_items`

- `id` ULID primary key.
- `quote_version_id` foreign key.
- `service_id` nullable.
- `package_id` nullable.
- `description`.
- `quantity` decimal.
- `unit` nullable.
- `unit_price` decimal.
- `discount_amount` decimal default zero.
- `tax_amount` decimal default zero.
- `line_total` decimal.
- `sort_order`.

#### `quote_events`

- `id` ULID primary key.
- `quote_id` foreign key.
- `quote_version_id` nullable.
- `actor_user_id` nullable.
- `event_type`.
- `summary`.
- `metadata` sanitised JSON nullable.
- `occurred_at`.

### 7.7 Documents and templates

#### `documents`

- `id` ULID primary key.
- `key` unique, such as `privacy-policy`.
- `title_en` and `title_sw`.
- `current_published_version_id` nullable.
- `is_public`.
- Timestamps.

#### `document_versions`

- `id` ULID primary key.
- `document_id` foreign key.
- `version_number`.
- `status` indexed.
- `content_en` long text.
- `content_sw` long text nullable.
- `change_summary`.
- `effective_at` nullable.
- `created_by`.
- `approved_by` nullable.
- `published_by` nullable.
- `published_at` nullable.
- `content_checksum`.
- Timestamps.
- Unique index on `document_id` and `version_number`.

#### `message_templates`

- `id` ULID primary key.
- `key` indexed.
- `channel`: `email`, `office` or future `sms`.
- `language`.
- `version_number`.
- `status`: `draft`, `active` or `retired`.
- `subject` nullable.
- `body`.
- `allowed_variables` JSON.
- `created_by`.
- Timestamps.
- Unique index on `key`, `language` and `version_number`.

### 7.8 Email and notifications

#### `email_messages`

- `id` ULID primary key.
- `related_type` and `related_id` nullable.
- `template_id` nullable.
- `message_type` indexed.
- `recipient_encrypted`.
- `recipient_hash` indexed.
- `subject_snapshot`.
- `body_snapshot_encrypted` or immutable template-version reference plus encrypted variables.
- `provider_message_id` nullable and indexed.
- `status`: `queued`, `accepted`, `delivered`, `bounced`, `complained` or `failed`.
- `queued_at`, `accepted_at`, `delivered_at`, `failed_at` nullable.
- `failure_code` nullable.
- `retry_count`.
- Timestamps.

`accepted` means the sending server accepted the message. `delivered` must only be used when an authenticated provider reports delivery through a trusted webhook.

#### `email_events`

- `id` ULID primary key.
- `email_message_id` foreign key.
- `provider_event_id` nullable and unique.
- `event_type` indexed.
- `metadata` sanitised JSON nullable.
- `occurred_at` indexed.

Laravel database notifications may separately power the office notification bell.

### 7.9 Audit and settings

#### `activity_logs`

- `id` ULID primary key.
- `actor_user_id` nullable.
- `action` indexed.
- `auditable_type` nullable.
- `auditable_id` nullable.
- `request_id` indexed.
- `ip_hash` nullable.
- `user_agent_summary` nullable.
- `description`.
- `changes` sanitised JSON nullable.
- `severity`: `info`, `warning` or `critical`.
- `created_at` indexed.

Do not store passwords, raw verification tokens, session IDs, API keys, SMTP credentials or unnecessary message contents in audit logs.

#### `settings`

- `key` unique.
- `value` JSON.
- `type`.
- `is_public`.
- `updated_by` nullable.
- Timestamps.

Only non-secret business settings belong here. Secrets remain in `.env` or the hosting secret configuration.

---

## 8. Critical database constraints

The following constraints are not optional:

- Unique verification token hash.
- Unique enquiry business-forward idempotency key.
- Unique quotation number.
- Unique document version number per document.
- Unique quote version number per quotation.
- Unique provider event ID where supplied.
- Foreign keys for all owned records.
- Decimal fields for money; never floating-point fields.
- Database transaction around verification confirmation and delivery reservation.
- Database transaction around quote locking and totals.
- Indexed status and date columns used by office filters and scheduled tasks.
- Soft deletion for normal office removal; controlled permanent deletion for approved retention actions.

### Verification transaction outline

1. Lock the verification record for update.
2. Validate token hash and expiry.
3. If already used, return `already_verified`.
4. Mark token used and enquiry verified.
5. Insert the unique business-forward delivery reservation.
6. Commit the transaction.
7. Queue the business-forward and confirmation emails.
8. Record success or failure without reverting the verified identity state.

This design prevents a double-click or concurrent requests from creating duplicate business enquiries.

---

## 9. Security baseline

### Authentication and sessions

- Disable public office registration.
- Require a strong password and two-factor authentication for Owner accounts.
- Apply login throttling by account and IP.
- Regenerate the session after authentication.
- Use secure, HTTP-only and SameSite cookies.
- Expire inactive office sessions.
- Require password confirmation for sensitive actions.
- Provide controlled account recovery with recovery codes.

### Authorisation

- Enforce permissions through middleware and Laravel policies.
- Apply least privilege to users and the MySQL account.
- Deny access by default.
- Test every restricted route directly, not only its visible button.
- Record denied sensitive actions without storing secrets.

### Application security

- CSRF protection on every state-changing browser request.
- Strict server-side validation and normalisation.
- Output escaping by default.
- Sanitisation for restricted rich-text content.
- Rate limits for the contact form, verification and acceptance endpoints.
- Content Security Policy and appropriate browser security headers.
- Hashed, expiring, single-use public tokens.
- Generic public errors; detailed errors only in protected logs.
- Dependency updates and production error reporting disabled.
- Separate staging and production environment values.

### Database and files

- MySQL user limited to the application database and required actions.
- No database administration interface exposed publicly by the application.
- Quote PDFs and attachments stored outside the public web root.
- Downloads served through authorised controllers.
- Encrypted backups with periodic restore testing.
- Approved file types, size limits and generated filenames for future uploads.
- Never trust a file extension or browser-provided MIME type alone.

### Audit integrity

- Capture when, where, who and what for important events.
- Make business and security events append-only to normal office users.
- Protect the audit viewer with a separate permission.
- Record access to sensitive exports and logs.
- Exclude passwords, tokens, secrets and excessive personal information.
- Use a request/correlation ID to join related events.

Security references:

- [Laravel authentication](https://laravel.com/docs/13.x/authentication)
- [Laravel authorization](https://laravel.com/docs/13.x/authorization)
- [OWASP Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)
- [OWASP Database Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Database_Security_Cheat_Sheet.html)

---

## 10. Privacy and retention

The platform will process names, email addresses, telephone numbers, project messages and administrative history. ZumaX should verify its obligations with Tanzania's Personal Data Protection Commission or a qualified Tanzanian adviser before production processing begins.

The 2023 regulations address controller/processor registration, lawful and specific processing, security, authorised access, audit trails, deletion procedures and justified storage periods.

Official reference:

- [Tanzania Personal Data Protection (Personal Data Collection and Processing) Regulations, 2023](https://pdpc.go.tz/documents/4/THE_PERSONAL_DATA_PROTECTION_PERSONAL_DATA_COLLECTION_AND_PROCESSING_REGULATIONS_2023.pdf)

### Proposed retention decisions for formal approval

| Record | Proposed handling | Final decision needed |
| --- | --- | --- |
| Unverified enquiry | Delete after 24 hours | Confirm 24-hour period |
| Verification outcome receipt | Keep minimal token hash/state for 30 days | Confirm operational need |
| Spam submission | Delete or anonymise quickly | Define review period |
| Verified inactive prospect | Review after 12 months from last activity | Confirm and justify period |
| Active client records | Retain while relationship is active | Define closure procedure |
| Quotations and contracts | Follow business, accounting and legal schedule | Obtain professional advice |
| Email snapshots | Retain only as long as the linked business record requires | Define per message type |
| Audit logs | Proposed 12–24 months based on security need | Approve documented period |
| Backups | Rolling encrypted retention, proposed 30–90 days | Confirm hosting capability |

These periods are design proposals, not legal conclusions.

### Data-subject operations

The office should eventually support controlled procedures to:

- Find a person's data.
- Correct inaccurate details.
- Export a readable copy.
- Restrict processing where appropriate.
- Delete or anonymise records when permitted.
- Record the request, decision and completion without recreating deleted content.

### Privacy-by-design rules

- Collect only information required for the enquiry.
- Do not add advertising consent to the project-enquiry agreement.
- Keep marketing permission separate and optional if introduced later.
- Store the Privacy Policy version presented at submission.
- Hash IP addresses when only abuse correlation is required.
- Avoid email-open tracking pixels by default.
- Anonymise reporting data when direct identity is unnecessary.
- Review the location and terms of any external mail, backup or analytics provider before transferring personal data outside Tanzania.

---

## 11. Email architecture

### Required message types

1. Client verification request.
2. Verified enquiry notification to `info@zumaxenterprises.com`.
3. Client confirmation.
4. Office password reset and security alert.
5. Follow-up reminder to an office user.
6. Quotation email.
7. Optional quote-expiry reminder.

### Delivery-state definitions

| State | Meaning |
| --- | --- |
| `queued` | The application created a send job |
| `accepted` | SMTP/server accepted the message for delivery |
| `delivered` | A trusted delivery webhook confirmed delivery |
| `bounced` | The receiving system rejected or returned the message |
| `complained` | A provider reported a spam complaint |
| `failed` | The application or sending service could not send it |

The application must never label a message `delivered` merely because PHP or SMTP returned success.

### Queue strategy for cPanel

- Begin with Laravel's database queue.
- Configure the scheduler through cPanel Cron every minute.
- Run short queue workers through the scheduler or an approved persistent worker when hosting supports it.
- Retry transient email failures with a maximum attempt count.
- Display failed jobs and email failures in the office dashboard.
- Never retry a business-forward job unless its idempotency reservation proves it was not completed.

References:

- [Laravel queues](https://laravel.com/docs/13.x/queues)
- [Laravel notifications](https://laravel.com/docs/13.x/notifications)

---

## 12. Reports and measurements

### First reports

- Enquiries by date.
- Enquiries by service.
- Verification completion rate.
- Pipeline conversion by stage.
- Average first-response time.
- Overdue follow-ups.
- Quotations sent, accepted, declined and expired.
- Quote value by month.
- Email failures.

### Measurement definitions

- **Verification completion rate:** verified enquiries divided by valid submitted enquiries.
- **First-response time:** first meaningful office contact timestamp minus verification timestamp.
- **Quote conversion rate:** accepted quotes divided by sent quotes.
- **Enquiry conversion rate:** won enquiries divided by verified non-spam enquiries.

Definitions must remain stable so reports do not change meaning between releases.

### Export rules

- CSV/PDF exports require explicit permission.
- Every export creates an audit event.
- Export only selected fields and records.
- Mask personal information where full values are not required.
- Do not expose database IDs or secret token hashes unnecessarily.

---

## 13. Deployment model

### Recommended directory concept

```text
/home/account/zumax-app/          Laravel application and private storage
/home/account/public_html/        Laravel public files / configured document root
```

The exact cPanel layout depends on whether the hosting account allows the main-domain document root to point to Laravel's `public` directory. If it does not, use a controlled deployment script or documented public-directory arrangement without exposing `.env`, `storage`, source code or vendor configuration.

### Required hosting capabilities

- Supported PHP version for Laravel 13.
- MySQL database and dedicated application user.
- Composer deployment locally or on the server.
- HTTPS.
- Cron jobs.
- Writable Laravel storage and cache directories.
- Authenticated SMTP.
- Backups that include both database and private files.

### Environment separation

Use separate values for:

- `APP_ENV` and `APP_DEBUG`.
- Application URL.
- Database credentials.
- SMTP credentials.
- Queue and cache configuration.
- Encryption key.
- Error-reporting integrations, if any.

Production requirements:

- `APP_ENV=production`.
- `APP_DEBUG=false`.
- HTTPS enforced.
- Configuration, routes and views cached after deployment.
- Staging database and mail recipient rules separated from production.

---

## 14. Migration from the current website

### Current state

The current package uses:

- Plain PHP pages.
- Protected JSON files under `storage/pending`.
- Minimal verified/expired receipts under `storage/status`.
- A 24-hour hashed verification token.
- Explicit confirmation before forwarding to `info@`.
- `mail()` for verification, business forwarding and confirmation.

The new platform must preserve those successful rules while replacing file persistence and unstructured operational history.

### Cutover sequence

1. Confirm hosting compatibility with Laravel, MySQL, Cron and SMTP.
2. Approve this blueprint and the privacy/retention decisions.
3. Create a private source repository and Laravel project.
4. Rebuild the existing public pages as Blade views without redesigning them.
5. Implement database migrations, seed roles and create the Owner account.
6. Implement the enquiry and verification transaction.
7. Build the minimum office inbox, timeline, notes and tasks.
8. Configure authenticated SMTP and queue processing.
9. Deploy to a new staging path or subdomain.
10. Test with external email accounts and multiple browsers.
11. Back up the existing public website and any real records.
12. Do not import staging/test enquiries by default.
13. If authorised real records exist, import them once through a reviewed command.
14. Place the old form in maintenance mode during final cutover.
15. Deploy the Laravel public directory and run production migrations.
16. Complete verification, repeat-link, expiry, email, office-role and backup tests.
17. Archive or securely delete the obsolete JSON storage after acceptance.
18. Monitor logs, email failures and form conversion closely after launch.

### Rollback requirement

Before launch, retain:

- A complete backup of the current public files.
- A database backup from immediately before migration.
- A documented restore procedure.
- A maintenance page that does not accept enquiries during rollback.

Rollback must never restore an old form that can send duplicates for enquiries already accepted by the new platform.

---

## 15. Implementation phases

### Phase 0 — Decisions and environment confirmation

- Confirm cPanel Laravel deployment method.
- Confirm PHP/MySQL versions, Composer, Cron and SMTP.
- Decide retention periods.
- Confirm PDPC registration/compliance position.
- Decide `/office` versus a future office subdomain.
- Confirm initial Owner email and secure setup process.

**Exit condition:** hosting and compliance decisions are documented.

### Phase 1 — Secure foundation

- Laravel application and environment separation.
- Database migrations.
- Owner login, password reset and two-factor authentication.
- Roles, permissions and policies.
- Audit foundation.
- Public pages migrated without visual redesign.

**Exit condition:** the Owner can securely access an otherwise empty office.

### Phase 2 — Enquiry management MVP

- Database contact form.
- Hashed verification tokens.
- Explicit verification confirmation.
- Duplicate-delivery protection.
- Enquiry inbox and detail page.
- Timeline, notes, status and assignment.
- Follow-up tasks.
- Email records and failure display.
- Automatic expiry and retention jobs.

**Exit condition:** a real enquiry can travel safely from form submission to managed office record.

### Phase 3 — Clients, services and quotations

- Client conversion and contact records.
- Services and packages.
- Quote builder and deterministic totals.
- Internal review and locked versions.
- Private PDF generation.
- Quote email and event history.

**Exit condition:** ZumaX can prepare, send and retain a professional versioned quote.

### Phase 4 — Documents and templates

- Versioned Privacy Policy and Terms.
- Draft/review/publish permissions.
- Published-version snapshots.
- Email and response templates.
- Public FAQ/service content where useful.

**Exit condition:** authorised office users can publish traceable content versions.

### Phase 5 — Reporting and operational maturity

- Conversion and response-time reports.
- Controlled exports.
- Backup monitoring and restore exercises.
- Delivery webhooks if supported.
- Security review and production hardening.

**Exit condition:** the platform is measurable, supportable and recoverable.

### Future phase candidates

- Secure quotation acceptance.
- Project records after a quote is won.
- Invoice integration with an accounting process.
- Client portal.
- Support tickets.
- Approved file attachments.
- Consent-based marketing list.
- API integration with other ZumaX systems.

Each candidate should be justified by an active business process before development.

---

## 16. Minimum viable office release

The first production administration release is complete only when it includes:

- Owner-only secure login and two-factor authentication.
- Enquiry dashboard.
- Pending, verified, expired and failed verification visibility.
- Searchable enquiry list and detail page.
- Complete event timeline.
- Notes, assignment, status and follow-up date.
- No business forwarding before confirmation.
- No duplicate forwarding after repeated confirmation.
- Automatic expired-record cleanup.
- Email failure visibility.
- Audit history for important office actions.
- Backup and tested restore procedure.
- Documented privacy and retention settings.

Quotations are the next release, not a reason to delay a secure enquiry-management MVP.

---

## 17. Acceptance tests

### Verification

- A valid submission creates one pending enquiry.
- `info@zumaxenterprises.com` receives nothing before confirmation.
- An invalid token cannot reveal enquiry details.
- An expired token displays the correct expiry message.
- A confirmation creates one verified event and one delivery reservation.
- Reusing the same link displays Already Verified.
- Repeating the final POST does not send another business message.
- Concurrent confirmation requests do not duplicate delivery.

### Office security

- Unauthenticated office requests redirect to login.
- Disabled users cannot sign in.
- Login attempts are throttled.
- Every restricted action is denied server-side for unauthorised roles.
- Two-factor authentication works and recovery codes are protected.
- Sensitive actions require password confirmation.
- Session cookies use production security attributes.

### Enquiries

- Search and every filter return correct records.
- Status changes create events.
- Assignment and follow-up changes create events.
- Notes are not visible publicly or sent in client emails.
- Spam and archived records remain distinguishable.
- Retention jobs affect only eligible records.

### Quotations

- Money calculations use decimals and match PDF totals.
- Sent versions cannot be edited.
- Revised quotes retain older versions.
- Expired quotes cannot be accepted without authorised renewal.
- Private PDFs cannot be downloaded without authorisation or a valid signed client link.

### Documents

- Drafts are not public.
- Only authorised users can publish.
- Published versions are immutable.
- Earlier Privacy Policy versions remain linked to historical submissions.
- Unsafe HTML and scripts cannot be published.

### Operations

- Failed email jobs appear in the office.
- Scheduled cleanup runs through Cron.
- Database and private files restore successfully from backup.
- Production errors do not expose stack traces or secrets.
- Logs exclude raw tokens, passwords and SMTP/database credentials.

---

## 18. Definition of done for every feature

A feature is complete only when:

- Business rules and edge cases are documented.
- Database migration and rollback are defined.
- Server-side validation is implemented.
- Authorisation policy is implemented.
- Audit events are identified.
- Automated tests cover success, rejection and duplicate requests.
- Responsive layout is tested.
- Accessibility labels and keyboard use are checked.
- Privacy and retention impact is reviewed.
- Errors are user-friendly and operationally traceable.
- Deployment and rollback instructions are updated.

---

## 19. Decisions required before coding

| Decision | Recommended answer | Approval |
| --- | --- | --- |
| Preserve current public appearance? | Yes | Pending |
| Build as one Laravel application? | Yes | Pending |
| Initial office path | `/office` | Pending |
| First office users | Owner only | Pending |
| Mandatory two-factor authentication | Yes for Owner | Pending |
| Public package prices | No; quote-based initially | Pending |
| Online payments in first release | No | Pending |
| Client accounts in first release | No | Pending |
| Initial currency | TZS | Pending |
| Quotation tax configuration | Configurable; confirm with accountant | Pending |
| Verified prospect retention | Proposed 12-month review | Pending |
| Audit-log retention | Proposed 12–24 months | Pending |
| Email method | Authenticated domain SMTP | Pending |
| Delivery webhook provider | Later if justified | Pending |
| Import existing staging enquiries | No | Pending |

---

## 20. Immediate next milestone

After approval of the decisions above, the next deliverable should be the **Phase 1 technical foundation package**, containing:

1. Laravel project structure.
2. Environment example without secrets.
3. Database migrations for users, roles, permissions and audit records.
4. Secure Owner account creation command.
5. Office authentication and two-factor flow.
6. Base office layout and navigation.
7. Public homepage converted to Blade while preserving the current appearance.
8. Automated foundation tests.
9. cPanel staging deployment instructions.

Only after that foundation passes staging acceptance should the production contact form be moved from JSON storage to the database.

---

## 21. Final recommendation

The highest-value sequence for ZumaX is:

1. **Secure office foundation.**
2. **Verified enquiry management.**
3. **Follow-ups and client conversion.**
4. **Professional quotation management.**
5. **Versioned legal and service content.**
6. **Reports and carefully justified integrations.**

This sequence creates operational value early without turning the website into an oversized system before its core business processes are dependable.
