@simitgroup/simpleapp-generator 1.0.21 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README copy.md +882 -0
  2. package/README.md +53 -824
  3. package/definations/category.cat.jsonschema.json +11 -13
  4. package/definations/level.lvl.jsonschema.json +48 -0
  5. package/definations/product.prd.jsonschema.json +8 -2
  6. package/dist/framework.js +42 -23
  7. package/dist/framework.js.map +1 -1
  8. package/dist/generate.js +3 -3
  9. package/dist/generate.js.map +1 -1
  10. package/dist/index.js +8 -7
  11. package/dist/index.js.map +1 -1
  12. package/openapitools.json +7 -0
  13. package/package.json +1 -1
  14. package/sampleconfig.json +3 -0
  15. package/src/framework.ts +37 -19
  16. package/src/generate.ts +3 -3
  17. package/src/index.ts +8 -7
  18. package/templates/nest/nest.env.eta +7 -0
  19. package/templates/{nest.main.eta → nest/nest.main.eta} +1 -1
  20. package/templates/nuxt/env.eta +5 -3
  21. package/backend1/.env +0 -5
  22. package/backend1/.eslintrc.js +0 -25
  23. package/backend1/.prettierrc +0 -4
  24. package/backend1/README.md +0 -73
  25. package/backend1/nest-cli.json +0 -8
  26. package/backend1/package.json +0 -75
  27. package/backend1/pnpm-lock.yaml +0 -5459
  28. package/backend1/src/app.controller.js +0 -71
  29. package/backend1/src/app.controller.js.map +0 -1
  30. package/backend1/src/app.controller.spec.js +0 -21
  31. package/backend1/src/app.controller.spec.js.map +0 -1
  32. package/backend1/src/app.controller.spec.ts +0 -22
  33. package/backend1/src/app.controller.ts +0 -12
  34. package/backend1/src/app.module.js +0 -67
  35. package/backend1/src/app.module.js.map +0 -1
  36. package/backend1/src/app.module.ts +0 -10
  37. package/backend1/src/app.service.js +0 -64
  38. package/backend1/src/app.service.js.map +0 -1
  39. package/backend1/src/app.service.ts +0 -8
  40. package/backend1/src/class/SimpleAppController.js +0 -38
  41. package/backend1/src/class/SimpleAppController.js.map +0 -1
  42. package/backend1/src/class/SimpleAppController.ts +0 -69
  43. package/backend1/src/class/SimpleAppService.js +0 -264
  44. package/backend1/src/class/SimpleAppService.js.map +0 -1
  45. package/backend1/src/class/SimpleAppService.ts +0 -213
  46. package/backend1/src/main.js +0 -22
  47. package/backend1/src/main.js.map +0 -1
  48. package/backend1/src/main.ts +0 -20
  49. package/backend1/test/app.e2e-spec.js +0 -45
  50. package/backend1/test/app.e2e-spec.js.map +0 -1
  51. package/backend1/test/app.e2e-spec.ts +0 -24
  52. package/backend1/test/jest-e2e.json +0 -9
  53. package/backend1/tsconfig.build.json +0 -4
  54. package/backend1/tsconfig.json +0 -1
  55. package/frontend1/README.md +0 -63
  56. package/frontend1/app.vue +0 -8
  57. package/frontend1/assets/css/tailwind.css +0 -28
  58. package/frontend1/components/CrudSimple.vue +0 -112
  59. package/frontend1/components/DebugDocumentData.vue +0 -20
  60. package/frontend1/components/EventMonitor.vue +0 -79
  61. package/frontend1/components/Menus.vue +0 -18
  62. package/frontend1/layouts/default.vue +0 -10
  63. package/frontend1/nuxt.config.js +0 -42
  64. package/frontend1/nuxt.config.js.map +0 -1
  65. package/frontend1/nuxt.config.ts +0 -42
  66. package/frontend1/package-lock.json +0 -11877
  67. package/frontend1/package.json +0 -38
  68. package/frontend1/pages/index.vue +0 -3
  69. package/frontend1/plugins/simpleapp.js +0 -73
  70. package/frontend1/plugins/simpleapp.js.map +0 -1
  71. package/frontend1/plugins/simpleapp.ts +0 -73
  72. package/frontend1/pnpm-lock.yaml +0 -8339
  73. package/frontend1/public/favicon.ico +0 -0
  74. package/frontend1/server/api/[...].js +0 -117
  75. package/frontend1/server/api/[...].js.map +0 -1
  76. package/frontend1/server/api/[...].ts +0 -131
  77. package/frontend1/server/tsconfig.json +0 -3
  78. package/frontend1/tailwind.config.js +0 -10
  79. package/frontend1/tailwind.config.js.map +0 -1
  80. package/frontend1/tailwind.config.ts +0 -9
  81. package/frontend1/tsconfig.json +0 -4
  82. package/src/installdependency.ts +0 -4
  83. package/templates/SimpleAppClient.eta +0 -116
  84. package/templates/app.vue.eta +0 -21
  85. package/templates/nest.env.eta +0 -5
  86. /package/templates/{SimpleAppController.eta → nest/SimpleAppController.eta} +0 -0
  87. /package/templates/{SimpleAppService.eta → nest/SimpleAppService.eta} +0 -0
  88. /package/templates/{app.module.eta → nest/app.module.eta} +0 -0
