# Organization workspace: production integration guide

Date: 16 October 2026. Status: implementation instructions and gap analysis; not an implementation or deployment report.

Implementation follow-up: see [local implementation and acceptance report](organization-workspace-implementation.md) for changes, validation evidence and outstanding deployment checks. This guide retains the original inspected baseline.

## 1. Purpose and inspected baseline

Bring the approved organization prototype into the existing Laravel API and React/Vite application, preserving the working personal workspace and SCORM editor. Implement the business rules on the server as well as in the interface. Use the prototype's distinct navy/teal organization appearance, with the application's existing typography, components, interaction conventions and bilingual support.

This review inspected the current working tree on `main` (HEAD `d6910e6`), the standalone prototype, and Stage 10 documentation/source references on `feature/stage-10-organizations-and-administration` (`24bd7e1`) using read-only Git commands. Branches were not switched or merged. Current uncommitted H5P and prototype work forms part of the inspected baseline and must be preserved.

Sources of truth:

- [Prototype walkthrough and boundaries](../frontend_prototype/ORGANIZATION_WORKSPACE.md).
- [Organization model](../frontend_prototype/src/organization/model.js), [views](../frontend_prototype/src/organization/views.js), [controller](../frontend_prototype/src/organization/controller.js), [translations](../frontend_prototype/src/organization/i18n.js), and [scoped appearance](../frontend_prototype/organization.css).
- [Existing production workspace structure](personal-workspace-design-migration.md).
- Stage 10: `docs/stage-10-organizations-and-administration.md` **on the feature branch**. It is not present on current `main`. Inspect with `git show feature/stage-10-organizations-and-administration:docs/stage-10-organizations-and-administration.md`.

The Stage 10 document reports an implementation and historical tests on its branch. Those claims do not establish that organizations exist on `main` or that the old implementation passes against today's code. In particular, that branch predates the current extracted workspace/studio modules and recent H5P changes. Treat it as a business specification and candidate backend reference; adapt deliberately rather than replacing current files.

Only this document is created by this task. No application code, database, environment, credentials, mail delivery or provider integration is changed. No runtime tests were rerun for this documentation review.

## 2. Business contract to implement

1. Every account retains its personal workspace and may join multiple organizations. Organization roles are admin and member; a platform `ultimate_admin` is a separate role.
2. Verified users can create an immediately active organization. There is no approval queue. Creation is idempotent; the creator becomes its first admin transactionally.
3. An organization owns its projects. `conversions.user_id` remains creator/provenance for organization projects, not an ongoing ownership grant. Removing the creator does not delete their work or preserve unauthorized access.
4. Organization admins create projects, assign people, manage folders and lifecycle. Members see only assigned projects. Members cannot create organization projects or manage these controls.
5. An assignment grants viewing. Editing and SCORM downloading are separate booleans, including editor-without-download and viewer-with-download. Editing includes authoring, uploads, rendering, packaging and narration generation.
6. Invitations last seven days, require the matching verified email, and use hashed secrets. Resend rotates the secret; old links stop working. Support pending, accepted, expired, revoked and email-mismatch outcomes.
7. Suspension blocks access while retaining assignments. Removal/leave clears assignments and that member's organization-project external grants. Rejoining needs a fresh invitation and new assignments. Projects and contributions remain.
8. Never allow demotion, suspension, removal or departure of the last active admin. Serialize changes in the database; two simultaneous requests must not bypass the rule. Globally suspended accounts do not count as active admins.
9. External sharing starts disabled. Enabling permits existing collaborator/review-link workflows, subject to the global sharing switch and entitlement. Disabling confirms and permanently revokes grants and links; enabling again does not restore them.
10. Organization narration uses organization credentials. Application fallback starts disabled and is controlled only by the platform super admin. Provider failures must not silently switch organization billing to another key. Preserve personal narration behavior.
11. Free launch uses unlimited commercial limits. Keep operational file/media/rendering/worker limits. Show real usage totals; no checkout, invoices, upgrade pressure, fabricated trends or learner analytics.
12. Workspace changes protect drafts with Save and switch / Discard and switch / Cancel. Close previous-workspace editor tabs after resolving drafts. Saved server content remains. Back, Forward and direct project URLs restore verified workspace context.

Deferred: personal-to-organization transfers, permanent organization deletion, departments, custom roles, approvals, SSO, real-time collaboration and payments. The prototype excludes platform super-admin screens, but production still needs the Stage 10 control plane for suspension, fallback, entitlement management and audited support access.

## 3. Existing features versus required edits

Paths in the following tables are relative to the repository root. `BE` means `documents_generator_tools_backend`; `FE` means `documents_generator_tools_frontend`.

