Structuring Your Application
Learn how to organize and structure your Stack9 application for scalability, maintainability, and team collaboration. This guide covers architecture patterns, folder organization, naming conventions, and best practices for building production-grade applications.
What You'll Learn
- ✅ Application architecture patterns
- ✅ Module organization strategies
- ✅ Entity folder structure
- ✅ Screen organization
- ✅ Query library organization
- ✅ Code organization best practices
- ✅ Naming conventions
- ✅ Scalability considerations
Time Required: 45-60 minutes
Prerequisites
- Completed Quick Start Guide
- Understanding of Core Concepts
- Basic familiarity with Stack9 project structure
Stack9 Project Structure Overview
A typical Stack9 application follows this structure:
stack9-stack/
├── src/
│ ├── entities/ # Data models
│ │ ├── custom/ # Your entities
│ │ └── core/ # System entities
│ ├── screens/ # UI definitions
│ ├── query-library/ # Data queries
│ ├── apps/ # Navigation apps
│ ├── automations/ # Workflows
│ ├── entity-hooks/ # Business logic
│ ├── action-types/ # Custom actions
│ ├── connectors/ # External APIs
│ ├── services/ # Reusable services
│ ├── document-templates/ # PDF/email templates
│ └── modules/ # Reusable packages
├── package.json
├── tsconfig.json
└── .env
Architecture Patterns
Pattern 1: Domain-Driven Design (DDD)
Organize by business domain/module:
src/
├── entities/
│ ├── custom/
│ │ ├── crm/ # Customer management domain
│ │ │ ├── customer.json
│ │ │ ├── customer_contact.json
│ │ │ ├── customer_note.json
│ │ │ └── customer_group.json
│ │ ├── sales/ # Sales domain
│ │ │ ├── sales_order.json
│ │ │ ├── order_item.json
│ │ │ ├── invoice.json
│ │ │ └── payment.json
│ │ ├── inventory/ # Inventory domain
│ │ │ ├── product.json
│ │ │ ├── category.json
│ │ │ ├── warehouse.json
│ │ │ └── stock_movement.json
│ │ └── hr/ # HR domain
│ │ ├── employee.json
│ │ ├── department.json
│ │ └── timesheet.json
├── screens/
│ ├── crm/
│ │ ├── customer_list.json
│ │ ├── customer_detail.json
│ │ └── customer_dashboard.json
│ ├── sales/
│ │ ├── order_list.json
│ │ ├── order_detail.json
│ │ └── invoice_list.json
│ └── inventory/
│ ├── product_list.json
│ └── stock_report.json
└── query-library/
├── crm/
│ ├── getcustomerlist.json
│ └── getcustomer.json
├── sales/
│ ├── getorderlist.json
│ └── getorderdetails.json
└── inventory/
├── getproductlist.json
└── getstocklevels.json
Benefits:
- ✅ Clear domain boundaries
- ✅ Easy to find related code
- ✅ Team can work on different domains independently
- ✅ Easier to extract domains into separate services
Pattern 2: Feature-Based Structure
Organize by feature/capability:
src/
├── entities/
│ └── custom/
│ ├── customer_management.json
│ ├── order_processing.json
│ ├── inventory_tracking.json
│ └── reporting.json
├── screens/
│ ├── customer_management/
│ │ ├── list.json
│ │ ├── detail.json
│ │ └── analytics.json
│ └── order_processing/
│ ├── order_entry.json
│ ├── order_fulfillment.json
│ └── order_tracking.json
└── query-library/
├── customer_management/
└── order_processing/
Benefits:
- ✅ Feature-focused organization
- ✅ All related files in one place
- ✅ Easy to add/remove features
- ✅ Clear feature boundaries
Pattern 3: Layer-Based Structure
Organize by technical layer (traditional approach):
src/
├── entities/
│ └── custom/
│ ├── customer.json
│ ├── order.json
│ └── product.json
├── screens/
│ ├── customer_list.json
│ ├── order_detail.json
│ └── product_catalog.json
├── query-library/
│ ├── getcustomerlist.json
│ ├── getorderdetails.json
│ └── getproductcatalog.json
└── entity-hooks/
├── customer.vat.ts
├── order.vat.ts
└── product.vat.ts
Benefits:
- ✅ Simple and straightforward
- ✅ Good for small applications
- ✅ Familiar structure
- ✅ Easy to learn
Module Organization
Modules are reusable packages that can be shared across Stack9 applications.
Creating a Module
File: src/modules/customer-management/module.json
{
"key": "customer_management",
"name": "Customer Management Module",
"version": "1.0.0",
"description": "Complete CRM functionality",
"author": "Your Company",
"dependencies": [],
"includes": {
"entities": [
"customer",
"customer_contact",
"customer_note",
"customer_address"
],
"screens": [
"customer_list",
"customer_detail",
"customer_dashboard"
],
"queries": [
"getcustomerlist",
"getcustomer",
"getcustomercontacts"
],
"apps": [
"crm"
],
"automations": [
"customer_welcome_email"
]
}
}
Module Folder Structure
src/modules/customer-management/
├── module.json # Module definition
├── entities/
│ ├── customer.json
│ ├── customer_contact.json
│ └── customer_note.json
├── screens/
│ ├── customer_list.json
│ ├── customer_detail.json
│ └── customer_dashboard.json
├── query-library/
│ ├── getcustomerlist.json
│ └── getcustomer.json
├── apps/
│ └── crm.json
├── entity-hooks/
│ ├── customer.vat.ts
│ └── customer.bat.ts
├── automations/
│ └── customer_welcome_email.json
├── document-templates/
│ └── customer_statement.html
└── README.md # Module documentation
Module Best Practices
1. Keep Modules Focused
✅ Good - Focused modules:
- customer-management
- order-processing
- inventory-tracking
❌ Bad - Too broad:
- business-logic
- utilities
- everything
2. Define Clear Dependencies
{
"dependencies": [
"customer-management@^1.0.0",
"product-catalog@^2.1.0"
]
}
3. Version Modules
Follow semantic versioning:
1.0.0- Initial release1.1.0- New features (backward compatible)2.0.0- Breaking changes
4. Document Modules
Include comprehensive README.md:
# Customer Management Module
## Overview
Complete CRM functionality for managing customer relationships.
## Features
- Customer CRUD operations
- Contact management
- Customer notes and history
- Customer segmentation
## Installation
1. Copy module to `src/modules/customer-management`
2. Run `npm run dev` to load entities
3. Configure app navigation
## Configuration
Set environment variables:
- `CRM_NOTIFICATION_EMAIL` - Email for notifications
- `CRM_DEFAULT_SALES_REP` - Default sales representative
## Usage
Navigate to `/crm/customer-list` to access customer management.
Entity Organization
Entity Naming Conventions
File Names
✅ Good:
- customer.json
- sales_order.json
- product_category.json
- order_line_item.json
❌ Bad:
- cust.json
- so.json
- cat.json
- oli.json
Entity Keys
{
"head": {
"key": "customer", // ✅ Singular, lowercase
"pluralisedName": "customers" // ✅ Plural
}
}
Field Keys
{
"fields": [
{
"key": "first_name", // ✅ snake_case
"label": "First Name" // ✅ Human-readable
},
{
"key": "email_address", // ✅ Descriptive
"label": "Email Address"
},
{
"key": "is_active", // ✅ Boolean prefix
"label": "Active"
}
]
}
Entity Organization Patterns
Pattern 1: Core + Custom Entities
entities/
├── core/ # System entities (don't modify)
│ ├── user.json
│ ├── user_group.json
│ └── security_role.json
└── custom/ # Your entities
├── customer.json
├── order.json
└── product.json
Pattern 2: Domain Subfolders
entities/custom/
├── crm/
│ ├── customer.json
│ ├── lead.json
│ └── opportunity.json
├── sales/
│ ├── order.json
│ ├── invoice.json
│ └── payment.json
└── inventory/
├── product.json
├── warehouse.json
└── stock_movement.json
Pattern 3: Prefixed Names
entities/custom/
├── crm_customer.json
├── crm_lead.json
├── sales_order.json
├── sales_invoice.json
├── inv_product.json
└── inv_warehouse.json
Entity Relationship Organization
Keep related entities close together:
// customer.json
{
"head": {
"key": "customer",
"name": "Customer"
},
"fields": [
{
"key": "contacts",
"type": "Grid",
"relationshipOptions": {
"ref": "customer_contact"
}
},
{
"key": "addresses",
"type": "Grid",
"relationshipOptions": {
"ref": "customer_address"
}
}
]
}
// customer_contact.json (child entity)
{
"head": {
"key": "customer_contact",
"name": "Customer Contact"
},
"fields": [
{
"key": "customer_id",
"type": "SingleDropDown",
"relationshipOptions": {
"ref": "customer"
}
}
]
}
Screen Organization
Screen Naming Conventions
✅ Good naming:
- customer_list.json # List view
- customer_detail.json # Detail view
- customer_create.json # Create drawer
- customer_edit.json # Edit drawer
- sales_dashboard.json # Dashboard
- monthly_sales_report.json # Report
❌ Bad naming:
- screen1.json
- customers.json
- view.json
- report.json
Screen Organization Patterns
Pattern 1: Entity-Based Organization
screens/
├── customer/
│ ├── customer_list.json
│ ├── customer_detail.json
│ ├── customer_create.json
│ ├── customer_edit.json
│ └── customer_dashboard.json
├── order/
│ ├── order_list.json
│ ├── order_detail.json
│ ├── order_create.json
│ └── order_fulfillment.json
└── product/
├── product_list.json
├── product_detail.json
└── product_catalog.json
Pattern 2: App-Based Organization
screens/
├── crm/
│ ├── customer_list.json
│ ├── customer_detail.json
│ ├── lead_list.json
│ └── opportunity_pipeline.json
├── sales/
│ ├── order_list.json
│ ├── quote_list.json
│ └── sales_dashboard.json
└── reports/
├── sales_report.json
├── inventory_report.json
└── customer_analytics.json
Pattern 3: Type-Based Organization
screens/
├── lists/
│ ├── customer_list.json
│ ├── order_list.json
│ └── product_list.json
├── details/
│ ├── customer_detail.json
│ ├── order_detail.json
│ └── product_detail.json
├── dashboards/
│ ├── sales_dashboard.json
│ └── operations_dashboard.json
└── reports/
├── sales_report.json
└── inventory_report.json
Screen Route Patterns
Maintain consistent route patterns:
{
"head": {
// List views
"route": "customer-list"
"route": "order-list"
// Detail views
"route": "customer-detail/:id"
"route": "order-detail/:id"
// Create screens
"route": "customer-create"
"route": "order-create"
// Dashboards
"route": "sales-dashboard"
"route": "crm-dashboard"
// Reports
"route": "sales-report"
"route": "inventory-report"
}
}
Query Library Organization
Query Naming Conventions
Use descriptive, action-based names:
✅ Good:
- getcustomerlist.json
- getcustomer.json
- getactiveorders.json
- searchproducts.json
- getmonthlysales.json
- getcustomerwithorders.json
❌ Bad:
- query1.json
- customers.json
- list.json
- data.json
Query Organization Patterns
Pattern 1: Entity-Based
query-library/
├── customer/
│ ├── getcustomerlist.json
│ ├── getcustomer.json
│ ├── searchcustomers.json
│ └── getcustomerorders.json
├ ── order/
│ ├── getorderlist.json
│ ├── getorder.json
│ └── getorderitems.json
└── product/
├── getproductlist.json
├── getproduct.json
└── getproductsbycategory.json
Pattern 2: Purpose-Based
query-library/
├── lists/
│ ├── getcustomerlist.json
│ ├── getorderlist.json
│ └── getproductlist.json
├── details/
│ ├── getcustomer.json
│ ├── getorder.json
│ └── getproduct.json
├── reports/
│ ├── getsalesreport.json
│ ├── getinventoryreport.json
│ └── getcustomeranalytics.json
└── searches/
├── searchcustomers.json
├── searchorders.json
└── searchproducts.json
Pattern 3: Flat with Prefixes
query-library/
├── getcustomerlist.json
├── getcustomer.json
├── getorderlist.json
├── getorder.json
├── getproductlist.json
└── getproduct.json
Query Folders
Use query folders for organization:
File: src/query-folders.json
{
"folders": [
{
"key": "customer_queries",
"name": "Customer Queries",
"description": "Queries related to customer management",
"order": 1
},
{
"key": "order_queries",
"name": "Order Queries",
"description": "Queries for order processing",
"order": 2
},
{
"key": "report_queries",
"name": "Report Queries",
"description": "Queries for reports and analytics",
"order": 3
},
{
"key": "search_queries",
"name": "Search Queries",
"description": "Full-text search queries",
"order": 4
}
]
}
Reference in queries:
{
"key": "getcustomerlist",
"name": "getCustomerList",
"folderKey": "customer_queries",
"connector": "stack9_api"
}
App Navigation Organization
App Structure Best Practices
1. Organize by Business Domain
File: src/apps/crm.json
{
"name": "Customer Management",
"key": "crm",
"icon": "UserOutlined",
"order": 10,
"children": [
{
"key": "customers",
"name": "Customers",
"nodeType": "menuGroup",
"children": [
{
"key": "customer_list",
"name": "All Customers",
"nodeType": "link",
"link": "/crm/customer-list"
},
{
"key": "customer_segments",
"name": "Customer Segments",
"nodeType": "link",
"link": "/crm/customer-segments"
}
]
},
{
"key": "leads",
"name": "Leads",
"nodeType": "menuGroup",
"children": [
{
"key": "lead_list",
"name": "All Leads",
"nodeType": "link",
"link": "/crm/lead-list"
},
{
"key": "lead_pipeline",
"name": "Sales Pipeline",
"nodeType": "link",
"link": "/crm/lead-pipeline"
}
]
}
]
}
2. Use Consistent Ordering
{
"apps": [
{ "key": "dashboard", "order": 1 },
{ "key": "crm", "order": 10 },
{ "key": "sales", "order": 20 },
{ "key": "inventory", "order": 30 },
{ "key": "reports", "order": 40 },
{ "key": "settings", "order": 999 }
]
}
3. Group Related Features
{
"children": [
{
"key": "data_management",
"name": "Data Management",
"nodeType": "menuGroup",
"children": [
{"key": "customers", "name": "Customers"},
{"key": "products", "name": "Products"},
{"key": "orders", "name": "Orders"}
]
},
{
"key": "analytics",
"name": "Analytics",
"nodeType": "menuGroup",
"children": [
{"key": "dashboards", "name": "Dashboards"},
{"key": "reports", "name": "Reports"}
]
}
]
}
Code Organization (Hooks & Actions)
Entity Hooks Organization
File Naming
entity-hooks/
├── customer.vat.ts # Validation (before transaction)
├── customer.bat.ts # Business logic (after transaction)
├── order.vat.ts
├── order.bat.ts
├── product.vat.ts
└── product.bat.ts
Code Structure
// customer.vat.ts
import {
CustomFunction,
CustomFunctionContext,
CustomFunctionResponse,
HookOperation,
} from '@april9/stack9-sdk';
import { DBCustomer } from '../models/stack9/Customer';
/**
* Customer Validation Hook
*
* Validates customer data before saving to database.
*
* Rules:
* - Email must be unique
* - Phone number format validation
* - Credit limit validation
*/
export class ValidateCustomer extends CustomFunction {
constructor(private context: CustomFunctionContext<DBCustomer>) {
super();
}
entityName = 'customer';
async exec(): Promise<CustomFunctionResponse> {
const { entity, operation, db, services } = this.context;
// Validate email uniqueness
if (operation === HookOperation.create || entity.email) {
const existingCustomer = await this.checkEmailUniqueness(
entity.email,
entity.id
);
if (existingCustomer) {
return {
valid: false,
errors: [{
field: 'email',
message: 'Email address already exists'
}]
};
}
}
// Validate phone number format
if (entity.phone) {
if (!this.isValidPhoneNumber(entity.phone)) {
return {
valid: false,
errors: [{
field: 'phone',
message: 'Invalid phone number format'
}]
};
}
}
// Validate credit limit
if (entity.credit_limit < 0) {
return {
valid: false,
errors: [{
field: 'credit_limit',
message: 'Credit limit cannot be negative'
}]
};
}
return { valid: true, entity };
}
/**
* Check if email address is unique
*/
private async checkEmailUniqueness(
email: string,
excludeId?: number
): Promise<boolean> {
const { db } = this.context;
const query = db('customers')
.where({ email, _is_deleted: false });
if (excludeId) {
query.whereNot({ id: excludeId });
}
const existing = await query.first();
return !!existing;
}
/**
* Validate phone number format
*/
private isValidPhoneNumber(phone: string): boolean {
const phoneRegex = /^\+?[\d\s\-\(\)]+$/;
return phoneRegex.test(phone);
}
}
Action Types Organization
action-types/
├── notifications/
│ ├── SendEmailAction.ts
│ ├── SendSMSAction.ts
│ └── PushNotificationAction.ts
├── integrations/
│ ├── SyncToSalesforceAction.ts
│ ├── CreateHubspotContactAction.ts
│ └── SendToSlackAction.ts
├── business-logic/
│ ├── CalculateDiscountAction.ts
│ ├── UpdateInventoryAction.ts
│ └── GenerateInvoiceAction.ts
└── utilities/
├── GeneratePDFAction.ts
├── ExportToCSVAction.ts
└── ArchiveRecordsAction.ts
Services Organization
services/
├── email/
│ ├── EmailService.ts
│ └── EmailTemplateService.ts
├── payment/
│ ├── PaymentProcessorService.ts
│ └── PaymentValidationService.ts
├── inventory/
│ ├── StockService.ts
│ └── WarehouseService.ts
└── reporting/
├── ReportGeneratorService.ts
└── ReportExportService.ts
Naming Conventions
General Rules
- Be Descriptive
✅ Good: customer_order_history.json
❌ Bad: data.json
- Use Consistent Case
✅ Files: snake_case
✅ Keys: snake_case or camelCase
✅ Labels: Title Case
- Follow Patterns
✅ Queries: get*, search*, list*
✅ Actions: send*, create*, update*
✅ Hooks: validate*, process*, calculate*
Entity Naming
{
"head": {
"name": "Sales Order", // Title Case
"key": "sales_order", // snake_case
"pluralisedName": "sales orders" // lowercase plural
},
"fields": [
{
"key": "order_number", // snake_case
"label": "Order Number" // Title Case
}
]
}
Screen Naming
{
"head": {
"title": "Customer List", // Title Case
"key": "customer_list", // snake_case
"route": "customer-list" // kebab-case
}
}
Query Naming
{
"key": "getcustomerlist", // camelCase
"name": "getCustomerList" // PascalCase
}
Scalability Considerations
1. Plan for Growth
Start with clean organization:
✅ Good from start:
entities/custom/
├── crm/
│ └── customer.json
├── sales/
│ └── order.json
└── inventory/
└── product.json
❌ Hard to scale:
entities/custom/
├── customer.json
├── customer2.json
├── order.json
├── order_new.json
└── product_v2.json
2. Use Modules for Reusability
Extract common functionality:
modules/
├── customer-management/ # Reusable CRM module
├── product-catalog/ # Reusable product module
└── order-processing/ # Reusable order module
3. Separate Configuration from Code
config/
├── environments/
│ ├── development.json
│ ├── staging.json
│ └── production.json
├── features/
│ └── feature-flags.json
└── integrations/
├── salesforce-config.json
└── stripe-config.json
4. Index Strategic Fields
{
"fields": [
{
"key": "email",
"type": "TextField",
"index": true // ✅ Frequently queried
},
{
"key": "order_date",
"type": "DateField",
"index": true // ✅ Used in filters
},
{
"key": "status",
"type": "OptionSet",
"index": true // ✅ Common filter
}
]
}
5. Optimize Queries
{
"$select": [
"id",
"name",
"email" // ✅ Only needed fields
],
"$limit": 50, // ✅ Reasonable limit
"$where": {
"is_active": true, // ✅ Indexed field
"_is_deleted": false // ✅ Always filter deleted
}
}
6. Use Caching Strategically
// Cache expensive queries
export class ReportService {
async getMonthlyReport(month: string) {
const cacheKey = `monthly_report_${month}`;
// Check cache
const cached = await cache.get(cacheKey);
if (cached) return cached;
// Generate report
const report = await this.generateReport(month);
// Cache for 1 hour
await cache.set(cacheKey, report, 3600);
return report;
}
}
Best Practices Summary
DO ✅
- Use clear, descriptive names
- Organize by domain or feature
- Keep related files together
- Document complex logic
- Follow consistent patterns
- Use modules for reusability
- Index frequently queried fields
- Plan for scale from the start
DON'T ❌
- Use generic names (data.json, screen1.json)
- Mix unrelated entities in one folder
- Create deep folder hierarchies (>3 levels)
- Duplicate code across entities
- Hardcode values in entities
- Skip documentation
- Ignore naming conventions
- Create monolithic modules
Example: Well-Structured Application
Let's look at a complete example of a well-structured e-commerce application:
stack9-ecommerce/
├── src/
│ ├── modules/
│ │ ├── customer-management/
│ │ │ ├── module.json
│ │ │ ├── entities/
│ │ │ │ ├── customer.json
│ │ │ │ ├── customer_address.json
│ │ │ │ └── customer_wishlist.json
│ │ │ ├── screens/
│ │ │ │ ├── customer_list.json
│ │ │ │ ├── customer_detail.json
│ │ │ │ └── customer_dashboard.json
│ │ │ ├── query-library/
│ │ │ │ ├── getcustomerlist.json
│ │ │ │ └── getcustomer.json
│ │ │ ├── apps/
│ │ │ │ └── customers.json
│ │ │ ├── entity-hooks/
│ │ │ │ ├── customer.vat.ts
│ │ │ │ └── customer.bat.ts
│ │ │ └── README.md
│ │ ├── product-catalog/
│ │ │ ├── module.json
│ │ │ ├── entities/
│ │ │ │ ├── product.json
│ │ │ │ ├── category.json
│ │ │ │ └── product_variant.json
│ │ │ ├── screens/
│ │ │ │ ├── product_list.json
│ │ │ │ ├── product_detail.json
│ │ │ │ └── category_list.json
│ │ │ └── query-library/
│ │ │ ├── getproductlist.json
│ │ │ └── getproduct.json
│ │ └── order-management/
│ │ ├── module.json
│ │ ├── entities/
│ │ │ ├── order.json
│ │ │ ├── order_item.json
│ │ │ └── shipment.json
│ │ ├── screens/
│ │ │ ├── order_list.json
│ │ │ ├── order_detail.json
│ │ │ └── fulfillment_queue.json
│ │ ├── query-library/
│ │ │ ├── getorderlist.json
│ │ │ └── getorder.json
│ │ ├── entity-hooks/
│ │ │ ├── order.vat.ts
│ │ │ └── order.bat.ts
│ │ └── automations/
│ │ ├── order_confirmation.json
│ │ └── shipment_notification.json
│ ├── services/
│ │ ├── payment/
│ │ │ └── PaymentService.ts
│ │ ├── inventory/
│ │ │ └── InventoryService.ts
│ │ └── shipping/
│ │ └── ShippingService.ts
│ ├── action-types/
│ │ ├── ProcessPaymentAction.ts
│ │ ├── UpdateInventoryAction.ts
│ │ └── CreateShipmentAction.ts
│ ├── config/
│ │ ├── payment-gateways.json
│ │ ├── shipping-providers.json
│ │ └── tax-rates.json
│ └── document-templates/
│ ├── order_confirmation.html
│ ├── invoice.html
│ └── shipping_label.html
├── package.json
├── tsconfig.json
├── .env.example
└── README.md
Key Features of This Structure
- Module-Based: Clear separation of concerns
- Self-Contained: Each module has all its dependencies
- Reusable: Modules can be shared across projects
- Scalable: Easy to add new modules
- Maintainable: Clear where to find/add code
- Documented: README files for each module
Migration Strategy
Migrating from Flat Structure
If you have a flat structure, migrate gradually:
Step 1: Create Module Structure
mkdir -p src/modules/customer-management/{entities,screens,query-library}
Step 2: Move Related Files
mv src/entities/custom/customer*.json src/modules/customer-management/entities/
mv src/screens/customer*.json src/modules/customer-management/screens/
mv src/query-library/getcustomer*.json src/modules/customer-management/query-library/
Step 3: Update References Update paths in import statements and configuration files.
Step 4: Test Thoroughly Ensure all functionality still works after migration.
Troubleshooting
Issue: Can't Find Entity
Problem: Stack9 can't load entity after reorganization
Solution:
- Restart Stack9:
npm run dev - Check file paths are correct
- Verify JSON syntax is valid
- Check console for errors
Issue: Screen Not Loading
Problem: Screen shows 404 after moving files
Solution:
- Check route in screen definition
- Verify app navigation links
- Clear browser cache
- Check screen key is unique
Issue: Query Not Found
Problem: Screen says query doesn't exist
Solution:
- Check query key matches screen reference
- Verify query file is in correct location
- Restart Stack9 to reload queries
- Check query JSON is valid
Summary
You now understand:
✅ Architecture Patterns - DDD, feature-based, layer-based ✅ Module Organization - Creating reusable modules ✅ Entity Structure - Organizing entities by domain ✅ Screen Organization - Grouping screens logically ✅ Query Organization - Structuring query library ✅ Naming Conventions - Consistent, clear naming ✅ Scalability - Building for growth ✅ Best Practices - Production-ready organization
Next Steps
- Creating Reusable Modules - Build shareable modules
- Performance Optimization - Optimize your application
- Building Workflows - Add automation
- Entity Relationships - Design data models