How Cmash can your IT Department!

Cmash — Featured Explained for the IT Department

Every feature of the Cmash platform, explained for the people who install, run, secure and integrate it.

This guide describes every Cmash feature in plain language. Each feature has a purpose (what it is and why it exists) and How it helps you (what it means for IT in practice).


1. Platform Foundation

Feature: Modular Package Architecture

Purpose: Cmash is not one monolith. Each capability is an independent Composer package (enobis/cmash-*) that ships a Laravel service provider and a Filament plugin. You install only the modules you need and register their plugins in the admin panel.

How it helps you: You keep the deployment surface small and the upgrade path clear. Each module is versioned and updated on its own. Behaviour stays consistent across modules because they share traits and components from the core. Pin the full module set you use, because some modules use others in code without declaring them in composer.json (see section 10).

Feature: Standard Laravel and Filament Stack

Purpose: The platform runs on PHP 8.3+, Laravel 13, Livewire 4 and Filament 5. The reference application builds its frontend with Tailwind 4 and Vite 8.

How it helps you: There is no proprietary runtime. Your team uses familiar tools: Composer, Artisan, queues, the scheduler, Eloquent and standard Laravel deployment practice. Hiring, debugging and monitoring follow what you already know.

Feature: Branded Admin Panel

Purpose: The core provides the admin panel with login, dashboard, navigation groups (Configuration, Content, Projects, Typst, Settings) and widgets. The header and login screen show either the logo or the application name (APP_NAME_OR_LOGO).

How it helps you: Support staff and editors work in one consistent interface. The dashboard widgets give a quick overview. Some widgets depend on other Cmash packages (for example the editor and typst packages) and appear when those are installed.

Feature: Shared Behaviours Across Modules

Purpose: The core supplies traits that every module reuses: assignee, creator tracking, "used by" cross-references, revision tracking and tagging.

How it helps you: You learn a behaviour once. Revisions, tags and "used by" work the same way for templates, forms, brandkits, documents and assets. This reduces training effort and unexpected differences in support cases.


2. Installation and Server Requirements

Feature: Clear Binary and Extension Requirements

Purpose: The platform calls external tools for rendering and colour work. The documentation separates what is required, what is needed for specific features and what is opt-in.

Level Item Used for
Required PHP 8.3+, ext-zip, ext-dom, ext-fileinfo, ext-libxml Core, embed, project, typst, addons, asset
Required typst binary (TYPST_BINARY) All compilation
Required Queue worker and schedule:run Asset processing, imports, batches, backups
Feature-specific qpdf PDF/X-4 finishing and merged batch PDFs
Feature-specific Imagick with LittleCMS ICC-managed digital and print variants
Feature-specific tar, internet access Addon installs from Typst Universe or GitHub
Feature-specific mysqldump/mysql, pg_dump/psql, sqlite3, gzip Database backups and restores
Opt-in Ghostscript, pStill, img2pdf Alternative conversion and PDF/X backends

How it helps you: You can plan the server image and the container build up front. Without Imagick/LittleCMS, plain asset storage still works. Ghostscript and pStill are off by default. The switches are technical only and are not licence grants, so review licensing before enabling them.

Feature: System Info Page

Purpose: A diagnostics page shows PHP, Laravel, Filament and Cmash versions, installed Cmash packages, PHP extensions, server software, the Typst version, image-handling capabilities (PNG, JPG, SVG, GIF, PDF, WEBP; TIFF/HEIC/PSD with Imagick; BMP with Imagick or GD), pending and failed jobs, scheduled tasks and a crontab check.

How it helps you: After a deployment you can confirm in one screen that binaries are found, the scheduler runs and the queue is healthy. Support can ask users for a screenshot instead of shell access.


3. Access Control and Security

Feature: Role-Based Permissions (Filament Shield)

Purpose: Permissions are generated per resource and page on top of Spatie Permission, such as View:<Page>, ViewAny, Create, Update and Delete. Special permissions ManageSystemEntities and ManageSampleEntities protect built-in content. Some settings pages and the job queue require specific permissions or the super_admin role.

How it helps you: You map your organisation's roles to precise capabilities without writing code. Editors can work on content while only a few people can change settings, variant types or the job queue.