| Area | Verified current foundation | Required production work |
| --- | --- | --- |
| Authentication | Sanctum cookies/CSRF, registration, profile, password recovery, language in `BE/app/Http/Controllers/Api/AuthController.php` and `FE/app/auth/` | Real email-verification send/verify flow; verification metadata; reset verification on email changes; preserve unverified personal access; feature discovery and organization onboarding intent |
| Workspace shell | `FE/app/workspace/components/workspace-layout.tsx`; personal and ultimate-admin pages | New organization shell, role-aware navigation and organization identity; account settings stay separate |
| Workspace switcher | `workspace-switcher.tsx` currently offers Personal/Ultimate admin, rendered for ultimate admins | All eligible users get Personal + memberships + Create organization; preserve ultimate-admin entry; suspended memberships show a clear unavailable state |
| Project catalogue | `FE/app/data/project-types.ts`, shared personal chooser and upload dialog | Reuse all six choices in organizations; retain current availability; pass workspace through upload, retry and created navigation |
| Project data | `BE/app/Models/Conversion.php`, personal `user_id`, UUIDs, private files and revisions | Nullable `organization_id`, organization relation, workspace metadata and creator/owner distinction; legacy rows stay personal |
| Authorization | `BE/app/Services/ProjectAccessService.php`, conversion-access concern and write lock | Organization-first access resolution, assigned viewing, independent edit/download, admin management, suspension and feature policy; apply across all endpoints |
| Project library | `ProjectController.php`; `FE/app/workspace/hooks/use-project-library.ts`, services/project-api.ts, cards and library | Organization query scope, permission-filtered totals, status/folder/sort/unassigned filters, grid/list, archive, details drawer and assignment editor |
| Folders | Personal ProjectFolder/ProjectFolderAssignment models and controller; shared accessible-project personal folders | Separate organization-wide folders with admin-only writes and member-visible assigned-project counts; do not reinterpret personal folder ownership |
| Sharing | ConversionShare/ConversionShareLink, authenticated sharing controllers, public shared controller/page | Organization policy and entitlement checks, revoke-all transaction, prohibited member bypass and public-link suspension; admin-only management |
| Editor | `FE/app/tools/powerpoint-to-scorm/studio/` has multi-tabs, dirty/busy guards, autosave, project picker, capabilities | Workspace-scoped tabs/pickers/navigation, organization breadcrumbs, authority revalidation, independent download controls and full draft-safe switching |
| Course features | Preparation/fonts/layout, slides, questions/groups, media/resources/captions, narration, course flow and H5P | Preserve features and revisions; check tenant access on every read/write/upload/preview/export and nested resource; retain all current H5P changes |
| Narration | Encrypted user key in User; ElevenLabsCredentials/Client, GenerateSlideNarration, profile forms | Encrypted organization key and scoped resolver, fallback policy, organization settings, usage reservations and pre-provider access revalidation |
| Background processing | Rendering/media/package/narration jobs, generation tokens, locks and existing queue settings | Persist actor/workspace operation context; revalidate rights at execution/publication; safe cancellation and idempotent usage |
| Activity | UltimateAdminAuditService and global admin project audit | Organization-scoped member-safe event records and admin-only searchable history; do not expose global admin events wholesale |
| Usage | No organization usage/entitlement layer found on current main | Durable usage accounting, free/unlimited defaults, reconciliation and actual totals; distinguish commercial from operational limits |
| Configuration/operations | Existing deployment runbook, queues, CORS and SMTP configuration | Organization flag, canonical links, mail delivery, migration rehearsal, restarts, controlled rollout and rollback constraints |

## 4. Screen-by-screen product delivery

| Screen | Production data and behavior | Existing pieces to reuse |
| --- | --- | --- |
| Admin overview | Organization name/logo, total projects, active members, ready packages, pending invitations, recent projects/activity, unassigned-project and narration setup actions. Define count scopes; counts are server aggregates, not sums of one page. No invented charts. | Workspace cards, summaries, icons, loading/error feedback; prototype overview composition |
| Projects | Server search over title/source filename, folder/status filters, sort, pagination, grid/list, archive access, clear open/edit/download indicators. Admin New project and folder controls; member assigned projects only. Preserve selected filters in URL. | Project library/cards/pagination/action locks; organization-specific folder presentation inside Projects |
| Project details/assignments | Organization ownership plus creator separately, real project status, active assignments and independent edit/download toggles. Validate all assignees belong to the same organization. Explain suspended assignments without deleting them. Show lifecycle/sharing only when permitted. | Existing Dialog and form controls, sharing permission presentation; prototype side drawer |
| People | Members/Invitations tabs; paginated search, role/status filters, invite, resend/revoke, role updates, suspend/reactivate/remove. Return last-admin reason with disabled action plus explanation. Failed updates keep the form/draft. | Profile identity/avatar, filters, dialogs and feedback; dedicated organization hooks/services |
| Activity | Admin-only, paginated history with actor/action/project/date/search filters. Include committed project, membership, invitation, settings and policy events. New actions invalidate history/overview queries. | Existing admin activity patterns; separate scoped response and endpoint |
| Settings: General | Required name/country/type/intended use, optional website/phone; private logo upload/removal (PNG/JPEG/WebP, 2 MB). Independent save, validation and unsaved-state feedback. | Profile forms and draft handling, safe upload components |
| Settings: Narration | Enabled/configured indicators, write-only key, voice ID, explicit removal; blank key preserves configured key. Application fallback read-only to organization admins. Independent save. | Existing account narration form behavior, new organization API adapter |
| Settings: Sharing | Starts off. Explain policy, show collaborator/review-link controls when enabled and entitled. Disable confirmation explains irreversible grant/link revocation. | Sharing controls and dialogs with organization policy wrapper |
| Settings: Usage | Actual member/project/storage/conversion/AI totals, reporting period and free/unlimited state; useful measurement definitions. Independent refresh/error state. | Summary and feedback primitives; no payment UI |
| Member landing | My projects and Organization information only; permitted edit/view/download actions. No administrative navigation or hidden direct-route access. | Project list/cards with server capabilities |
| Organization information | Read-only identity and membership info plus Leave organization; explain retained contributions and last-admin protection. | Identity/forms/dialogs |
| Create/join | Registration intent or switcher entry, real verification, required details, immediate activation, optional first invitations, resumable login/acceptance outcomes. | Existing auth pages/session; new onboarding pages |
| Exceptional states | Loading, retryable errors, empty, no results, unavailable project, suspended account/membership/organization, revoked permission, expired/mismatched invitation and feature disabled. Distinguish retryable network failure from denied access. | Feedback/empty-state primitives and bilingual copy |

