# Legacy Resource Visibility Plan

This document records which fields should be visible in each Laravel/Filament
resource after comparing the legacy administrator pages in
`/Users/mac/Downloads/yemensnackfood/Ya@dm_n` with the migrated schema.

The conditional rules in this document are implemented in the current Filament
forms where the migrated schema contains the corresponding fields. API
resources are intentionally excluded because the API will be implemented later.

Some legacy conditions refer to columns that are not present in the migrated
tables (for example notification item links/audiences and gateway credential
columns). Those conditions remain documented here and are deferred until their
schema is migrated rather than introducing non-persisted form fields.

## Visibility rules

- **Table/list** contains the operational columns used by the old index page.
- **Create/edit** contains fields an administrator is expected to enter or
  maintain. Primary keys, timestamps, audit metadata, IP addresses, user-agent
  values, encrypted values, and derived counters are hidden.
- **View** may show immutable technical values when they help support staff,
  but sensitive values (passwords, tokens, secrets, encrypted payloads) are
  always hidden.
- Legacy `active` fields map to `is_active`; bilingual `*_arabic` and
  `*_english` fields map to a translatable JSON attribute; `sections` maps to
  `categories`; product `section_id` maps to `category_id`.
- Foreign keys are shown through localized relationship labels, not raw IDs.
- Child records are managed in relation managers or related pages instead of
  separate top-level resources where the old system treated them as part of a
  parent record.

## Resource matrix

### Administration and accounts

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Admin | `admins.php` | name, username, email, active, 2FA enabled, updated at | name, username, email, phone, active, password on create only, roles/permissions | password hash, recovery codes, remember token, IDs, timestamps except read-only updated at |
| Role | Shield role resource | name, guard, permissions count | role name and permissions | IDs and pivot metadata |
| Customer/User | `accounts-users.php` | name, username, email, phone, account type, active, verified, created at | identity/contact fields, gender, birth date, account type, active, notification preference, password on create | password hash, login tokens, IP/user-agent, internal IDs, audit fields |
| Driver | `accounts-drivers.php` | user name, phone, provider, active, availability, rating | identity/contact fields, provider, license/vehicle details, active/availability | password/token fields, coordinates/history, device payloads, IDs |
| Provider | `accounts-providers.php` | provider name, owner/contact, active, rating | identity/contact fields, business details, active, delivery settings | credentials, secret keys, internal IDs |

### Geography and configuration

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Country | `world_countries.php` | localized name, ISO2/ISO3, dial code, continent, active, publication status | names, codes, dial code, continent, flag, active, status | IDs, timestamps, imported metadata |
| City | `world_cities.php` | localized name, country, active, status | country, names, coordinates, active, status | IDs/timestamps |
| Zone | `world_city_districts.php` | localized name, city, active, status | city, names, coordinates/bounds, active, status | IDs/timestamps |
| Currency | `currencies.php` | localized name, code, symbol, active, status | names, code, symbol, decimal precision, round prices, active, status | IDs/timestamps |
| Currency exchange rate | `currency_exchange.php` | from/to currency, rate, active, effective date | currencies, rate, date range, active, status | calculated display values, IDs/timestamps |
| Delivery time | `delivery-times.php` | localized label, type, duration, active, status | label, type enum, duration/min-max, active, status | IDs/timestamps |
| Address type | `addresses-types.php` | localized name, active, status | translatable name, active, status | IDs/timestamps |
| Configuration | `configuration.php` | key, localized label, type, active | key, localized label/help, value, type, active | encrypted secrets, raw casting metadata, IDs/timestamps |

