# Overview This is a multitenant corporate iistwin platform with a React frontend and an Express backend, designed to provide organizations with independent management of users, projects, and workflows on shared infrastructure. It ensures data isolation, scalability, and security, offering real-time communication and efficient task handling. Key capabilities include custom JS pages, data tables, advanced workflow transitions with conditional approvals, hierarchical subtasks, inline editable tables, and an event-driven notification system. # User Preferences Preferred communication style: Simple, everyday language. Preferred language: Russian — always respond in Russian, no exceptions. # System Architecture ## Frontend The frontend uses React with TypeScript and Vite, employing a component-based architecture with `shadcn/ui`, Radix UI, and Tailwind CSS. Wouter handles routing, TanStack Query manages server state, and React Hook Form with Zod is used for form handling. Authentication is context-based using JWT tokens. ## Backend The backend is built with Express.js, featuring a layered architecture (API, Service, Data Access) and Drizzle ORM for database abstraction. Custom middleware enforces tenant isolation, authentication, and request validation. ## Authentication & Authorization JWT-based authentication uses access and refresh tokens. Role-based access (Admin, User) is enforced, and bcrypt secures passwords. ## Super Admin System A separate system-level super admin panel exists at `/superadmin` (login at `/superadmin/login`). Super admins are stored in the `super_admins` table (no organizationId — system-level users). They authenticate via a separate JWT with `{ isSuperAdmin: true, audience: 'workflow-superadmin' }` checked by `requireSuperAdmin` middleware. The panel shows all organizations with stats (users, tasks, last activity) and allows toggling organization access. First super admin is created via `POST /api/superadmin/seed` (protected by optional `SUPERADMIN_SEED_TOKEN` env var). ## Multitenancy Tenant isolation is implemented at the database (via `organizationId`), API (middleware filtering), and authentication levels. ## Database A PostgreSQL database with Drizzle ORM is used, featuring core entities like Organizations, Users, and User Sessions with serial primary keys and foreign key relationships. ## Security & Legal Compliance ### HTTP Security Headers `helmet` middleware is configured in `server/index.ts` with a Content Security Policy that allows `unsafe-eval` and `unsafe-inline` for the Monaco editor and Babel runtime. `crossOriginEmbedderPolicy` is disabled to support iframe embeds. `frameguard` (X-Frame-Options) is disabled and `frame-ancestors` allows `https://*.replit.dev`, `https://*.repl.co`, `https://*.replit.com` so the app can be embedded in the Replit IDE preview and Canvas. **HSTS and upgrade-insecure-requests** are conditionally enabled per-request when the server detects it is behind an HTTPS reverse proxy. Detection uses two conditions (either is sufficient): 1. `HTTPS_PROXY=true` env var — static override, set in docker-compose or deployment config. 2. `X-Forwarded-Proto: https` request header — sent automatically by Nginx/Traefik/Caddy when proxying HTTPS traffic. When either condition is true: `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` and CSP `upgrade-insecure-requests` are added to the response. When neither is true (plain HTTP dev/local): these headers are omitted. ### Personal Data (152-ФЗ Compliance) - Consent checkbox with link to `/privacy-policy` is required on both registration forms (Register.tsx and InviteRegister.tsx) - Privacy Policy page at `/privacy-policy` (PrivacyPolicy.tsx) explains data processing in accordance with Russian Federal Law 152-ФЗ - Known remaining gaps (for production deployments): DB localization to Russian hosting, replace SendGrid with a Russian email provider, add user data export/deletion self-service UI ### Remaining xlsx Vulnerabilities The `xlsx` (SheetJS) package has 1 high + 7 moderate known vulnerabilities with no fix available upstream. This affects the Excel import/export feature for data tables. ## Real-time Communication The system includes real-time chat with optimistic updates and `@mentions`. Server-Sent Events (SSE) provide instant read receipts and `task_updated` events, with polling as a fallback. ## Server-Side TTL Cache A lightweight in-memory TtlCache (`server/utils/cache.ts`) is used for frequently accessed data like forms and minimal task lists, with a 60-second TTL and invalidation on data changes. ## Custom Data Tables Organizations can create custom data tables with named columns, inline editing, three-tier access control, Excel import/export, and integration as a form field type. ## Workflow Transitions Forms support customizable statuses and transitions with conditional approvals, dynamic approver assignment, and real-time UI updates via SSE. ## Task Tabs System Task fields can be organized into configurable tabs within the form editor, supporting 'fields' or 'table' types. A modular plugin system allows for new tab types and custom declarative tab modules (JSON configurations). These modules support various component types, including `info_panel`, `image_gallery`, `chart`, `tabs`, `layout`, and `formula`, allowing user input storage in `task_tab_values`. ## JS Code Editor for Custom Tabs A `js_component` module type enables writing arbitrary React+JSX code in the browser using the Monaco Editor. Code is executed in a sandboxed environment via `@babel/standalone` and `new Function()`, with a `ctx` object providing access to React, UI components, API calls, user info, task data, and messaging functions. ## Regular Tables Forms can include 'table' type tabs, providing customizable tables with inline editing, various column types (text, number, date, select, table reference), resizable columns, and compact display. ## Hierarchical Subtasks Tasks support unlimited nesting of subtasks with parent-child relationships, automatic numbering, depth tracking, and UI navigation. ## Event-Driven Notification System An event-driven notification system allows users to subscribe to events like `task.created` or `task.status.changed`, delivering notifications via in-app alerts, email, and real-time push via SSE. `@mentions` always trigger notifications. ## Billing System A multi-tenant billing system allows super admins to manage organization balances and pricing. Key features: - `organization_billing` table: per-org settings (balance, pricePerUser, currency, nextBillingDate, blockedAt) - `billing_transactions` table: credit/debit transaction history with descriptions - `billingBlocked` flag on organizations for fast access checks - Billing cycle worker: runs every 24h, charges `activeUsers × pricePerUser`, blocks orgs with insufficient balance - Super admin panel: view/edit billing settings, top up balance, unblock orgs, view transaction history - Org admin billing page at `/billing`: read-only view of balance, active users, estimated charge, transaction history - `billingBlocked` check in `authenticateToken` middleware returns HTTP 402 for non-whitelisted endpoints - Whitelist: `/api/auth/`, `/api/superadmin/`, `/api/billing/`, `/api/health` - Layout.tsx shows a blocking overlay when `billingBlocked=true` (except on `/billing` route itself) - Billing link added to the sidebar dropdown for admins ## File Upload System Form fields of type `file` allow users to upload files to tasks. The system supports two storage backends selected automatically via environment variables: **Local disk mode (default/Replit/dev):** Files saved to `uploads/`, served via `express.static` at `/uploads/`. No extra config needed. **S3/MinIO mode (production/Docker):** Activated when `MINIO_ENDPOINT` env var is set. Files uploaded to MinIO S3 bucket via `@aws-sdk/client-s3`. Served via proxy endpoint `GET /api/files/:key` (streams from S3). File deletion uses `DeleteObjectCommand`. Helper: `server/utils/s3.ts`. Both modes: upload endpoint `POST /api/upload` (multer, 10 MB limit, MIME-type allowlist), protected by `authenticateToken`. Stored field values are JSONB objects `{ url, name, size }`. File deletion correctly handles both single files and arrays — only removes files missing from the new value (`deleteRemovedFiles`). **Docker deployment:** `docker-compose.yml` has `with-minio` profile adding MinIO (ports 9000/9001) and WebDAV via rclone (port 8080) for file browsing from Windows Explorer/Finder. See `DOCKER.md` for full instructions. ## Task Audit Log A chronological history of all task changes is stored in `task_audit_log`, tracking actions like creation, status changes, updates, and field value modifications. This log is accessible via an API and displayed in the UI as a timeline. ## Inline Editing of Task Form Fields Custom form field values can be edited directly on the task detail page. This feature provides type-specific editors, save/cancel actions, and records changes in the `task_audit_log`. ## Task Reminders System Tasks support scheduled reminders with flexible recipient configuration (individual users or roles). A background worker processes and sends these reminders via the notification system. ## Push Notifications Infrastructure The system includes infrastructure for mobile push notifications with tenant isolation, using `device_tokens` for FCM/APNs, `user_presence` for online status, and a push queue for offline users. ### VAPID Keys for Web Push Web push notifications require stable VAPID keys. Without them, new keys are generated on every server restart, invalidating all existing browser push subscriptions. **Setup (one-time):** Generate permanent keys and set them as environment secrets: ```bash npx web-push generate-vapid-keys ``` Set the output as `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY` in your environment secrets (Replit Secrets tab or `.env` for Docker). If keys are missing, the server logs a warning and generates temporary keys for that session only. See `DOCKER.md` → "Генерация VAPID-ключей для веб-пушей" for Docker deployment instructions. ## Mobile UI Adaptations The UI adapts for mobile devices (screen width <768px), with chat always in a separate tab and a visible tab selector. ## Progressive Web App (PWA) The system supports PWA installation, offering offline access and push notifications via `manifest.json`, a Service Worker (`sw.js`), and a PWA Install Button. ## Global Fields System Reusable global fields with pre-filled settings (type, options, validation) can be used across all organization forms. They serve as templates, and changes to global fields do not affect existing form fields. ## Automations System JavaScript automations stored in the `automations` table allow server-side code execution in a Node.js `vm` sandbox in response to triggers (`manual`, `task.created`, `task.status_changed`). A `ctx` object provides logging and access to forms and tasks. ## JS Layout Editor for Task Detail Page Admins can write custom React/JSX components to replace the default field display on any task detail page. The code is stored in `forms.detailLayoutCode` and edited via a Monaco editor in the FormEditor. ## Task Relations System Many-to-many task relations are stored in `task_relations`, created automatically via "task" type fields or manually via a "Link" button in chat. Related tasks are displayed in a dedicated UI tab, showing a flattened list grouped by form. ## Performance Optimizations Optimizations include aggregated API endpoints, React Query caching, server-side pagination with sorting, strategic database indexing, and server-side computation of user `fullName`. # External Dependencies ## Database - **Neon Database**: Serverless PostgreSQL database. - **Drizzle ORM**: Type-safe database toolkit. ## Authentication & Security - **JWT**: JSON Web Tokens. - **bcrypt**: Password hashing. - **Express rate limiter**: For API protection. ## Email Services - **SendGrid**: Email delivery service. ## UI Frameworks - **Radix UI**: Unstyled, accessible UI primitives. - **Tailwind CSS**: Utility-first CSS framework. - **shadcn/ui**: Pre-built component library. ## Development Tools - **Vite**: Build tool and development server. - **TypeScript**: Static type checking. ## Code Editor & JS Runtime - **@monaco-editor/react**: Monaco Editor for in-browser JavaScript editing. - **@babel/standalone**: In-browser Babel for JSX transformation. ## HTML Sanitization - **dompurify**: For safe HTML rendering.