Do not ship the prototype Demo controls, identity simulation, Reset demo, synthetic analytics, pretend email, simulated download outcomes or fixture/sessionStorage persistence as product behavior. Keep fixtures only in tests/development stories. Production upload, email, download and narration use real existing server workflows after authorization.

## 5. Database and ownership implementation

Add migrations; never reset existing application tables. Use compatible UUID/foreign-key types and indexes for the deployed database. Confirm exact schema against current migrations before writing SQL.

| Entity/change | Minimum fields/invariants |
| --- | --- |
| organizations | UUID, name, country, type, intended_use, website/phone, private logo path, active/suspended state, encrypted narration key, voice/enabled flags, sharing default false, fallback default false, creator/creation idempotency identity, timestamps |
| organization_memberships | Organization + user unique, admin/member, active/suspended/removed, timestamps; preserve removed state for audit while revoking access |
| organization_invitations | UUID, organization, normalized email, role, token hash, expires_at, accepted/revoked markers, inviter, timestamps; never store plaintext token; resend rotates and resets expiry |
| conversions.organization_id | Nullable, indexed with archive/update fields, restrictive organization deletion; existing user_id and file paths retained |
| organization_project_assignments | Conversion + user unique, can_edit and can_download_package default false; assignment itself permits view; membership required and checked transactionally |
| organization_folders / folder_assignments | Organization-owned folder, name/color/order; one folder per project if matching existing prototype behavior; validate conversion and folder share organization |
| workspace_audit_events | Organization, actor, stable action code, project reference/safe title snapshot, safe structured metadata, timestamp; indexes for tenant/date/filter queries; no secrets |
| workspace_plans / entitlements | Free default, null commercial limits = unlimited, feature overrides; distinct workspace, organization and subscription status |
| workspace_usage_events | Workspace + unique operation key, actor/project, metric, quantity, reserved/completed/released state, UTC monthly period; retry-safe transitions |
| users | Existing email_verified_at becomes functional; add global suspension metadata for Stage 10 control plane without changing membership scope |

Organization, first membership and creation idempotency must commit together. Add unique constraints rather than relying only on frontend button disabling. Keep organization setting writes and invitation/member changes under organization-level transactional locking. Establish one documented lock order across membership, project, assignment and quota operations to avoid deadlocks; handle retryable contention safely.

Do not cascade project deletion from membership removal. Do not backfill personal projects into an organization. Do not change existing conversion UUIDs, private paths, settings/preparation/document revisions or package snapshots. A project workspace cannot be changed by an update payload. Any future ownership transfer requires its own separately reviewed feature.

The branch migration `2026_10_11_000001_add_organization_workspaces.php` is a reference for these tables. Reconcile its assumptions and date with current migrations, including the uncommitted H5P overall-settings migration. Verify a restored legacy personal project survives with identical fields and file checksums, then verify a repeated migrate is a no-op.

## 6. Central authorization and access matrix

Extend `BE/app/Services/ProjectAccessService.php`; do not build a second competing project permission system. Current code checks creator identity first and grants personal editors package downloading automatically. Preserve that behavior for personal projects only. For organization projects, first resolve active organization/account/membership, organization admin, active assignment or permitted external grant. Creator identity alone grants nothing.

| Action | Org admin | Assigned member | External collaborator | Public review link |
| --- | --- | --- | --- | --- |
| View | All org projects | Assigned only | Active policy-permitted grant | Valid policy-permitted link |
| Edit/upload/render/package/narration | Yes | can_edit | Share editor permission | No |
| Download SCORM | Yes | can_download_package | Explicit download grant | Explicit link download flag |
| Assign/lifecycle/folders/create | Yes | No | No | No |
| Manage external sharing | Yes, if policy permits | No | No | No |
| Organization people/settings/activity | Yes | Information only | No | No |

Platform super-admin access is a separate audited path, not an organization membership shortcut. Suspension blocks normal organization access and generation. Support reads may remain available to super admins, but suspended organizations must not dispatch processing/provider work. Global account suspension invalidates sessions/tokens and blocks new work across workspaces; membership suspension affects only its organization.

Apply the matrix to project listing/detail, assignments, folders, sharing/public links, all conversion controllers and all nested resources. Reject cross-project slide/media/question/H5P IDs even when both IDs are valid. A removed/suspended member must not regain organization access through an old external grant. Preserve archive/processing guards, action locking and document revision conflicts.

Review `ConversionWriteLock` ability selection: organization members must not gain lifecycle/assignment rights through a generic edit check, and valid view/download operations must not accidentally require edit permission. Keep authorization in the relevant service/controller as well as lock middleware. Return server capabilities in summary/editor responses and use them consistently in UI controls; never infer authorization from selected workspace or local storage.