### Catalogue

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Category | `sections.php` | localized name, parent, sort order, in home, active, status | parent, translatable name/description, icon/image, sort order, in home, active, status | IDs, old image fields, visit counters, timestamps |
| Brand | `brands.php` | localized name, sort order, active, status | translatable name/description, image, sort order, active, status | visit counters, IDs/timestamps |
| Product | `products.php` | localized name, brand, category, price, quantity, in home, chosen, active, status | brand, category, translatable name/description, price, quantity/stock, image, sort order, in home, chosen, active, status | visit/order counters, IDs/timestamps |
| Product image | `images-gallary.php` | product, image thumbnail, sort order, primary, active | product, image upload, alt text, sort order, primary, active | storage internals, IDs/timestamps |
| Variant section | `products-variants-sections.php` | localized name, product/category scope, sort order, active | translatable name, product/category scope, sort order, required/multiple, active | IDs/timestamps |
| Product variant | legacy product variant controls | product, variant section, localized value, price delta, active | product, section, translatable value, SKU, price/stock adjustments, active | IDs/timestamps |
| Favorite | `favorites.php` | user, product, created at | normally no standalone create/edit; manage from user/product relation | user/product IDs may be read-only; deletion only |

### Orders, payments, and fulfilment

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Order | `orders.php` | order number, customer, provider, total, payment status, order status, created at | normally status, notes, delivery assignment, cancellation reason; do not edit financial totals | immutable totals/snapshots, internal IDs, IP/user-agent, audit fields |
| Order item | `order_details.php` | product/variant, quantity, unit price, line total | generally read-only after order creation; allow controlled quantity/status correction only | order/product IDs, price snapshots are read-only |
| Order delivery | `order_map.php` | driver, address, delivery status, scheduled time, delivered at | driver, address, delivery time, status, proof/notes | coordinates history, internal IDs/timestamps |
| Order status event | `orders.php` history | status, actor, note, occurred at | no direct create/edit; generated by workflow | actor/order IDs can be read-only; request metadata hidden |
| Order audit event | `orders.php` history | event, actor, occurred at | no direct create/edit | payload, IP, user-agent and internal IDs hidden by default |
| Payment method | `payment-ways.php` | localized name, code, active, sort order, status | translatable name/description, code, icon, fees, active, status | provider secrets and gateway credentials |
| Order payment | `orders.php` payment details | order, method, amount, status, paid at, reference | normally generated; allow status/reference reconciliation | raw gateway payload, signatures, tokens, IDs/timestamps |
| Payment method availability | payment configuration | method, country/city/zone, active | scope relationships, limits/fees, active | IDs/timestamps |

### Discounts, wallet, and loyalty

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Coupon | `coupons.php` | code, type, value, usage, start/end, active, status | code, translatable description, type, value, limits, validity, scope, active, status | redemption counters can be read-only; IDs/timestamps |
| Coupon redemption | coupon usage history | coupon, user, order, redeemed at, discount | no direct create/edit | IDs and request metadata hidden |
| Wallet entry | `accounts-users-wallet.php` | user, type, amount, balance effect, order/payment, status, created at | amount, type, status, notes only through audited adjustment action | IP, user-agent, admin/driver IDs, raw payment data, immutable balance snapshots |
| Loyalty condition | `loyalty_points_conditions.php` | localized name, trigger, points, active, status | translatable name/description, trigger, points, limits, active, status | IDs/timestamps |
| Loyalty coupon | `loyalty_points_coupons.php` | coupon, points cost, active, status | coupon, points cost, limits, active, status | IDs/timestamps |
| Loyalty entry | loyalty history | user, type, points, source, status, created at | no direct edit; controlled adjustment action | internal IDs, IP/user-agent, immutable balance snapshots |

### Ratings and feedback

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Rating question | `orders-rate-questions.php` | localized question, sort order, active, status | translatable title, image, sort order, active, status | IDs and old image fields |
| Order rating | `orders-rate.php` | order, user, driver/provider, score, comment, active, status, created at | normally read-only; moderate active/status and response | IDs, private moderation metadata |
| Rating answer | rating details | rating question, answer/score | generally read-only after submission | IDs/timestamps |
| Order evaluation | `evaluate_provider.php` | order, evaluator, target, score, comment, status | moderation status/response only | private payload, IDs/timestamps |

### Content, communication, and system operations