Feature: User Management and API Tokens

Purpose: The core manages users, roles and Sanctum API tokens in the admin.

How it helps you: Integration accounts get their own tokens, which you can issue and revoke without touching the application's password flow. Creator tracking records which token created a record.

Feature: Group-Based Tenant Scoping

Purpose: Users can be restricted to one or more groups (brands, departments or customers). The restriction is enforced in the admin and in the API. The group switcher in the panel is only a convenience for filtering.

How it helps you: A partner or regional team sees only its own content, even through API calls. The server enforces the boundary, so it does not rely on UI behaviour. Document, template, form, brandkit and asset records can all be scoped.

Feature: Signed, Expiring Editor URLs

Purpose: The embed module issues HMAC-signed editor links at /embed/editor/{project}. They expire after url_lifetime (default 1440 minutes). Tampered or expired links are rejected. Optional theme_mode and custom_toolbar_width can be appended without breaking the signature.

How it helps you: End users can edit without accounts, while access stays time-limited and tamper-proof. Your shop or portal requests a fresh link when needed.

Feature: Framing Control

Purpose: The embed module sets Content-Security-Policy frame-ancestors from the allowed_origins list. * allows all origins. When specific origins are set, 'self' is added automatically. The default framing block is removed for these pages only.

How it helps you: You decide which sites may embed the editor. Everything else in the application keeps the default protection against clickjacking.

Feature: Server-Side Private Data

Purpose: Projects carry a private_data field that is stored server-side and never serialised to the browser editor.

How it helps you: Your shop can pass order numbers, customer identifiers or pricing context into a project without exposing them to the end user's browser.

Feature: Content-Based Upload Validation

Purpose: Uploaded file types are detected from the actual content, not from the file name or the client-supplied MIME type. One shared rule applies to admin, API and editor uploads. Accepted labels include JPEG, PNG, GIF, SVG, TIFF, BMP, WebP, HEIC, PSD and PDF. The exact list depends on the converters installed in core.

How it helps you: Renamed or disguised files are caught. You maintain one validation rule rather than three, and security reviews have a single place to check.

Feature: Protected System and Sample Content

Purpose: System and Sample entities are read-only unless the user has the matching permission.

How it helps you: Built-in content cannot be changed or deleted by accident, which keeps shipped defaults reliable.

Feature: Origin Protection on Templates

Purpose: Templates record their origin (Internal for the admin, External for the API) and are origin-protected.

How it helps you: You can tell at a glance whether content was created through the admin or an integration, and you can prevent integrations from overwriting admin-managed content.


4. Integration and API

Feature: Token-Secured REST API

Purpose: The platform exposes JSON REST endpoints secured by Laravel Sanctum bearer tokens.

Resource Base path
Documents /api/documents
Projects /api/projects (+ POST /{project}/render)
Forms /api/forms (with schema endpoint)
Templates /templates
Workspaces /workspaces
Groups /api/groups
Brandkits /api/brandkits
Tags /api/tags (+ /tree, /{uuid}/children)
Assets /api/assets
User assets /user-assets
Typst /typst/fonts, /typst/snippets, /typst/compilations

How it helps you: Anything an editor can do in the admin can largely be automated. List endpoints support filters (search, tags with any/all matching, workspace, active state) and pagination. API users are bound by the group restrictions of the token's user.

Write scope is deliberately limited in places. The document API does not accept state or tags on write, and the brandkit API leaves phrases, variables, assets and imports to the admin. Plan manual steps for those if you automate.

Feature: Embed API for Shops and Portals

Purpose: /api/embed lets an external system create a project from a document, update its data, obtain a signed editor URL, render or download output, and track batches.

Step Endpoint
Create project POST /api/embed/projects
Read or update GET/PUT /projects/{uuid}
New editor link GET /projects/{uuid}/editor-url
Render (pdf, png, svg) POST /projects/{uuid}/render
List renderers and URLs GET /projects/{uuid}/download-options
Download with a renderer POST /projects/{uuid}/download/{rendererUuid}
Batch download POST /projects/{uuid}/download-batch/{rendererUuid} (async or ?sync=true)
Batch progress and result GET /batches/{batchUuid}/status, /download (409 while running)

