gettingStarted.md 19 KB
Newer Older
1 2
# The City Portal Web Application sample with UB 4 

3 4 5 6
The following City Portal sample demonstrates accounting of citizens request on city departments. 


You will learn how you can create an application using the UnityBase platform. 
7

8
By constructing a website for a fictional city portal on the instruction of this tutorial, 
9
you will be able to create, read, update and delete (CRUD) different objects. 
10

11
Let’s start the practice. 
12

13 14 15 16 17 18 19 20 21 22 23 24 25 26
[Prerequisites](#Prerequisites)  
[Create a model](#model)  
[UnityBase Server Configuration](#config)  
[Create the Database](#db)  
[create Store](#store)  
[initDB](#initDB)  
[generateDDL](#generateDDL)  
[initialize](#initialize)  
[Short call for all three previously described generation commands](#initcmd)  
[Start a Server](#start_server)  
[Working with AdminUI](#adminui)  
[New Desktop](#desktop)  
[Create a navigation shortcut](#shortcut)  
[Under the Hood](#under_the_hood)  
27

28 29 30 31 32 33

These are a few screens we are going to create:

(!) The UI style of the site (front-end) - has been used predefined UI templates of UnityBase.


34
<a name ='Prerequisites'></a>
35 36 37
## Prerequisites


38
1. Install UnityBase and configure the environment by following  [UnityBase setup instruction](https://git-pub.intecracy.com/unitybase/ubjs)
39 40


41
2. Create the directory `D:\ubProject\CityPortal\`     
42
where the:  
43 44
   `ubProject` is the root folder for all project  
   `CityPortal` is the name of project  
45

46
[+ For working with the console we recommend to install [ConEmu](https://conemu.github.io/ru/) and [Far Manager](http://www.farmanager.com/download.php) +]
47

48
3. Initialize your project with Node Package Manager in a root of the project `D:\ubProject\CityPortal\`.  
49
```>npm init```  
50
This utility will walk you through creating a package.json file.  You may press Enter of all instruction or input your data.
51
It only covers the most common items and tries to guess sensible defaults.  
52

53
4. install a package  `@unitybase/adminui-pub`  and save it as a dependency in the package.json file. This package contains UB models for your project.  
54 55 56 57
```
>npm install --save @unitybase/adminui-pub  
>npm install --save @unitybase/ubq
```
58

59
5. Create the directory `D:\ubProject\CityPortal\models\requests` where  
60 61
   `models` the mandatory folder for creating folder  
   `requests` the folder name where saving all used files  
62

63
6. In root of the project create a folder for storing log files 
64
`logs`
65

66 67

<a name ='model'></a> 
68 69 70
## Create a model


71
UnityBase applications are built on the principle of Model-driven 
72 73
engineering (MDE) - a software development methodology which focuses on creating and exploiting domain models which are conceptual models of all the topics related to a specific problem. 
In most of enterprise systems, the large-scale areas of responsibility are used. 
74
In UnityBase this level of abstraction is called models.   
75

76

77
All models should consist of entities.   
78
Our model will consist of three entities: Departments, SubDepartment, and RequestList.  
79 80
Let's create them.  
[+ (!) Every entity has a mandatory section called Mixin. Don’t forget to add it, you may leave it empty though. +]  
81 82 83 84
Follow this link to get more details about entity schema: 
https://unitybase.info/models/UB/docson/index.html#../schemas/entity.schema.json


85
* The Departmenеs Entity
86 87


88
Create a file `D:\ubProject\CityPortal\models\requests\req_depart.meta`, with the following code:  
89 90 91


```javascript
92 93 94 95 96 97 98 99 100 101 102
{
 "caption": "department", // entity name
 "description": "department",  // entity description
 "descriptionAttribute": "name",
 "attributes": {
   "name": {
     "dataType": "String",
     "size": 255,
     "caption": "Department Name",
     "description": "Department Name",
     "allowNull": false,
103 104
     "isMultiLang": false,
     "isUnique" : true
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
   },
   "postAddr": {
     "dataType": "String",
     "size": 255,
     "caption": "Department Address",
     "description": "Department Address ",
     "allowNull": false,
     "isMultiLang": false
   },
   "phoneNum": {
     "dataType": "String",
     "size": 255,
     "caption": "Department Phone",
     "description": "Department Phone",
     "allowNull": false,
     "isMultiLang": false
   }

},
 "mixins": { // the mandatory section (can be empty)
  "mStorage": {
  }
 }
}
129
```
130 131


132
* The SubDepartment Entity
133

134
Create a file `D:\ubProject\CityPortal\models\requests\req_subDepart.meta`, with the following code:
135

136
```javascript
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
{
 "caption": "subDepartment", // entity name
 "description": "subDepartment",  // entity description
 "descriptionAttribute": "name",
 "attributes": {
   "name": {
     "dataType": "String",
     "size": 255,
     "caption": "Department Name",
     "description": "Department Name",
     "allowNull": false,
     "isMultiLang": false
   },
   "department":{
      "dataType": "Entity",
      "associatedEntity": "req_depart",
      "caption": "department",
      "allowNull": false
       }
 
	},
 "mixins": { // the mandatory section (can be empty)
  "mStorage": {
	      }
 }
}
163 164
```

165 166


167
* The RequestList Entity
168

169
Create a file `D:\ubProject\CityPortal\models\requests\req_reqList.meta` with the following code:
170

171 172

```javascript
173 174 175 176 177
{
 "caption": "request", // entity name
 "description": "request",  // entity description
 "sqlAlias": "req",
 "attributes": {
178
   "reqDate": {
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
     "dataType": "Date",
     "caption": "Request Date",
     "description": "Request Date",
     "allowNull": false
   },
   "applicantPhone": {
     "dataType": "String",  
     "size": 255,
     "caption": "Applicant`s phone",
     "description": "Applicant`s phone",
     "allowNull": false,
     "isMultiLang": false
   },
   "applicantInfo": {
     "dataType": "String",  
     "size": 255,
     "caption": "Applicant`s contact info",
     "description": "Applicant`s contact info",
     "allowNull": false,
     "isMultiLang": false
   },

   "department": { // name of attributes (column name on AdminUI)
     "dataType": "Entity",  
     "associatedEntity": "req_depart", // association with other entity 
     "caption": "Request department", // caption of the object on AdminUI  
     "allowNull": false //it can`t be empty.
   },
   "subDepartment": { // name of attributes (column name on AdminUI)
     "dataType": "Entity",  
     "associatedEntity": "req_subDepart", // association with other entity 
     "caption": "Subdepartment", // caption of the object on AdminUI  
     "allowNull": true //it can`t be empty.
   },
   "reqText": {
     "dataType": "Text",
     "size": 2500,
     "caption": "Text of Request",
     "description": "Text of request",
     "allowNull": false,
     "isMultiLang": false
   } ,
   "reqDoc":{
	"dataType": "Document",
	"caption":"attach",
	"description" :"doc",
	"storename": "attach"
	},
   "answer":
	{
        "dataType": "Text",
        "size": 2500,
        "caption": "Request answer",
        "description": "Request answer",
        "allowNull": true,
        "isMultiLang": false
        } 
             
},
 "mixins": { // the mandatory section (can be empty)
  "mStorage": {  
  }
 }
}
243
```
244 245 246 247




248
<a name ='config'></a>
249
## UnityBase Server Configuration
250 251


252
The configuration file `ubConfig.json`   in root of project ` D:\ubProject\CityPortal` should consist of following mandatory blocks:    
253

254
```
255 256 257 258 259 260
httpServer (Built-in HTTP server configuration)
logging (Logging configuration)
application (Business logic configuration)
connections (Database connections)
blobStores (Database connections definition for application)
uiSettings (Settings, passed to UI in getAppInfo method)
261
```
262

263
Follow this link to get more details: https://unitybase.info/models/UB/docson/index.html#../schemas/ubConfig.schema.json   
264 265 266 267 268 269 270


If values of the following properties:  "serverType", "protocol", "host", "port" are not defined they take defaults values.




271
```javascript
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
{
 "httpServer": { // Built-in HTTP server configuration
   "host": "+", // Host name for server. +' will bound to all domain names for the specified port
   "port": "888" //port to listen on
 },
 "logging": { //Logging configuration
   "levels": [ // Type of events to put to log file. If * all types of errors
     "*"
   ],
   "path": ".\\logs" //Path to folder where server place flog files (including rotated logs)
 },
 "security":{ //List of supported authentication methods
   "authenticationMethods": ["UB"] //can be used as default method
 },
 "application": { //Business logic configuration
   "defaultLang": "en",
   "domain": { //Domain models. Loaded in the order in which they appear in this array
        "models": [ // list of models which should be loaded 

				{
					"name": "UB",
					"path": "./node_modules/@unitybase/ub",
					"moduleName": "@unitybase/ub"
				},
				{
					"name": "UBA",
					"path": "./node_modules/@unitybase/uba",
					"moduleName": "@unitybase/uba"
				},
				{
					"name": "UBS",
					"path": "./node_modules/@unitybase/ubs",
					"moduleName": "@unitybase/ubs"
				},
				{
					"name": "UBM",
					"path": "./node_modules/@unitybase/ubm",
					"moduleName": "@unitybase/ubm"
				},
				{
					"name": "ub-pub",
					"publicPath": "./node_modules/@unitybase/ub-pub",
					"path": "_public_only_",
					"moduleName": "@unitybase/ub-pub"
				},
				{
					"name": "adminui-pub",
					"publicPath": "./node_modules/@unitybase/adminui-pub",
					"path": "_public_only_",
					"moduleName": "@unitybase/adminui-pub"
				},
				{
					"name": "adminui-reg",
					"path": "./node_modules/@unitybase/adminui-reg",
					"moduleName": "@unitybase/adminui-reg"
				},
       {
         "name": "RequestList", //The model which has been created
         "path": "./models/requests" //path to the created our model 
       }
	
     ]
   },
335 336
  
  "connections": [ // Here define the database connections
337 338 339 340 341 342 343
    {
       "name": "main", //Unique connection name
       "isDefault": true, //Is this connection is default for application 
       "driver": "SQLite3", //Database driver used for connection       
       "dialect": "SQLite3",//Database dialect
       "databaseName": "./mainDB.db", // Name of the database
       "supportLang": [ //Array of supported locales
344
         "en"
345 346 347 348 349 350 351 352 353 354 355 356 357 358
       ]
     }
   ], 

   "blobStores": [
     {
       "name": "avatars", // Unique blobStore name. 
       "path": "./avatars", // The path to store root folder
       "storeSize": "Simple", // Approximate number of files to store. Simple = up to    10000
       "isDefault": true //Is this store default for application
     },
     {
       "name": "mdb",
       "storeType": "Virtual"
359 360 361 362 363 364 365
     },
     {
       "name": "attach", // Unique blobStore name. 
       "path": ".\\docs\\attach\\", // The path to store root folder
       "storeSize": "Medium", // Approximate number of files to store. Simple = up to    10000
       "isDefault": false, //Is this store default for application
	"historyDepth":2
366 367 368 369 370 371 372 373 374 375 376 377 378 379
     }

   ]
 },

 "uiSettings": {
   "adminUI": { //Settings for admin UI
     "endpoint": "adm",
     "applicationName": "City Portal", //Name of application for show on the login form
     "applicationTitle": "Requests", //Title of HTML page for adminUI
     "defaultPasswordForDebugOnly": "admin" //For development purpose only
   }
 }
}
380
```
381 382


383
<a name ='db'></a>
384
## Create the Database
385

386
The entity’s data is stored in database tables. So at this stage, you’ll create the database structure. In order to successfully complete this task, you need to execute the following commands. 
387

388 389 390 391

First, you should go to the current project root   
`D:\ubProject\CityPortal`

392
Now you'll generate the Database. The process of requesting the data will automatically trigger the creation.
393

394
<a name ='store'></a>
395 396 397 398 399
## Create Store 

Create folders for storing files in the filesystem:  
`>ubcli createStore`

400
<a name ='initDB'></a>
401 402
## initDB 

403
Create a new database (schema) and a minimal set of DB object for UnityBase:  
404 405
`> ubcli initDB -u admin -p admin -drop -create -host http://localhost:888`

406
<a name ='generateDDL'></a>
407 408 409 410 411 412
## generateDDL

Create a data definition statements for database tables:  
`> ubcli generateDDL -u admin -p admin -host http://localhost:888 -autorun`


413
<a name ='initialize'></a>
414 415 416 417 418 419
## initialize

Initializing DB. Filling up domain entities by its initial values.  
`> ubcli initialize -u admin -p admin -host http://localhost:888`  


420
<a name ='initcmd'></a>
421 422 423 424 425
## Short call for all three previously described generation commands

You can create a short call for all three previously described generation commands. Just create the init.cmd file put into following code  

```
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
call ubcli createStore
if errorlevel 1 goto err

call ubcli initDB -u admin -p admin -drop -create -host http://localhost:888
if errorlevel 1 goto err

call ubcli generateDDL -u admin -p admin -host http://localhost:888 -autorun
if errorlevel 1 goto err

call ubcli initialize -u admin -p admin -host http://localhost:888
if errorlevel 1 goto err

goto eof

:err 
echo Something wrong
exit 1

:eof
445 446
```

447

448
and save it as init.cmd into the project folder  `ubProject\CityPortal`
449 450


451
<a name ='start_server'></a>
452
## Start a Server
453

454
In order to start a server, call the ub.exe from the root of the project  
455
`D:\ubProject\CityPortal> ub.exe`
456 457 458 459



For running UnityBase server in developer mode use the key - dev(with SHIFT + Enter)
460
`D:\ubProject\CityPortal>ub - dev`
461

462
![server_devMode](img/gettingStarted/server_devMode.png)
463

464
<a name ='adminui'></a>
465 466 467
## Working with AdminUI


468 469
Now we can start working with Front-End AdminUI.

470
AdminUI is a Rich Internet application, designed to create a desktop-like user interface. It allows creating intranet Web application with auto generation/declarative description of UI. All UI elements are based on Domain model and often automatically generated. Thus it’s enough to define entity on the server side. 
471

472

473 474 475
Since we’ve previously configured our adminUI endpoint to http://localhost:888/adm , just follow this link. 


476
While the initDB command is executed, the user with admin/admin as a login/password pair is created by default. You can change your password using profile menu in upper right corner of AdminUI. So at the beginning, you log in under admin/admin. 
477

478
Usually, enterprise application has many menu items (shortcuts). We recommend grouping our entities into the desktops. Each desktop has its own stack of commands. We’ll configure the desktop CityPortal and add shortcuts to display the students’ environment and course data so we can use CRUD operations on them.
479

480 481

<a name ='desktop'></a>
482 483 484
## New Desktop

Let’s create a new “CityPortal” desktop for our system.    
485
[+ (!) You must have logged under admin account +]  
486 487
* Go to UI menu and select Desktops menu
* Click on Add (Ctrl+ins)
488 489
* Fill mandatory fields 
* Check By default? checkbox a CityPortal desktop will be the default.
490

491
![cityReq_desktop](img/gettingStarted/cityReq_desktop.png)
492

493
* Click on Save and close (Ctrl + enter)
494 495 496 497 498

	The new desktop should appear on adminUI navigation bar (or press F5).
	
We’ve created a desktop, but there’re still no entities in it. So now we’ll add Departments, SubDepartments and RequestList shortcuts to the “CityPortal” desktop to obtain a result shown below. 

499
![cityReq_menu](img/gettingStarted/cityReq_menu.png)
500

501
<a name ='shortcut'></a>
502
## Create a navigation shortcut
503 504


505 506 507 508 509
Let’s start with the folder for Departments shortcuts.  
Do the following steps:  
* Chose the Shortcuts menu in the left section
* Click on Add (Ctrl+ins)
* Fill up the following fields
510
* “Desktop”: Choose the name of the created desktop in previous steps 
511 512 513 514 515
* “Shortcuts caption”: add the Departments name 
* “Code”: add the req_departments_folder (the same as models name)
* Check Is folder?
* Click on Save and close (Ctrl + enter)

516 517
![department_folder](img/gettingStarted/department_folder.png)

518

519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
## Add shortcut for “Departments” entity. 
 
Do the following steps:  
* Chose the Shortcuts menu in the left section
* Click on Add (Ctrl+ins)
* Fill up the following fields
* “Desktop”: Choose the the name of the created desktop in previous steps 
* “Shortcuts folder”: add the Departments name 
* “Shortcuts caption”: add the Departments name 
* “Code”: add the req_depart (the same as models name)
* “Icon css class name”: fa fa-building-o
* Enter following code into the code place


```javascript
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
{
    "cmdType": "showList",
    "cmdData": {
        "params": [
            {
                "entity": "req_depart",
                "method": "select",
                "fieldList": [
                    "ID",
                    "name",
                    "postAddr",
                    "phoneNum"
                ]
            }
        ]
    }
}

552
```
553

554
![department_shortcut](img/gettingStarted/department_shortcut.png)
555

556 557 558 559
* Click on Save and close (Ctrl + enter)
* Go to CityPortal desktop
* Click on Departments menu item so the Department's form could be opened  
* Click on Add (Ctrl+ins) and, as a result, you’ll get a “Department” edit form shown on the following picture.  
560

561
![department_shortcut](img/gettingStarted/department_creating.png)
562 563


564
* Click on Save and close (Ctrl + enter). The following picture demonstrates what you’ll get as a result. 
565

566 567
![department_list](img/gettingStarted/department_list.png)

568 569 570 571 572 573 574 575


Add SubDepartments and Request List shortcuts in same way.


If you did all the previous steps correctly, you’ll see the shortcuts at CityPortal desktop as pictured above. 


576
<a name ='under_the_hood'></a>
577 578 579 580 581 582 583 584 585 586
## Under the Hood


Previously we have described the entities for CityPortal application. UnityBase platform made the following actions:  
Created the database in the triple form taking all the required indexes and constraints into account. The script for a database creation was generated into main_0.sql file.   
Generated user interface based on entities’ metadata.   
Mixin mStorage has added the methods select, insert, update & delete for basic operation to entities.  
Model UBA connected to the list of models (in the configuration file) has added to our application everything that is necessary for building a security layer:  
authorization and authentication. security section of the configuration file  
```
587 588 589
"security":{ //List of supported authentication methods
   "authenticationMethods": ["UB"] //can be used as default method
 }
590 591 592
 ```
 
Authorization tools integrated within the platform are resistant to most attack types including Men-in-the-middle (MIT) & Replay attack.  
593

594
Automatic change audit:  
595

596 597
![department_audit](img/gettingStarted/department_audit.png)    
![audit_update](img/gettingStarted/audit_update.png)
598 599 600 601 602



The system is monitoring the connections between the objects in accordance with metadata which, as an example, allows to introduce data as Master->Detail

603 604
![dep_req_details](img/gettingStarted/dep_req_details.png)

605

606 607 608 609
Server provides the external applications with API in accordance with metadata. For example, the system’s administrative interface works using the server’s API.   
The application created by us is production ready and can bring its services to tens of thousands of system’s users.    

We’ll analyze a creation of complex UI forms, portal solutions and tools of access control related to data in accordance with user’s roles in our next tutorials.  
610

611
## Summary
612 613 614 615
Congratulations! You have created a simple application that uses the UnityBase Platform using SQLite3 to store data. However, it’s just a small example of what you can do with support from this platform.