Package downloading is independent from packaging: edit-without-download may build, but cannot fetch the ZIP. Download-without-edit may fetch an available package but cannot build. Check this on direct endpoints as well as buttons. Existing signed assets and expiry windows remain; preview viewing cannot prevent saving visible bytes or recall previously downloaded content. Document the actual revocation window rather than promising immediate recall.

## 7. Production API contract

All paths below are under `/api/v1`, through existing Sanctum/CSRF, locale handling, validation, throttles and JSON error conventions. These are target contracts, not routes already present on main. Reuse Stage 10 route names where feasible. Nested resources must be scoped by organization server-side.

| API | Purpose / implementation note |
| --- | --- |
| GET /auth/features | Public organization availability; no tenant/private details |
| GET /workspaces | Personal plus accessible memberships, identity/logo/role/status/capabilities; preserve super-admin navigation separately |
| POST /auth/email-verification; signed authenticated GET /auth/verify-email/{id}/{hash} | Send/complete verification, one-hour expiry, rate limits, current email binding |
| POST /organizations | Required details + UUID creation_key; verified user, idempotent active organization/first admin |
| GET/PATCH /organizations/{id} | Member-safe information vs admin-only general/policy changes; field allowlists; fallback cannot be changed by org admin |
| GET /organizations/{id}/overview | New aggregate/read model required for approved overview; admin only |
| GET /projects?organization_id={id} | Existing list extended for explicit organization scope; scoped search/folder/status/sort/unassigned/pagination. Omission preserves personal default |
| GET /projects/{conversion} | Existing detail extended with workspace and capabilities; assignment data separately protected |
| POST /powerpoint-to-scorm/conversions | Existing real PPTX upload + optional organization_id; admin membership verified before creating/upload admission |
| GET /organizations/{id}/members; PATCH /members/{userId}; POST /leave | Membership management; last-admin transaction and clear conflict reason |
| GET/POST /organizations/{id}/invitations; DELETE /invitations/{invite} | List/invite/revoke; admin only; seven-day expiry |
| POST /organizations/{id}/invitations/{invite}/resend | Explicit target endpoint for resend/rotation; do not assume historical branch exposes this exact route |
| POST /organization-invitations/{invite}/accept | Token in request body, verified matching email, safe idempotent acceptance |
| GET /organization-invitations/{invite} | Proposed minimal invitation landing lookup if needed; require token/auth as appropriate, no arbitrary private organization/member disclosure |
| GET/PUT /organizations/{id}/projects/{conversion}/assignments; DELETE /assignments/{userId} | Active same-org users, independent flags, atomic validated updates |
| GET/POST /organizations/{id}/folders; PUT /folders/order; PATCH/DELETE /folders/{folder}; PUT /projects/{conversion}/folder | Organization folder operations; member read/count filtering; admin writes |
| GET /organizations/{id}/activity | New admin-only organization event history with actor/action/project/date/search and pagination |
| PUT /organizations/{id}/elevenlabs | Admin update, blank key preserves, explicit removal disables; write-only key |
| GET/POST/DELETE /organizations/{id}/logo | Private read/upload/removal; deletion route is an explicit target extension |
| GET /organizations/{id}/usage | Real totals, UTC period, free plan and effective limits/features |
| Existing project share/link/public routes | Retain URLs and secret handling; add organization policy, revocation and independent download rules |
| Existing /admin routes + Stage 10 workspace administration | Organization/user suspension, audited support, fallback, entitlements, usage and processing; ultimate-admin middleware required |

Overview/activity APIs are gaps between the newer prototype and the older Stage 10 controller surface. Design their query DTOs and audit schema deliberately. Do not fabricate their contents from frontend fixtures or fetch the entire global dataset to filter in the browser.

Extend project response contracts additively: organization_id, workspace identity/ownership, creator, project type where appropriate, can_edit, can_download_package, can_manage_sharing, can_manage_lifecycle, can_manage_assignments and effective availability. Keep existing fields/statuses and `data`/pagination conventions. Define stable machine-readable errors for last-admin protection, suspended access, expired/revoked/email-mismatched invitations, disabled feature, usage limit and document conflict; render localized explanations.

Settings writes should send only the edited section. Return authoritative saved values and configured booleans; never return narration keys or invitation tokens in normal lists. Use versions/conditional updates or scoped field patches so unrelated section saves do not overwrite concurrent changes. Confirmation and duplicate-submission locks are required for revocation/lifecycle/member changes.

## 8. Files and module changes

### Backend additions

Adapt/create focused models and services from Stage 10 references: Organization, OrganizationMembership, OrganizationInvitation, OrganizationProjectAssignment; WorkspaceService, OrganizationMembershipService, OrganizationInvitationService, WorkspaceEntitlementService. Add organization folder models if using their own tables, organization audit/read-model services for overview/activity, notifications, email verification controller, organization controllers, workspace admin controller, OrganizationWriteLock, EnsureActiveAccount, shared job access checks, configuration, translations and additive migrations. Small dedicated invitation/assignment/settings controllers are preferable if a single controller becomes unwieldy.

### Existing backend files to change

