f4d99b6cfd
Task #372: Replaced the manual PDFKit coordinate-based PDF renderer with an HTML table-based approach using Playwright's headless Chromium. Key changes: - Created `pdf-html-renderer.ts` with `buildScheduleHtml()` (generates full HTML with embedded base64 fonts, proper `<table>`, RTL/LTR support, row colors, merged cells, attendees formatting) and `htmlToPdfBuffer()` (renders HTML to PDF via Playwright Chromium). - Updated `pdf-renderer.ts`: `renderSchedulePdf()` now delegates to the new HTML renderer via dynamic import. Legacy PDFKit code preserved as `renderSchedulePdf_LEGACY()` for fallback reference. - Added `playwright-core` dependency and configured esbuild externals. - Chromium binary discovery: searches `.cache/ms-playwright/` directories with env var override (`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH`). Browser instance is cached as singleton with launch mutex to prevent concurrent double-launch. - Process shutdown hook closes browser on exit. Requirements met: - Each meeting in exactly one `<tr>` with 4 `<td>` cells - No text outside table, attendees ~3 per line inline - Time always in its column, `page-break-inside: avoid`, `table-layout: fixed` - Matches reference design (blue header, centered text, DIN Next LT Arabic)
66 lines
7.0 KiB
Markdown
66 lines
7.0 KiB
Markdown
# Tx OS
|
|
|
|
## Overview
|
|
|
|
Tx OS is a bilingual (Arabic/English), full-stack internal web platform designed with an OS-like interface and glassmorphism aesthetics. It aims to provide a comprehensive suite of internal tools and services, enhancing user experience and operational efficiency within the organization. The project focuses on delivering a visually appealing and highly functional platform.
|
|
|
|
## User Preferences
|
|
|
|
I want iterative development.
|
|
Ask before making major changes.
|
|
Do not make changes to the folder `artifacts/api-server/tests`.
|
|
Do not make changes to the folder `artifacts/tx-os/tests`.
|
|
Do not make changes to the folder `lib/db/scripts`.
|
|
Do not make changes to the file `artifacts/api-server/src/lib/pdf-renderer.ts` (legacy PDFKit code kept for fallback).
|
|
Do not make changes to the file `artifacts/api-server/src/lib/pdf-html-renderer.ts` (HTML-table PDF renderer via Playwright).
|
|
Do not make changes to the file `artifacts/tx-os/src/App.tsx`.
|
|
Do not make changes to the file `artifacts/tx-os/src/components/executive-meetings/upcoming-meeting-alert.tsx`.
|
|
Do not make changes to the file `artifacts/tx-os/src/pages/executive-meetings.tsx`.
|
|
Do not make changes to the file `artifacts/tx-os/src/locales/ar.json`.
|
|
Do not make changes to the file `artifacts/tx-os/src/locales/en.json`.
|
|
Do not make changes to the file `lib/api-client-react/src/custom-fetch.ts`.
|
|
Do not make changes to the file `lib/db/src/schema/executive-meetings.ts`.
|
|
Do not make changes to the file `scripts/post-merge.sh`.
|
|
|
|
## System Architecture
|
|
|
|
The project is structured as a pnpm monorepo.
|
|
|
|
### UI/UX Decisions
|
|
- **Bilingual Support**: Arabic (RTL) and English (LTR) with user-persisted locale settings.
|
|
- **Glassmorphism OS UI**: Features animated gradient backgrounds and frosted glass panels.
|
|
- **OS Home Screen**: Includes a live clock status bar with customizable styles, an app grid, and a bottom dock.
|
|
- **Custom Attendee Subheadings**: Allows interleaving free-text section headers within attendee lists in Executive Meetings, distinct from person rows.
|
|
- **Shared Row Colors**: Executive Meeting schedule row colors are stored on the meeting object itself, ensuring consistent viewing across all users and devices.
|
|
|
|
### Technical Implementations
|
|
- **Monorepo**: Managed with pnpm workspaces.
|
|
- **Backend**: Node.js 24 with TypeScript 5.9, using Express 5, `express-session` with `connect-pg-simple` for PostgreSQL sessions, `bcryptjs` for hashing, and Socket.IO for real-time communication.
|
|
- **Database**: PostgreSQL with Drizzle ORM for schema definition and Zod for validation.
|
|
- **API Codegen**: Orval is used to generate React Query hooks and Zod schemas from an OpenAPI specification.
|
|
- **Frontend**: Built with React and Vite, styled using Tailwind CSS v4, `wouter` for routing, and `i18next` with `react-i18next` for internationalization.
|
|
- **Authentication**: Session-based authentication with Role-Based Access Control (RBAC) supporting admin and user roles.
|
|
- **Real-time Features**: Implemented using Socket.IO for chat and real-time notifications.
|
|
- **Executive Meetings Module**: A comprehensive module with scheduling, CRUD operations for meetings, change requests, approvals, tasks, notifications, and an audit log. RBAC is enforced via five role sets (READ/MUTATE/APPROVE/REQUEST/ADMIN_AUDIT). All mutations are wrapped in database transactions to ensure data consistency and atomic audit logging.
|
|
- **Optimistic Locking**: Implemented for Executive Meeting postponements to prevent concurrent updates from silently overwriting changes, using `expectedUpdatedAt` and returning a 409 conflict on mismatch.
|
|
- **Upcoming Meeting Alert**: A global, draggable alert component appears when an Executive Meeting is within five minutes of starting, providing options to postpone, reschedule, or cancel the meeting.
|
|
- **PDF Generation (HTML Table)**: Executive meetings PDFs are now generated via a real HTML `<table>` rendered by Playwright's headless Chromium (`pdf-html-renderer.ts`). This replaced the manual PDFKit drawing approach to guarantee each meeting occupies exactly one `<tr>` row with 4 `<td>` cells (number, title, attendees, time). The Chromium binary is auto-discovered from `.cache/ms-playwright/` or via `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` env var. The browser instance is cached (singleton with launch mutex) and closed on process exit. The legacy PDFKit renderer is preserved as `renderSchedulePdf_LEGACY` in `pdf-renderer.ts` for fallback reference.
|
|
- **Custom Editor Fonts**: The in-place rich-text cell editor (attendee names, meeting titles, etc.) ships a curated set of self-hosted Arabic + Latin font families (DIN Next LT Arabic, Tajawal, Helvetica Neue LT Arabic, Helvetica Neue, Majalla) declared in `artifacts/tx-os/src/custom-fonts.css` with `font-display: swap`. Files live under `artifacts/tx-os/public/fonts/`. The site default body font is **DIN Next LT Arabic** (`--app-font-sans` in `index.css`), and Google Fonts is no longer fetched at page load. The Executive Meetings **Font Settings** page exposes the same five families plus `system` as the user/global picker; the values are kept in lockstep with the backend Zod allowlist (`FONT_FAMILIES` in `routes/executive-meetings.ts`), the rich-text sanitizer's font-family allowlist (`FONT_NAME_PART` in `lib/sanitize.ts`), and the PDF renderer's family map (`FAMILY_MAP` in `lib/pdf-renderer.ts`). When adding or removing a family, update all four locations together. Note the intentional asymmetry of the `system` value: in the web UI it resolves to whatever the CSS default is (currently DIN Next LT Arabic, a sans family), while in server-side PDF rendering it maps to the bundled Naskh stand-in (`NotoNaskhArabic`) — PDFs are document-style output where Naskh is the more conventional Arabic body face, so this is by design.
|
|
- **Tab Quick-Add Attendees**: Pressing Tab inside an attendee name cell commits the current value and immediately opens a new pending attendee row right after, so users can keep typing names without using the mouse. Implemented via an `onTabNext` prop on `EditableCell` and a `chainStartAdd` prop on `AttendeeFlow` that bypasses the single-pending UI gate (the parent's state-level guard still prevents truly overlapping pendings).
|
|
|
|
### Feature Specifications
|
|
- **خدماتي (My Services)**: Displays a grid of service cards with availability status.
|
|
- **Internal Chat**: Real-time messaging with conversation lists via Socket.IO.
|
|
- **Notifications**: Tracks unread notifications and provides a "mark all as read" function.
|
|
- **Admin Panel**: CRUD functionalities for applications, services, and users. Includes dependency warnings on deletion and transactional app creation with pre-set permissions.
|
|
|
|
## External Dependencies
|
|
|
|
- **PostgreSQL**: Primary database for the application.
|
|
- **Drizzle ORM**: Used for database interactions and schema management.
|
|
- **Socket.IO**: For real-time communication features like chat and notifications.
|
|
- **Orval**: API code generation tool.
|
|
- **i18next & react-i18next**: For internationalization.
|
|
- **Tailwind CSS v4**: CSS framework for styling.
|
|
- **Vite**: Frontend build tool.
|
|
- **Express 5**: Backend web framework. |