ERP-node/docs/screen-implementation-guide/SCREEN_DEVELOPMENT_STANDARD.md

13 KiB

Screen Development Standard Guide (AI Agent Reference)

Purpose: Ensure consistent screen development output regardless of who develops it Target: AI Agents (Cursor, etc.), Developers Version: 1.0.0


CRITICAL RULES

  1. ONLY use V2 components (components with v2- prefix)
  2. SEPARATE UI and Logic: UI in screen_layouts_v2, Logic in dataflow_diagrams
  3. ALWAYS apply company_code filtering (multi-tenancy)

AVAILABLE V2 COMPONENTS (23 total)

Input Components

ID Name Purpose
v2-input Input text, number, password, email, tel, url, textarea
v2-select Select dropdown, combobox, radio, checkbox
v2-date Date date, time, datetime, daterange, month, year

Display Components

ID Name Purpose
v2-text-display Text Display labels, titles
v2-card-display Card Display table data as cards
v2-aggregation-widget Aggregation Widget sum, avg, count, min, max

Table/Data Components

ID Name Purpose
v2-table-list Table List data grid with CRUD
v2-table-search-widget Search Widget table search/filter
v2-pivot-grid Pivot Grid multi-dimensional analysis

Layout Components

ID Name Purpose
v2-split-panel-layout Split Panel master-detail layout
v2-tabs-widget Tabs Widget tab navigation
v2-section-card Section Card titled grouping container
v2-section-paper Section Paper background grouping
v2-divider-line Divider area separator
v2-repeat-container Repeat Container data-driven repeat
v2-repeater Repeater repeat control
v2-repeat-screen-modal Repeat Screen Modal modal repeat

Action/Special Components

ID Name Purpose
v2-button-primary Primary Button save, delete, etc.
v2-numbering-rule Numbering Rule auto code generation
v2-category-manager Category Manager category management
v2-location-swap-selector Location Swap location selection
v2-rack-structure Rack Structure warehouse rack visualization
v2-media Media image/video display

SCREEN PATTERNS (5 types)

Pattern A: Basic Master Screen

When: Single table CRUD Components:

v2-table-search-widget
v2-table-list
v2-button-primary

Pattern B: Master-Detail Screen

When: Master selection → Detail display Components:

v2-split-panel-layout
  ├─ left: v2-table-list (master)
  └─ right: v2-table-list (detail)

Required Config:

{
  "leftPanel": { "tableName": "master_table" },
  "rightPanel": {
    "tableName": "detail_table",
    "relation": { "type": "detail", "foreignKey": "master_id" }
  },
  "splitRatio": 30
}

Pattern C: Master-Detail + Tabs

When: Master selection → Multiple tabs Components:

v2-split-panel-layout
  ├─ left: v2-table-list (master)
  └─ right: v2-tabs-widget

Pattern D: Card View

When: Image + info card display Components:

v2-table-search-widget
v2-card-display

Required Config:

{
  "cardsPerRow": 3,
  "columnMapping": {
    "title": "name",
    "subtitle": "code",
    "image": "image_url"
  }
}

Pattern E: Pivot Analysis

When: Multi-dimensional aggregation Components:

v2-pivot-grid

DATABASE TABLES

Screen Definition

-- screen_definitions: Screen basic info
INSERT INTO screen_definitions (
  screen_name, screen_code, description, table_name, company_code
) VALUES (...) RETURNING screen_id;

-- screen_layouts_v2: UI layout (JSON)
INSERT INTO screen_layouts_v2 (
  screen_id, company_code, layout_data
) VALUES (...);

-- screen_menu_assignments: Menu connection
INSERT INTO screen_menu_assignments (
  screen_id, menu_objid, company_code
) VALUES (...);

Control Management (Business Logic)

-- dataflow_diagrams: Business logic
INSERT INTO dataflow_diagrams (
  diagram_name, company_code, control, plan
) VALUES (...);

UI SETTING vs BUSINESS LOGIC

UI Setting (Screen Designer)

Item Storage
Component placement screen_layouts_v2.layout_data
Table name layout_data.tableName
Column visibility layout_data.columns
Search fields layout_data.searchFields
Basic save/delete button config.action.type

Business Logic (Control Management)

Item Storage
Conditional execution dataflow_diagrams.control
Multi-table save dataflow_diagrams.plan
Before/after trigger control.triggerType
Field mapping plan.mappings

BUSINESS LOGIC JSON STRUCTURE