- `app/Models/Conversion.php`, `User.php`: relationships, verification, encrypted organization settings held on Organization, immutable ownership boundaries and safe serialization.
- `app/Services/ProjectAccessService.php`, `ProjectSummaryService.php`: workspace-aware query/capability/identity output.
- `app/Http/Controllers/Api/ProjectController.php`, `ProjectFolderController.php`: personal isolation, organization list/detail dispatch and management rules. Personal queries must explicitly exclude organization-owned creations after organization ownership is introduced.
- `ProjectShareController.php`, `ProjectShareLinkController.php`, `PublicSharedProjectController.php`: policy and suspension on grant creation/use/download, revoke-all and member bypass prevention.
- `Concerns/AuthorizesConversionAccess.php`, `Http/Middleware/ConversionWriteLock.php`: preserve shared authorization, archive/processing/revision locks and rollback behavior.
- `PowerPointToScormConversionController.php`, PreparationController, SlideLayoutController, slides/quiz/groups/media/narration/course-flow controllers: scoped upload/actor dispatch, capabilities and nested checks.
- `H5pStudioController.php` and H5P services: authenticated operations must use centralized tenant checks; specifically review signed/public sample/preview routes, package asset paths and their expiration/revocation behavior. Retain recent package/runtime/overall-settings fixes.
- `ElevenLabsCredentials.php`, `ElevenLabsClient.php`, narration dispatch: workspace-aware credential resolution; no organization failure fallback; preserve established personal fallback.
- `Jobs/ProcessPowerPoint.php`, RenderPreparedPresentation, RenderSlideLayoutPreview/Original, ProcessMediaAsset, GenerateScormPackage, GenerateSlideNarration and publishing services: actor checks, generation-safe cancellation and accounting. DeleteConversion retains authorized asynchronous cleanup semantics.
- `AuthController.php`, `bootstrap/app.php`, `routes/api.php`, `AppServiceProvider.php`, configuration/.env.example and English/Arabic message files: new middleware, verification, safe links, flags and registrations.

### Frontend structure

Keep React/Vite and the existing dependency set. Implement organization pages as typed React modules, not copied imperative HTML/controller code from the standalone prototype. Recommended addition under `FE/app/organizations/`:

```text
pages/        overview, projects, people, activity, settings, information,
              create-organization, invitation, verify-email
components/   organization-shell, identity, navigation, project-details,
              assignments, invitation/member dialogs, settings sections
hooks/        workspace-context, membership, organization-projects,
              activity, settings-drafts, switch-guard
services/     typed organization API adapters using existing apiRequest/apiUpload
types.ts      workspace, membership, invitation, assignments, settings, usage
i18n.ts       English/Arabic product copy
organizations.css   scoped navy/teal design and responsive behavior
```

Reuse compatible `FE/app/workspace/components/ui.tsx`, icons, pagination, cards, chooser, uploads, sharing controls and feedback. Add narrow optional workspace/theme/capability props rather than duplicating their logic. Existing personal components remain compatible by default.

Edit `FE/src/main.tsx` for lazy organization pages, protected routes, route-aware language controls and title/Back behavior. Current routing is custom path matching, not a framework router: do not add a new router merely for this feature. Edit `auth/auth-context.tsx` for verification/suspension metadata and workspace reload on account changes; retain session/CSRF handling.

Extend `workspace/components/workspace-switcher.tsx` and its visibility in workspace-layout for normal members as well as ultimate admins. Extend typed project query/upload/dialog props for organization identity. Scope hooks/cache keys and abort controllers by authenticated user + workspace + filters; clear obsolete results on workspace changes. Update `workspace/types.ts` and editor DTOs together; do not force organization admins into the old personal-owner interpretation.

## 9. Routes and editor integration

The prototype uses hash routes; production uses pathname routes. Do not copy prototype hashes into production. Recommended mappings:

| Prototype route | Production target |
| --- | --- |
| #org/{id}[/overview] | /organizations/{id}[/overview], role-aware default |
| #org/{id}/projects, people, activity, settings/{section}, information | /organizations/{id}/… |
| #organizations/new | /organizations/new (match before generic ID route) |
| #invitation/{id}/{generation} | /organization-invitation/{id}; secret handled by secure production acceptance flow |
| Organization project editor | Keep /tools/powerpoint-to-scorm/{conversionUUID}; derive workspace from authorized response |
| Existing personal/account/public/admin routes | Preserve /dashboard, /account, /shared/{id}, editor URLs and existing admin query parameters |

If organization-specific editor aliases are desired, resolve both IDs server-side and redirect to the canonical existing editor URL. An organization ID in the URL or sessionStorage never grants access. Configure deployment SPA fallback for refreshing new paths without intercepting API/private asset routes.

`studio/editor-workspace.tsx` currently stores tab metadata under `docudeck:editor-tabs:${user?.id}`. Extend to user + workspace namespace, such as `docudeck:editor-tabs:{userId}:organization:{id}` or `…:personal:{userId}`. Legacy metadata must be revalidated before reuse, not blindly treated as personal. Store navigation/tab metadata only, not production project content, secrets or authoritative permissions.

Extend the existing SessionHandle dirty/busy/save/discard lifecycle instead of adding a conflicting guard. Include settings and narration drafts, in-flight autosave/uploads and every editor tab. On Save and switch, await all required saves and remain in the old workspace if any fail. Preserve conflicts for resolution. Discard cancels pending timers/requests where possible and reloads authoritative saved content; it cannot undo a mutation already committed. Cancel does not navigate, change selected workspace or clear tabs. Incomplete creation forms should offer discard/cancel rather than creating implicitly.

