Skip to main content

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​

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 release
  • 1.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​

For the complete reference on App properties, node types, and validation rules, see the App Schema Reference.

App Structure Best Practices​

1. Organize by Business Domain​

File: src/apps/crm.json

{
"name": "Customer Management",
"key": "crm",
"nodeType": "appNode",
"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 }
]
}
{
"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 '@april9au/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​

  1. Be Descriptive
✅ Good: customer_order_history.json
❌ Bad: data.json
  1. Use Consistent Case
✅ Files: snake_case
✅ Keys: snake_case or camelCase
✅ Labels: Title Case
  1. 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 ✅​

  1. Use clear, descriptive names
  2. Organize by domain or feature
  3. Keep related files together
  4. Document complex logic
  5. Follow consistent patterns
  6. Use modules for reusability
  7. Index frequently queried fields
  8. Plan for scale from the start

DON'T ❌​

  1. Use generic names (data.json, screen1.json)
  2. Mix unrelated entities in one folder
  3. Create deep folder hierarchies (>3 levels)
  4. Duplicate code across entities
  5. Hardcode values in entities
  6. Skip documentation
  7. Ignore naming conventions
  8. 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​

  1. Module-Based: Clear separation of concerns
  2. Self-Contained: Each module has all its dependencies
  3. Reusable: Modules can be shared across projects
  4. Scalable: Easy to add new modules
  5. Maintainable: Clear where to find/add code
  6. 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:

  1. Restart Stack9: npm run dev
  2. Check file paths are correct
  3. Verify JSON syntax is valid
  4. Check console for errors

Issue: Screen Not Loading​

Problem: Screen shows 404 after moving files

Solution:

  1. Check route in screen definition
  2. Verify app navigation links
  3. Clear browser cache
  4. Check screen key is unique

Issue: Query Not Found​

Problem: Screen says query doesn't exist

Solution:

  1. Check query key matches screen reference
  2. Verify query file is in correct location
  3. Restart Stack9 to reload queries
  4. 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​