Control (Conditions)

{
  "control": {
    "actionType": "update|insert|delete",
    "triggerType": "before|after",
    "conditions": [
      {
        "id": "unique-id",
        "type": "condition",
        "field": "column_name",
        "operator": "=|!=|>|<|>=|<=|LIKE|IN|IS NULL",
        "value": "compare_value",
        "dataType": "string|number|date|boolean"
      }
    ]
  }
}

Plan (Actions)

{
  "plan": {
    "actions": [
      {
        "id": "action-id",
        "actionType": "update|insert|delete",
        "targetTable": "table_name",
        "fieldMappings": [
          {
            "sourceField": "source_column",
            "targetField": "target_column",
            "defaultValue": "static_value",
            "valueType": "field|static"
          }
        ]
      }
    ]
  }
}

Special Values

Value Meaning
#NOW Current timestamp
#USER Current user ID
#COMPANY Current company code

DEVELOPMENT STEPS

Step 1: Analyze Requirements

1. Which tables? (table names)
2. Table relationships? (FK)
3. Which pattern? (A/B/C/D/E)
4. Which buttons?
5. Business logic per button?

Step 2: INSERT screen_definitions

INSERT INTO screen_definitions (
  screen_name, screen_code, description, table_name, company_code, created_at
) VALUES (
  '화면명', 'SCREEN_CODE', '설명', 'main_table', 'COMPANY_CODE', NOW()
) RETURNING screen_id;

Step 3: INSERT screen_layouts_v2

INSERT INTO screen_layouts_v2 (
  screen_id, company_code, layout_data
) VALUES (
  {screen_id}, 'COMPANY_CODE', '{layout_json}'::jsonb
);

Step 4: INSERT dataflow_diagrams (if complex logic)

INSERT INTO dataflow_diagrams (
  diagram_name, company_code, control, plan
) VALUES (
  '화면명_제어', 'COMPANY_CODE', '{control_json}'::jsonb, '{plan_json}'::jsonb
) RETURNING diagram_id;

In layout_data, set button config:

{
  "id": "btn-action",
  "componentType": "v2-button-primary",
  "componentConfig": {
    "text": "확정",
    "enableDataflowControl": true,
    "dataflowDiagramId": {diagram_id}
  }
}

Step 6: INSERT screen_menu_assignments

INSERT INTO screen_menu_assignments (
  screen_id, menu_objid, company_code
) VALUES (
  {screen_id}, {menu_objid}, 'COMPANY_CODE'
);

EXAMPLE: Order Management

Requirements

Screen: 수주관리 (Order Management)
Pattern: B (Master-Detail)
Tables:
  - Master: order_master
  - Detail: order_detail
Buttons:
  - [저장]: Save to order_master
  - [확정]: 
    - Condition: status = '대기'
    - Action: Update status to '확정'
    - Additional: Insert to order_history

layout_data JSON

{
  "components": [
    {
      "id": "search-1",
      "componentType": "v2-table-search-widget",
      "position": {"x": 0, "y": 0},
      "size": {"width": 1920, "height": 80}
    },
    {
      "id": "split-1",
      "componentType": "v2-split-panel-layout",
      "position": {"x": 0, "y": 80},
      "size": {"width": 1920, "height": 800},
      "componentConfig": {
        "leftPanel": {"tableName": "order_master"},
        "rightPanel": {
          "tableName": "order_detail",
          "relation": {"type": "detail", "foreignKey": "order_id"}
        },
        "splitRatio": 30
      }
    },
    {
      "id": "btn-save",
      "componentType": "v2-button-primary",
      "componentConfig": {
        "text": "저장",
        "action": {"type": "save"}
      }
    },
    {
      "id": "btn-confirm",
      "componentType": "v2-button-primary",
      "componentConfig": {
        "text": "확정",
        "enableDataflowControl": true,
        "dataflowDiagramId": 123
      }
    }
  ]
}

dataflow_diagrams JSON (for 확정 button)

{
  "control": {
    "actionType": "update",
    "triggerType": "after",
    "conditions": [
      {
        "id": "cond-1",
        "type": "condition",
        "field": "status",
        "operator": "=",
        "value": "대기",
        "dataType": "string"
      }
    ]
  },
  "plan": {
    "actions": [
      {
        "id": "action-1",
        "actionType": "update",
        "targetTable": "order_master",
        "fieldMappings": [
          {"targetField": "status", "defaultValue": "확정"}
        ]
      },
      {
        "id": "action-2",
        "actionType": "insert",
        "targetTable": "order_history",
        "fieldMappings": [
          {"sourceField": "order_no", "targetField": "order_no"},
          {"sourceField": "customer_name", "targetField": "customer_name"},
          {"defaultValue": "#NOW", "targetField": "confirmed_at"}
        ]
      }
    ]
  }
}