After a successful switch, close old-workspace editor sessions, stop polling/autosave and clear stale picker results. Opening a direct project URL loads its real workspace before restoring tabs. Revalidate on activation and handle revoked permission while open with read-only/unavailable state and no subsequent writes. Account settings remain account-wide and retain a clear return context.

Project picker and upload must receive workspace explicitly. New project always displays the existing six-type catalogue; only PowerPoint to SCORM is available. Map its stable type to the real SCORM upload endpoint. Do not derive new API tools from display names or enable the other converters. Use real upload status/slide counts rather than the prototype's zero-slide synthetic project behavior.

## 10. Same style and accessibility instructions

Match the approved organization design while retaining application conventions. Personal workspace remains warm ivory/green/coral; the editor retains its existing design. Organization design uses navy `#142638`, light slate `#F4F7FA`, white surfaces, primary teal `#087F79`, 12px radii and restrained shadows. Use Segoe UI/Tahoma and existing BrandMark/icons/button/form/dialog behavior. Shared structure does not require recoloring personal screens.

1. Use an `.organization-workspace` root and scoped organization modal class. Scope all organization colors, spacing, states and animations. Do not add global `button`, `dialog`, `aside` or `body` overrides.
2. Existing personal CSS is scoped under `.personal-workspace`, including shared-looking controls. Extract only genuinely shared primitives or provide organization-scoped styles for reused components. Simply mounting personal components outside that root will not guarantee styling. Port prototype tokens/layout deliberately.
3. Preserve navy sidebar, prominent organization identity/switcher, clear page title and one primary action. Admin folders live inside Projects. Members see only My projects and Organization information. Account settings are separate from organization settings.
4. Desktop navigation can collapse; tablet navigation collapses; phone navigation becomes an accessible drawer. Stack project/member rows, keep filters usable and make mobile dialogs full width with vertical scrolling. Avoid clipping long names or translating UUIDs/filenames.
5. Use CSS logical properties and real `dir`/language state for RTL. Keep file conversion route symbols readable LTR. Translate validation, statuses, confirmation text, empty/error states, dates and permissions. English/Arabic keys must stay in parity.
6. Maintain visible focus, labels, keyboard operability, semantic tables/lists and selected navigation state. Native dialogs need focus trapping/Escape/restoration; focus must also move sensibly between type chooser/upload steps. Primary touch targets are at least 44px.
7. Measure actual text/control/focus contrast: normal text at least 4.5:1, large text 3:1, meaningful control boundaries/focus indicators 3:1. Do not rely only on color or disabled opacity to explain permission/status. Use text reasons for last-admin/unavailable actions.
8. Show saving/saved/error per section; preserve unrelated drafts. Pending actions prevent duplicate mutations and accidental dismissal. Retry preserves user input where safe.
9. Compare directly with prototype screenshots in `out/organization-prototype/`, including project-type chooser and Arabic/mobile. Check desktop, tablet, 390px/320px, short landscape and actual 200% browser zoom. Compact viewport testing does not replace native zoom acceptance.

## 11. Narration, processing, usage and operational policy

Current ElevenLabsCredentials resolves a user/application key; ElevenLabsClient can retry a rejected personal key using application credentials. Add a conversion/workspace-aware resolution path. For organization projects, ignore the individual actor's personal key, use the organization's enabled/configured key, and allow application fallback only when explicitly configured by the super admin. Provider rejection must fail clearly rather than changing credential source. Encrypt keys with the existing APP_KEY, expose configured flags only, and remove secrets from logs/audits/queue payloads/packages.

GenerateSlideNarration already has requestedBy and generation identity, but current narration generation uses the requesting user's credentials. Update this flow without losing actor attribution. Other jobs currently have varying generation checks; HTTP authorization alone does not protect work that starts later. Capture actor/project/workspace/operation IDs, revalidate current account/organization/membership/assignment policy before work, before provider calls and before publishing. Do not put credentials in serialized jobs. Old queued personal jobs need compatible defaults; organization jobs must never fall back to creator ownership when actor metadata is absent.

Revoked operations must not publish stale or unauthorized output. Write replacements to generation-specific paths, retain the previous valid package/audio where applicable, cancel safely, clean temporary files and release unused reservations. Work already completed by a provider may still count even if attachment/publication is rejected. Preserve operational timeouts, concurrency locks, retry_after, backoff and worker settings; do not repurpose membership changes as job deletion.

Usage definitions follow Stage 10: project count includes archives and excludes pending deletion; storage includes retained historical generations and organization assets; monthly periods are UTC calendar months; conversion count reflects full rendering rather than preview/build clicks; AI measures requested characters/provider attempts rather than money. Reserve under locking before admission, complete/release idempotently with a unique operation key, and include outstanding reservations in limit checks. Null commercial limits mean unlimited; zero prevents additional use. Current operational limits still apply.

Implement a dry-run reconciliation command before offering `--apply`. Reconcile abandoned reservations against actual generation/job state; do not release active work solely because it is old, retry provider calls or infer provider invoices. Show measurement timestamp and period in Usage if totals are eventually reconciled. No billing system is needed.