How it helps you: Your developers integrate in a few calls. A new project inherits template, form, workspace, brandkit, group, preflight setting and tags from its document, so the integration sends only what is specific to the order.

Feature: Browser Bridge (cmash-bridge.js)

Purpose: A JavaScript bridge over postMessage, publishable to public/vendor/cmash-embed. Methods: connect(), preflightCheck(), getVariables()/setVariables(), setZoom(), getDataCollection()/setDataCollection(), importCsvData(rows, mode) and destroy().

How it helps you: The host page can read and write variables, trigger a preflight check, import CSV rows and control zoom without custom protocols. The bridge uses plain postMessage. Earlier documentation mentioned Penpal, which the current code does not use.

Feature: Web-to-Print Customer Portal

Purpose: The w2p-portal package provides a ready-made customer front end and a separate Filament admin panel that talk to the Cmash W2P API with an API key. The editor embeds by iframe or JavaScript SDK. Panel access is controlled by the w2p-admin-access gate (default is_admin), which you can override in your AuthServiceProvider.

How it helps you: If you do not want to build a front end, you can start with the portal. Config, views, translations and migrations are publishable (w2p-config, w2p-views, w2p-lang, w2p-migrations). W2P_ASSETS=cdn runs without a front-end build, while vite suits custom builds. Settings stored in the panel appear to take precedence over the config file for API URL, key, editor type and tag filter. This is inferred from the panel's read logic and was not confirmed in the API service.

Feature: Generated API Documentation

Purpose: Earlier documentation states that the core generates OpenAPI documentation for the API (not re-verified in this review).

How it helps you: Integration teams can work from a machine-readable description. Confirm it in your installation before promising it to partners.


5. Rendering Pipeline

Feature: Typst Compilation to PDF, PNG and SVG

Purpose: Templates are Typst sources compiled by the external typst binary. Each compilation runs in its own temporary directory. Brand variables, form values and structured data are injected. Full compilations store status (pending, compiling, completed, failed), duration, error log and output. Previews return SVG (single or all pages) without storing a record. TYPST_TIMEOUT (default 60 s) bounds each run.

How it helps you: Output is deterministic and isolated, so one broken job cannot affect another. The error log is stored per compilation, which makes failures easy to diagnose without server access.

Feature: Data Injection into Templates

Purpose: Templates read data through #let variables, {{placeholders}}, CLI inputs and a structured data.json. Files for colours, fonts, phrases and variables are generated and auto-imported at compile time. Active snippets are available as snippets/<slug>.typ, next to a shared cmash.typ library.

How it helps you: Template authors do not have to wire brand data by hand, and IT does not need to deploy template changes. Everything is data-driven from the admin.

Feature: Renderer Profiles

Purpose: A renderer defines the output type and settings.

Type Options
PNG ppi (default 144), embed_resolution_metadata (pHYs)
PDF pdf_version 1.4–2.0 or auto; PDF/A-1a/1b, 2a/2b/2u, 3a/3b/3u, 4/4f/4e; PDF/UA-1; PDF/X-4 (needs 1.6); no_pdf_tags (forced on for PDF/UA-1)
Common asset_variant_type_id, variant_fallback_chain, batch_output_format (ZIP or combined PDF), post-processing hooks

How it helps you: You offer several output profiles (for example screen PDF, print PDF, PNG preview) from the same project. Invalid combinations are rejected on save. A Test PDF Settings action compiles a small sample, and an output-capabilities report shows what the server can produce.

Feature: PDF/X-4 Finishing

Purpose: After Typst creates the PDF, qpdf stamps the OutputIntent, page boxes and XMP identification. A preflight runs and its result is stored per compilation. The OutputIntent comes from the colour profile of the asset variant type the renderer uses, with an optional override recorded in the report. Nothing is colour-converted or flattened in this step.

Failure policy per renderer is fail (default) or warn. Backends are qpdf (default), pstill and ghostscript. There is no automatic fallback between backends. PDF/X cannot be combined with PDF/A or PDF/UA.

How it helps you: Print-ready output is part of the pipeline. Choose the backend deliberately for your licensing and quality needs. The documentation does not claim certification, so validate final PDFs against your printer's requirements.