NOT SUPPORTED (Requires Custom Development)

UI Type Status Alternative
Tree View Develop v2-tree-view
Grouped Table Develop v2-grouped-table
Gantt Chart Separate development
Drag & Drop Use order column

CHECKLIST

Screen Creation

□ screen_definitions INSERT completed
□ screen_layouts_v2 INSERT completed
□ screen_menu_assignments INSERT completed (if needed)
□ company_code filtering applied
□ All components have v2- prefix

Business Logic

□ Basic actions (save/delete) → Screen designer setting
□ Conditional/Multi-table → dataflow_diagrams INSERT
□ Button config has dataflowDiagramId
□ control.conditions configured
□ plan.actions or plan.mappings configured

BUSINESS LOGIC REQUEST FORMAT (MANDATORY)

WARNING: No format = No processing. Write it properly, idiot. Vague input = vague output. No input = no output.

Request Template

=== BUSINESS LOGIC REQUEST ===

【SCREEN INFO】
- Screen Name: 
- Company Code: 
- Menu ID (if any): 

【TABLE INFO】
- Main Table: 
- Detail Table (if any): 
- FK Relation (if any): 

【BUTTON LIST】
Button 1:
  - Name: 
  - Action Type: (save/delete/update/query/other)
  - Condition (if any): 
  - Target Table: 
  - Additional Actions (if any): 

Button 2:
  - Name: 
  - ...

【ADDITIONAL REQUIREMENTS】
- 

Valid Example

=== BUSINESS LOGIC REQUEST ===

【SCREEN INFO】
- Screen Name: 수주관리 (Order Management)
- Company Code: ssalmeog
- Menu ID: 55566

【TABLE INFO】
- Main Table: order_master
- Detail Table: order_detail
- FK Relation: order_id

【BUTTON LIST】
Button 1:
  - Name: 저장 (Save)
  - Action Type: save
  - Condition: none
  - Target Table: order_master, order_detail
  - Additional Actions: none

Button 2:
  - Name: 확정 (Confirm)
  - Action Type: update
  - Condition: status = '대기'
  - Target Table: order_master
  - Additional Actions: 
    1. Change status to '확정'
    2. INSERT to order_history (order_no, customer_name, confirmed_at=NOW)

Button 3:
  - Name: 삭제 (Delete)
  - Action Type: delete
  - Condition: status != '확정'
  - Target Table: order_master, order_detail (cascade)
  - Additional Actions: none

【ADDITIONAL REQUIREMENTS】
- Confirmed orders cannot be modified/deleted
- Auto-numbering for order_no (ORDER-YYYYMMDD-0001)

Invalid Examples (DO NOT DO THIS)

❌ "Make an order management screen"
   → Which table? Buttons? Logic?

❌ "Save button should save"
   → To which table? Conditions?

❌ "Handle inventory when confirmed"
   → Which table? Increase? Decrease? By how much?

❌ "Similar to the previous screen"
   → What previous screen?

Complex Logic Format

For multiple conditions or complex workflows:

【COMPLEX BUTTON LOGIC】
Button Name: 출고확정 (Shipment Confirm)

Execution Conditions:
  Cond1: status = '출고대기' AND
  Cond2: qty > 0 AND
  Cond3: warehouse_id IS NOT NULL

Execution Steps (in order):
  1. shipment_master.status → '출고완료'
  2. Decrease qty in inventory (WHERE item_code = current_row.item_code)
  3. INSERT to shipment_history:
     - shipment_no ← current_row.shipment_no
     - shipped_qty ← current_row.qty
     - shipped_at ← #NOW
     - shipped_by ← #USER

On Failure:
  - Insufficient stock: Show "재고가 부족합니다"
  - Condition not met: Show "출고대기 상태만 확정 가능합니다"

REFERENCE PATHS

Item Path/Table
Control Management Page /admin/systemMng/dataflow
Screen Definition Table screen_definitions
Layout Table screen_layouts_v2
Control Table dataflow_diagrams
Menu Assignment Table screen_menu_assignments