## 12. Creation, verification, invitations and email

Use existing authentication rather than a second organization login. Personal/Organization registration intent leads through the same account form. Verification gates organization creation and acceptance only; existing personal behavior stays available. Persist a safe return destination through login/verification and reject arbitrary redirect URLs. Changing email clears verification and invalidates old-email links.

Creation validates organization name, country, allowed type and intended use; optional website/phone; unique per-user creation key makes retries return the same result. Create active organization and first admin in one transaction, then offer optional invites. Logo upload follows activation and enforces MIME/content/size on the server, private storage and authorized serving; remove old logo safely.

Invitations are delivered after the invitation transaction commits, with a canonical frontend URL. Store token hashes only, redact acceptance tokens from logs/analytics and avoid third-party page assets leaking link secrets. A token can be consumed from a URL fragment and submitted in an authenticated body, but choose one consistent frontend/email contract and strip it from history once captured. The prototype's generation integer is not a production secret.

Acceptance validates matching current verified email, expiry, revocation, organization/account status and role under locks. Repeated acceptance is idempotent only while the membership remains active; an old accepted invitation must not reactivate a removed/suspended member. Resend rotates secret and restarts seven days; revoke blocks acceptance. Expiry uses server time. Handle delivery failure distinctly from saved invitation state and allow a safe resend without double invitations. Existing mail configuration defaults to `log` when MAIL_MAILER is absent; configure and verify SMTP before calling email delivery functional.

## 13. Implementation sequence and completion gates

| Phase | Work | Gate before continuing |
| --- | --- | --- |
| 0. Baseline | Preserve current dirty work in an isolated implementation workflow; record current tests/lint/build and API contracts; read relevant Stage 10 diff without automatic merge | Scope list agreed, personal/H5P behavior captured; do not overwrite another task's changes |
| 1. Ownership | Add models/schema, workspace lookup, central organization-first authorization, query isolation and capability output behind disabled flag | Legacy personal migration rehearsal and direct-access/creator-removal tests pass |
| 2. Membership | Real verification, creation, invitation lifecycle, membership/last-admin transactions and audit | Email/expiry/rotation/idempotency and simultaneous last-admin tests pass |
| 3. Projects | Scoped list/detail/upload, assignments, organization folders, lifecycle, all nested endpoints/public assets, sharing policy | Independent permissions, cross-tenant/nested ID denial and revocation tests pass |
| 4. Processing | Actor checkpoints, tenant credentials, cancellation-safe publishing, entitlement/usage reservations/reconciliation | Revoked queued/running work and retry/idempotency/provider isolation tests pass |
| 5. Interface | Organization React modules, role navigation, overview/projects/people/activity/settings/info, chooser and responsive bilingual styles | Real API journeys work; no fixture persistence or Demo controls in production |
| 6. Editor integration | Workspace resolution, picker/tab namespaces, dirty switching, permission refresh, personal compatibility | Save/discard/cancel and direct URLs/Back/Forward pass with failed saves and conflicts |
| 7. Control plane | Ultimate-admin organization/account suspension, fallback/entitlement controls and audited support | Ordinary organization admins cannot reach privileged APIs; suspension semantics verified |
| 8. Release | MySQL rehearsal, SMTP, Linux worker/provider/SCORM/LMS checks, controlled flag rollout | Acceptance matrix below signed off with evidence and unresolved limitations |

Implement backend API/schema and frontend as compatible increments. Keep organizations disabled until tenant-aware code is deployed everywhere that can touch organization projects. Prefer small reviewable changes with migration/authorization first, not a frontend-only launch backed by owner-only endpoints.

## 14. Required validation matrix

| Area | Required evidence |
| --- | --- |
| Existing regressions | Current frontend suite/build/lint; backend account/project/folder/sharing/ultimate-admin, preparation/layout/slides/questions/media/narration/course-flow/H5P/package tests. Record baseline failures separately; no rule disabling |
| Isolation | Personal plus two organizations; admin/member/external/public/support roles; lists, counts, search, folders, editor picker, every nested asset route; changing supplied workspace/project IDs grants nothing |
| Ownership | Remove creator; organization retains full project/files; creator loses membership-derived access; personal projects remain personal |
| Permissions | All four edit/download combinations; direct GET/write/upload/render/package/download; UI and API agree; member cannot create/rename/lifecycle/assign/manage folders |
| Membership/concurrency | Suspend preserves assignment, removal clears it, fresh rejoin, last admin each forbidden operation; simultaneous MySQL transactions; global suspension session/token invalidation |
| Invitations | Real test mail, delivery failure/retry, pending/accepted/expired/revoked/mismatch/unverified, seven-day boundary, token rotation, acceptance races, changed email and old-link rejection |
| Sharing | Starts disabled, global/entitlement override, enable/grant/link, confirmed disable/revoke, re-enable does not restore; suspended/removed member cannot bypass; signed-link expiry documented |
| Narration/queues | Personal fallback unchanged, organization key isolation, fallback admin-only, no failure-triggered switching, no secret serialization; removal/suspension before provider/work/publication; native workers and safe previous output |
| Usage | Free/unlimited rendering, accurate definitions, zero/null/finite limits, reservations/races, retry/duplicate completion, release/reconcile, historical storage and successful provider work counted |
| Drafts/routing | Every editor/settings/narration draft, in-flight save/upload, save failure/conflict, discard/cancel, old-tab closure, refresh/direct URLs/Back/Forward, expired login, account switch, blocked sessionStorage |
| UX/accessibility | Admin/member EN/AR at desktop/tablet/390px/320px, actual 200% zoom, long names, no horizontal page overflow, native dialogs/focus restoration, keyboard/drawer, screen-reader labels, contrast |
| Migration/deployment | Production-like restored MySQL plus private-file checksums, unchanged legacy rows/revisions/packages, second migrate, real SMTP/canonical links/CORS, worker restart and recovery |
| End-to-end course | Existing real PPTX through preparation/editing, H5P/media/narration, render/package/download, SCORM validation and Moodle playback; another supported LMS if promising cross-LMS support |