| Resource | Legacy page | Table/list shown | Create/edit shown | View-only or hidden |
|---|---|---|---|---|
| Content page | `content.php` | localized title, slug, active, status, updated at | translatable title/body, slug, SEO fields, active, status | rendered/cache metadata, IDs/timestamps |
| Advertisement | `ads.php` | localized title, target, placement, schedule, active, status | translatable title/body, media, target, placement, schedule, active, status | impressions/click counters, tracking payloads, IDs |
| Welcome slider | `welcome-slider.php` | localized title, image, sort order, active, status | translatable title/subtitle, image, sort order, active, status | IDs/timestamps |
| Notification | `notifications.php` | localized title, type, audience, sent/scheduled at, status | translatable title/body, type, audience, schedule, data, status | delivery attempts and provider payloads are read-only/hidden |
| Notification recipient | notification details | user, channel, read/delivered at, status | normally generated; allow read/status moderation if needed | token/provider response, IDs |
| Scheduled notification | notification scheduler | notification, schedule, status, last run | notification, schedule, enabled/status | job internals, lock metadata, IDs |
| Contact message | legacy support/contact screen | sender, subject, status, created at | status, internal reply/notes | private headers, IP/user-agent, IDs/timestamps |
| Activity log | `logs.php`, `admins-logs.php` | actor, event, subject, date | no create/edit | payload, IP, user-agent, request metadata; use activity-log plugin |

## Conditional visibility and field behavior

The legacy forms do not show every field for every record. The following rules
must be carried into Filament with `->visible()`, `->hidden()`,
`->required()`, `->disabled()`, and dependent relationship queries. A hidden
field must also be cleared or ignored when its controlling value changes.