package/README.md CHANGED
@@ -1,829 +1,58 @@
1
- after generate
2
- 1. `./backend/tsconfig.ts` add bolow into compile options
3
- ```typescript
4
- "resolveJsonModule": true,
5
- "esModuleInterop": true,
6
- ```
7
- 2.`./backend/.env` change mongodb setting as below example:
8
- ```bash
9
- MONGODB_URL='mongodb://mongoadmin:secret@localhost:27017/admin?authMechanism=DEFAULT'
10
- ```
11
- 3. download http://localhost:8080/api into `./openapi.yaml`
12
- 4. regenerate code (for frontend can function completely)
13
- 5.
14
-
15
-
16
- 1. install openapi-generator, pnpm, nest, rename openapi for new setup
17
- 2. load backend tsconfig and add more property: **
18
- 3. add prettier formating option for frontend
19
- 4. error messages
20
- 5. fix single and multi select bugs
21
- 6. function of remain menulist
22
- 7. security of string input, block xss
23
-
24
-
25
- errors formating
26
- 18.keep audit trail into db
27
- 10.add backend find options
28
- 10.add frontend find options
29
- 11.retain modifications of controller, service, apiclients
30
- 14.add permission control
31
- 16.access right
32
- 17.setting of tenants
33
-
34
- authentication in nuxt
35
- jwt in backend
36
-
37
-
38
- 9. beautify default tailwind ui
39
- 1. front page
40
- 2. top bar
41
- 3. menu bars
42
- 4. default with of each component is it nicely fit
43
- 5. table layout
44
- 7. error formating
45
- 9. write proper user guide
46
- 13.add workflow functions
47
-
48
-
49
-
50
- hold
51
-
52
- 10.plugin for ajv
53
- long string format for description
54
-
55
- # Todo
56
- x21.control csrf
57
- x8. simpleapp generate currentfolder error **
58
- x1. override app.vue *
59
- x2. create layout
60
- simpleapp (first time only)
61
- /default *
62
- x3. components/ (first time only)
63
- x /MonitorEvent.vue *
64
- x /CrudBasic.vue **
65
- x /Menubar *
66
- 4. create page/docs (everytime)
67
- /index.ts
68
- //create page if docs/documentname not exists ***
69
- //override if docs/documentname/delete-me-for-avoid-override exists *
70
- 5. login/logout sessions
71
- x6. auto create *
72
- x server/api to backend *
73
-
74
-
75
-
76
-
77
-
78
- 1. define foreign key relationship in json schema2
79
- 2. auto index and block deletion
80
- 3. when delete identify foreign connected documents
81
- 4. how to unique key
82
- 5. how to multi-tenancy
83
- 6. login/logout in nuxt
84
- 7. jwt in nestjs
85
- 8. format errors at server side link back client side
86
- 9. how to auto toast
87
- 10.server side custom validation link back client side
88
- 11.permission controls
89
- 12.find records
90
- 13.audit trail
91
- 14.data isolation by org, branch and tenant
92
- 15.statistics, aggregations
93
- 16.auto generate frontend page
94
- 17.
95
-
96
-
97
-
98
-
99
-
100
- # simpleapp-generator
101
- ## this project still in alpha stage!
102
-
103
- SimpleApp is an frontend and backend code generator, the ideal of this project is to allow developer build reliable and scalable application with low code methods.
104
-
105
- It suitable for complex schema +complex calculation such as:
106
- 1. sales invoice: having parent and childs as 1 document, it need to calculate tax, discount, exchange rate
107
- 2. delivery order: need to calculate total quantity, unit of measurement conversion
108
-
109
- Key Ideal:
110
- 1. Every data store as json format, name as `document`
111
- 2. Every document defined by jsonschema, and store in folder `definations`
112
- 3. We store jsonschema as `<uniquedocumentname>.<uniquedocumentshortname>.jsonschema.json`. Example: `purchaseorder.po.jsonschema.json`, `student.std.jsonschema.json`
113
- 4. `JsonSchema` used to generate:
114
- - multiple pattern of data types for database, dto, frontend, backend. The data type match to `jsonschema`
115
- - api controller (openapi)
116
- - simpleapp frontend and backend objects
117
- 5. Generated code will control data validation in both frontend and backend using `ajv`
118
- 6. There is few important keyword need to know:
119
- - `jsondata`: actual data like `{"document_no":"PO001",amount:300}`
120
- - `jsonschema`: it is schema of `jsondata`, we use it to generate CRUD codes
121
- - `frontend`: user interface framework using nuxt (vue+typescript), it doesn't store any data
122
- - `backend`: api server using nest(typescript), it provide openapi, and store data into mongodb
123
- - `doc service`: a typescript class use for process specific document in server. example" `po.service.ts`
124
- - `doc controller`: it is api router for route http traffic to document service. example: `po.controller.ts`
125
- - `doc client`: frontend client, it provide reactive data and data processing mechanism for frontend
126
-
127
- 6. To make our app useful, we perform development at
128
- - backend: modify `api controller` and `backend document service`
129
- - frontend: layout user interface, bind input fields to `doc client` , and modify `doc client` required
130
- 7. We may frequently change `jsonschema`, `doc service`, `doc controller`, `doc client`:
131
- - the previous modified code remain when you regenerate code (with specific rules)
132
- 8. After regenerate codes, some data processing codes in `doc service` will sync into `doc client`, to reduce repeat coding at both end
133
-
134
- ## Benefit
135
- - Use `jsonschema` generate most of the frontend and backend code
136
- - Generated frontend and backend code in typescript+OOP.
137
- - it control as tight as possible the frontend and backend data consistency
138
- - support complex data schema, included parent and childs, nested objects
139
- - enforce frontend and backend use same data type
140
- - data store in mongodb, exactly same with schema, no join no headache
141
- - flexible frontend, you can code react or vue, no problem. `simpleapp generator` only focus data, not ui
142
- - allow developer enforce specific data processing in frontend and backend
143
- - you can regenerate source code multiple time without worry your customization gone (there is a way!)
144
-
145
-
146
- Init Nuxt script
147
- 1. npm i -D @sidebase/nuxt-auth
148
- 2. pnpm i --save next-auth@4.21.1
149
- npm i -D @sidebase/nuxt-session
150
-
151
-
152
-
153
- ## You shall know
154
- This project assume you familiar with below:
155
- 1. typescript (no typescript, not reliable frontend)
156
- 2. mongodb
157
- 3. vue/react kind of ecosystem
158
-
159
- # Special Format:
160
- There is special format value:
161
- 1. `field-autcomplete-code`:field for document code, like `student_code,document_no`
162
- 2. `field-autocomplete-label`: field for document name, like `student_name, product_name`
163
-
164
- # Special properties:
165
- ## object:
166
- * autocomplete-src=category => autocomplete list from server-url/category/autocomplete
167
-
168
- You need to install mongodb and openapi generator:
169
- 1. https://www.mongodb.com/docs/manual/installation/
170
- 2. https://openapi-generator.tech/docs/installation/
171
-
172
- # Quick Start
173
- This quick start create a example project developed by simpleapp-generator
174
- 1. Install `simpleapp-generator`
1
+ # Quick start
2
+ ** You need to have mongodb installed **
3
+ 1. git clone from simpleapp-generator
175
4
  ```sh
176
- npm install -g simpleapp-generator
5
+ npm -i @simitgroup/simpleapp-generator@latest
6
+ git clone https://github.com/SIMITGROUP/simpleapp-generator-template myapp
7
+ # edit myapp/config.json to match you mongodb connection string
8
+ cd ~/myapp
9
+ simpleapp-generator -c config.json
177
10
  ```