Prototype tests are useful rule examples but use synthetic storage and do not prove production database, authorization, email or queue behavior. Port their assertions into real feature/React tests. Add dedicated suites for organization API, membership/invitations, workspace processing/usage and production organization UI. Historical branch test totals must not be reported as current results.

Run existing commands when implementing (not run as part of this document):

```powershell
# From documents_generator_tools_frontend/
npm test
npm run test:workspace
npm run lint

# From frontend_prototype/ to protect the reference
npm run check
npm test
```

Backend tests must use an explicitly isolated test database. For this Windows environment, the established in-memory SQLite invocation is below. Inspect phpunit.xml/bootstrap first for conflicting connection settings; use a separate shell and do not use these variables for development/production workers. SQLite does not validate MySQL concurrency/locking.

```powershell
# From documents_generator_tools_backend/, dedicated test shell only
$env:APP_ENV = 'testing'
$env:DB_CONNECTION = 'sqlite'
$env:DB_DATABASE = ':memory:'
$env:DB_URL = ''
& 'C:/laragon/bin/php/php8.3/php.exe' -d extension=php_pdo_sqlite.dll -d extension=php_sqlite3.dll vendor/bin/phpunit
```

## 15. Deployment and rollback instructions

Follow [the existing Ubuntu deployment runbook](ubuntu-apache-deployment.md), preserving worker queues and operational settings. The following steps are a release plan, not commands executed by this review.

1. Verify actual target database, PHP extensions, application release, storage disk and queue topology. Back up DB, private project storage and APP_KEY; rehearse restore and migration on isolated production-like MySQL.
2. Add organizations configuration with `ORGANIZATIONS_ENABLED=false`. Configure canonical APP_URL/FRONTEND_URL, mail, stateful domains/CORS and optional organization limits through controlled config, not a browser environment editor. Keep existing local localhost/5173 CORS fixes.
3. Quiesce writes/workers according to the existing maintenance sequence before schema-sensitive deployment. Apply additive migrations; publish tenant-aware API and built frontend as one compatible release. Do not run migrate:fresh or alter existing ownership/file paths.
4. Clear/cache configuration and restart all affected long-running conversion, layout and media/narration workers; reload PHP-FPM as appropriate. Verify health, route cache compatibility and new SPA deep links.
5. Validate existing personal login/dashboard/profile/sharing/editor/upload/package/download first. Then enable organizations only in a controlled acceptance environment, test real verification/invitation mail and complete the matrix above.
6. Enable production onboarding only after acceptance. Monitor tenant-scoped errors, denied publications, mail failures, queue retries and reservation reconciliation without logging secrets.
7. Document disabled-flag behavior for existing memberships and already queued organization work: block ordinary organization use/new processing, preserve audited support and personal access, retain data and safe outputs. The flag is not a substitute for authorization.

Once organization projects exist, never roll back to owner-only code: it would treat creator user_id as ownership and can expose organization data. Disable onboarding/access if necessary, keep tenant-aware authorization and fix forward. Do not drop populated organization tables. A full rollback needs a verified compatible database/storage/application backup and an explicitly reviewed restoration procedure.

## 16. Definition of done and implementer handoff

- All approved prototype screens use production APIs and the navy/teal organization design; existing personal/editor appearance and URLs remain compatible.
- Server authorization, verified onboarding, independent permissions, last-admin protection, sharing revocation, credential isolation and safe queued processing are implemented and tested.
- Project chooser shows all existing project types with their actual availability before real upload; unavailable tools have no callable conversion flow.
- Usage is real and free/unlimited; no sample identities, fake success, fixture storage, Demo controls or billing features are shipped.
- Schema, routes/DTOs, new configuration, worker changes, email contracts and rollback constraints are documented. Updated Stage 10 documentation distinguishes migrated work from remaining gaps.
- Provide EN/AR desktop/mobile screenshots, accessibility findings, exact test/build/lint outcomes, MySQL/SMTP/worker/LMS evidence and explicit remaining blockers. Local test passes alone do not establish production readiness.

Suggested implementation instruction:

> Implement this guide incrementally against the current application, using the standalone organization prototype as the visual/interaction reference and Stage 10 as the business-rule reference. Preserve current personal workspace, studio/H5P changes and API compatibility. Reuse the existing permission service, write locks, React workspace primitives and project catalogue. Start with additive ownership and server authorization behind a disabled organization flag; then implement membership, scoped project workflows, processing/usage, organization screens and editor switching. Do not switch branches or wholesale merge/replace the older feature implementation. Complete the validation and deployment gates, reporting only checks actually run.
