make the booking in many steps
Build & Deploy / Build & Push Docker Image (push) Successful in 8m27s
Test / Type Check (all packages) (push) Successful in 3m34s
Build & Deploy / Deploy to VPS (push) Successful in 2s
Test / API Unit Tests (push) Failing after 3m16s
Test / Homepage Unit Tests (push) Failing after 2m40s
Test / Storefront Unit Tests (push) Failing after 24s
Test / Admin Unit Tests (push) Failing after 22s
Test / Dashboard Unit Tests (push) Failing after 24s
Test / API Integration Tests (push) Failing after 33s
Build & Deploy / Build & Push Docker Image (push) Successful in 8m27s
Test / Type Check (all packages) (push) Successful in 3m34s
Build & Deploy / Deploy to VPS (push) Successful in 2s
Test / API Unit Tests (push) Failing after 3m16s
Test / Homepage Unit Tests (push) Failing after 2m40s
Test / Storefront Unit Tests (push) Failing after 24s
Test / Admin Unit Tests (push) Failing after 22s
Test / Dashboard Unit Tests (push) Failing after 24s
Test / API Integration Tests (push) Failing after 33s
This commit is contained in:
@@ -0,0 +1,634 @@
|
||||
# Progressive Reservation Creation: Action Plan
|
||||
|
||||
## 1. Objective
|
||||
|
||||
Replace the single long reservation form at:
|
||||
|
||||
`/dashboard/reservations/new`
|
||||
|
||||
with a progressive wizard that:
|
||||
|
||||
* Shows one focused section at a time.
|
||||
* Validates only the current section before continuing.
|
||||
* Preserves entered information when moving backward or forward.
|
||||
* Provides a final review before creating the reservation.
|
||||
* Works correctly in English, French, and Arabic.
|
||||
* Supports desktop, mobile, light mode, dark mode, LTR, and RTL.
|
||||
* Prevents duplicate submissions and handles partial API failures safely.
|
||||
|
||||
The reservation should not be created until the user confirms the final review step.
|
||||
|
||||
---
|
||||
|
||||
## 2. Problems in the Current Implementation
|
||||
|
||||
The existing page combines all responsibilities inside one component:
|
||||
|
||||
* Customer search and selection.
|
||||
* New customer creation.
|
||||
* Customer identity information.
|
||||
* Driver license information.
|
||||
* License image upload.
|
||||
* Vehicle selection.
|
||||
* Rental dates and locations.
|
||||
* Deposit and payment method.
|
||||
* Additional driver information.
|
||||
* Notes.
|
||||
* Validation.
|
||||
* Customer creation and updates.
|
||||
* Reservation submission.
|
||||
* Translated copy.
|
||||
|
||||
This creates several practical problems:
|
||||
|
||||
1. The user sees too much information at once.
|
||||
2. Validation returns one generic error instead of identifying the exact field.
|
||||
3. Adding a customer is confusing because required identity and license fields appear outside the customer creation panel.
|
||||
4. Navigation away from the page loses the entire form.
|
||||
5. Customer updates, license uploads, and reservation creation can partially succeed.
|
||||
6. The component will become increasingly difficult to maintain.
|
||||
7. Vehicle availability is currently based only on `status === 'AVAILABLE'`, not the selected rental dates. That does not reliably prevent conflicting reservations.
|
||||
|
||||
---
|
||||
|
||||
## 3. Proposed Wizard Structure
|
||||
|
||||
Use six fixed steps. Six is the upper reasonable limit here. More steps would create needless clicking; fewer would leave several sections overloaded.
|
||||
|
||||
### Step 1: Customer
|
||||
|
||||
Purpose: Identify who is making the reservation.
|
||||
|
||||
Fields and actions:
|
||||
|
||||
* Choose `Existing customer` or `New customer`.
|
||||
* Search existing customers.
|
||||
* Select an existing customer.
|
||||
* For a new customer:
|
||||
|
||||
* First name.
|
||||
* Arabic first name.
|
||||
* Last name.
|
||||
* Arabic last name.
|
||||
* Email.
|
||||
* Phone.
|
||||
|
||||
Completion requirements:
|
||||
|
||||
* Existing customer mode: a customer must be selected.
|
||||
* New customer mode: first name, last name, email, and phone must be valid.
|
||||
|
||||
Important behavior:
|
||||
|
||||
* Selecting an existing customer preloads known identity and license data.
|
||||
* Creating a new customer should not call the API at this step.
|
||||
* Switching between existing and new customer modes must not silently mix the two records.
|
||||
* Changing the selected customer after editing loaded data should display a confirmation before replacing those edits.
|
||||
|
||||
### Step 2: Identity
|
||||
|
||||
Purpose: Verify the renter’s personal information.
|
||||
|
||||
Fields:
|
||||
|
||||
* Date of birth.
|
||||
* Nationality.
|
||||
* CIN or passport number.
|
||||
* Full address.
|
||||
* International permit number, optional.
|
||||
|
||||
Completion requirements:
|
||||
|
||||
* Date of birth is present and in the past.
|
||||
* Nationality is present.
|
||||
* Identity document number is present.
|
||||
* Full address is present.
|
||||
|
||||
The section should display whether values were loaded from an existing customer and allow the user to correct them.
|
||||
|
||||
### Step 3: Driver License
|
||||
|
||||
Purpose: Verify that the primary renter is legally eligible to drive.
|
||||
|
||||
Fields:
|
||||
|
||||
* Driver license number.
|
||||
* License country.
|
||||
* License issue date.
|
||||
* License expiry date.
|
||||
* License category.
|
||||
* License image, optional unless business rules later require it.
|
||||
|
||||
Completion requirements:
|
||||
|
||||
* Required license fields are complete.
|
||||
* Issue date is not in the future.
|
||||
* Expiry date is after the issue date.
|
||||
* Expiry date has not already passed.
|
||||
* Uploaded file is a supported image type and within the configured size limit.
|
||||
|
||||
The current image and newly selected preview should be clearly distinguished.
|
||||
|
||||
### Step 4: Rental Details
|
||||
|
||||
Purpose: Define what is being rented and when.
|
||||
|
||||
Recommended field order:
|
||||
|
||||
1. Start date and time.
|
||||
2. End date and time.
|
||||
3. Vehicle.
|
||||
4. Pickup location.
|
||||
5. Return location.
|
||||
|
||||
Completion requirements:
|
||||
|
||||
* Start date is valid.
|
||||
* End date is later than the start date.
|
||||
* A vehicle is selected.
|
||||
* The vehicle remains available for the chosen period.
|
||||
|
||||
Important correction:
|
||||
|
||||
The current implementation lists vehicles using only their general `AVAILABLE` status. The final implementation should request or revalidate date-based availability. A vehicle can be marked available now while already reserved for the requested dates.
|
||||
|
||||
If the API does not currently support date-based availability, this must be recorded as a backend dependency rather than pretending the status filter is sufficient.
|
||||
|
||||
### Step 5: Payment and Extras
|
||||
|
||||
Purpose: Collect optional and commercial details.
|
||||
|
||||
Main fields:
|
||||
|
||||
* Deposit amount.
|
||||
* Payment method.
|
||||
* Notes.
|
||||
|
||||
Optional additional driver:
|
||||
|
||||
* Display a compact `Add another driver` control.
|
||||
* Opening it reveals an additional-driver panel or nested form.
|
||||
* Allow removal before submission.
|
||||
* Structure the state as an array even if the current interface initially supports only one driver.
|
||||
|
||||
Additional-driver fields:
|
||||
|
||||
* First and last name.
|
||||
* Arabic first and last name.
|
||||
* Email, optional.
|
||||
* Phone, optional.
|
||||
* Date of birth, optional.
|
||||
* Nationality, optional.
|
||||
* License number.
|
||||
* License issue date, optional.
|
||||
* License expiry date, optional.
|
||||
|
||||
Completion requirements:
|
||||
|
||||
* Deposit cannot be negative.
|
||||
* A payment method must be selected.
|
||||
* If an additional driver is enabled, name and license number are required.
|
||||
* Any entered additional-driver dates must be logically valid.
|
||||
|
||||
### Step 6: Review and Confirm
|
||||
|
||||
Purpose: Prevent avoidable mistakes before committing data.
|
||||
|
||||
Display concise summaries for:
|
||||
|
||||
* Customer.
|
||||
* Identity.
|
||||
* Primary driver license.
|
||||
* Vehicle.
|
||||
* Rental period.
|
||||
* Pickup and return locations.
|
||||
* Payment.
|
||||
* Additional drivers.
|
||||
* Notes.
|
||||
|
||||
Each summary section should include an `Edit` action that returns directly to the relevant step.
|
||||
|
||||
Final actions:
|
||||
|
||||
* Back.
|
||||
* Cancel.
|
||||
* Create reservation.
|
||||
|
||||
The final button must display a loading state and remain disabled after the first click until the request succeeds or fails.
|
||||
|
||||
---
|
||||
|
||||
## 4. Navigation and Progress Behavior
|
||||
|
||||
### Desktop
|
||||
|
||||
Use a horizontal stepper containing:
|
||||
|
||||
* Step number.
|
||||
* Short step label.
|
||||
* Completed state.
|
||||
* Current state.
|
||||
* Future state.
|
||||
|
||||
### Mobile
|
||||
|
||||
Use a compact header:
|
||||
|
||||
`Step 3 of 6 · Driver license`
|
||||
|
||||
Include a progress bar rather than compressing all six labels into unusable decorative confetti.
|
||||
|
||||
### Navigation rules
|
||||
|
||||
* `Continue` validates the current step.
|
||||
* `Back` never discards information.
|
||||
* Completed steps may be revisited.
|
||||
* Future incomplete steps cannot be opened directly.
|
||||
* The final review step is available only after all previous steps are valid.
|
||||
* Pressing Enter must not accidentally submit the final reservation from an earlier step.
|
||||
* The footer containing Back and Continue should remain visible on long steps where practical.
|
||||
|
||||
---
|
||||
|
||||
## 5. Validation Strategy
|
||||
|
||||
Replace the current generic `Please fill all required fields` behavior with step-specific validation.
|
||||
|
||||
Use Zod, which is already installed, to create separate schemas:
|
||||
|
||||
* `customerStepSchema`
|
||||
* `identityStepSchema`
|
||||
* `licenseStepSchema`
|
||||
* `rentalStepSchema`
|
||||
* `paymentExtrasStepSchema`
|
||||
* `completeReservationSchema`
|
||||
|
||||
Validation behavior:
|
||||
|
||||
* Validate on Continue.
|
||||
* Show the message beside the invalid field.
|
||||
* Focus the first invalid field.
|
||||
* Clear an error once the value becomes valid.
|
||||
* Run complete validation again before final submission.
|
||||
* Translate validation messages into English, French, and Arabic.
|
||||
|
||||
Do not depend on disabled buttons alone. A disabled button gives the user no useful explanation and is a remarkably efficient way to make software feel broken.
|
||||
|
||||
---
|
||||
|
||||
## 6. State Management Refactor
|
||||
|
||||
Replace the large collection of independent `useState` calls with one structured draft state managed by `useReducer`.
|
||||
|
||||
Suggested shape:
|
||||
|
||||
```ts
|
||||
type ReservationDraft = {
|
||||
customer: {
|
||||
mode: 'existing' | 'new'
|
||||
selectedCustomerId: string | null
|
||||
firstName: BilingualField
|
||||
lastName: BilingualField
|
||||
email: string
|
||||
phone: string
|
||||
}
|
||||
identity: {
|
||||
dateOfBirth: string
|
||||
nationality: string
|
||||
fullAddress: string
|
||||
identityDocumentNumber: string
|
||||
internationalLicenseNumber: string
|
||||
}
|
||||
license: {
|
||||
number: string
|
||||
country: string
|
||||
issuedAt: string
|
||||
expiry: string
|
||||
category: string
|
||||
existingImageUrl: string | null
|
||||
newImageFile: File | null
|
||||
}
|
||||
rental: {
|
||||
vehicleId: string
|
||||
startDate: string
|
||||
endDate: string
|
||||
pickupLocation: string
|
||||
returnLocation: string
|
||||
}
|
||||
payment: {
|
||||
depositAmount: string
|
||||
paymentMode: string
|
||||
notes: string
|
||||
}
|
||||
additionalDrivers: AdditionalDriverDraft[]
|
||||
}
|
||||
```
|
||||
|
||||
The reducer should support explicit actions such as:
|
||||
|
||||
* Select existing customer.
|
||||
* Start new customer.
|
||||
* Update step field.
|
||||
* Add additional driver.
|
||||
* Remove additional driver.
|
||||
* Hydrate customer information.
|
||||
* Clear customer information.
|
||||
* Store a newly created customer ID after partial submission.
|
||||
* Reset the entire draft.
|
||||
|
||||
This makes state transitions testable and prevents unrelated fields from being scattered throughout the page.
|
||||
|
||||
---
|
||||
|
||||
## 7. Component Structure
|
||||
|
||||
Reduce `page.tsx` to a data-loading and route-level shell.
|
||||
|
||||
Suggested structure:
|
||||
|
||||
```text
|
||||
src/components/reservations/new/
|
||||
├── ReservationWizard.tsx
|
||||
├── ReservationStepper.tsx
|
||||
├── ReservationWizardActions.tsx
|
||||
├── ReservationReview.tsx
|
||||
├── reservationWizard.types.ts
|
||||
├── reservationWizard.reducer.ts
|
||||
├── reservationWizard.schemas.ts
|
||||
├── reservationWizard.copy.ts
|
||||
├── reservationWizard.submit.ts
|
||||
├── steps/
|
||||
│ ├── CustomerStep.tsx
|
||||
│ ├── IdentityStep.tsx
|
||||
│ ├── LicenseStep.tsx
|
||||
│ ├── RentalDetailsStep.tsx
|
||||
│ ├── PaymentExtrasStep.tsx
|
||||
│ └── ReviewStep.tsx
|
||||
└── __tests__/
|
||||
```
|
||||
|
||||
Responsibilities:
|
||||
|
||||
* `page.tsx`: load customers and vehicles, render the wizard.
|
||||
* `ReservationWizard`: control current step and draft state.
|
||||
* Step components: render fields only.
|
||||
* Schemas: validation only.
|
||||
* Reducer: state transitions only.
|
||||
* Submission module: API orchestration only.
|
||||
* Copy file: typed English, French, and Arabic labels.
|
||||
* Review component: display formatted summaries only.
|
||||
|
||||
---
|
||||
|
||||
## 8. API Submission Strategy
|
||||
|
||||
No customer or reservation records should be created merely because the user moved to another step.
|
||||
|
||||
On final confirmation:
|
||||
|
||||
1. Validate the complete draft.
|
||||
2. Revalidate vehicle availability.
|
||||
3. For a new customer:
|
||||
|
||||
* Create the customer using the accumulated customer, identity, and license fields.
|
||||
4. For an existing customer:
|
||||
|
||||
* Patch only changed customer fields.
|
||||
5. Upload the license image when a new image was selected.
|
||||
6. Create the reservation.
|
||||
7. Redirect to the new reservation details page.
|
||||
|
||||
### Partial-failure handling
|
||||
|
||||
The current operations are not atomic. For example, customer creation may succeed while reservation creation fails.
|
||||
|
||||
The wizard must therefore:
|
||||
|
||||
* Remember the newly created customer ID in memory.
|
||||
* Retry using that customer instead of creating another duplicate.
|
||||
* Show which operation failed.
|
||||
* Keep all form data available for correction or retry.
|
||||
* Never redirect until reservation creation succeeds.
|
||||
|
||||
### Recommended backend improvement
|
||||
|
||||
The strongest solution is a dedicated backend operation that creates or updates the customer, uploads document metadata, validates vehicle availability, and creates the reservation as one controlled workflow.
|
||||
|
||||
Without such an endpoint, the frontend can handle retries carefully, but it cannot provide a true database transaction across the current independent requests.
|
||||
|
||||
---
|
||||
|
||||
## 9. Data Loading and Customer Hydration
|
||||
|
||||
Current customer and vehicle loading should be extracted from the form component.
|
||||
|
||||
Required behavior:
|
||||
|
||||
* Show a proper loading state for the wizard shell.
|
||||
* Show separate customer-load and vehicle-load errors where possible.
|
||||
* Do not overwrite user-edited customer data when background data refreshes.
|
||||
* Hydrate fields only when the selected customer actually changes.
|
||||
* Cancel or ignore stale requests when the component unmounts.
|
||||
* Avoid loading arbitrary large lists indefinitely as the database grows.
|
||||
|
||||
Future improvement:
|
||||
|
||||
Replace `pageSize=100` customer loading with server-side customer search. Loading the first 100 customers and searching them in the browser will eventually fail as a business grows, which is traditionally when software chooses to reveal its assumptions.
|
||||
|
||||
---
|
||||
|
||||
## 10. Draft-Loss Protection
|
||||
|
||||
For the first implementation:
|
||||
|
||||
* Keep all information when navigating between wizard steps.
|
||||
* Warn before leaving the page when unsaved changes exist.
|
||||
* Do not persist license images in browser storage.
|
||||
* Clear the draft after successful creation.
|
||||
* Clear object URLs used for image previews.
|
||||
|
||||
Do not automatically store sensitive customer identity and license information in long-lived local storage.
|
||||
|
||||
A server-side draft feature can be designed separately if staff need to resume reservations across devices or sessions.
|
||||
|
||||
---
|
||||
|
||||
## 11. Accessibility and Localization
|
||||
|
||||
The wizard must preserve the application’s existing multilingual requirements.
|
||||
|
||||
Requirements:
|
||||
|
||||
* English and French use LTR.
|
||||
* Arabic uses true RTL.
|
||||
* Step order and navigation layout adapt correctly in RTL.
|
||||
* Every field has an associated label.
|
||||
* Required fields are announced to assistive technology.
|
||||
* Errors use `aria-describedby`.
|
||||
* The active step uses `aria-current="step"`.
|
||||
* Focus moves to the step heading after navigation.
|
||||
* Keyboard users can operate all controls.
|
||||
* Color is not the only indicator of progress or error.
|
||||
* Buttons and inputs remain usable in dark mode.
|
||||
* Dates and amounts are presented using the active locale on the review screen.
|
||||
|
||||
The current hardcoded English license-image alt text must also be localized.
|
||||
|
||||
---
|
||||
|
||||
## 12. Testing Plan
|
||||
|
||||
### Unit tests
|
||||
|
||||
Test:
|
||||
|
||||
* Reducer actions.
|
||||
* Step validation schemas.
|
||||
* Date relationships.
|
||||
* Deposit normalization.
|
||||
* Existing customer hydration.
|
||||
* Switching customer modes.
|
||||
* Additional-driver add and remove behavior.
|
||||
* Final payload construction.
|
||||
|
||||
### Component tests
|
||||
|
||||
Test:
|
||||
|
||||
* Only the active step is displayed.
|
||||
* Continue blocks invalid data.
|
||||
* Back preserves data.
|
||||
* Completed steps can be revisited.
|
||||
* Existing customer details are prefilled.
|
||||
* New customer information remains in draft state.
|
||||
* Additional-driver fields appear conditionally.
|
||||
* Edit actions on the review page open the correct step.
|
||||
* Arabic step layout uses RTL correctly.
|
||||
|
||||
### Submission tests
|
||||
|
||||
Test:
|
||||
|
||||
* Existing customer reservation.
|
||||
* New customer reservation.
|
||||
* License image upload.
|
||||
* Customer update failure.
|
||||
* Image upload failure.
|
||||
* Reservation creation failure after customer creation.
|
||||
* Retry without duplicate customer creation.
|
||||
* Double-click prevention.
|
||||
* Vehicle availability conflict.
|
||||
|
||||
### Required verification
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
npm run type-check
|
||||
npm run test
|
||||
npm run build
|
||||
```
|
||||
|
||||
for the dashboard workspace after implementation.
|
||||
|
||||
---
|
||||
|
||||
## 13. Implementation Sequence
|
||||
|
||||
### Phase 1: Extract and stabilize
|
||||
|
||||
* Create typed draft models.
|
||||
* Extract copy, validation, and payload-building logic.
|
||||
* Add tests around current behavior.
|
||||
* Do not change the visible interface yet.
|
||||
|
||||
### Phase 2: Build the wizard shell
|
||||
|
||||
* Add stepper.
|
||||
* Add reducer.
|
||||
* Add navigation.
|
||||
* Add shared action footer.
|
||||
* Render one step at a time.
|
||||
|
||||
### Phase 3: Move form sections
|
||||
|
||||
* Move customer fields.
|
||||
* Move identity fields.
|
||||
* Move license fields.
|
||||
* Move rental fields.
|
||||
* Move payment and optional driver fields.
|
||||
* Build the review screen.
|
||||
|
||||
### Phase 4: Correct submission behavior
|
||||
|
||||
* Delay new-customer creation until final confirmation.
|
||||
* Add partial-failure recovery.
|
||||
* Prevent duplicate requests.
|
||||
* Revalidate vehicle availability.
|
||||
* Preserve the draft after recoverable errors.
|
||||
|
||||
### Phase 5: Accessibility and responsive refinement
|
||||
|
||||
* Add keyboard and screen-reader behavior.
|
||||
* Verify mobile presentation.
|
||||
* Verify dark mode.
|
||||
* Verify Arabic RTL.
|
||||
* Verify translated error messages.
|
||||
|
||||
### Phase 6: Testing and regression review
|
||||
|
||||
* Complete unit and component tests.
|
||||
* Run type-check, tests, and production build.
|
||||
* Verify both existing-customer and new-customer flows manually.
|
||||
* Confirm redirect to the created reservation.
|
||||
|
||||
---
|
||||
|
||||
## 14. Acceptance Criteria
|
||||
|
||||
The work is complete only when:
|
||||
|
||||
* Exactly one focused step is displayed at a time.
|
||||
* The user can see their current position and progress.
|
||||
* Invalid current-step fields prevent progression and explain why.
|
||||
* Going backward does not lose information.
|
||||
* New customers are not created before final confirmation.
|
||||
* Existing-customer data is loaded without repeatedly overwriting edits.
|
||||
* Additional drivers remain optional.
|
||||
* The final review contains all reservation information.
|
||||
* Every review section can be edited.
|
||||
* Duplicate reservations cannot be created by repeated clicks.
|
||||
* Partial API failures do not force the user to restart.
|
||||
* Vehicle availability is revalidated for the selected dates.
|
||||
* English, French, and Arabic are complete.
|
||||
* Arabic layout is true RTL.
|
||||
* Mobile, desktop, light mode, and dark mode work.
|
||||
* Type-check, tests, and production build pass.
|
||||
|
||||
---
|
||||
|
||||
## 15. Scope Boundaries
|
||||
|
||||
Included:
|
||||
|
||||
* Progressive reservation wizard.
|
||||
* Refactoring of the current new-reservation page.
|
||||
* Step validation.
|
||||
* Review screen.
|
||||
* Existing and new customer flows.
|
||||
* License image handling.
|
||||
* Additional-driver handling.
|
||||
* API failure recovery.
|
||||
* Responsive, multilingual, and accessible behavior.
|
||||
* Relevant tests.
|
||||
|
||||
Not included unless separately approved:
|
||||
|
||||
* Redesigning the reservation details page.
|
||||
* Server-side saved drafts.
|
||||
* OCR extraction from driver licenses.
|
||||
* Multiple primary renters.
|
||||
* Payment processing.
|
||||
* Contract generation.
|
||||
* Changing unrelated dashboard pages.
|
||||
* Broad customer-management redesign.
|
||||
@@ -0,0 +1,775 @@
|
||||
# RentalDriveGo Dashboard Menu and Subscription Entitlements Plan
|
||||
|
||||
## Document status
|
||||
|
||||
- **Purpose:** Implementation plan only
|
||||
- **Source code changes:** None
|
||||
- **Target applications:** Dashboard, Admin, API, Database, Shared i18n package
|
||||
- **Primary objective:** Make the initial dashboard sidebar match the approved seven-item menu while allowing platform administrators to control advanced modules by subscription plan.
|
||||
- **Localization objective:** Provide one consistent terminology system for English (`en`), French (`fr`), and Arabic (`ar`), including true RTL behavior for Arabic.
|
||||
|
||||
---
|
||||
|
||||
## 1. Approved baseline sidebar
|
||||
|
||||
The default owner sidebar must contain exactly these items, in this order:
|
||||
|
||||
| Order | Menu item | System key | Route |
|
||||
|---:|---|---|---|
|
||||
| 10 | Dashboard | `dashboard` | `/` |
|
||||
| 20 | Reservations | `reservations` | `/reservations` |
|
||||
| 30 | Fleet | `fleet` | `/fleet` |
|
||||
| 40 | Customers | `customers` | `/customers` |
|
||||
| 50 | Reports | `reports` | `/reports` |
|
||||
| 60 | Billing | `billing` | `/billing` |
|
||||
| 70 | Settings | `settings` | `/settings` |
|
||||
|
||||
The existing sidebar styling, layout, branding, theme controls, language controls, responsive behavior, and RTL behavior must remain unchanged.
|
||||
|
||||
---
|
||||
|
||||
## 2. Advanced subscription modules
|
||||
|
||||
The following existing modules will remain available as configurable advanced features:
|
||||
|
||||
- Online Reservations
|
||||
- Offers
|
||||
- Team
|
||||
- Contracts
|
||||
- Notifications
|
||||
- Reviews
|
||||
- Complaints
|
||||
|
||||
Initial entitlement proposal:
|
||||
|
||||
| Module | STARTER | GROWTH | PRO |
|
||||
|---|:---:|:---:|:---:|
|
||||
| Dashboard | Yes | Yes | Yes |
|
||||
| Reservations | Yes | Yes | Yes |
|
||||
| Fleet | Yes | Yes | Yes |
|
||||
| Customers | Yes | Yes | Yes |
|
||||
| Reports | Yes | Yes | Yes |
|
||||
| Billing | Yes | Yes | Yes |
|
||||
| Settings | Yes | Yes | Yes |
|
||||
| Online Reservations | No | Yes | Yes |
|
||||
| Offers | No | Yes | Yes |
|
||||
| Team | No | Yes | Yes |
|
||||
| Contracts | No | Yes | Yes |
|
||||
| Notifications | No | Yes | Yes |
|
||||
| Reviews | No | No | Yes |
|
||||
| Complaints | No | No | Yes |
|
||||
|
||||
The platform administrator may later change the advanced-module assignments. Core baseline modules remain protected.
|
||||
|
||||
---
|
||||
|
||||
## 3. Multilingual terminology and translation contract
|
||||
|
||||
All menu items must use immutable system keys and shared translation keys. Application logic must never depend on translated labels.
|
||||
|
||||
### 3.1 Approved menu terminology
|
||||
|
||||
| System key | Translation key | English (`en`) | French (`fr`) | Arabic (`ar`) |
|
||||
|---|---|---|---|---|
|
||||
| `dashboard` | `navigation.dashboard` | Dashboard | Tableau de bord | لوحة التحكم |
|
||||
| `reservations` | `navigation.reservations` | Reservations | Réservations | الحجوزات |
|
||||
| `fleet` | `navigation.fleet` | Fleet | Flotte | الأسطول |
|
||||
| `customers` | `navigation.customers` | Customers | Clients | العملاء |
|
||||
| `reports` | `navigation.reports` | Reports | Rapports | التقارير |
|
||||
| `billing` | `navigation.billing` | Billing | Facturation | الفوترة |
|
||||
| `settings` | `navigation.settings` | Settings | Paramètres | الإعدادات |
|
||||
| `online-reservations` | `navigation.onlineReservations` | Online Reservations | Réservations en ligne | الحجوزات عبر الإنترنت |
|
||||
| `offers` | `navigation.offers` | Offers | Offres | العروض |
|
||||
| `team` | `navigation.team` | Team | Équipe | الفريق |
|
||||
| `contracts` | `navigation.contracts` | Contracts | Contrats | العقود |
|
||||
| `notifications` | `navigation.notifications` | Notifications | Notifications | الإشعارات |
|
||||
| `reviews` | `navigation.reviews` | Reviews | Avis | التقييمات |
|
||||
| `complaints` | `navigation.complaints` | Complaints | Réclamations | الشكاوى |
|
||||
|
||||
These translations are the approved product glossary. Core labels are protected and must not be edited casually from the Admin application.
|
||||
|
||||
### 3.2 Shared localization architecture
|
||||
|
||||
Recommended structure:
|
||||
|
||||
```text
|
||||
packages/i18n/
|
||||
├── locales/
|
||||
│ ├── en.json
|
||||
│ ├── fr.json
|
||||
│ └── ar.json
|
||||
├── glossary.ts
|
||||
├── validation.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Dashboard, Admin, and any future storefront or mobile application must consume the same translation package. Independent translation copies are prohibited because they create terminology drift.
|
||||
|
||||
Example menu definition:
|
||||
|
||||
```ts
|
||||
{
|
||||
systemKey: "reservations",
|
||||
labelKey: "navigation.reservations",
|
||||
route: "/reservations"
|
||||
}
|
||||
```
|
||||
|
||||
The database and API may store `systemKey` and `labelKey`. They must not use translated text as an identifier.
|
||||
|
||||
### 3.3 Translation publishing rules
|
||||
|
||||
- Core menu translations are locked.
|
||||
- Custom modules require English, French, and Arabic labels before publishing.
|
||||
- A label override must provide all three languages.
|
||||
- Empty translations are rejected.
|
||||
- Unknown or obsolete translation keys are rejected.
|
||||
- Translation variables must match across all languages.
|
||||
- Administrators may configure plan access, roles, order, status, and icons without modifying protected terminology.
|
||||
- Only `SUPER_ADMIN` may approve changes to the shared product glossary.
|
||||
|
||||
### 3.4 Fallback behavior
|
||||
|
||||
The application fallback order is:
|
||||
|
||||
```text
|
||||
Requested locale
|
||||
→ English fallback in local development only
|
||||
→ Validation or build failure before production deployment
|
||||
```
|
||||
|
||||
Production must not silently display English labels inside French or Arabic interfaces.
|
||||
|
||||
### 3.5 Arabic RTL requirements
|
||||
|
||||
When Arabic is selected:
|
||||
|
||||
```html
|
||||
<html lang="ar" dir="rtl">
|
||||
```
|
||||
|
||||
When English or French is selected:
|
||||
|
||||
```html
|
||||
<html lang="en" dir="ltr">
|
||||
<html lang="fr" dir="ltr">
|
||||
```
|
||||
|
||||
Arabic verification must include:
|
||||
|
||||
- Sidebar alignment
|
||||
- Menu indentation
|
||||
- Chevron direction
|
||||
- Breadcrumb order
|
||||
- Form and modal layout
|
||||
- Text alignment
|
||||
- Number formatting
|
||||
- Date formatting
|
||||
- Currency formatting
|
||||
- Mobile navigation behavior
|
||||
|
||||
Only directional icons should be mirrored. Neutral icons such as Settings, Billing, Fleet, and Reports must keep their original orientation.
|
||||
|
||||
### 3.6 Locale-aware formatting
|
||||
|
||||
Dates, numbers, percentages, and currencies must use locale-aware formatting rather than translated strings.
|
||||
|
||||
```ts
|
||||
new Intl.DateTimeFormat(locale).format(date);
|
||||
|
||||
new Intl.NumberFormat(locale, {
|
||||
style: "currency",
|
||||
currency: "MAD",
|
||||
}).format(amount);
|
||||
```
|
||||
|
||||
Stored values remain locale-independent.
|
||||
|
||||
---
|
||||
|
||||
## 4. Authorization rule
|
||||
|
||||
A module is available only when all required conditions are true:
|
||||
|
||||
```text
|
||||
Module is globally enabled
|
||||
AND module is included in the company's subscription plan
|
||||
AND the company has not disabled the module
|
||||
AND the employee role is allowed to use the module
|
||||
AND the subscription status permits access
|
||||
```
|
||||
|
||||
Company-level settings may disable or reorder entitled modules. They must not unlock a module outside the active subscription plan.
|
||||
|
||||
Sidebar visibility alone is not authorization. The API and direct routes must enforce the same entitlement rules.
|
||||
|
||||
---
|
||||
|
||||
## 5. Role behavior
|
||||
|
||||
Subscription access and employee-role access remain separate.
|
||||
|
||||
Recommended baseline policy:
|
||||
|
||||
| Module | OWNER | MANAGER | AGENT |
|
||||
|---|:---:|:---:|:---:|
|
||||
| Dashboard | Yes | Yes | Yes |
|
||||
| Reservations | Yes | Yes | Yes |
|
||||
| Fleet | Yes | Yes | Yes |
|
||||
| Customers | Yes | Yes | Yes |
|
||||
| Reports | Yes | Yes | Optional |
|
||||
| Billing | Yes | Optional | No |
|
||||
| Settings | Yes | Optional | No |
|
||||
|
||||
The final role matrix must be approved before implementation. The screenshot represents the owner-level default menu, not automatic access for every employee.
|
||||
|
||||
---
|
||||
|
||||
## 6. Subscription-status behavior
|
||||
|
||||
| Subscription status | Menu behavior |
|
||||
|---|---|
|
||||
| `ACTIVE` | Full entitled menu |
|
||||
| `TRIALING` | Full entitled menu |
|
||||
| `PAST_DUE` | Configurable restricted or read-only behavior |
|
||||
| `SUSPENDED` | Recovery menu only |
|
||||
| `EXPIRED` | Recovery menu only |
|
||||
| `CANCELLED` | Recovery menu only |
|
||||
| Missing subscription | Onboarding or recovery menu only |
|
||||
|
||||
Recommended recovery menu:
|
||||
|
||||
- Dashboard
|
||||
- Billing
|
||||
- Settings
|
||||
|
||||
This keeps account recovery possible without exposing paid operational modules.
|
||||
|
||||
---
|
||||
|
||||
## 7. Data model
|
||||
|
||||
### 7.1 Menu module catalog
|
||||
|
||||
Each module should define:
|
||||
|
||||
```text
|
||||
id
|
||||
systemKey
|
||||
defaultLabel
|
||||
localizedLabels
|
||||
routeOrUrl
|
||||
icon
|
||||
defaultOrder
|
||||
parentId
|
||||
minimumRole or allowedRoles
|
||||
isRequired
|
||||
isGloballyEnabled
|
||||
createdAt
|
||||
updatedAt
|
||||
```
|
||||
|
||||
### 7.2 Subscription-plan entitlement
|
||||
|
||||
```text
|
||||
plan
|
||||
menuItemId
|
||||
enabled
|
||||
displayOrder
|
||||
```
|
||||
|
||||
### 7.3 Company override
|
||||
|
||||
```text
|
||||
companyId
|
||||
menuItemId
|
||||
enabled
|
||||
displayOrder
|
||||
optionalLabelOverride
|
||||
optionalIconOverride
|
||||
```
|
||||
|
||||
### 7.4 Audit record
|
||||
|
||||
```text
|
||||
actorId
|
||||
action
|
||||
targetType
|
||||
targetId
|
||||
before
|
||||
after
|
||||
reason
|
||||
createdAt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Implementation phases
|
||||
|
||||
## Phase 1: Confirm the menu contract
|
||||
|
||||
### Work
|
||||
|
||||
- Approve the seven baseline items.
|
||||
- Approve the initial advanced-module plan matrix.
|
||||
- Approve the employee-role matrix.
|
||||
- Define protected system fields.
|
||||
- Define subscription-status behavior.
|
||||
- Confirm whether companies may customize labels and icons.
|
||||
- Approve the English, French, and Arabic terminology glossary.
|
||||
- Confirm which translation fields are protected.
|
||||
|
||||
### Deliverable
|
||||
|
||||
A frozen entitlement matrix and protected-module contract.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- No unresolved module ownership questions.
|
||||
- No unresolved role-access questions.
|
||||
- No unresolved downgrade behavior.
|
||||
- No unresolved translation or RTL terminology decisions.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Database migration and seed
|
||||
|
||||
### Work
|
||||
|
||||
- Create or update the menu catalog.
|
||||
- Seed the seven baseline modules.
|
||||
- Assign the baseline modules explicitly to `STARTER`, `GROWTH`, and `PRO`.
|
||||
- Seed the advanced-module plan assignments.
|
||||
- Normalize menu order.
|
||||
- Create company-override records only where required.
|
||||
- Add unique constraints for `systemKey`.
|
||||
- Add audit support if missing.
|
||||
- Detect and report existing assignments that exceed subscription access.
|
||||
- Make the migration idempotent.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Database migration, seed, and rollback procedure.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Re-running the migration causes no duplicates.
|
||||
- No navigable module relies on implicit plan access.
|
||||
- Existing companies receive deterministic menus.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Central entitlement resolver in the API
|
||||
|
||||
### Work
|
||||
|
||||
Create one canonical entitlement service used by both menu generation and API authorization.
|
||||
|
||||
Suggested responsibility:
|
||||
|
||||
```ts
|
||||
resolveModuleAccess({
|
||||
companyId,
|
||||
employeeId,
|
||||
systemKey,
|
||||
})
|
||||
```
|
||||
|
||||
The resolver must evaluate:
|
||||
|
||||
- Global module state
|
||||
- Active subscription plan
|
||||
- Subscription status
|
||||
- Explicit plan entitlement
|
||||
- Company override
|
||||
- Employee role
|
||||
- Required recovery access
|
||||
|
||||
### Deliverable
|
||||
|
||||
A reusable entitlement service with unit tests.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Menu generation and API guards use the same decision logic.
|
||||
- Company overrides cannot grant higher-plan access.
|
||||
- Missing plan assignments mean unavailable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Harden menu-management API
|
||||
|
||||
### Work
|
||||
|
||||
- Protect required modules.
|
||||
- Prevent ordinary administrators from changing:
|
||||
- `systemKey`
|
||||
- Core routes
|
||||
- Required status
|
||||
- Core plan assignments
|
||||
- Core role assignments
|
||||
- Parent relationships
|
||||
- Validate unique system keys.
|
||||
- Prevent circular parent relationships.
|
||||
- Require explicit plan selection for new navigable modules.
|
||||
- Record all changes in the audit log.
|
||||
- Require a reason and expiration for exceptional plan overrides.
|
||||
- Add clear validation errors.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Secure admin menu endpoints and boundary tests.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Required modules cannot be weakened through general update endpoints.
|
||||
- Invalid menu trees are rejected.
|
||||
- All entitlement-changing actions are auditable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Enforce advanced-module API access
|
||||
|
||||
### Work
|
||||
|
||||
Apply reusable entitlement middleware to advanced modules:
|
||||
|
||||
```ts
|
||||
requireModuleEntitlement("online-reservations")
|
||||
requireModuleEntitlement("offers")
|
||||
requireModuleEntitlement("team")
|
||||
requireModuleEntitlement("contracts")
|
||||
requireModuleEntitlement("notifications")
|
||||
requireModuleEntitlement("reviews")
|
||||
requireModuleEntitlement("complaints")
|
||||
```
|
||||
|
||||
Also enforce baseline role restrictions where applicable.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Server-side module protection across all relevant routes.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Entering a hidden route manually does not bypass access.
|
||||
- Calling an advanced API directly does not bypass the subscription.
|
||||
- Unauthorized responses are consistent and testable.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Refine the Admin menu-management interface
|
||||
|
||||
### Work
|
||||
|
||||
Create a clear plan matrix as the primary management view:
|
||||
|
||||
```text
|
||||
Module | STARTER | GROWTH | PRO | Roles | Enabled | Order
|
||||
```
|
||||
|
||||
Add:
|
||||
|
||||
- Plan tabs or columns
|
||||
- Required-item locks
|
||||
- Role controls
|
||||
- Ordering controls
|
||||
- Company and role preview
|
||||
- Subscription-status preview
|
||||
- Audit history
|
||||
- Warning before removing a module used by active companies
|
||||
- Supported icon selector instead of unrestricted icon text
|
||||
- Advanced configuration restricted to `SUPER_ADMIN`
|
||||
|
||||
### Deliverable
|
||||
|
||||
A safer, plan-oriented administration interface.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- An administrator can configure advanced subscriptions without editing routes or system keys.
|
||||
- The preview matches the actual dashboard menu.
|
||||
- Protected items are visibly locked.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Update the Dashboard sidebar
|
||||
|
||||
### Work
|
||||
|
||||
- Replace the large hardcoded fallback with the seven approved baseline items.
|
||||
- Preserve the exact approved order.
|
||||
- Keep the API-generated menu as the source of truth.
|
||||
- Distinguish:
|
||||
- Loading state
|
||||
- API failure
|
||||
- Successful empty response
|
||||
- Successful populated response
|
||||
- Treat a successful empty response as intentional.
|
||||
- Never restore advanced modules after an empty response.
|
||||
- Use a role-aware safe fallback only when the API genuinely fails.
|
||||
- Remove the separate Subscription item from the initial menu.
|
||||
- Keep subscription access available through Billing or Settings.
|
||||
- Preserve visual design and unrelated behavior.
|
||||
|
||||
### Deliverable
|
||||
|
||||
A deterministic sidebar matching the approved design.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- A `STARTER` owner sees exactly seven items.
|
||||
- No menu flicker exposes restricted modules.
|
||||
- RTL, mobile, theme, and localization behavior remain intact.
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: Route guards in Dashboard and Admin
|
||||
|
||||
### Work
|
||||
|
||||
- Align frontend route guards with API entitlements.
|
||||
- Show a clear access-denied or upgrade-required screen.
|
||||
- Do not silently redirect users to unrelated pages.
|
||||
- Prevent stale cached menus after plan or role changes.
|
||||
- Invalidate menu data after admin updates.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Consistent frontend route protection.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Hidden modules cannot be opened by entering their URL.
|
||||
- Downgrades remove route access without requiring a new login.
|
||||
- Upgrade messaging is explicit and accurate.
|
||||
|
||||
---
|
||||
|
||||
## Phase 9: Implement shared localization validation
|
||||
|
||||
### Work
|
||||
|
||||
- Create or update the shared `packages/i18n` package.
|
||||
- Add the approved `en`, `fr`, and `ar` navigation keys.
|
||||
- Replace hardcoded menu labels in Dashboard and Admin with translation keys.
|
||||
- Validate that all locale files contain the same required keys.
|
||||
- Validate that interpolation variables match across languages.
|
||||
- Reject empty, unknown, and obsolete keys.
|
||||
- Add CI checks for translation completeness.
|
||||
- Add development logging for missing keys.
|
||||
- Ensure Arabic applies `lang="ar"` and `dir="rtl"` at the document root.
|
||||
- Verify locale-aware dates, numbers, and MAD currency formatting.
|
||||
- Prevent translated labels from being used in permissions, routes, plan assignments, or database lookups.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Shared translation package, approved glossary, validation script, and CI enforcement.
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Every required English key exists in French and Arabic.
|
||||
- No navigation label is hardcoded in Dashboard or Admin.
|
||||
- Core glossary terms are protected.
|
||||
- Arabic uses true RTL layout.
|
||||
- Missing translations fail CI before deployment.
|
||||
|
||||
---
|
||||
|
||||
## Phase 10: Testing
|
||||
|
||||
### API tests
|
||||
|
||||
- Explicit plan assignment is required.
|
||||
- Company override cannot upgrade a plan.
|
||||
- Required items cannot be disabled by ordinary admins.
|
||||
- Suspended subscriptions receive only recovery access.
|
||||
- Role restrictions remain active.
|
||||
- Advanced APIs reject unauthorized requests.
|
||||
- Audit entries are created.
|
||||
|
||||
### Localization tests
|
||||
|
||||
- Every navigation key exists in English, French, and Arabic.
|
||||
- Core terminology matches the approved glossary exactly.
|
||||
- Missing or empty translations fail CI.
|
||||
- Interpolation variables match across locales.
|
||||
- Switching language does not change routes, permissions, subscription access, or system keys.
|
||||
- French labels do not overflow.
|
||||
- Arabic labels do not truncate.
|
||||
- Arabic sets `lang="ar"` and `dir="rtl"`.
|
||||
- Directional icons mirror correctly and neutral icons do not.
|
||||
- Dates, numbers, and MAD currency values format correctly by locale.
|
||||
|
||||
### Dashboard tests
|
||||
|
||||
- `STARTER` owner sees exactly seven items.
|
||||
- Approved order is preserved.
|
||||
- Empty successful response remains empty.
|
||||
- API failure uses only the safe fallback.
|
||||
- Advanced modules appear only when entitled.
|
||||
- Direct routes are blocked.
|
||||
- Mobile and desktop menus behave consistently.
|
||||
- EN, FR, and AR labels render correctly.
|
||||
- Arabic remains true RTL.
|
||||
|
||||
### Admin tests
|
||||
|
||||
- Plan toggles save correctly.
|
||||
- Locked modules cannot be modified.
|
||||
- Preview matches the generated employee menu.
|
||||
- Invalid parent relationships are rejected.
|
||||
- Removing a widely used entitlement produces a warning.
|
||||
- Audit history displays the change.
|
||||
|
||||
### Deliverable
|
||||
|
||||
Unit, integration, boundary, and end-to-end test coverage.
|
||||
|
||||
---
|
||||
|
||||
## Phase 11: Deployment and rollback
|
||||
|
||||
### Deployment order
|
||||
|
||||
1. Database migration and seed
|
||||
2. API entitlement resolver
|
||||
3. API route enforcement
|
||||
4. Admin management interface
|
||||
5. Dashboard sidebar and route guards
|
||||
6. End-to-end verification
|
||||
|
||||
### Rollback requirements
|
||||
|
||||
- Database rollback or compensating migration
|
||||
- Feature flag for new entitlement enforcement
|
||||
- Ability to restore previous menu assignments
|
||||
- Audit record of rollback actions
|
||||
- No destructive deletion of historical menu configuration
|
||||
|
||||
### Exit criteria
|
||||
|
||||
- Production smoke tests pass.
|
||||
- Existing companies retain expected access.
|
||||
- No restricted module is exposed.
|
||||
- Recovery access remains available.
|
||||
|
||||
---
|
||||
|
||||
## 9. File-level work areas
|
||||
|
||||
Expected targets, subject to repository verification:
|
||||
|
||||
### Dashboard
|
||||
|
||||
```text
|
||||
src/components/layout/Sidebar.tsx
|
||||
src/components/layout/DashboardAccessGuard.tsx
|
||||
src/components/layout/Sidebar.boundary.test.ts
|
||||
src/components/layout/DashboardAccessGuard.boundary.test.ts
|
||||
```
|
||||
|
||||
### Admin
|
||||
|
||||
```text
|
||||
src/app/dashboard/menu-management/page.tsx
|
||||
related menu-management components
|
||||
related API client modules
|
||||
related tests
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
```text
|
||||
src/modules/menu/menu.service.ts
|
||||
src/modules/menu/menu.entitlement.ts
|
||||
src/middleware/requireModuleEntitlement.ts
|
||||
menu administration routes
|
||||
advanced-module routes
|
||||
related unit, boundary, and E2E tests
|
||||
```
|
||||
|
||||
### Database
|
||||
|
||||
```text
|
||||
Prisma schema
|
||||
menu seed
|
||||
subscription entitlement seed
|
||||
migration
|
||||
rollback or repair script
|
||||
```
|
||||
|
||||
### Shared i18n package
|
||||
|
||||
```text
|
||||
packages/i18n/locales/en.json
|
||||
packages/i18n/locales/fr.json
|
||||
packages/i18n/locales/ar.json
|
||||
packages/i18n/glossary.ts
|
||||
packages/i18n/validation.ts
|
||||
packages/i18n/index.ts
|
||||
related localization tests
|
||||
```
|
||||
|
||||
No file should be changed until the repository structure is verified against these expected paths.
|
||||
|
||||
---
|
||||
|
||||
## 10. Non-goals
|
||||
|
||||
This milestone will not:
|
||||
|
||||
- Redesign the sidebar visually.
|
||||
- Change dashboard branding.
|
||||
- Change the theme system.
|
||||
- Change localization architecture.
|
||||
- Replace existing pages.
|
||||
- Introduce machine translation at runtime.
|
||||
- Allow translated labels to control routes, permissions, or entitlements.
|
||||
- Add unrelated subscription billing features.
|
||||
- Grant tenant administrators permission to alter platform routes.
|
||||
- Treat hidden navigation as sufficient security.
|
||||
|
||||
---
|
||||
|
||||
## 11. Definition of done
|
||||
|
||||
The implementation is complete only when:
|
||||
|
||||
- The initial owner sidebar contains exactly the seven approved items.
|
||||
- The order matches the approved design.
|
||||
- Advanced items are explicitly assigned by subscription plan.
|
||||
- Company overrides cannot bypass subscription entitlements.
|
||||
- Employee roles remain enforced.
|
||||
- Subscription status affects access.
|
||||
- Direct frontend routes are protected.
|
||||
- Direct API calls are protected.
|
||||
- Required system items cannot be weakened by ordinary administrators.
|
||||
- Admin previews match actual dashboard results.
|
||||
- All changes are audited.
|
||||
- Existing visual behavior remains unchanged.
|
||||
- English, French, and Arabic use the approved shared terminology.
|
||||
- Arabic uses true RTL behavior.
|
||||
- Missing or inconsistent translations fail CI.
|
||||
- Routes, permissions, subscriptions, and API logic use immutable system keys rather than translated labels.
|
||||
- Tests pass across Dashboard, Admin, API, and Database.
|
||||
- Deployment and rollback procedures are documented.
|
||||
|
||||
---
|
||||
|
||||
## 12. Execution gate
|
||||
|
||||
Implementation must not begin until these items are approved:
|
||||
|
||||
1. Baseline seven-item menu
|
||||
2. Advanced-module plan matrix
|
||||
3. Employee-role matrix
|
||||
4. Subscription-status policy
|
||||
5. Company customization limits
|
||||
6. Required-item protection rules
|
||||
7. Database migration strategy
|
||||
8. Approved EN/FR/AR glossary
|
||||
9. Translation fallback and CI policy
|
||||
10. Arabic RTL acceptance criteria
|
||||
|
||||
This prevents the usual ritual of coding first and discovering the business rules afterward.
|
||||
Reference in New Issue
Block a user