Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!-- COLDBOX-CLI:START -->
- <!-- ⚡ This section is managed by ColdBox CLI and will be refreshed on `coldbox ai refresh`. -->
- <!-- ⚠️ Do NOT edit content between COLDBOX-CLI:START and COLDBOX-CLI:END markers — changes will be overwritten. -->
- # my-api - AI Agent Instructions
- This is a ColdBox HMVC application using the **flat template structure** where all application code lives in the webroot. Compatible with Adobe ColdFusion 2018+, Lucee 5.x+, and BoxLang 1.0+.
- ## Project Overview
- **Language Mode:** CFML
- **ColdBox Version:** ^8.0.5+33
- **Template Type:** Flat (traditional webroot structure)
- ## Application Structure
- ```
- / - Application root (webroot)
- ├── Application.cfc - Bootstrap that directly loads ColdBox
- ├── index.cfm - Front controller
- ├── config/ - Framework and app configuration
- ├── handlers/ - Event handlers (controllers)
- ├── models/ - Service objects, business logic
- ├── views/ - HTML templates
- ├── layouts/ - Page layouts wrapping views
- ├── includes/ - Public assets (CSS, JS, images)
- ├── modules_app/ - Application modules (HMVC)
- ├── tests/ - Test suites
- └── lib/ - Framework dependencies
- ```
- **Key Characteristics:**
- - Everything in webroot (simpler for traditional hosting)
- - No `/app` vs `/public` separation
- - All code is web-accessible by default
- - `COLDBOX_APP_MAPPING = ""` (empty, app at root)
- ## Framework Knowledge
- **Important:** The following sections contain essential framework documentation that is always available in your context. These guidelines cover core concepts, conventions, and best practices for ColdBox development.
- ---
- # ColdBox Framework Core Guidelines
- ## Overview
- ColdBox is a conventions-based HMVC (Hierarchical Model-View-Controller) framework for CFML and BoxLang applications. It provides a complete ecosystem for building modern, scalable web applications and REST APIs.
- ## Application Structure
- ---
- title: ColdBox Flat Project Structure
- description: Canonical flat ColdBox directory layout for legacy or simplified apps, defining where handlers, models, views, layouts, interceptors, modules, and tests should live.
- ---
- ```
- /config - Application configuration
- /handlers - Event handlers (controllers)
- /models - Business logic and services
- /views - View templates
- /layouts - Layout wrappers
- /interceptors - Event interceptors (AOP)
- /modules - ColdBox modules (sub-applications)
- /tests - TestBox test suites
- ```
- ## Event Handlers (Controllers)
- ### Handler Conventions
- - Extend `coldbox.system.EventHandler`
- - Located in `/handlers/` directory
- - Use plural nouns: `Users.cfc`, `Orders.cfc`, `Products.cfc`
- - Actions are public functions receiving `event`, `rc`, `prc`
- ### Basic Handler
- ```boxlang
- class Users extends coldbox.system.EventHandler {
- property name="userService" inject;
- property name="log" inject="logbox:logger:{this}";
- function index( event, rc, prc ) {
- prc.users = userService.getAll()
- event.setView( "users/index" )
- }
- function show( event, rc, prc ) {
- prc.user = userService.getById( rc.id ?: 0 )
- event.setView( "users/show" )
- }
- function create( event, rc, prc ) {
- var user = userService.create( rc )
- flash.put( "notice", "User created successfully" )
- relocate( "users.show", { id: user.id } )
- }
- }
- ```
- ### RESTful Handler
- ```boxlang
- class API extends coldbox.system.EventHandler {
- property name="userService" inject;
- function index( event, rc, prc ) {
- prc.data = userService.getAll()
- event.renderData(
- data = prc.data,
- formats = "json,xml"
- )
- }
- function show( event, rc, prc ) {
- prc.data = userService.getById( rc.id ?: 0 )
- event.renderData( data = prc.data )
- }
- function create( event, rc, prc ) {
- prc.data = userService.create( rc )
- event.renderData(
- data = prc.data,
- statusCode = 201
- )
- }
- function update( event, rc, prc ) {
- prc.data = userService.update( rc.id, rc )
- event.renderData( data = prc.data )
- }
- function delete( event, rc, prc ) {
- userService.delete( rc.id )
- event.renderData(
- data = { message: "Deleted successfully" },
- statusCode = 204
- )
- }
- }
- ```
- ## Request Context (Event Object)
- The `event` object is your gateway to request data and framework features.
- ### Getting/Setting Values
- ```boxlang
- // Get from RC (request collection - URL/FORM merged)
- var userId = event.getValue( "userId", 0 )
- var email = event.getTrimValue( "email", "" )
- // Set in PRC (private request collection - safe, internal)
- event.setValue( "userName", user.name )
- event.setPrivateValue( "internalData", sensitiveData )
- // Param a value (set default if not exists)
- event.paramValue( "page", 1 )
- event.paramValue( "perPage", 25 )
- // Get entire collections
- var rc = event.getCollection()
- var prc = event.getPrivateCollection()
- ```
- ### Request Metadata
- ```boxlang
- // Current execution info
- var handler = event.getCurrentHandler() // "users"
- var action = event.getCurrentAction() // "index"
- var eventName = event.getCurrentEvent() // "users.index"
- var module = event.getCurrentModule() // "admin" (if in module)
- // View/Layout info
- var view = event.getCurrentView()
- var layout = event.getCurrentLayout()
- // Routing info
- var route = event.getCurrentRoute()
- var routeName = event.getCurrentRouteName()
- ```
- ### Rendering
- ```boxlang
- // Set view to render
- event.setView( "users/index" )
- event.setView( view="users/show", layout="custom" )
- // Set layout only
- event.setLayout( "admin" )
- // Render data (JSON/XML/PDF/etc)
- event.renderData(
- data = users,
- type = "json",
- statusCode = 200
- )
- // Prevent rendering
- event.noRender()
- // Render nothing (204 response)
- event.noExecution()
- ```
- ### Navigation
- ```boxlang
- // Relocate to another event
- relocate( "users.index" )
- relocate( event="users.show", queryString="id=5" )
- // Build links
- var url = event.buildLink( "users.show" )
- var url = event.buildLink( to="users.edit", queryString="id=#user.id#" )
- var url = event.buildLink( to="api.users.show", ssl=true )
- ```
- ### HTTP Operations
- ```boxlang
- // Get HTTP method
- var method = event.getHTTPMethod() // GET, POST, PUT, DELETE
- // Check HTTP method
- if ( event.isGET() ) { }
- if ( event.isPOST() ) { }
- if ( event.isPUT() ) { }
- if ( event.isDELETE() ) { }
- // Request type
- if ( event.isAjax() ) { }
- if ( event.isSSL() ) { }
- // Set HTTP headers
- event.setHTTPHeader( name="X-Custom-Header", value="value" )
- event.setHTTPHeader( statusCode=404, statusText="Not Found" )
- ```
- ## Dependency Injection (WireBox)
- ### Property Injection
- ```boxlang
- class Users extends coldbox.system.EventHandler {
- // Auto-inject by name convention
- property name="userService" inject;
- // Inject from specific path
- property name="utils" inject="models.Utils";
- // Inject by ID
- property name="mailService" inject="id:MailService";
- // Inject using DSL
- property name="cache" inject="cachebox:default";
- property name="log" inject="logbox:logger:{this}";
- property name="settings" inject="coldbox:setting:mySettings";
- property name="wirebox" inject="wirebox";
- }
- ```
- ### getInstance() Method
- ```boxlang
- // Get instances programmatically
- var userService = getInstance( "UserService" )
- var cache = getInstance( "cachebox:default" )
- var settings = getInstance( "coldbox:setting:appName" )
- ```
- ## Routing
- ### Route Configuration
- Located in `config/Router.cfc`:
- ```boxlang
- function configure() {
- // Enable full rewrites
- setFullRewrites( true )
- // Basic route
- route( "/" ).to( "main.index" )
- route( "/about" ).to( "main.about" )
- // Route with placeholders
- route( "/blog/:year/:month/:day/:slug" ).to( "blog.show" )
- // Optional placeholders
- route( "/search/:term?/:page?" ).to( "search.results" )
- // Constrained placeholders
- route( "/user/:id-numeric" ).to( "users.show" )
- route( "/blog/:year-regex:(\\d{4})" ).to( "blog.archive" )
- // Named routes
- route( "/contact" )
- .as( "contactPage" )
- .to( "main.contact" )
- // RESTful resources
- resources( "users" )
- // Creates: index, create, show, update, delete routes
- // API routes
- group( { pattern="/api/v1", handler="api" }, () => {
- route( "/users" ).to( "users.index" )
- route( "/users/:id" ).to( "users.show" )
- } )
- // Route to view directly
- route( "/terms" ).toView( "legal/terms" )
- // Route to response function
- route( "/health" ).toResponse( ( event, rc, prc ) => {
- return { status: "ok", timestamp: now() }
- } )
- // Redirect routes
- route( "/old-page" ).toRedirect( "/new-page", 301 )
- }
- ```
- ### Module Routing
- ```boxlang
- // In module's config/Router.cfc
- function configure() {
- route( "/" ).to( "home.index" )
- route( "/products" ).to( "products.list" )
- }
- // Access: /mymodule/products
- // Or with custom entrypoint: /shop/products
- ```
- ## Interceptors (AOP)
- Interceptors provide aspect-oriented programming for cross-cutting concerns.
- ### Built-in Interception Points
- ```boxlang
- // Application lifecycle
- afterConfigurationLoad
- afterAspectsLoad
- afterCacheStartup
- onException
- onRequestCapture
- preProcess
- preEvent
- postEvent
- postProcess
- preLayout
- postLayout
- preRender
- postRender
- // Module lifecycle
- preModuleLoad
- postModuleLoad
- preModuleUnload
- postModuleUnload
- ```
- ### Creating Interceptors
- ```boxlang
- class SecurityInterceptor extends coldbox.system.Interceptor {
- property name="securityService" inject;
- function preProcess( event, interceptData ) {
- if ( !securityService.isLoggedIn() && !event.valueExists( "public" ) ) {
- flash.put( "error", "Please log in" )
- relocate( "auth.login" )
- }
- }
- function onException( event, interceptData ) {
- // interceptData contains: exception, type, timestamp
- log.error(
- "Exception occurred: #interceptData.exception.message#",
- interceptData.exception
- )
- }
- }
- ```
- ### Registering Interceptors
- In `config/ColdBox.cfc`:
- ```boxlang
- interceptors = [
- { class="interceptors.SecurityInterceptor" },
- {
- class="interceptors.RequestLogger",
- properties={ logPath="/logs/requests" }
- }
- ]
- ```
- ### Announcing Custom Events
- ```boxlang
- // In handlers or models
- announceInterception( "onUserLogin", { user: user } )
- announceInterception( "onOrderComplete", { order: order, total: total } )
- // In interceptors - listen for custom events
- function onUserLogin( event, interceptData ) {
- var user = interceptData.user
- log.info( "User logged in: #user.email#" )
- }
- ```
- ## Modules
- Modules are self-contained sub-applications that can be plugged into any ColdBox application.
- ### Module Structure
- ```
- /modules/shop/
- ModuleConfig.cfc
- /handlers
- /models
- /views
- /layouts
- /interceptors
- config/Router.cfc
- ```
- ### Module Configuration
- ```boxlang
- component {
- this.title = "Shop Module"
- this.author = "Your Name"
- this.version = "1.0.0"
- this.entryPoint = "/shop"
- function configure() {
- settings = {
- currency: "USD",
- taxRate: 0.08
- }
- interceptors = [
- { class="interceptors.ShopSecurity" }
- ]
- }
- }
- ```
- ## Configuration (config/ColdBox.cfc)
- ```boxlang
- component {
- function configure() {
- coldbox = {
- appName = "My Application",
- reinitPassword = "",
- handlersIndexAutoReload = true, // Dev only
- handlerCaching = false, // Dev only
- viewCaching = false, // Dev only
- eventCaching = false, // Dev only
- defaultEvent = "main.index",
- requestStartHandler = "main.onRequestStart",
- requestEndHandler = "main.onRequestEnd",
- applicationStartHandler = "main.onAppInit",
- onInvalidEvent = "main.notFound",
- customErrorTemplate = "/views/main/error.cfm"
- }
- settings = {
- mySettings = "value",
- apiKey = getSystemSetting( "API_KEY", "" )
- }
- interceptors = [
- { class="interceptors.Security" }
- ]
- moduleSettings = {
- cbdebugger = {
- enabled = true
- }
- }
- }
- }
- ```
- ## Flash Scope
- Persist data across redirects:
- ```boxlang
- // Put data in flash
- flash.put( "notice", "User created successfully" )
- flash.put( "user", user )
- // Get from flash
- var notice = flash.get( "notice", "" )
- var user = flash.get( "user" )
- // Keep flash for next request
- flash.keep( "userData" )
- // Discard flash
- flash.discard( "tempData" )
- ```
- ## Best Practices
- - **Use RESTful naming** - Handlers are plural nouns, actions are standard REST verbs
- - **Leverage dependency injection** - Use `property inject` instead of manual creation
- - **Use PRC for internal data** - Keep RC for user input only
- - **Create service layers** - Keep handlers thin, move logic to services
- - **Use interceptors for cross-cutting concerns** - Security, logging, caching
- - **Build in modules** - Organize large applications into modules
- - **Use named routes** - Makes refactoring easier with `buildLink( name="routeName" )`
- - **Cache aggressively** - Use CacheBox for expensive operations
- - **Log appropriately** - Use LogBox with proper severity levels
- - **Test everything** - Use TestBox for unit and integration tests
- ## Documentation
- For complete ColdBox documentation, modules, and advanced features, consult the ColdBox MCP server or visit:
- https://coldbox.ortusbooks.com
- ---
- # CFML Core Guidelines
- ## Overview
- CFML (ColdFusion Markup Language) is a dynamic, rapid application development language for the JVM. It supports both tag-based and script-based syntax, making it flexible for different coding styles.
- ## Syntax Styles
- CFML supports two syntax styles that can be mixed in the same file:
- ### Script Syntax (Recommended)
- ```cfml
- component {
- property name="userService" inject;
- function getAll() {
- return userService.findAll();
- }
- function create( required struct data ) {
- return userService.create( data );
- }
- }
- ```
- ### Tag Syntax
- ```cfml
- <cfcomponent>
- <cffunction name="getAll" access="public" returntype="array">
- <cfreturn userService.findAll()>
- </cffunction>
- </cfcomponent>
- ```
- **Best Practice:** Use script syntax (CFScript) for better readability and consistency with modern languages.
- ## Component Structure
- ### Basic Component
- ```cfml
- component {
- // Properties
- property name="firstName";
- property name="lastName";
- property name="email";
- // Constructor
- function init( required string firstName, required string lastName ) {
- variables.firstName = arguments.firstName;
- variables.lastName = arguments.lastName;
- return this;
- }
- // Methods
- function getFullName() {
- return variables.firstName & " " & variables.lastName;
- }
- function setEmail( required string email ) {
- variables.email = arguments.email;
- }
- }
- ```
- ### Accessors
- ```cfml
- component accessors="true" {
- property name="firstName" type="string";
- property name="lastName" type="string";
- property name="age" type="numeric";
- }
- // Automatically generates:
- // - getFirstName()
- // - setFirstName( string firstName )
- // - getLastName()
- // - setLastName( string lastName )
- // - getAge()
- // - setAge( numeric age )
- ```
- ## Functions
- ### Function Declaration
- ```cfml
- // Public function
- function getUserById( required numeric id ) {
- return userDAO.find( arguments.id );
- }
- // Private function
- private function validateUser( required struct user ) {
- // Validation logic
- return true;
- }
- // Typed function
- public array function getActiveUsers() {
- return userDAO.findAll().filter( function( user ) {
- return user.active;
- } );
- }
- // Function with default arguments
- function sendEmail(
- required string to,
- required string subject,
- string from = "[email protected]",
- boolean html = true
- ) {
- // Email logic
- }
- ```
- ## Data Types
- ### Arrays
- ```cfml
- // Array creation
- var items = [];
- var numbers = [ 1, 2, 3, 4, 5 ];
- var users = [ { name: "Luis" }, { name: "Brad" } ];
- // Array methods
- items.append( "new item" );
- items.prepend( "first item" );
- var length = items.len();
- var hasItem = items.find( "value" );
- // Iteration
- items.each( function( item ) {
- writeOutput( item );
- } );
- // Map/Filter/Reduce
- var doubled = numbers.map( function( n ) { return n * 2; } );
- var evens = numbers.filter( function( n ) { return n % 2 == 0; } );
- var sum = numbers.reduce( function( acc, n ) { return acc + n; }, 0 );
- ```
- ### Structs
- ```cfml
- // Struct creation
- var user = {};
- var person = {
- firstName: "Luis",
- lastName: "Majano",
- age: 40
- };
- // Accessing values
- var name = user.firstName;
- var name = user[ "firstName" ];
- // Struct methods
- user.append( { email: "[email protected]" } );
- var keys = user.keyArray();
- var values = user.valueArray();
- var hasKey = user.keyExists( "email" );
- // Iteration
- user.each( function( key, value ) {
- writeOutput( "#key#: #value#" );
- } );
- ```
- ### Queries
- ```cfml
- // QueryExecute (modern, recommended)
- var qUsers = queryExecute(
- "SELECT * FROM users WHERE active = :active",
- { active: true },
- { datasource: "myDB" }
- );
- // Query properties
- var rowCount = qUsers.recordCount;
- var columnList = qUsers.columnList;
- // Query iteration
- for ( var row in qUsers ) {
- writeOutput( row.firstName & " " & row.lastName );
- }
- qUsers.each( function( row, index ) {
- writeOutput( row.email );
- } );
- // Query of queries
- var filtered = queryExecute(
- "SELECT * FROM qUsers WHERE age > :minAge",
- { minAge: 18 },
- { dbtype: "query" }
- );
- ```
- ## Control Flow
- ### Conditionals
- ```cfml
- // If/else if/else
- if ( user.active ) {
- sendWelcomeEmail( user );
- } else if ( user.pending ) {
- sendReminderEmail( user );
- } else {
- logInactiveUser( user );
- }
- // Ternary operator
- var status = user.active ? "Active" : "Inactive";
- // Elvis operator (null coalescing)
- var displayName = user.nickname ?: user.firstName;
- // Switch
- switch ( status ) {
- case "pending":
- processPending();
- break;
- case "approved":
- processApproved();
- break;
- case "rejected":
- processRejected();
- break;
- default:
- handleUnknown();
- }
- ```
- ### Loops
- ```cfml
- // For loop
- for ( var i = 1; i <= 10; i++ ) {
- writeOutput( i );
- }
- // For-in loop (arrays)
- for ( var item in items ) {
- writeOutput( item );
- }
- // For-in loop (structs)
- for ( var key in user ) {
- writeOutput( "#key#: #user[ key ]#" );
- }
- // While loop
- var i = 1;
- while ( i <= 10 ) {
- writeOutput( i );
- i++;
- }
- // Array each
- items.each( function( item, index ) {
- writeOutput( "#index#: #item#" );
- } );
- ```
- ## Exception Handling
- ```cfml
- try {
- var user = userService.getById( id );
- processUser( user );
- } catch ( EntityNotFound e ) {
- writeLog( type="error", text="User not found: #id#" );
- writeDump( e );
- // Handle specific exception
- } catch ( database e ) {
- writeLog( type="fatal", text="Database error: #e.message#" );
- // Handle database errors
- } catch ( any e ) {
- writeLog( type="error", text="Unexpected error: #e.message#" );
- rethrow;
- } finally {
- // Cleanup code (always executes)
- cleanup();
- }
- // Throw custom exception
- if ( !isValid( "email", email ) ) {
- throw(
- type = "ValidationException",
- message = "Invalid email address",
- detail = "Email: #email#"
- );
- }
- ```
- ## Built-in Functions (BIFs)
- ### String Functions
- ```cfml
- var str = "Hello World";
- var upper = str.ucase(); // HELLO WORLD
- var lower = str.lcase(); // hello world
- var length = str.len(); // 11
- var contains = str.find( "World" ); // 7
- var replaced = str.replace( "World", "CFML" ); // Hello CFML
- var trimmed = " text ".trim(); // text
- var split = str.listToArray( " " ); // [ "Hello", "World" ]
- ```
- ### Array Functions
- ```cfml
- var arr = [ 1, 2, 3, 4, 5 ];
- arr.append( 6 ); // [ 1, 2, 3, 4, 5, 6 ]
- arr.prepend( 0 ); // [ 0, 1, 2, 3, 4, 5, 6 ]
- var length = arr.len(); // 7
- var slice = arr.slice( 2, 4 ); // [ 1, 2, 3 ]
- var sorted = arr.sort( "numeric" ); // [ 0, 1, 2, 3, 4, 5, 6 ]
- var unique = [ 1, 2, 2, 3 ].arrayUnique(); // [ 1, 2, 3 ]
- ```
- ### Struct Functions
- ```cfml
- var user = { name: "Luis", age: 40 };
- user.keyExists( "name" ); // true
- var keys = user.keyArray(); // [ "name", "age" ]
- var values = user.valueArray(); // [ "Luis", 40 ]
- var isEmpty = user.isEmpty(); // false
- user.delete( "age" ); // Removes age key
- ```
- ### Date Functions
- ```cfml
- var now = now(); // Current date/time
- var today = dateFormat( now, "yyyy-mm-dd" );
- var time = timeFormat( now, "HH:mm:ss" );
- var tomorrow = dateAdd( "d", 1, now );
- var diff = dateDiff( "d", startDate, endDate );
- var parsed = parseDateTime( "2024-01-01" );
- ```
- ## ColdBox Handler Example
- ```cfml
- component extends="coldbox.system.EventHandler" {
- property name="userService" inject;
- property name="log" inject="logbox:logger:{this}";
- function index( event, rc, prc ) {
- prc.users = userService.getAll();
- event.setView( "users/index" );
- }
- function show( event, rc, prc ) {
- prc.user = userService.getById( rc.id ?: 0 );
- event.setView( "users/show" );
- }
- function save( event, rc, prc ) {
- try {
- if ( rc.id ?: 0 ) {
- var user = userService.update( rc.id, rc );
- } else {
- var user = userService.create( rc );
- }
- flash.put( "notice", "User saved successfully" );
- relocate( "users.show", { id: user.id } );
- } catch ( ValidationException e ) {
- flash.put( "error", e.message );
- flash.put( "data", rc );
- relocate( "users.edit" );
- }
- }
- }
- ```
- ## Service Layer Example
- ```cfml
- component singleton {
- property name="userDAO" inject;
- property name="cache" inject="cachebox:default";
- property name="log" inject="logbox:logger:{this}";
- function getAll() {
- return cache.getOrSet( "userList", function() {
- return userDAO.findAll();
- }, 60 );
- }
- function getById( required numeric id ) {
- var cacheKey = "user-#arguments.id#";
- return cache.getOrSet( cacheKey, function() {
- return userDAO.find( arguments.id );
- }, 30 );
- }
- function create( required struct data ) {
- transaction {
- try {
- var user = userDAO.create( data );
- cache.clear( "userList" );
- log.info( "User created: #user.id#" );
- return user;
- } catch ( any e ) {
- transaction action="rollback";
- log.error( "Failed to create user", e );
- rethrow;
- }
- }
- }
- function update( required numeric id, required struct data ) {
- var user = userDAO.update( arguments.id, arguments.data );
- cache.clear( "user-#arguments.id#" );
- cache.clear( "userList" );
- return user;
- }
- }
- ```
- ## Best Practices
- - **Use CFScript** over tag-based syntax for consistency
- - **Leverage accessors** for automatic getters/setters
- - **Use queryExecute()** instead of `<cfquery>` tags
- - **Scope all variables** explicitly (var, variables, arguments)
- - **Use member functions** on arrays, structs, and strings (`.map()`, `.filter()`, etc.)
- - **Handle exceptions** appropriately with specific catch blocks
- - **Use transactions** for database operations that need atomicity
- - **Cache expensive operations** using CacheBox
- - **Log important events** using LogBox
- - **Validate input** before processing
- ## Documentation
- For complete CFML documentation and built-in functions, visit:
- - https://cfdocs.org
- - https://modern-cfml.ortusbooks.com
- ## AI Integration & Resources
- This project includes AI-powered development assistance with on-demand guidelines, skills, and MCP documentation servers.
- ## Project-Specific Conventions
- ### Code Style
- - **Semicolons:** Optional in CFML/BoxLang. Only use when demarcating properties or in inline component syntax
- - **Handler naming:** Plural nouns (Users.cfc, Orders.cfc)
- - **Service naming:** Descriptive with "Service" suffix (UserService.cfc)
- - **Dependency injection:** Use `property name="service" inject` over manual getInstance()
- ### Testing
- - Tests located in `/tests/specs/`
- - Integration tests extend `BaseTestCase` with `appMapping="/app"`
- - **Critical:** Always call `setup()` in `beforeEach()` for test isolation
- - Run tests: `box testbox run`
- ### Configuration
- - Environment variables defined in `.env` (copy from `.env.example`)
- - Access via `getSystemSetting("VAR_NAME", "default")`
- - Framework config in `config/ColdBox.cfc`
- - Routes in `config/Router.cfc`
- ### Application Helpers
- - `includes/helpers/ApplicationHelper.cfm` - Available in all handlers/views
- - Add common utility functions here
- ### Development Workflow
- ```bash
- # Install dependencies
- box install
- # Start server
- box server start
- # Format code
- box run-script format
- # Run tests
- box testbox run
- # Reinit framework (dev)
- /?fwreinit=true
- ```
- ## AI Integration
- This project includes AI-powered development assistance with guidelines, skills, and MCP documentation servers.
- ### Directory Structure
- ```
- /.ai/
- /manifest.json - AI configuration (language, agents, guidelines, skills, MCP servers)
- /guidelines/ - Framework documentation and best practices
- /core/ - Core ColdBox/BoxLang guidelines
- /modules/ - Module-specific guidelines
- /custom/ - Your custom guidelines
- /overrides/ - Override core guidelines
- /skills/ - Implementation cookbooks (how-to guides)
- /core/ - Core development patterns
- /modules/ - Module-specific patterns
- /custom/ - Your custom skills
- /overrides/ - Override core skills
- /mcp-servers/ - MCP server configurations
- ```
- ### Manifest
- The `.ai/manifest.json` file contains the complete AI integration configuration:
- - **language**: Project language mode (boxlang, cfml, hybrid)
- - **templateType**: Application template (modern, flat)
- - **guidelines**: Array of installed guideline names
- - **skills**: Array of installed skill names
- - **agents**: Array of configured AI agents
- - **mcpServers**: Configured MCP documentation servers (core, module, custom)
- - **activeAgent**: Currently active AI agent (if set)
- - **lastSync**: Last synchronization timestamp
- **Reading the manifest** helps you understand available resources and project configuration.
- ### Using Guidelines & Skills
- **Core framework guidelines (ColdBox and language) are already included above.** Additional guidelines and all skills are available on request:
- - **Module Guidelines** provide documentation for installed ColdBox modules
- - **Skills** offer step-by-step implementation patterns for specific features
- - Request specific guidelines or skills by name when you need them
- ### Available Guidelines
- The following additional guidelines are available for this project. Request them by name when needed:
- **To load a guideline:** Request it by name when you need detailed framework or module documentation.
- ### Available Skills
- The following skills provide step-by-step implementation patterns. Request specific skills when you need detailed how-to instructions:
- **Core Skills (Available on request):**
- - **handler-development** - Implementation patterns for ColdBox handler development including CRUD operations, dependency injection, and event handling
- - **rest-api-development** - Build RESTful APIs in ColdBox with proper HTTP methods, validation, error handling, and API best practices
- - **module-development** - Create reusable ColdBox modules with proper structure, configuration, and integration patterns
- - **interceptor-development** - Build ColdBox interceptors for cross-cutting concerns, event listening, and aspect-oriented programming
- - **routing-development** - Configure ColdBox routes, RESTful resources, route groups, and advanced routing patterns
- - **event-model** - Master the ColdBox request context object for handling requests, responses, and application flow control
- - **view-rendering** - Advanced view rendering techniques including partials, caching, helpers, and dynamic content generation
- - **layout-development** - Create and manage ColdBox layouts and views with proper rendering, helpers, and dynamic content
- - **cache-integration** - Implement caching strategies using CacheBox for improved application performance and scalability
- - **cfml-development** - Reusable starter for authoring high-quality skills with clear trigger phrases, implementation steps, testing expectations, and framework-aligned coding conventions.
- - **testing-bdd** - Practical guide to TestBox BDD workflows, including spec structure, readable scenario naming, expectation style, setup/teardown patterns, and maintainable behavior-focused tests.
- - **testing-unit** - Comprehensive guide to writing unit tests with TestBox, including test organization, assertions, expectations, data providers, and testing best practices for isolated component testing
- - **testing-integration** - Comprehensive guide to integration testing in ColdBox applications, including database integration, API testing, external service integration, and full-stack testing strategies
- - **testing-handler** - Comprehensive guide to testing ColdBox event handlers, including request context mocking, event execution, HTTP method testing, and validation testing for controllers
- - **testing-mocking** - Complete guide to mocking dependencies in tests using MockBox, including creating mocks, stubs, spies, and verification patterns
- - **testing-fixtures** - Comprehensive guide to test data management including fixtures, factories, seeders, and data builders for consistent and maintainable test data
- - **testing-coverage** - Complete guide to code coverage analysis in CFML/BoxLang applications, including coverage metrics, reporting, CI integration, and improving test coverage
- - **testing-ci** - Complete guide to setting up continuous integration for automated testing, build pipelines, deployment workflows, and CI best practices
- **To load a skill:** Request it by name when implementing specific features or patterns.
- ## Important Notes
- - Framework reinit: Use `?fwreinit=true` or configure `reinitPassword` for production
- - Module routes process before app routes - be aware of conflicts
- - Use PRC for internal data, RC only for user input
- - Always validate user input from RC
- ## MCP Documentation Servers
- This project has access to the following Model Context Protocol (MCP) documentation servers for live, up-to-date information:
- **Core Documentation Servers:**
- - **boxlang**: BoxLang Language Documentation - https://ai.ortusbooks.com/~gitbook/mcp
- - **coldbox**: ColdBox Framework Documentation - https://coldbox.ortusbooks.com/~gitbook/mcp
- - **commandbox**: CommandBox CLI Documentation - https://commandbox.ortusbooks.com/~gitbook/mcp
- - **testbox**: TestBox Testing Framework - https://testbox.ortusbooks.com/~gitbook/mcp
- - **wirebox**: WireBox Dependency Injection - https://wirebox.ortusbooks.com/~gitbook/mcp
- - **cachebox**: CacheBox Caching Framework - https://cachebox.ortusbooks.com/~gitbook/mcp
- - **logbox**: LogBox Logging Framework - https://logbox.ortusbooks.com/~gitbook/mcp
- **Module Documentation Servers:**
- - **cbsecurity**: CBSecurity Authentication/Authorization - https://coldbox-security.ortusbooks.com/~gitbook/mcp
- - **cbvalidation**: CBValidation Validation Framework - https://coldbox-validation.ortusbooks.com/~gitbook/mcp
- - **quick**: Quick ORM Active Record - https://quick.ortusbooks.com/~gitbook/mcp
- - **cbmailservices**: CBMailServices Email Integration - https://coldbox-mailservices.ortusbooks.com/~gitbook/mcp
- - **relax**: Relax REST API Documentation - https://coldbox-relax.ortusbooks.com/~gitbook/mcp
- **Using MCP Servers:** Query these servers when you need current documentation, API references, or code examples. They provide live, up-to-date information directly from official documentation sources.
- ## Additional Resources
- - ColdBox Docs: https://coldbox.ortusbooks.com
- - TestBox: https://testbox.ortusbooks.com
- - WireBox: https://wirebox.ortusbooks.com
- <!-- COLDBOX-CLI:END -->
- <!-- ℹ️ YOUR PROJECT DOCUMENTATION — Add your custom details below. ColdBox CLI will NOT overwrite this section. -->
- ## Custom Application Details
- <!-- Add project-specific information below -->
- ### Business Domain
- <!-- Describe what this application does -->
- ### Key Services/Models
- <!-- List important services and their responsibilities -->
- ### Authentication/Security
- <!-- Describe authentication approach if applicable -->
- ### API Endpoints
- <!-- Document REST API routes if applicable -->
- ### Deployment
- <!-- Document deployment process -->
- ### Third-Party Integrations
- <!-- List external services, APIs, or integrations -->
Advertisement