| Resource | Condition | Show/require | Hide/disable |
|---|---|---|---|
| Admin | Create page | show and require password | hide password on edit; never show hash/recovery data |
| User | `account_type` is customer, driver, or provider | show the common identity fields; show role-specific relation managers only for the matching type | hide driver-only/provider-only fields for other account types |
| Driver/Provider | country/city/zone data exists | show country, then city filtered by country, then zones filtered by city; show only active + published options (retain current value when editing) | hide/disable child location selectors until the parent is selected |
| Driver/Provider | provider sections are available | show section assignment for providers; require it when the legacy page required a provider section | hide provider-section assignment for customers and drivers |
| User/Driver/Provider | editing an existing record | show a password-change action, not a password input | hide password input on edit; password input is create-only |
| Address | `AllowChangeOrderLocalAreas` is enabled | show country/city/zone selectors and filter each level by its parent | hide location selectors when the configuration disables changing order areas |
| Address | map/location integration is enabled | show latitude, longitude, zoom/map picker; require coordinates when map mode is enabled | hide map controls when map integration is disabled |
| Category | editing a root category | show parent selector with root categories only; prevent selecting itself | hide/disable self and descendant categories; `is_has_sub` is derived, not manually edited |
| Category/Brand/Product/Content/Advertisement/WelcomeSlider | create page | show image upload as an empty upload field | on edit, show current image preview and replacement/delete actions; do not expose legacy `image_old` fields |
| Delivery time | `parent_id` is empty (root/day) | show type, day/order, and require both localized titles | hide hourly `from_time`/`to_time` fields |
| Delivery time | `parent_id` is set (child/hour) | show `from_time` and `to_time`; localized titles may be optional as in legacy | hide root/day-only controls; inherit parent type/order where applicable |
| Product | `in_home` or `chosen_product` is enabled | show those boolean controls; expose ordering when the record participates in the home/chosen list | hide legacy visit/order counters; counters are read-only if displayed |
| Product | variants/variant sections exist | show variant relation managers after the product has been created | do not show variant controls on an unsaved product |
| Coupon | coupon type is free delivery | show delivery scope/eligibility fields | hide percentage/fixed discount amount fields |
| Coupon | coupon type is percentage or fixed discount | show and require discount amount; validate percentage range for percentage coupons | hide free-delivery-only fields |
| Coupon | edit page | show code and usage counters as read-only | disable code/type changes when redemptions exist |
| Payment method | type is bank/account-based (legacy types 2/3) | show and require account number | hide electronic API credential fields |
| Payment method | type is electronic gateway (legacy type 4) and development integration is enabled | show gateway account ID, username, and password/secret fields | hide these credentials when integration is disabled; never display stored secrets after save |
| Payment method | create vs edit | show icon upload on create; show preview and replacement on edit | hide legacy icon-old fields |
| Order | status allows assignment | show driver/provider assignment and delivery controls | disable assignment after terminal/cancelled status |
| Order | payment method/status requires payment details | show payment reference/status/reconciliation fields | hide gateway payloads, signatures, and tokens |
| Order | delivery order has an address | show address, city/zone, coordinates, and delivery fee details | hide delivery-specific fields for non-delivery orders |
| Order | status is cancelled/rejected | show cancellation reason and moderation note | hide cancellation fields for active/non-cancelled orders |
| Order | configuration enables coupons, wallet, or loyalty points | show the corresponding discount/payment/points fields | hide disabled features and do not accept their values from the form |
| Notification | type is a linked/entity notification (legacy types other than 0/2/3/4) | show and require `item_id` with a type-specific label | hide `item_id` for global/link-only notification types |
| Notification | type is link-based (legacy types 2 or 3) | show and require `item_url` | hide URL field for non-link notifications |
| Notification | city/zone audience filters are selected | show city, then zone filtered by city; include only active + published choices | hide zone until city is selected; hide both for global audience |
| Configuration | distance-based delivery fee calculation is enabled | show cost-per-kilometre and free-distance threshold | hide distance fee fields when distance calculation is disabled |
| Configuration | percentage feature is enabled | show the relevant percentage value and validate 0–100 | hide percentage inputs when the feature is disabled |
| Rating/evaluation | record is submitted | show score/comment as read-only; allow only moderation status/response | hide answer editing and immutable submission fields |
| Wallet/Loyalty/Order events | record already exists | show immutable transaction/event data and controlled adjustment actions | disable direct editing of amount, balance snapshots, actor, and timestamps |
| Activity log | all records | show read-only actor/event/subject/date list | no create/edit resource; hide raw payload, IP, user-agent, and request metadata |

### Dependent selects

The old system filters relationship options at runtime rather than merely
validating IDs. The migrated forms should therefore implement these dependencies:

1. Country → City → Zone: clear the child value when its parent changes and
   query only active + published records belonging to the selected parent.
2. Notification audience → City → Zone: only render geographic selectors for a
   geographic audience; global notifications have no location selectors.
3. Category parent: exclude the current category and its descendants while
   editing; root categories may be selected as parents.
4. Payment method type: change visible account/API fields immediately when the
   type changes and clear values belonging to the previous type.

These are visibility and validation requirements, not just cosmetic behavior;
the save action must enforce the same conditions server-side.

## Implementation sequence

1. Confirm each legacy page and its SQL columns against the source dump before
   changing a resource.
2. Apply the **table/list shown** column set to Filament tables and the
   **create/edit shown** set to forms, using one-column sections by default.
3. Keep immutable snapshots, status histories, financial totals, and audit
   events read-only and expose them through relation managers where appropriate.
4. Add policies and action-level authorization for status changes, wallet
   adjustments, refunds, and moderation actions.
5. Add focused Filament tests for the visible columns, hidden sensitive fields,
   relationship labels, and nullable fields.

## Naming decisions to review

| Legacy name | Laravel name | Reason |
|---|---|---|
| `sections` | `categories` | Matches catalogue terminology in the migrated application. |
| `section_id` | `category_id` | Keeps product relationships consistent with `Category`. |
| `active` | `is_active` | Boolean naming convention. |
| `title_arabic` / `title_english` and similar pairs | `title` (JSON) | Uses Spatie Laravel Translatable and avoids duplicate columns. |