178
- 2. mkdir project folder for store frontend and backend codes
179
- ```sh
180
- mkdir ~/myapp
181
- cd myapp
182
- ```
183
- 3. generate sample project
184
- ```sh
185
- simpleapp-generator -e person # -e mean use example schema "person". Currently only 1 example
186
- ```
187
-
188
- 4. run backend apiserver
189
- ```sh
190
- cd backend
191
- pnpm start:dev
192
- ```
193
- 5. browse to `http://localhost:8000/api` for swagger ui, `http://localhost:8000/api-yaml` for openapi documents
194
- 6. You may use vscode to see the example code in `backend/src/docs/pes`:
195
- - pes.controller.ts //document api controller
196
- - pes.service.ts //document service controller
197
- - pes.type.ts, pes.apischema.ts, pes.model.ts //multiple datatype or schema
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
- ```
207
- mkdir definations #we put json schema here
208
-
209
- ```
210
- 3. create configuration file `config.json`
211
- ```sh
212
- echo '{"definationsFolder":"./definations","backendFolder":"./backend", "frontendFolder":"./frontend","openapi3Yaml":""}' > config.json
213
- ```
214
- 4. create below content and save as `~/myapp/definations/person.pes.jsonschema.json`
215
- ```json
216
- {
217
- "type": "object",
218
- "properties": {
219
- "name": {
220
- "type": "object",
221
- "properties": {
222
- "firstName": {
223
- "type": "string",
224
- "examples": [
225
- "John"
226
- ]
227
- },
228
- "lastName": {
229
- "type": "string",
230
- "examples": [
231
- "Fox"
232
- ]
233
- }
234
- }
235
- },
236
- "age": {
237
- "type": "integer",
238
- "examples": [
239
- 20
240
- ]
241
- },
242
- "email": {
243
- "type": "string",
244
- "examples": [
245
- "john@example.com"
246
- ],
247
- "format": "email"
248
- },
249
- "dob": {
250
- "type": "string",
251
- "examples": [
252
- "2000-01-01"
253
- ],
254
- "format": "date"
255
- },
256
- "hobbies": {
257
- "type": "array",
258
- "items": {
259
- "type": "string",
260
- "examples": [
261
- "badminton",
262
- "dota",
263
- "reading"
264
- ]
265
- }
266
- },
267
- "addresses": {
268
- "type": "array",
269
- "items": {
270
- "type": "object",
271
- "required": [
272
- "street1",
273
- "street2",
274
- "postcode"
275
- ],
276
- "properties": {
277
- "street1": {
278
- "type": "string",
279
- "examples": [
280
- "11, Fox Road"
281
- ]
282
- },
283
- "street2": {
284
- "type": "string",
285
- "examples": [
286
- "My Home Town"
287
- ]
288
- },
289
- "postcode": {
290
- "type": "integer",
291
- "examples": [
292
- 12345
293
- ]
294
- }
295
- }
296
- }
297
- }
298
- }
299
- }
300
- ```
301
- 5. generate backend and frontend codes, and define backend/.env `mongodb connection` string:
302
- ```sh
303
- simpleapp-generator -c ./config.json
304
- code backend # use vscode open backend project, edit .env
305
- ```
306
- 6. You can start backend server and try the generated api at `http://localhost:8000/api`
11
+ 2. start backend
307
12
  ```sh
308
13
  cd ~/myapp/backend
309
- pnpm start:dev
310
- ```
311
- 7. Next we need more frontend work, put content of `http://localhost:8000/api-yaml` into `~/myapp/openapi.yaml`, and edit config.json as:
312
- ```json
313
- {
314
- "definationsFolder":"./definations",
315
- "backendFolder":"./backend",
316
- "frontendFolder":"./frontend",
317
- "openapi3Yaml":"./openapi.yaml"
318
- }
319
- ```
320
- 8. regenerate source code, and use vscode open both backend and frontend project:
321
- ```sh
322
- simpleapp-generator -c ./config.json
323
- code ./frontend ;
324
- code ./backend ;
325
- ```
326
-
327
-
328
- # The complete development process:
329
- 1. Prepare documents
330
- a. Prepare sample json data
331
- b. Convert `json` data to `jsonschema`
332
- c. touch up jsonschema, like define require fields, format, minLength and etc
333
- d. place json schema into `definations` folder
334
- 2. Generate source codes
335
- a. generate source code into backend project
336
- b. start backend service, obtain yaml content and save into project folder
337
- c. re-generate source code, it create required codes for frontend
338
- 3. Begin Frontend development:
339
- a. use vscode open frontend project
340
- b. create user interface with several input fields, bind to generated simpleapp object
341
-
342
- ## 1. Prepare documents
343
- 1. [click here](https://www.convertsimple.com/convert-javascript-to-json/) allow you create json data with lesser effort. Lets use this example:
344
- ```json
345
- {
346
- "docNo": "SI001",
347
- "customer": "My Customer Pte Ltd",
348
- "amount": 200,
349
- "products": [
350
- "apple",
351
- "orange"
352
- ],
353
- "details": [
354
- {
355
- "item": "apple",
356
- "qty": 100,
357
- "unitprice": 1,
358
- "subtotal": 100
359
- },
360
- {
361
- "item": "orange",
362
- "qty": 100,
363
- "unitprice": 1,
364
- "subtotal": 100
365
- }
366
- ],
367
- "remarks": "need fast delivery"
368
- }
369
- ```
370
- b. Copy generated json data to [here](https://redocly.com/tools/json-to-json-schema) using below setting, you may define data type/format/required parameters according [jsonschema standard](https://json-schema.org/understanding-json-schema/reference/index.html)
371
- ```
372
- output format: json
373
- add example to schema: true
374
- infer require property for array items: true
375
- disable additionalProperty: true
376
- ```
377
- Here is the result:
378
- ```json
379
- {
380
- "type": "object",
381
- "properties": {
382
- "docNo": {
383
- "type": "string",
384
- "examples": [
385
- "SI001"
386
- ]
387
- },
388
- "customer": {
389
- "type": "string",
390
- "examples": [
391
- "My Customer Pte Ltd"
392
- ]
393
- },
394
- "amount": {
395
- "type": "integer",
396
- "examples": [
397
- 200
398
- ]
399
- },
400
- "products": {
401
- "type": "array",
402
- "items": {
403
- "type": "string",
404
- "examples": [
405
- "apple",
406
- "orange"
407
- ]
408
- }
409
- },
410
- "details": {
411
- "type": "array",
412
- "items": {
413
- "type": "object",
414
- "required": [
415
- "item",
416
- "qty",
417
- "unitprice",
418
- "subtotal"
419
- ],
420
- "properties": {
421
- "item": {
422
- "type": "string",
423
- "examples": [
424
- "apple",
425
- "orange"
426
- ]
427
- },
428
- "qty": {
429
- "type": "integer",
430
- "examples": [
431
- 100,
432
- 100
433
- ]
434
- },
435
- "unitprice": {
436
- "type": "integer",
437
- "examples": [
438
- 1,
439
- 1
440
- ]
441
- },
442
- "subtotal": {
443
- "type": "integer",
444
- "examples": [
445
- 100,
446
- 100
447
- ]
448
- }
449
- }
450
- }
451
- },
452
- "remarks": {
453
- "type": "string",
454
- "examples": [
455
- "need fast delivery"
456
- ]
457
- }
458
- }
459
- }
460
- ```
461
- c. save the json data into `definations` folder
462
-
463
-
464
-
465
-
466
-
467
- ## Backend NestJS project preparation
468
- 1. install backend nest application: `npm i -g pnpm @nestjs/cli` (cli tools for pnpm and nestjs)
469
- 2. create a folder `~/myapp`
470
- 3. cd `~/myapp`
471
- 4. create blank nest project `nest new backend`, pick `pnpm`
472
- 5. enter backend folder: `cd backend`
473
- 6. install dependency: `pnpm install --save @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config` (ignore ✕ missing peer webpack)
474
- 7. create .env file with following settings:
475
- ```sh
476
- MONGODB_URL='mongodb://<user>:<pass>@<host>:<port>/<db>?authMechanism=DEFAULT'
477
- HTTP_PORT=8000
478
- PROJECT_NAME='SimpleApp Demo1'
479
- PROJECT_DESCRIPTION='Try CRUD'
480
- PROJECT_Version='1.0.0'
481
- ```
482
- 7. change `src/main.ts`, allow openapi document:
483
- ```ts
484
- import { NestFactory } from '@nestjs/core';
485
- import { AppModule } from './app.module';
486
- import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
487
-
488
- async function bootstrap() {
489
- const app = await NestFactory.create(AppModule);
490
- app.enableCors();
491
- const config = new DocumentBuilder()
492
- .setTitle(process.env.PROJECT_NAME)
493
- .setDescription(process.env.PROJECT_DESCRIPTION)
494
- .setVersion(process.env.PROJECT_VERSION)
495
- .build();
496
- const document = SwaggerModule.createDocument(app, config);
497
- SwaggerModule.setup('api', app, document, {
498
- swaggerOptions: { showExtensions: true },
499
- });
500
-
501
- await app.listen(process.env.HTTP_PORT); //listen which port
502
- }
503
- bootstrap();
504
- ```
505
- 9. start backend server `pnpm start:dev`, monitor [http://localhost:3000/api](http://localhost:3000/api)
506
-
507
-
508
- ## Frontend NuxtJS project preparation (or, any others framework if you have know how)
509
- 1. `cd ~/myapp`
510
- 2. create new frontend nuxt project `npx nuxi@latest init frontend`
511
- 3. `cd frontend`
512
- 4. install required package: `pnpm install ajv ajv-formats axios json-schema`
513
- 5. create .env file with below content
514
- ```sh
515
- SIMPLEAPP_BACKEND_URL=http://localhost:8000
516
- PORT=8800
517
- ```
518
- 6. run frontend: `pnpm dev -o`
519
-
520
-
521
- ## setup Mongodb
522
- 1. you can use mongodb, either docker or install binary
523
- https://www.mongodb.com/docs/manual/installation/
524
- ** remember create database, and define suitable credentials (user/password)
525
-
526
- ## Setup openapi-generator
527
- Refer below:
528
- https://openapi-generator.tech/docs/installation/
529
-
530
- I'm using mac, so i use `brew install openapi-generator`
531
-
532
-
533
- # Job Begin!
534
- 3 steps:
535
- 1. Prepare json schema
536
- 2. use json schema generate frontend and backend codes
537
- 3. persom simple development
538
-
539
- ## 1. Prepare sample data schema
540
- 1. lets assume we have a sample data:
541
- ```json
542
- {
543
- "name":{"firstName":"John","lastName":"Fox"},
544
- "age":20,
545
- "email":"john@example.com",
546
- "dob":"2000-01-01",
547
- "hobbies":["badminton","dota","reading"],
548
- "addresses": [{"street1":"11, Fox Road","street2":"My Home Town","postcode":12345}]
549
- }
550
- ```
551
- 2. Generate it become `jsonschema` [here](https://redocly.com/tools/json-to-json-schema), format as json. Follow below settings:
552
- ```
553
- add example to schema: true
554
- infer require property for array items: true
555
- disable additionalProperty: true
556
- ```
557
-
558
- Below is the sample of jsonschema:
559
- ```json
560
- {
561
- "type": "object",
562
- "properties": {
563
- "name": {
564
- "type": "object",
565
- "properties": {
566
- "firstName": {
567
- "type": "string",
568
- "examples": [
569
- "John"
570
- ]
571
- },
572
- "lastName": {
573
- "type": "string",
574
- "examples": [
575
- "Fox"
576
- ]
577
- }
578
- }
579
- },
580
- "age": {
581
- "type": "integer",
582
- "examples": [
583
- 20
584
- ]
585
- },
586
- "email": {
587
- "type": "string",
588
- "examples": [
589
- "john@example.com"
590
- ],
591
- "format": "email"
592
- },
593
- "dob": {
594
- "type": "string",
595
- "examples": [
596
- "2000-01-01"
597
- ],
598
- "format": "date"
599
- },
600
- "hobbies": {
601
- "type": "array",
602
- "items": {
603
- "type": "string",
604
- "examples": [
605
- "badminton",
606
- "dota",
607
- "reading"
608
- ]
609
- }
610
- },
611
- "addresses": {
612
- "type": "array",
613
- "items": {
614
- "type": "object",
615
- "required": [
616
- "street1",
617
- "street2",
618
- "postcode"
619
- ],
620
- "properties": {
621
- "street1": {
622
- "type": "string",
623
- "examples": [
624
- "11, Fox Road"
625
- ]
626
- },
627
- "street2": {
628
- "type": "string",
629
- "examples": [
630
- "My Home Town"
631
- ]
632
- },
633
- "postcode": {
634
- "type": "integer",
635
- "examples": [
636
- 12345
637
- ]
638
- }
639
- }
640
- }
641
- }
642
- }
643
- }
644
- ```
645
-
646
- ## Generate Code
647
- 1. install simpleapp-generetor `npm install -g simpleapp-generator`
648
- 2. create a folder `~/myapp/definations`
649
- 3. copy above jsonschema example as `~/myapp/definations/person.ps.jsonschema.json`.
650
- * `person`: unique document name (small letter alphabet `[a-z]`)
651
- * `ps`: unique document type (small letter `[a-z]`)
652
- * `jsonschema.json`: all files ending with this extension will process
653
- 4. create `~/myapp/config.json` with below content
654
- ```json
655
- {
656
- "definationsFolder":"./definations",
657
- "backendFolder":"../backend",
658
- "frontendFolder":"../frontend",
659
- "openapi3Yaml":"openapi.yaml"
660
- }
661
- ```
662
- 5. run `simpleapp-generator -c ./config.json`
663
- 6. restart nestjs, the microservice is ready and you can test at `http://localhost:8000/api`. All generated api accessible via swagger-ui.
664
- 7. Frontend need further work. Browse `http://localhost:8000/api-yaml`, save content as `openapi.yaml`
665
- 8. Rerun `simpleapp-generator -c ./config.json`, it will help us to generate axios executable using openapi.yaml
666
- 9. use vscode open both `~/myapp/frontend` and `~/myapp/backend`
667
-
668
-
669
-
670
- ## perform simple development
671
- 1. in `frontend` project, edit `app.vue`, put in below code:
672
- ```vue
673
- <template>
674
- <div>
675
- <div>
676
- <label>Firstname</label>
677
- <input v-model="reactivedata.name.firstName">
678
- </div>
679
- {{ reactivedata }}
680
- <button @click="person.create().then((res)=>console.log(res.data))">try</button>
681
- </div>
682
- </template>
683
- <script setup lang="ts">
684
- import {PersonDoc} from './server/docs/PersonDoc'
685
- const person = new PersonDoc()
686
-
687
- // person.update().then((res)=>console.log("dosomething"))
688
- // person.delete('record-id').then((res)=>console.log("dosomething"))
689
- // person.getById('record-id').then((res)=>console.log("dosomething"))
690
- // person.list().then((res)=>console.log(res))
691
- const noreactivedata = person.getData() //give not reactive data, it cant apply 2 way data binding
692
- const reactivedata = person.getReactiveData() //give vue reactive data, it can apply 2 way data binding using v-model
693
- </script>
694
- ```
695
-
696
- We notice:
697
- 1. `PersonDoc` auto generated, it come with plenty of build in crud features which you can use without knowing API:
698
- ```typescript
699
- person.create().then((res)=>console.log("dosomething"))
700
- person.update().then((res)=>console.log("dosomething"))
701
- person.delete('record-id').then((res)=>console.log("dosomething"))
702
- person.getById('record-id').then((res)=>console.log("dosomething"))
703
- person.list().then((res)=>console.log(res))
704
- ```
705
- 2. `person.getData()` gave reactive object, we can bind all properties directly to `vue` component using `v-model`
706
- 3. you may try add more input bind to `reactivedata.name.lastName`,`reactivedata.email`, `reactivedata.age` and monitor result
707
- 4. `button` can directly trigger `save` method from person.getData()
708
- 5. You wont able to save the record because it not pass validation rules, check browser console it tell you what is happening
709
- 6. There is UI component `simpleapp-uicomponent` which can integrate nicely with with `PersonDoc`. Refer the link [here](...)
710
-
711
- # We can do more With SimpleApp
712
- ## no time for full documentation yet
713
- 1. Monitor variable change at frontend
714
- step 1: add new methods for frontend's class `PesonDoc.ts`
715
- ```
716
- watchChanges = ()=>{
717
- watch(this.getReactiveData(),(newdata)=>{
718
- this.getReactiveData().age=calculateAge(newdata.dob)
719
- //apply others changes here
720
- })
721
- }
722
- ```
723
- step 2: edit `app.vue` to on the watcher
724
- ```typescript
725
- //others codes
726
- const person = new PersonDoc()
727
- person.watchChanges() //<-- add this line to on watcher at frontend
728
- //others codes
729
- ```
730
-
731
- 2. create more api to `person`, such as `post /person/:id/sendEmail {title:"title",body:"body"}`
732
- step 1: edit backend `<backend>/src/docs/pes/pes.controller.ts`, add new source code between `<begin-controller-code>` and `<end-controller-code>`:
733
- ```typescript
734
- //<begin-controller-code>
735
- //new api, wont override when regenerate code
736
- @Get('/try/:id')
737
- @ApiResponse({
738
- status: 200,
739
- description: 'success',
740
- type: pesapischema.Person,
741
- })
742
- @ApiResponse({ status: 404, description: 'Document not found' })
743
- @ApiResponse({ status: 500, description: 'Internal error' })
744
- @ApiOperation({ operationId: 'newFindOne' }) //important, frontend access it via person.newFindOne()
745
- async newFindOne(@Param('id') id: string) {
746
- return this._findOne(id);
747
- }
748
- //<end-controller-code>
749
- ```
750
- step 2: try browse to `http://localhost:8000/api` to check new api appear or not.
751
- step 3: You shall regenerate the code
752
- ```bash
753
- simpleapp-generator -c ./config.json
754
- ```
755
- step 4: go frontend project, edit `app.vue` you may try type `person.newFindOne()` see new method exists?
756
-
757
- step 3: Regenerate code for frontend
758
-
759
- 4. create backend only execution for `person`. It is useful cause some work only
760
- step 1: Edit backend `backend/src/docs/pes/pes.service.ts`, add new source code between `<begin-backend-code>` and `<end-backend-code>`:
761
- ```typescript
762
- //<begin-backend-code>
763
- //new method, wont override when regenerate code
764
- logSomething = () => {
765
- console.log('Access try api');
766
- };
767
- //<end-backend-code>
768
- ```
769
- step 2: modify `<backend>/src/docs/pes/pes.controller.ts`, call the new method
770
- ```typescript
771
- async newFindOne(@Param('id') id: string) {
772
- this.service.logSomething(); //this.service is our service class
773
- return this._findOne(id);
774
- }
775
- ```
776
-
777
-
778
- 5. create frontend only code for `person`, such as:
779
- `person.addHobbies('hobby1')`,`person.addAddress({})`,`person.delAddress(index:number)` edit `newFindOne`:
780
- ```
14
+ pnpm start:dev
781
15
  ```
782
- 6. create bothend code for `person`
783
-
784
-
785
-
786
- foreign key
787
- cat
788
- category_id
789
- category_code
790
- category_name
791
-
792
- product
793
- product_id
794
- product_code
795
- product_name
796
- category => category_id: category_code
797
-
798
-
799
-
800
- invoice
801
- invoice_id
802
- invoice_no
803
- invoice_date
804
- total
805
- details =>
806
- product => product_id: product_code
807
- qty
808
- price
809
- subtotal
810
-
811
- order
812
- order_id
813
- order_no
814
- order_date
815
- total
816
- details =>
817
- product => product_id: product_code
818
- qty
819
- price
820
- subtotal
821
-
822
-
823
- cat => foreignkey: []
824
- prd => foreignkey: category => category
825
- invoice => foreignkey: detail.product=>product
826
- order => foreignkey: detail.product=>product
827
-
828
- cat =[product.category]
829
- product=[invoice.detail.product, order.detail.product]
16
+ 3. start frontend
17
+ ```sh
18
+ cd ~/myapp/frontend
19
+ pnpm dev
20
+ ```
21
+ 4. try ui:
22
+ * frontend: [http://localhost:8080](http://localhost:8080)
23
+ * backend: [http://localhost:8000/api](http://localhost:8000/api)
24
+ 5. Open project with vscode, explore json schema and the generated forms
25
+ ```sh
26
+ code ~/mydoc
27
+ ```
28
+ explore codes in:
29
+ * myapp/backend/src/class/docs/*, especially `controller,service,apischema`
30
+ * myapp/backend/.env
31
+ * myapp/backend/dicts/foreignkeys.json
32
+ * myapp/frontend/pages/*
33
+ * myapp/frontend/simpleapps/docs
34
+ * myapp/frontend/.env
35
+
36
+ # Concept of Development
37
+ Development using simpleapp-generator involve below steps:
38
+ ## Simple
39
+ 1. create appropriate jsonschema
40
+ 2. generate frontend and backend architectures
41
+ 3. start backend service, obtain and save api definations into openapi.yaml
42
+ 4. regenerate codes so frontend can obtain openapi clients
43
+ 5. align frontend UI, add necessary component such as css and ui components
44
+
45
+ ## Advance
46
+ 1. complete simple task
47
+ 2. add more api/process at backend `controller`,`service`,`schema`. Such as:
48
+ a. customized search and filters
49
+ b. customized workflows
50
+ c. connect external api
51
+ d. additional data processing and validation which is not supported by jsonschema (AJV)
52
+ 3. security like sso/jwt, plugins
53
+ a. keycloak integration at frontends
54
+ b. backend manage jwt
55
+ 4. allow additional field formats, validations by modifying ajv
56
+ a. allow custom jsonschema field property, and do something at backend
57
+ b. allow custom field format, and do something at backend
58
+ 5. repeat same typscript formula at frontend and backend