midway-fatcms
v0.0.9
Published
This is a midway component sample
Readme
Midway FatCMS
Why Midway FatCMS?
Stop writing repetitive CRUD boilerplate. Stop struggling with API versioning. Stop worrying about multi-tenant data isolation.
Midway FatCMS is a battle-tested, enterprise-grade low-code platform that transforms weeks of development into hours of configuration. Built on top of the robust Midway.js framework, it empowers teams to ship faster without sacrificing security, scalability, or control.
The Problem We Solve
| Traditional Development | With Midway FatCMS | |------------------------|-------------------| | 2 weeks to build a CRUD module | 15 minutes of configuration | | Manual API documentation | Auto-generated, always in sync | | Complex multi-tenant logic | Built-in tenant isolation | | Hand-coded sharding & pagination | Cross-shard queries out of the box | | Reinventing the wheel | Production-ready building blocks |
Core Engines
CRUD-Pro Engine — Zero-Code Data Operations
Transform database tables into fully functional REST APIs with zero code. CRUD-Pro is the heart of Midway FatCMS, providing configuration-driven SQL execution with built-in validation, security, and multi-database support.
Features:
- Instant CRUD — Auto-generated Create, Read, Update, Delete endpoints via
sqlSimpleName - Advanced Querying — Pagination, sorting, filtering, joins, and MongoDB-style query operators
- Field-Level Security — Granular control over visibility (
allowCfg), read-only, and rejected fields (rejectCfg) - Built-in Validation — 20+ validators (email, phone, date, regex, length, range, enum, etc.)
- Smart Relations — Automatic data enrichment via
columnsRelation(dict, sysConfig, account, workbench, custom) - Soft Delete — Logical deletion with recovery support (
enableSoftDelete) - Audit Trail — Automatic tracking of creators, modifiers, and timestamps (
enableStandardUpdateCfg) - Data Type Conversion — Auto-convert JS arrays to PostgreSQL array literals, JSON strings parsed automatically
- Multi-Database — MySQL, PostgreSQL, SQL Server support with dialect-aware SQL generation
- Custom SQL — Template-based SQL with
@@placeholdersyntax for complex queries - Transaction Support — Built-in transaction management with configurable isolation levels
- Configuration Cache — Database-stored configurations with TTL-based caching
10-Step Execution Pipeline:
1. Receive Request (RequestModel)
↓
2. Load Configuration (RequestCfgModel)
↓
3. Field Filtering (filterDataByTableMeta) — Remove non-existent columns based on table schema
↓
4. Data Type Conversion (convertDataTypeByTableMeta) — Auto-convert based on column types (e.g. PG ARRAY)
↓
5. Data Validation (validateByAllow/rejectCfg/validateCfg)
↓
6. Permission Check (validateByAuthCfg)
↓
7. Default Value Setting (updateByCfg)
↓
8. Generate SQL (generateSQLList)
↓
9. Execute SQL (executeSQLList)
↓
10. Return Result (ExecuteContext)Quick Example:
const cfgJson: IRequestCfgModel = {
method: 'article.list',
sqlTable: 'article',
sqlSimpleName: KeysOfSimpleSQL.SIMPLE_QUERY_PAGE,
};
const reqJson: IRequestModel = {
columns: 'id,title,content,author_id,created_at',
condition: {
status: 1,
category_id: { $in: [1, 2, 3] },
created_at: { $gte: '2024-01-01' },
},
pageNo: 1,
pageSize: 20,
orderBy: 'created_at-',
};
const ctx = await crudPro.executeCrudByCfg(reqJson, cfgJson);
const { rows, total_count } = ctx.getResModelForQueryPage();Full CRUD-Pro documentation: src/libs/crud-pro/README.md · Built-in Functions: src/libs/crud-pro/README_FUNC.md
Sharding Engine — Scalable Table Partitioning
Built on top of CRUD-Pro, the Sharding Engine provides transparent table partitioning with automatic routing, cross-shard pagination, and smart result merging — zero code changes required.
Sharding Strategies:
| Strategy | Enum | Suffix Example | Best For |
|----------|------|----------------|----------|
| By Year | ShardingType.YEAR | _2024, _2025 | Annual reports, yearly archives |
| By Month | ShardingType.MONTH | _202401, _202402 | Order systems, log tables |
| By Day | ShardingType.DAY | _20240101 | High-volume daily logs |
| By Range | ShardingType.RANGE | _0 ~ _99 | Numeric ID-based partitioning |
| By Hash | ShardingType.HASH | _01 ~ _16 | Even distribution, user-based |
| Custom | ShardingType.CUSTOM | User-defined | Tenant-based, business-specific |
Key Features:
- Automatic Routing — Insert/update/delete routed to the correct shard based on data fields
- Cross-Shard Pagination — Transparent
queryPage()across multiple shards with direct-offset optimization - Smart Batch Insert —
batchInsert()auto-groups data by shard, parallel writes across tables - COUNT Query Cache — LRU + TTL cache for historical shard COUNT queries, real-time for current period
- Table Existence Filtering — Non-existent shards silently skipped in queries, error on insert
- Multi-Sort Support — Primary time-based sort + secondary field sorts within each shard
Quick Example:
const sharding = curdProService.getShardingCrud('mydb', SqlDbType.mysql, {
type: ShardingType.MONTH,
baseTable: 't_order',
timeColumn: 'created_at',
autoCreateTable: true,
countCache: { ttlSeconds: 300, maxSize: 1000 },
});
// Insert — auto-routes to t_order_202403
await sharding.insert({
data: { order_id: '001', amount: 100, created_at: '2024-03-15' }
});
// Cross-shard pagination — automatic merging
const page = await sharding.queryPage({
condition: { status: 'paid' },
pageNo: 1,
pageSize: 10,
orderBy: 'created_at DESC',
});Full Sharding documentation: src/libs/crud-sharding/ROUTING_LOGIC.md
Any API — Three Ways to Build APIs
Whether you need a simple query or complex business logic, we've got you covered.
1. SQL Query API
Write SQL, get REST. It's that simple.
- Native SQL with automatic parameter binding
- SQL injection protection built-in
- Ideal for complex reports and data analytics
2. Sandbox Script API
Safe, sandboxed Node.js execution.
- Isolated VM environment for secure code execution
- Pre-loaded utilities (axios, lodash, moment)
- Direct access to database, Redis, and OSS
3. Custom Code API
Full control when you need it.
- Serverless-like function deployment
- Hot-reload without service restart
- Complete business logic freedom
Enterprise Security:
- JWT authentication & role-based access control
- Token bucket rate limiting
- Circuit breaker & timeout protection
- IP whitelist/blacklist
API Gateway & Proxy — Enterprise-Grade Traffic Management
A full-featured API gateway that handles the complexity so you don't have to.
Load Balancing Strategies
- Round Robin
- Weighted Round Robin
- Random & Weighted Random
- IP Hash (sticky sessions by IP)
- User Hash (sticky sessions by user)
- Session Hash (sticky sessions by session)
Traffic Control
- Request rate limiting
- Configurable timeouts
- Automatic retry mechanisms
- Circuit breaker & fallback
Security & Context
- Real IP forwarding through proxies
- User context propagation
- Customizable headers (Host, Origin)
- Request/response header manipulation
Multi-Tenant Architecture — True SaaS-Ready
Deploy once, serve unlimited customers. Complete tenant isolation without the complexity.
Tenant Isolation:
- Domain Recognition — Automatic tenant detection by domain
- Data Separation — Complete data isolation between tenants
- Permission Boundaries — Independent user, role, and permission management
- Resource Isolation — Files, configurations, and apps are tenant-scoped
Flexible Configuration:
- Primary domain + 2 backup domains per tenant
- Wildcard domain support
- Tenant templates for rapid onboarding
- Customizable tenant branding
Workflow Engine — Automate Business Processes
Streamline approvals and business flows with a flexible workflow engine.
- Visual process definition
- Process instance tracking
- Task assignment and approval workflows
- Real-time status monitoring
- Historical flow records
Document Management System — Enterprise Knowledge Base
A complete document management solution with version control and analytics.
- Document Libraries — Multiple document repositories
- Hierarchical Structure — Tree-based organization
- Version Control — Full document versioning
- Analytics — PV/UV tracking with IP deduplication
- Access Control — Document-level permissions
File Service — Complete File Management
Enterprise file handling with cloud storage integration.
- Upload & Download — Single and batch file uploads
- Cloud Storage — Alibaba Cloud OSS integration (public & private buckets)
- File Preview — Images, PDFs, Office documents
- Access Control — Time-limited secure URLs
- Organization — Categories and tags
System Management — Everything You Need
User & Permissions:
- User account management
- Role-based access control
- Feature-level permissions
- Permission allocation workflows
Application Management:
- Application registry
- Page management
- Menu configuration
- Low-code templates
System Configuration:
- Data dictionaries
- System parameters
- Enumeration management
- Scheduled tasks
Monitoring & Operations:
- Access statistics
- Operation logs
- System health info
- Deployment management
Security First
We take security seriously. Built-in protection at every layer:
Access Control
- JWT Token authentication
- Session management with Redis
- Super admin mechanism
- Granular permission control (
authType: free | login | byRoleCode | byFuncCode)
Attack Prevention
- SQL injection protection (parameterized queries)
- XSS protection
- CSRF token validation
- Path traversal prevention
- User-Agent blacklisting (scanner detection)
- IP-based rate limiting
Data Protection
- AES-128-CBC encryption
- Asymmetric encryption support
- Sensitive field encryption
- Salted password hashing
Architecture
Technology Stack
| Layer | Technology | |-------|-----------| | Framework | Midway.js 3.x (Enterprise Node.js) | | Web Server | Koa | | Language | TypeScript | | Database | MySQL / PostgreSQL / SQL Server | | Cache | Redis | | File Storage | Alibaba Cloud OSS / S3-compatible |
Core Middleware
Global Middleware:
- User session management
- Multi-tenant isolation
- Transaction management
- Request-level logging
- Unified response formatting
- Real IP extraction
Security Middleware:
- Login verification (
checkLogin) - Role verification (
checkRole) - Permission verification (
checkPermission) - Path blacklist (
Forbidden) - Distributed locking (
RedisLock) - Response caching (
RedisCache)
Project Structure
midway-fatcms/
├── src/
│ ├── config/ # Configuration files
│ ├── controller/ # Controllers
│ │ ├── base/ # Base controllers
│ │ ├── gateway/ # Gateway APIs (CRUD, AnyAPI, Proxy, etc.)
│ │ ├── manage/ # Management APIs
│ │ ├── myinfo/ # Personal info & Auth APIs
│ │ └── render/ # Rendering APIs
│ ├── filter/ # Exception filters
│ ├── libs/ # Core libraries
│ │ ├── crud-pro/ # CRUD-Pro engine (SQL generation, validation, execution)
│ │ ├── crud-sharding/ # Sharding engine (routing, merging, caching)
│ │ ├── global-config/ # Global configuration
│ │ └── utils/ # Shared utilities
│ ├── middleware/ # Middleware (auth, permission, tx, cache, lock)
│ ├── models/ # Data models & type definitions
│ ├── schedule/ # Scheduled tasks
│ ├── service/ # Business services
│ │ ├── anyapi/ # Dynamic API (SQL, Sandbox, Custom Code)
│ │ ├── asyncTask/ # Async task runner
│ │ ├── base/ # Base services (cache, rate limiter)
│ │ ├── crudstd/ # Standard CRUD (gateway-level)
│ │ ├── curd/ # CRUD service layer (context injection, soft delete, relations)
│ │ ├── flow/ # Workflow engine
│ │ └── proxyapi/ # Proxy API gateway
│ └── views/ # View templates
├── ddl/ # Database initialization scripts
├── scripts/ # Utility scripts
└── package.json # Project configurationService Layer Architecture
Business Code
│
├── CurdMixService (orchestrator: CRUD + relation enrichment)
│ ├── CurdMixByDictService → relatedType: 'dict'
│ ├── CurdMixBySysConfigService → relatedType: 'sysCfgEnum'
│ ├── CurdMixByAccountService → relatedType: 'accountBasic'
│ ├── CurdMixByWorkbenchService → relatedType: 'workbenchBasic'
│ └── CurdMixByLinkToCustomService → relatedType: 'linkToCustom'
│
└── CurdProService (core service layer)
├── CrudProQuick → Quick CRUD (fluent API)
├── ShardingCrudPro → Sharded CRUD
├── fixCfgModel() → Standard field auto-fill
└── fixSoftDelete() → Soft delete handlingFull service layer documentation: src/service/curd/README.md
API Reference
CrudProQuick — Fluent CRUD API
The quickest way to perform database operations. All methods automatically inherit context (visitor, transaction, soft delete, standard fields).
const quick = curdProService.getQuickCrud('mydb', SqlDbType.mysql, 't_user');
// Query methods
const users = await quick.getList({ condition: { status: 'active' } });
const page = await quick.getListPage({ condition: { status: 'active' }, pageNo: 1, pageSize: 20 });
const user = await quick.getUniqueOne({ condition: { email: '[email protected]' } });
const exists = await quick.isExist({ condition: { phone: '13800138000' } });
const count = await quick.getTotalCount({ condition: { status: 'active' } });
// Write methods
const result = await quick.insertObject({ data: { name: 'Alice', email: '[email protected]' } });
const batch = await quick.batchInsert({ data: [{ name: 'A' }, { name: 'B' }] });
const updated = await quick.updateObject({ condition: { id: 1 }, data: { name: 'Bob' } });
const deleted = await quick.deleteObject({ condition: { id: 1 } });
const upserted = await quick.insertOnDuplicateUpdate({ data: { id: 1, name: 'A' } }, ['id']);
// Raw SQL
const rows = await quick.executeSQL('SELECT * FROM t_user WHERE status = ?', ['active']);Query Condition Operators
MongoDB-style operators for powerful queries:
const condition = {
status: 1, // Equal
age: { $gt: 18, $lt: 60 }, // Greater than / Less than
id: { $in: [1, 2, 3] }, // IN
code: { $nin: ['a', 'b'] }, // NOT IN
amount: { $between: [100, 500] }, // BETWEEN
name: { $like: '张' }, // Prefix match
title: { $likeInclude: '文章' }, // Contains match
deleted_at: { $isNull: true }, // IS NULL
updated_at: { $isNotNull: true }, // IS NOT NULL
$or: [{ name: { $like: '张' } }, { name: { $like: '李' } }], // OR
};Sorting Syntax
// Standard SQL format
orderBy: 'created_at DESC, amount ASC'
// Shorthand format (+ ascending, - descending)
orderBy: 'created_at-, amount+'
// Array format (mixed strings & objects)
orderBy: ['order_id', { fieldName: 'created_at', orderType: 'desc' }, 'amount+']ShardingCrudPro API
| Method | Returns | Description |
|--------|---------|-------------|
| insert(reqJson) | ExecuteContext | Insert single record (auto-route) |
| batchInsert(reqJson) | IShardingSmartBatchInsertResult | Batch insert (cross-shard, parallel) |
| update(reqJson) | ExecuteContext | Update data |
| delete(reqJson) | ExecuteContext | Delete data |
| insertOrUpdate(reqJson) | ExecuteContext | Insert or update |
| insertOnDuplicateUpdate(reqJson) | ExecuteContext | Native upsert |
| queryOne(reqJson) | any \| null | Query single record |
| query(reqJson) | any[] | List query (auto-merge shards) |
| queryPage(reqJson) | IShardingPageQueryResult | Cross-shard pagination |
| queryCount(reqJson) | number | Count across shards |
| isExist(reqJson) | boolean | Existence check across shards |
Built-in Functions
CrudPro provides 30+ built-in functions for updateCfg, validateCfg, executeWhen, and validate:
DateTime: getCurrentTimeStampMs, getCurrentTimeStampSecond, getCurrentTimeString, getCurrentDateFormat, getYesterdayDateFormat
Compare: eq, ne, gt, gte, lt, lte
Utility: isNil, isNotNil, isEmpty, isNotEmpty, equals, equalsIgnoreCase, startsWith, isValidFieldName, selectNotEmpty, hasAny, parseValueByType, sleepMs, uuid, generateSnowflakeId
Type Check: isBasicType, isBoolean, isString, isInteger, isNumber, isNumeric, isValidName, isChinesePhone, isEmailStrValid, pickNumber
Full function reference: src/libs/crud-pro/README_FUNC.md
Soft Delete
When enableSoftDelete: true, operations are automatically rewritten:
| Operation | Original | With Soft Delete |
|-----------|----------|-----------------|
| INSERT | Normal insert | Auto-set data.deleted_at = 0 |
| DELETE | Physical DELETE | UPDATE: deleted_at = timestamp, deleted_by = userId |
| QUERY | Normal query | Auto-append condition.deleted_at = 0 |
Standard Field Auto-Fill
When enableStandardUpdateCfg: true, standard fields are automatically populated:
| Operation | Auto-Filled Fields |
|-----------|--------------------|
| INSERT | created_by, created_avatar, created_nickname, created_account_type |
| UPDATE | modified_by, modified_avatar, modified_nickname, modified_account_type |
| DELETE | — (condition auto-includes created_by for ownership check) |
Data Type Auto-Conversion
CrudPro automatically converts data types based on table schema before INSERT/UPDATE:
PostgreSQL ARRAY — JS arrays are automatically converted to PG array literal format:
| Input | Converted | Description |
|-------|-----------|-------------|
| ["a","b","c"] | {"a","b","c"} | String arrays: double-quoted |
| [1,2,3] | {1,2,3} | Number arrays: no quotes |
| [true,false] | {t,f} | Boolean arrays: t/f notation |
| [1,null,3] | {1,NULL,3} | Null handling |
| [] | {} | Empty arrays |
| ['he"llo'] | {"he\"llo"} | Special character escaping |
Only applies to PostgreSQL; MySQL and SQL Server drivers handle type conversion natively.
Quick Start
Prerequisites
- Node.js >= 10
- MySQL >= 5.7 / PostgreSQL >= 8 / SQL Server >= 11
- Redis >= 3.0
Installation
# Clone the repository
git clone <repository-url>
cd midway-fatcms
# Install dependencies
npm installConfiguration
- Configure database connection in
src/config/config.default.ts - Set up Redis connection
- Configure OSS (optional)
- Configure workbench information
Database Setup
-- Run initialization SQL
source ddl/2025-12-20.sqlStart Development
# Development mode with hot reload
npm run dev
# Build for production
npm run build
# Start production server
npm startCode Quality
# Check code style
npm run lint
# Auto-fix issues
npm run lint:fixTesting
# Run tests
npm test
# Generate coverage report
npm run covUse Cases
Enterprise Back-Office Systems
- Rapid admin dashboard creation
- Business system configuration hubs
- Internal tool platforms
SaaS Platforms
- Multi-tenant applications
- White-label products
- Industry-specific solutions
API Platforms
- API management & gateways
- Data open platforms
- Microservice aggregation
High-Volume Data Systems
- Sharded order management (millions of records per month)
- Time-series log storage with auto-routing
- Real-time analytics across partitioned tables
Low-Code Development
- Rapid business system development
- Form-driven applications
- Data analysis platforms
Content Management
- Document repositories
- Knowledge bases
- Content publishing platforms
Utility Endpoints
Encryption Helper
http://127.0.0.1:7002/ns/api/helpers/cryptoAes128CBC?input=123Documentation Index
| Document | Description | |----------|-------------| | CRUD-Pro Guide | Configuration-driven CRUD operations, validation, permissions | | Built-in Functions | 30+ functions: date, compare, utility, type check | | Service Layer Guide | Context injection, soft delete, quick CRUD, sharding, relations | | Sharding Routing Logic | Shard strategies, cross-shard pagination, COUNT cache |
Version
Current Version: 0.0.1-beta.82
License
MIT License — Use it freely, contribute often.
Contributing
We welcome contributions! Whether it's bug reports, feature requests, or pull requests, your input helps make Midway FatCMS better for everyone.
