11 KiB
| name | version | description | trigger_conditions | |||
|---|---|---|---|---|---|---|
| web-application-spec | 1.0.0 | Standardized specification for web applications built with bricks frontend, ahserver backend framework, and apppublic/sqlor foundation modules. |
|
Web Application Specification
Overview
This specification defines the standard architecture for web applications built using:
- Frontend: bricks framework
- Backend: ahserver application framework
- Foundation: apppublic and sqlor modules
- Optional Modules: appbase, rbac, and other developed modules
All web applications must follow this exact structure and configuration pattern.
Required Dependencies
Core Dependencies (Mandatory)
pip install git+https://git.opencomputing.cn/yumoqing/apppublic
pip install git+https://git.opencomputing.cn/yumoqing/sqlor
pip install git+https://git.opencomputing.cn/yumoqing/ahserver
Database Web Application Dependencies (If using database)
pip install git+https://git.opencomputing.cn/yumoqing/appbase
pip install git+https://git.opencomputing.cn/yumoqing/rbac
Application Directory Structure
${appname}/
├── app/
│ └── ${appname}.py # Main application entry point
├── conf/
│ └── config.json # Application configuration
├── files/ # File storage directory
├── logs/ # Log files directory
├── wwwroot/
│ ├── imgs/ # SVG and image files
│ └── bricks/ # Bricks framework distribution
├── build.sh # Initialization and deployment script
└── .env # Environment variables
File Specifications
app/${appname}.py (Main Application)
from ahserver.webapp import webapp
from ahserver.serverenv import ServerEnv
import bricks_for_python # registers bui processor
from bricks_for_python.init import load_pybricks # registers UiWindow etc.
from appbase.init import load_appbase
from rbac.init import load_rbac
def get_module_dbname(m):
return 'dbname'
def password_encode(s):
if s is None:
return ''
from ahserver.globalEnv import password_encode as _orig
return _orig(s)
def init():
env = ServerEnv() # ← MUST be before load_rbac
env.get_module_dbname = get_module_dbname
env.password_encode = password_encode
load_appbase()
load_rbac()
load_pybricks()
if __name__ == '__main__':
webapp(init)
conf/config.json (Configuration)
Must include the following sections:
password_key: System encryption keylogger: Logging configuration with name, level, and file pathfilesroot: File storage root path using$[workdir]$placeholderdatabases: Database connection configurations with driver and kwargswebsite: Web server configuration including paths, processors, session settings
Key Configuration Patterns:
- Use
$[workdir]$placeholder for work directory references - Database names in
databasessection must matchget_module_name()return values - Critical: processors must include
.tmpl→tmpl. The BricksUIProcessor (handler for.uifiles) internally loads/bricks/header.tmpland other templates. Without[".tmpl", "tmpl"], the app returns 500'NoneType' has no attribute 'be_call'on/and/index.ui:"processors": [ [".tmpl", "tmpl"], [".ui", "bui"], [".dspy", "dspy"] ] - Website processors must include
.ui→buiand.dspy→dspymappings - Website indexes: Must include
"index.ui"for bricks-based apps. Without it, visiting/or/module/returns 500 "invalid path" because ahserver cannot resolve directory URLs:"indexes": ["index.ui", "index.html"] - WebSocket support: Must include
[".wss", "ws"]in processors list, otherwise.wssfiles are served as static files and WebSocket connections fail. Nginx/wss/block strips the prefix viaproxy_pass, so the backend receives the path without/wss(e.g.,/module/file.wss).
WebSocket Configuration Details
When adding WebSocket (.wss) endpoints to a module:
-
Backend config.json: Add
[".wss", "ws"]towebsite.processors:"processors": [ [".wss", "ws"], [".ws", "ws"], [".ui", "bui"], [".dspy", "dspy"] ] -
Nginx: The
/wss/location block handles WebSocket upgrade and strips the prefix:location /wss/ { proxy_pass http://localhost:9180/; # strips /wss prefix proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } -
Frontend: Connect to
/wss/module/file.wss(with/wssprefix):var url = protocol + '//' + host + '/wss/module/file.wss'; var ws = new WebSocket(url); // browser auto-sends cookie -
RBAC permissions: Register paths without
/wssprefix (nginx strips it):python set_role_perm.py "logined" "/module/file.wss" -
Common pitfall: If ahserver logs
handle as a normal filefor a.wssrequest, the[".wss","ws"]processor mapping is missing fromconfig.json. ahserver only recognizes extensions explicitly listed inprocessors.
build.sh (Deployment Script)
The build script must perform these operations in order:
A) Module Dependencies Setup
- Install xls2ddl tool: After creating virtual environment, install xls2ddl first:
pip install xls2ddl - Module Installation: Clone and pip install all required modules
- Database DDL Generation: For modules with
models/directory:- If models contain
.xlsxfiles:cd models/ xls2ddl mysql . > mysql.ddl.sql mysql -h db -u[user] -p[password] [dbname] < mysql.ddl.sql - If models contain
.jsonfiles:cd models/ json2ddl mysql . > mysql.ddl.sql mysql -h db -u[user] -p[password] [dbname] < mysql.ddl.sql
- If models contain
- Initial Data Import: For modules with
data/directory:dbloader $cdir [dbname] data.xlsx - CRUD Generation: For modules with
json/directory:cd json/ xls2ui -m ../models -o ../wwwroot ${modulename} *.json - wwwroot Symlinking: Create symbolic links for each module:
ln -s $cdir/pkgs/$m/wwwroot $cdir/wwwroot/$m
B) Bricks Framework Setup
- Execute bricks build.sh and symlink dist directory:
ln -s $cdir/pkgs/bricks/dist $cdir/wwwroot/bricks
C) System Service Configuration
- Create systemd service file with proper user/group context
- Generate start.sh and stop.sh scripts with environment loading
- Enable and start the service on system boot
D) Cron Job Management
- Add application-specific cron jobs without duplication
.env (Environment Variables)
- Export all runtime environment variables required by the application
- Include database credentials, API keys, and system paths
Build Script Requirements
Directory Creation
- Create
pkgs/directory for module clones - Create
logs/directory for application logging
Module Processing Order
- Install foundation modules (apppublic, sqlor, ahserver, bricks)
- Clone and process database modules (appbase, rbac):
- Clone from Git repositories to pkgs/ directory
- Install via pip
- Generate DDL from models/ directory (.xlsx or .json files)
- Generate CRUD UI from json/ directory using xls2ui
- Install business modules (accounting, pricing, contract_management, etc.) following the same pattern as database modules
Database Operations
- Process all modules that have
models/,json/, ordata/directories (including appbase and rbac) - Use proper error handling for database operations
- Maintain database isolation per module when configured
Symbolic Links
- All module wwwroot directories must be symlinked to application wwwroot
- Bricks dist directory must be symlinked to wwwroot/bricks
Service Management
- Create proper systemd service with logging redirection
- Implement graceful start/stop scripts
- Set appropriate file permissions (chmod +x for scripts)
Bricks UI Development Pitfalls
See references/ragserver-pitfalls.md for complete debugging recipes.
See references/sage-module-pitfalls.md for SQL column names, params_kw=None, deployment, and error investigation rules.
- Widget
idat top level (NOT inoptions) - DOM order for
app.<id>resolution .tmplprocessor required in configbricks_for_pythonimport +load_pybricks()call- DataViewer response format (
{status, data:{rows,total}}) - Menu widget target pattern
- Float model fields needing
length+dec
Widget id at Top Level (Not in options)
// CORRECT
{"widgettype":"VBox","id":"main_content","options":{"css":"filler"}}
// WRONG — id inside options is ignored
{"widgettype":"VBox","options":{"id":"main_content","css":"filler"}}
DOM Order Affects app.<id> Resolution
Put the content area BEFORE the sidebar in subwidgets. Bricks initializes widgets left-to-right.
Configuration Best Practices
Security
- Store sensitive data (passwords, keys) in encrypted form in config.json
- Use environment variables for runtime secrets via .env file
- Implement proper file permissions for logs and files directories
Performance
- Configure appropriate client_max_size for file uploads
- Set optimal session timeout values (session_max_time, session_issue_time)
- Use Redis for session storage in production
Maintainability
- Use consistent naming patterns across all configuration sections
- Document custom processor mappings in website.processors
- Maintain clear separation between development and production configurations
Verification Checklist
.tmpl→tmplprocessor inwebsite.processors(required for bricks UI, or/returns 500)bricks_for_pythonimported andload_pybricks()called ininit()ServerEnvinitialized BEFOREload_rbac()/load_appbase()- Website
indexesconfig includes"index.ui"(required for directory URL resolution) session_max_timeandsession_issue_timein config for Redis session persistence (restart won't lose login)- All required dependencies are installed from correct Git repositories
- Application directory structure matches specification exactly
- Main application file includes proper module loading pattern
- Configuration file uses correct placeholders and structure
- Build script handles all module types (foundation, database, business)
- Database DDL generation works for all modules with models/
- CRUD generation executes for all modules with json/
- Initial data loads correctly for modules with data/
- All wwwroot symlinks are created properly
- Bricks framework is built and linked correctly
- System service starts and stops gracefully
- Environment variables are loaded from .env file
- Application runs with proper logging and error handling