Feature: Batch Rendering

Purpose: A project's data_collection (a JSON array of per-item overrides) produces many outputs in one run. A batch tracks total, completed and failed items and duration, and links to a project and renderer. Output is a ZIP of individual files or one PDF assembled with qpdf. Assembly time-out: CMASH_BATCH_OUTPUT_TIMEOUT (120 s).

How it helps you: Large runs such as name badges or personalised mailings run asynchronously on the queue. Callers poll the status endpoint, so web requests do not time out.

Feature: Typst Fonts, Snippets and Packages

Purpose: Fonts and reusable snippets are managed in the admin. The Addons page installs Typst packages from Typst Universe, GitHub or ZIP into configurable paths (TYPST_PACKAGES_PATH, TYPST_LOCAL_PACKAGES_PATH, TYPST_REGISTRY_URL). A manifest records each install, and typst:packages:restore rebuilds a fresh server from it. ZIP-installed packages cannot be restored automatically. The --force option is declared but no code using it was found.

How it helps you: Template capabilities grow without a deployment. Point TYPST_REGISTRY_URL at an internal mirror for restricted networks. Both package folders are part of media backups.

Feature: Template Editor Integration

Purpose: The typst-editor package adds full-screen editor and preview pages that embed the editor in an iframe. The plugin registers TemplatePreview. TypstEditor::canAccess() returns true, so any panel user can open the pages.

How it helps you: Authors design and preview in the admin. Review the access rule against your own access model.


6. Assets and Colour Management

Feature: Central Asset Library

Purpose: The asset module stores images and graphics with metadata, tags, active state and thumbnails. Deletion guards protect assets that are in use, and deleting an asset removes its variants, thumbnails and cached detection files.

How it helps you: One governed library replaces scattered folders. Accidental deletion of in-use files is prevented.

Feature: Original Preservation and Variants

Purpose: The original and its source ICC profile are always kept. Variants are generated per variant type: Digital (sRGB) or Print (CMYK per press condition). Status values are pending, ready, stale and failed.

How it helps you: Source quality is never lost. If a profile changes, affected variants become stale and are rebuilt. You can always regenerate.

Feature: ICC-Managed Conversion

Purpose: LittleCMS via Imagick converts between RGB, CMYK and Grayscale using profiles from the colour profile library. A CMYK PDF that provably contains only CMYK and matches the target profile is reused byte for byte.

How it helps you: Conversions are consistent and avoid needless re-encoding. The documentation is explicit that this supports the workflow but does not certify assets for PDF/X.

Feature: Configurable Conversion Pipelines

Purpose: Pipelines are data in the admin: source MIME type, purpose, target format (PDF, JPG, PNG, SVG), converter steps, priority and active state. An availability check shows what the server supports, and shipped defaults can be restored. Optional converters (Ghostscript, img2pdf) are enabled by environment switches. Rasterisation limits: pdf_timeout 30 s, pdf_raster_dpi 300, pdf_max_pixels 40 000 000, svg_user_unit_dpi 96.

How it helps you: You tune conversion behaviour without code changes and see which converters your server can actually run.

Feature: On-Demand Variant Generation and Policies

Purpose: Modes sync, queue and off control when variants are created. Budgets are 15 000 ms per render, 5 000 ms per editor preview and 3 s lock wait. The missing-variant policy is strict (error) or lax (warning and fallback), set separately for the library and for user uploads. The fallback chain is: specific type, default Digital, default Print, original.

How it helps you: You trade latency against strictness. Strict mode guarantees print quality. Lax mode keeps users unblocked. Time budgets protect the server from slow conversions.

Feature: Asset Preflight Thresholds

Purpose: Preflight checks compare assets against min_dpi (300), min_width/min_height (100) and allowed_colorspaces (RGB, CMYK, Grayscale).

How it helps you: Low-resolution or wrong-colourspace files are flagged before they reach print.

Feature: Manual Variant Upload

Purpose: Digital variants accept JPEG or PNG. Print variants accept JPEG or PDF. Uploads are protected from automatic overwrite, with a size limit manual_upload_max_kb (20480).

