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_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.