How it helps you: Designers can supply hand-tuned files and rely on the system not replacing them.

Feature: Scheduled Folder Imports

Purpose: cmash:run-asset-imports runs every minute, while each import job has its own cron. A file must be stable for file_stable_seconds (30) before pickup. Failed files move to an error/ folder, overlap is prevented and logs are detailed.

How it helps you: Agencies or other systems can drop files on a share and they appear in the library. A half-copied file will not be imported.

Feature: Variant Reset and Maintenance

Purpose: cmash:reset-asset-variants --force backs up records and files, then removes variants. Originals, thumbnails and source profiles are kept.

How it helps you: After changing profiles or pipelines you can rebuild cleanly with a safety net.

Feature: Job Queue Monitor

Purpose: A page for super admins shows pending, failed and batched jobs, with retry, forget and flush.

How it helps you: You manage stuck conversions from the admin instead of the command line.

Feature: Customer Uploads (User Assets)

Purpose: End users upload their own images. Missing colour profiles get a default for screen images. Where one cannot be assumed, the user must confirm, which triggers print-file generation. Print variants follow the user_asset_variant_type_ids setting. Originals are kept even if conversion fails.

Commands:

  • cmash:reprocess-user-assets [--missing-profile] [--user=ID] [--dry-run]
  • cmash:purge-user-assets {user} [--force] for privacy and deletion requests

How it helps you: Customer images become print-capable without manual work. You can reprocess after changing settings and honour deletion requests with one command.


7. Content Model and Data

Feature: Templates, Forms, Brandkits, Workspaces, Documents and Projects

Purpose: The content model separates concerns.

Entity Role
Template Typst source, design tokens and layouts
Form SurveyJS JSON schema, multilingual, group-scoped
Brandkit Colours, assets, fonts, phrases, variables and imports
Workspace Renderers, editor theme, sidebar layout and save-button toggle
Document Bundle of template, form, brandkit, workspace and group. Published or unpublished
Project An instance of a document with user data

How it helps you: Each piece is managed independently. Changing a brand colour in the brandkit updates every document that uses it. Publishing a document makes it available through the API.

Feature: Project Data Model

Purpose: Projects have data (flat JSON visible to the browser and template), data_collection (JSON array for batches) and private_data (server-only). States are Temp (default), Draft and Finished. Deleting a project also removes its rendered files.

How it helps you: Storage and cleanup behaviour is predictable. The three data fields give you a clean split between public, bulk and secret information.

Feature: UUIDs and Slugs

Purpose: Records carry UUIDs and the API addresses most resources by UUID or slug.

How it helps you: Identifiers are stable across environments and safe to expose in URLs.

Feature: Tagging and Hierarchical Tag Types

Purpose: The tag module provides tag types and a five-level hierarchy, a tag picker, filter and column, and query scopes with any, all and none matching by ID or UUID. A model becomes taggable with the HasCmashTags trait. The Brandkit tag type exists but is not enabled in the tag manager.

How it helps you: Content classification is shared by all modules. API consumers filter by tag, and the portal can restrict visible documents with a tag filter.

Feature: Revision History with Restore

Purpose: Versioned entities store a snapshot per save with a diff view and one-click restore. max_revisions caps the count (0 = unlimited). A maintenance action deletes revisions older than N days.

How it helps you: You get an audit trail for content changes and quick rollback. Control database growth with the cap or the clean-up action.

Feature: Duplicate and "Used By"

Purpose: Records can be duplicated. "Used by" lists show which records depend on an item.

How it helps you: Before deleting or changing a shared asset, brandkit or form, you see the impact. Duplication speeds up variants of existing content.

Feature: Multilingual Content

Purpose: English and German are provided for the interface. Content languages are configurable per group, form and general setting (available_locales). The portal documents how to add a language. Note that the document and group APIs validate a single language while the model uses a languages array. Test language handling on API writes.

How it helps you: One setup serves several markets. Check the API behaviour before automating multilingual content.


8. Operations and Reliability

Feature: Built-In Database and Media Backups

Purpose: Gzipped database dumps support MySQL/MariaDB, PostgreSQL and SQLite. Media backups are tar.gz archives of uploaded assets, user assets, brand and brandkit logos, document images, Typst fonts and Typst packages. Admin actions create, download, restore and delete backups. Retention is *_max_keep (default 7 each). Commands: cmash:backup-database and cmash:backup-media.

How it helps you: You get a working backup baseline without extra tooling. Download endpoints require a logged-in user. You should still copy backups off the server as part of your disaster-recovery plan.

Feature: Scheduled Jobs

Purpose: Database backup (db_backup_cron, default 0 2 * * *), media backup (media_backup_cron, default 0 3 * * *) and asset imports (every minute) run through the Laravel scheduler.

How it helps you: A single schedule:run cron entry drives everything. The schedules for backups are editable in the admin without a deploy.

Feature: Runtime Settings in the Admin

Purpose: Core General Settings (site name, locales, primary colour, content width, group selector, revision limit, backup schedules) and Asset Settings (thumbnail rules, variant defaults, policies, budgets, preflight thresholds) are stored in the database via Spatie Settings. enable_code_editor is stored but not shown on the settings page.

How it helps you: Operational tuning needs no deployment. Environment variables are reserved for binaries, timeouts and routing.

Feature: Diagnostics and Auditability

Purpose: Compilation history records status, duration, output and error log per compilation and batch. Render and download endpoints return diagnostics in response headers. Records carry creator and origin and, where relevant, the API token used.

How it helps you: You can answer "who created this, when and through what" and trace failed renders quickly.


9. Extensibility

Feature: Filament Plugins per Module

Purpose: Every package registers as a Filament plugin, for example CmashTypstEditorPlugin.

How it helps you: You can add, remove or replace modules in the panel without touching others.

Feature: Reusable UI Components

Purpose: Core and tag provide translatable text inputs, a colour picker, a tag select, filter and column, and an asset picker table.

How it helps you: Your own Filament resources get the same controls and look as the standard modules.

Feature: Data-Driven Extension Points

Purpose: Conversion pipelines, Typst snippets, packages, renderers and post-processing hooks are configured as data rather than code. Asset processing emits events other modules can react to.

How it helps you: Many changes are admin tasks rather than development tasks. Developers can still hook in through events.

Feature: Datasource Addons

Purpose: Earlier documentation describes custom datasource types as addon packages with NP Portal as the reference (not part of this review).

How it helps you: Treat this as a planned extension route. Check the datasource package before relying on it.


10. Known Points to Review Before Rollout

# Finding What to do
1 Document, embed and renderer use cmash-group, cmash-datasource, cmash-project, cmash-asset and cmash-hook in code without requiring them in composer.json Install the full module set. A partial install may fail at runtime
2 cmash-form and cmash-surveyjs both register /api/forms and a FormResource Test which one applies before installing both
3 language vs languages mismatch in document and group APIs Test language writes
4 Limited API write scope (state, tags, brandkit phrases and variables) Plan admin steps
5 TypstEditor::canAccess() returns true Check against your access model
6 Workspace has both CmashWorkspacePlugin and CmashWorkspacesPlugin Clarify the canonical one
7 typst:packages:restore --force is declared but unused Do not rely on it
8 Embed and surveyjs preview links assume the panel is at /admin Adjust if you changed the path
9 AES-256 credential encryption and SSRF-protected image proxy were documented earlier for the datasource package, which was not reviewed Verify in that package
10 git fetch failed, so the source is the last fetched origin/main. Several packages are behind their remote Re-run the review against current branches

11. Quick Reference: What IT Gets

Need Cmash feature
Self-hosting on a standard stack PHP 8.3, Laravel 13, Filament 5
Fine-grained access Shield permissions, group scoping
Safe external editing Signed expiring URLs, framing control, private data
Integration Sanctum REST API, Embed API, postMessage bridge, ready-made portal
Print-ready output Renderer profiles, PDF/X-4 via qpdf, ICC-managed variants
Large runs Batch rendering on the queue
Health checks System Info, job queue monitor, compilation history
Recovery Database and media backups, revision restore, Typst package manifest
Change tracking Revisions, creator and origin, API token tracking
Growth Filament plugins, shared traits, data-driven pipelines

Cmash — Professional documents, created by anyone, at any scale.