@simitgroup/simpleapp-generator 1.0.1

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 (55) hide show
  1. package/.prettierrc +6 -0
  2. package/LICENSE +201 -0
  3. package/README.md +668 -0
  4. package/definations/person.pes.jsonschema.json +84 -0
  5. package/definations/salesinvoice.si.jsonschema.json +84 -0
  6. package/dist/app.module.ts +14 -0
  7. package/dist/constant.js +6 -0
  8. package/dist/constant.js.map +1 -0
  9. package/dist/createproject.js +123 -0
  10. package/dist/createproject.js.map +1 -0
  11. package/dist/generate.js +225 -0
  12. package/dist/generate.js.map +1 -0
  13. package/dist/index.js +65 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/libs.js +15 -0
  16. package/dist/libs.js.map +1 -0
  17. package/dist/processors/jsonschemabuilder.js +116 -0
  18. package/dist/processors/jsonschemabuilder.js.map +1 -0
  19. package/dist/type.js +13 -0
  20. package/dist/type.js.map +1 -0
  21. package/package.json +44 -0
  22. package/sampleconfig.json +6 -0
  23. package/src/constant.ts +2 -0
  24. package/src/createproject.ts +96 -0
  25. package/src/generate.ts +254 -0
  26. package/src/index.ts +73 -0
  27. package/src/libs.ts +14 -0
  28. package/src/processors/jsonschemabuilder.ts +137 -0
  29. package/src/type.ts +42 -0
  30. package/templates/SimpleAppClient.eta +111 -0
  31. package/templates/SimpleAppController.eta +66 -0
  32. package/templates/SimpleAppService.eta +134 -0
  33. package/templates/app.module.eta +15 -0
  34. package/templates/app.vue.eta +21 -0
  35. package/templates/basic/apiclient.eta +56 -0
  36. package/templates/basic/apischema.eta +29 -0
  37. package/templates/basic/backend.config.eta +1 -0
  38. package/templates/basic/beforesave.eta +7 -0
  39. package/templates/basic/controller.eta +103 -0
  40. package/templates/basic/controller2.eta +86 -0
  41. package/templates/basic/frontend.config.eta +1 -0
  42. package/templates/basic/jsonschema.eta +6 -0
  43. package/templates/basic/model-converter.etabackup +21 -0
  44. package/templates/basic/model.eta +35 -0
  45. package/templates/basic/module.eta +20 -0
  46. package/templates/basic/readme.eta +3 -0
  47. package/templates/basic/service.eta +32 -0
  48. package/templates/basic/service.etabackupe +106 -0
  49. package/templates/basic/type.eta +27 -0
  50. package/templates/basic/type.etabackup +23 -0
  51. package/templates/basic/uischema.eta +13 -0
  52. package/templates/nest.env.eta +5 -0
  53. package/templates/nest.main.eta +20 -0
  54. package/templates/nuxt.env.eta +2 -0
  55. package/tsconfig.json +17 -0
package/README.md ADDED
@@ -0,0 +1,668 @@
1
+ # simpleapp-generator
2
+ ## this project still in alpha stage!
3
+
4
+ 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.
5
+
6
+ It suitable for complex schema +complex calculation such as:
7
+ 1. sales invoice: having parent and childs as 1 document, it need to calculate tax, discount, exchange rate
8
+ 2. delivery order: need to calculate total quantity, unit of measurement conversion
9
+
10
+ Key Ideal:
11
+ 1. Every data store as json format, name as `document`
12
+ 2. Every document defined by jsonschema, and store in folder `definations`
13
+ 3. We store jsonschema as `<uniquedocumentname>.<uniquedocumentshortname>.jsonschema.json`. Example: `purchaseorder.po.jsonschema.json`, `student.std.jsonschema.json`
14
+ 4. `JsonSchema` used to generate:
15
+ - multiple pattern of data types for database, dto, frontend, backend. The data type match to `jsonschema`
16
+ - api controller (openapi)
17
+ - simpleapp frontend and backend objects
18
+ 5. Generated code will control data validation in both frontend and backend using `ajv`
19
+ 6. There is few important keyword need to know:
20
+ - `jsondata`: actual data like `{"document_no":"PO001",amount:300}`
21
+ - `jsonschema`: it is schema of `jsondata`, we use it to generate CRUD codes
22
+ - `frontend`: user interface framework using nuxt (vue+typescript), it doesn't store any data
23
+ - `backend`: api server using nest(typescript), it provide openapi, and store data into mongodb
24
+ - `doc service`: a typescript class use for process specific document in server. example" `po.service.ts`
25
+ - `doc controller`: it is api router for route http traffic to document service. example: `po.controller.ts`
26
+ - `doc client`: frontend client, it provide reactive data and data processing mechanism for frontend
27
+
28
+ 6. To make our app useful, we perform development at
29
+ - backend: modify `api controller` and `backend document service`
30
+ - frontend: layout user interface, bind input fields to `doc client` , and modify `doc client` required
31
+ 7. We may frequently change `jsonschema`, `doc service`, `doc controller`, `doc client`:
32
+ - the previous modified code remain when you regenerate code (with specific rules)
33
+ 8. After regenerate codes, some data processing codes in `doc service` will sync into `doc client`, to reduce repeat coding at both end
34
+
35
+ ## Benefit
36
+ - Use `jsonschema` generate most of the frontend and backend code
37
+ - Generated frontend and backend code in typescript+OOP.
38
+ - it control as tight as possible the frontend and backend data consistency
39
+ - support complex data schema, included parent and childs, nested objects
40
+ - enforce frontend and backend use same data type
41
+ - data store in mongodb, exactly same with schema, no join no headache
42
+ - flexible frontend, you can code react or vue, no problem. `simpleapp generator` only focus data, not ui
43
+ - allow developer enforce specific data processing in frontend and backend
44
+ - you can regenerate source code multiple time without worry your customization gone (there is a way!)
45
+
46
+
47
+ ## You shall know
48
+ This project assume you familiar with below:
49
+ 1. typescript (no typescript, not reliable frontend)
50
+ 2. mongodb
51
+ 3. vue/react kind of ecosystem
52
+
53
+
54
+ You need to install mongodb and openapi generator:
55
+ 1. https://www.mongodb.com/docs/manual/installation/
56
+ 2. https://openapi-generator.tech/docs/installation/
57
+
58
+ # Quick Start
59
+ This quick start create a example project developed by simpleapp-generator
60
+ 1. Install `simpleapp-generator`
61
+ ```sh
62
+ npm install -g simpleapp-generator
63
+ ```
64
+ 2. mkdir project folder for store frontend and backend codes
65
+ ```sh
66
+ mkdir ~/myapp
67
+ cd myapp
68
+ ```
69
+ 3. generate sample project
70
+ ```sh
71
+ simpleapp-generator -e person # -e mean use example schema "person". Currently only 1 example
72
+ ```
73
+
74
+ 4. run backend apiserver
75
+ ```sh
76
+ cd backend
77
+ pnpm start:dev
78
+ ```
79
+ 5. browse to `http://localhost:8000/api` for swagger ui, `http://localhost:8000/api-yaml` for openapi documents
80
+ 6. You may use vscode to see the example code in `backend/src/docs/pes`:
81
+ - pes.controller.ts //document api controller
82
+ - pes.service.ts //document service controller
83
+ - pes.type.ts, pes.apischema.ts, pes.model.ts //multiple datatype or schema
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+ ```
93
+ mkdir definations #we put json schema here
94
+
95
+ ```
96
+ 3. create configuration file `config.json`
97
+ ```sh
98
+ echo '{"definationsFolder":"./definations","backendFolder":"./backend", "frontendFolder":"./frontend","openapi3Yaml":""}' > config.json
99
+ ```
100
+ 4. create below content and save as `~/myapp/definations/person.pes.jsonschema.json`
101
+ ```json
102
+ {
103
+ "type": "object",
104
+ "properties": {
105
+ "name": {
106
+ "type": "object",
107
+ "properties": {
108
+ "firstName": {
109
+ "type": "string",
110
+ "examples": [
111
+ "John"
112
+ ]
113
+ },
114
+ "lastName": {
115
+ "type": "string",
116
+ "examples": [
117
+ "Fox"
118
+ ]
119
+ }
120
+ }
121
+ },
122
+ "age": {
123
+ "type": "integer",
124
+ "examples": [
125
+ 20
126
+ ]
127
+ },
128
+ "email": {
129
+ "type": "string",
130
+ "examples": [
131
+ "john@example.com"
132
+ ],
133
+ "format": "email"
134
+ },
135
+ "dob": {
136
+ "type": "string",
137
+ "examples": [
138
+ "2000-01-01"
139
+ ],
140
+ "format": "date"
141
+ },
142
+ "hobbies": {
143
+ "type": "array",
144
+ "items": {
145
+ "type": "string",
146
+ "examples": [
147
+ "badminton",
148
+ "dota",
149
+ "reading"
150
+ ]
151
+ }
152
+ },
153
+ "addresses": {
154
+ "type": "array",
155
+ "items": {
156
+ "type": "object",
157
+ "required": [
158
+ "street1",
159
+ "street2",
160
+ "postcode"
161
+ ],
162
+ "properties": {
163
+ "street1": {
164
+ "type": "string",
165
+ "examples": [
166
+ "11, Fox Road"
167
+ ]
168
+ },
169
+ "street2": {
170
+ "type": "string",
171
+ "examples": [
172
+ "My Home Town"
173
+ ]
174
+ },
175
+ "postcode": {
176
+ "type": "integer",
177
+ "examples": [
178
+ 12345
179
+ ]
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ ```
187
+ 5. generate backend and frontend codes, and define backend/.env `mongodb connection` string:
188
+ ```sh
189
+ simpleapp-generator -c ./config.json
190
+ code backend # use vscode open backend project, edit .env
191
+ ```
192
+ 6. You can start backend server and try the generated api at `http://localhost:8000/api`
193
+ ```sh
194
+ cd ~/myapp/backend
195
+ pnpm start:dev
196
+ ```
197
+ 7. Next we need more frontend work, put content of `http://localhost:8000/api-yaml` into `~/myapp/openapi.yaml`, and edit config.json as:
198
+ ```json
199
+ {
200
+ "definationsFolder":"./definations",
201
+ "backendFolder":"./backend",
202
+ "frontendFolder":"./frontend",
203
+ "openapi3Yaml":"./openapi.yaml"
204
+ }
205
+ ```
206
+ 8. regenerate source code, and use vscode open both backend and frontend project:
207
+ ```sh
208
+ simpleapp-generator -c ./config.json
209
+ code ./frontend ;
210
+ code ./backend ;
211
+ ```
212
+
213
+
214
+ # The complete development process:
215
+ 1. Prepare documents
216
+ a. Prepare sample json data
217
+ b. Convert `json` data to `jsonschema`
218
+ c. touch up jsonschema, like define require fields, format, minLength and etc
219
+ d. place json schema into `definations` folder
220
+ 2. Generate source codes
221
+ a. generate source code into backend project
222
+ b. start backend service, obtain yaml content and save into project folder
223
+ c. re-generate source code, it create required codes for frontend
224
+ 3. Begin Frontend development:
225
+ a. use vscode open frontend project
226
+ b. create user interface with several input fields, bind to generated simpleapp object
227
+
228
+ ## 1. Prepare documents
229
+ 1. [click here](https://www.convertsimple.com/convert-javascript-to-json/) allow you create json data with lesser effort. Lets use this example:
230
+ ```json
231
+ {
232
+ "docNo": "SI001",
233
+ "customer": "My Customer Pte Ltd",
234
+ "amount": 200,
235
+ "products": [
236
+ "apple",
237
+ "orange"
238
+ ],
239
+ "details": [
240
+ {
241
+ "item": "apple",
242
+ "qty": 100,
243
+ "unitprice": 1,
244
+ "subtotal": 100
245
+ },
246
+ {
247
+ "item": "orange",
248
+ "qty": 100,
249
+ "unitprice": 1,
250
+ "subtotal": 100
251
+ }
252
+ ],
253
+ "remarks": "need fast delivery"
254
+ }
255
+ ```
256
+ 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)
257
+ ```
258
+ output format: json
259
+ add example to schema: true
260
+ infer require property for array items: true
261
+ disable additionalProperty: true
262
+ ```
263
+ Here is the result:
264
+ ```json
265
+ {
266
+ "type": "object",
267
+ "properties": {
268
+ "docNo": {
269
+ "type": "string",
270
+ "examples": [
271
+ "SI001"
272
+ ]
273
+ },
274
+ "customer": {
275
+ "type": "string",
276
+ "examples": [
277
+ "My Customer Pte Ltd"
278
+ ]
279
+ },
280
+ "amount": {
281
+ "type": "integer",
282
+ "examples": [
283
+ 200
284
+ ]
285
+ },
286
+ "products": {
287
+ "type": "array",
288
+ "items": {
289
+ "type": "string",
290
+ "examples": [
291
+ "apple",
292
+ "orange"
293
+ ]
294
+ }
295
+ },
296
+ "details": {
297
+ "type": "array",
298
+ "items": {
299
+ "type": "object",
300
+ "required": [
301
+ "item",
302
+ "qty",
303
+ "unitprice",
304
+ "subtotal"
305
+ ],
306
+ "properties": {
307
+ "item": {
308
+ "type": "string",
309
+ "examples": [
310
+ "apple",
311
+ "orange"
312
+ ]
313
+ },
314
+ "qty": {
315
+ "type": "integer",
316
+ "examples": [
317
+ 100,
318
+ 100
319
+ ]
320
+ },
321
+ "unitprice": {
322
+ "type": "integer",
323
+ "examples": [
324
+ 1,
325
+ 1
326
+ ]
327
+ },
328
+ "subtotal": {
329
+ "type": "integer",
330
+ "examples": [
331
+ 100,
332
+ 100
333
+ ]
334
+ }
335
+ }
336
+ }
337
+ },
338
+ "remarks": {
339
+ "type": "string",
340
+ "examples": [
341
+ "need fast delivery"
342
+ ]
343
+ }
344
+ }
345
+ }
346
+ ```
347
+ c. save the json data into `definations` folder
348
+
349
+
350
+
351
+
352
+
353
+ ## Backend NestJS project preparation
354
+ 1. install backend nest application: `npm i -g pnpm @nestjs/cli` (cli tools for pnpm and nestjs)
355
+ 2. create a folder `~/myapp`
356
+ 3. cd `~/myapp`
357
+ 4. create blank nest project `nest new backend`, pick `pnpm`
358
+ 5. enter backend folder: `cd backend`
359
+ 6. install dependency: `pnpm install --save @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config` (ignore ✕ missing peer webpack)
360
+ 7. create .env file with following settings:
361
+ ```sh
362
+ MONGODB_URL='mongodb://<user>:<pass>@<host>:<port>/<db>?authMechanism=DEFAULT'
363
+ HTTP_PORT=8000
364
+ PROJECT_NAME='SimpleApp Demo1'
365
+ PROJECT_DESCRIPTION='Try CRUD'
366
+ PROJECT_Version='1.0.0'
367
+ ```
368
+ 7. change `src/main.ts`, allow openapi document:
369
+ ```ts
370
+ import { NestFactory } from '@nestjs/core';
371
+ import { AppModule } from './app.module';
372
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
373
+
374
+ async function bootstrap() {
375
+ const app = await NestFactory.create(AppModule);
376
+ app.enableCors();
377
+ const config = new DocumentBuilder()
378
+ .setTitle(process.env.PROJECT_NAME)
379
+ .setDescription(process.env.PROJECT_DESCRIPTION)
380
+ .setVersion(process.env.PROJECT_VERSION)
381
+ .build();
382
+ const document = SwaggerModule.createDocument(app, config);
383
+ SwaggerModule.setup('api', app, document, {
384
+ swaggerOptions: { showExtensions: true },
385
+ });
386
+
387
+ await app.listen(process.env.HTTP_PORT); //listen which port
388
+ }
389
+ bootstrap();
390
+ ```
391
+ 9. start backend server `pnpm start:dev`, monitor [http://localhost:3000/api](http://localhost:3000/api)
392
+
393
+
394
+ ## Frontend NuxtJS project preparation (or, any others framework if you have know how)
395
+ 1. `cd ~/myapp`
396
+ 2. create new frontend nuxt project `npx nuxi@latest init frontend`
397
+ 3. `cd frontend`
398
+ 4. install required package: `pnpm install ajv ajv-formats axios json-schema`
399
+ 5. create .env file with below content
400
+ ```sh
401
+ SIMPLEAPP_BACKEND_URL=http://localhost:8000
402
+ PORT=8800
403
+ ```
404
+ 6. run frontend: `pnpm dev -o`
405
+
406
+
407
+ ## setup Mongodb
408
+ 1. you can use mongodb, either docker or install binary
409
+ https://www.mongodb.com/docs/manual/installation/
410
+ ** remember create database, and define suitable credentials (user/password)
411
+
412
+ ## Setup openapi-generator
413
+ Refer below:
414
+ https://openapi-generator.tech/docs/installation/
415
+
416
+ I'm using mac, so i use `brew install openapi-generator`
417
+
418
+
419
+ # Job Begin!
420
+ 3 steps:
421
+ 1. Prepare json schema
422
+ 2. use json schema generate frontend and backend codes
423
+ 3. persom simple development
424
+
425
+ ## 1. Prepare sample data schema
426
+ 1. lets assume we have a sample data:
427
+ ```json
428
+ {
429
+ "name":{"firstName":"John","lastName":"Fox"},
430
+ "age":20,
431
+ "email":"john@example.com",
432
+ "dob":"2000-01-01",
433
+ "hobbies":["badminton","dota","reading"],
434
+ "addresses": [{"street1":"11, Fox Road","street2":"My Home Town","postcode":12345}]
435
+ }
436
+ ```
437
+ 2. Generate it become `jsonschema` [here](https://redocly.com/tools/json-to-json-schema), format as json. Follow below settings:
438
+ ```
439
+ add example to schema: true
440
+ infer require property for array items: true
441
+ disable additionalProperty: true
442
+ ```
443
+
444
+ Below is the sample of jsonschema:
445
+ ```json
446
+ {
447
+ "type": "object",
448
+ "properties": {
449
+ "name": {
450
+ "type": "object",
451
+ "properties": {
452
+ "firstName": {
453
+ "type": "string",
454
+ "examples": [
455
+ "John"
456
+ ]
457
+ },
458
+ "lastName": {
459
+ "type": "string",
460
+ "examples": [
461
+ "Fox"
462
+ ]
463
+ }
464
+ }
465
+ },
466
+ "age": {
467
+ "type": "integer",
468
+ "examples": [
469
+ 20
470
+ ]
471
+ },
472
+ "email": {
473
+ "type": "string",
474
+ "examples": [
475
+ "john@example.com"
476
+ ],
477
+ "format": "email"
478
+ },
479
+ "dob": {
480
+ "type": "string",
481
+ "examples": [
482
+ "2000-01-01"
483
+ ],
484
+ "format": "date"
485
+ },
486
+ "hobbies": {
487
+ "type": "array",
488
+ "items": {
489
+ "type": "string",
490
+ "examples": [
491
+ "badminton",
492
+ "dota",
493
+ "reading"
494
+ ]
495
+ }
496
+ },
497
+ "addresses": {
498
+ "type": "array",
499
+ "items": {
500
+ "type": "object",
501
+ "required": [
502
+ "street1",
503
+ "street2",
504
+ "postcode"
505
+ ],
506
+ "properties": {
507
+ "street1": {
508
+ "type": "string",
509
+ "examples": [
510
+ "11, Fox Road"
511
+ ]
512
+ },
513
+ "street2": {
514
+ "type": "string",
515
+ "examples": [
516
+ "My Home Town"
517
+ ]
518
+ },
519
+ "postcode": {
520
+ "type": "integer",
521
+ "examples": [
522
+ 12345
523
+ ]
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
529
+ }
530
+ ```
531
+
532
+ ## Generate Code
533
+ 1. install simpleapp-generetor `npm install -g simpleapp-generator`
534
+ 2. create a folder `~/myapp/definations`
535
+ 3. copy above jsonschema example as `~/myapp/definations/person.ps.jsonschema.json`.
536
+ * `person`: unique document name (small letter alphabet `[a-z]`)
537
+ * `ps`: unique document type (small letter `[a-z]`)
538
+ * `jsonschema.json`: all files ending with this extension will process
539
+ 4. create `~/myapp/config.json` with below content
540
+ ```json
541
+ {
542
+ "definationsFolder":"./definations",
543
+ "backendFolder":"../backend",
544
+ "frontendFolder":"../frontend",
545
+ "openapi3Yaml":"openapi.yaml"
546
+ }
547
+ ```
548
+ 5. run `simpleapp-generator -c ./config.json`
549
+ 6. restart nestjs, the microservice is ready and you can test at `http://localhost:8000/api`. All generated api accessible via swagger-ui.
550
+ 7. Frontend need further work. Browse `http://localhost:8000/api-yaml`, save content as `openapi.yaml`
551
+ 8. Rerun `simpleapp-generator -c ./config.json`, it will help us to generate axios executable using openapi.yaml
552
+ 9. use vscode open both `~/myapp/frontend` and `~/myapp/backend`
553
+
554
+
555
+
556
+ ## perform simple development
557
+ 1. in `frontend` project, edit `app.vue`, put in below code:
558
+ ```vue
559
+ <template>
560
+ <div>
561
+ <div>
562
+ <label>Firstname</label>
563
+ <input v-model="reactivedata.name.firstName">
564
+ </div>
565
+ {{ reactivedata }}
566
+ <button @click="person.create().then((res)=>console.log(res.data))">try</button>
567
+ </div>
568
+ </template>
569
+ <script setup lang="ts">
570
+ import {PersonDoc} from './server/docs/PersonDoc'
571
+ const person = new PersonDoc()
572
+
573
+ // person.update().then((res)=>console.log("dosomething"))
574
+ // person.delete('record-id').then((res)=>console.log("dosomething"))
575
+ // person.getById('record-id').then((res)=>console.log("dosomething"))
576
+ // person.list().then((res)=>console.log(res))
577
+ const noreactivedata = person.getData() //give not reactive data, it cant apply 2 way data binding
578
+ const reactivedata = person.getReactiveData() //give vue reactive data, it can apply 2 way data binding using v-model
579
+ </script>
580
+ ```
581
+
582
+ We notice:
583
+ 1. `PersonDoc` auto generated, it come with plenty of build in crud features which you can use without knowing API:
584
+ ```typescript
585
+ person.create().then((res)=>console.log("dosomething"))
586
+ person.update().then((res)=>console.log("dosomething"))
587
+ person.delete('record-id').then((res)=>console.log("dosomething"))
588
+ person.getById('record-id').then((res)=>console.log("dosomething"))
589
+ person.list().then((res)=>console.log(res))
590
+ ```
591
+ 2. `person.getData()` gave reactive object, we can bind all properties directly to `vue` component using `v-model`
592
+ 3. you may try add more input bind to `reactivedata.name.lastName`,`reactivedata.email`, `reactivedata.age` and monitor result
593
+ 4. `button` can directly trigger `save` method from person.getData()
594
+ 5. You wont able to save the record because it not pass validation rules, check browser console it tell you what is happening
595
+ 6. There is UI component `simpleapp-uicomponent` which can integrate nicely with with `PersonDoc`. Refer the link [here](...)
596
+
597
+ # We can do more With SimpleApp
598
+ ## no time for full documentation yet
599
+ 1. Monitor variable change at frontend
600
+ step 1: add new methods for frontend's class `PesonDoc.ts`
601
+ ```
602
+ watchChanges = ()=>{
603
+ watch(this.getReactiveData(),(newdata)=>{
604
+ this.getReactiveData().age=calculateAge(newdata.dob)
605
+ //apply others changes here
606
+ })
607
+ }
608
+ ```
609
+ step 2: edit `app.vue` to on the watcher
610
+ ```typescript
611
+ //others codes
612
+ const person = new PersonDoc()
613
+ person.watchChanges() //<-- add this line to on watcher at frontend
614
+ //others codes
615
+ ```
616
+
617
+ 2. create more api to `person`, such as `post /person/:id/sendEmail {title:"title",body:"body"}`
618
+ step 1: edit backend `<backend>/src/docs/pes/pes.controller.ts`, add new source code between `<begin-controller-code>` and `<end-controller-code>`:
619
+ ```typescript
620
+ //<begin-controller-code>
621
+ //new api, wont override when regenerate code
622
+ @Get('/try/:id')
623
+ @ApiResponse({
624
+ status: 200,
625
+ description: 'success',
626
+ type: pesapischema.Person,
627
+ })
628
+ @ApiResponse({ status: 404, description: 'Document not found' })
629
+ @ApiResponse({ status: 500, description: 'Internal error' })
630
+ @ApiOperation({ operationId: 'newFindOne' }) //important, frontend access it via person.newFindOne()
631
+ async newFindOne(@Param('id') id: string) {
632
+ return this._findOne(id);
633
+ }
634
+ //<end-controller-code>
635
+ ```
636
+ step 2: try browse to `http://localhost:8000/api` to check new api appear or not.
637
+ step 3: You shall regenerate the code
638
+ ```bash
639
+ simpleapp-generator -c ./config.json
640
+ ```
641
+ step 4: go frontend project, edit `app.vue` you may try type `person.newFindOne()` see new method exists?
642
+
643
+ step 3: Regenerate code for frontend
644
+
645
+ 4. create backend only execution for `person`. It is useful cause some work only
646
+ step 1: Edit backend `backend/src/docs/pes/pes.service.ts`, add new source code between `<begin-backend-code>` and `<end-backend-code>`:
647
+ ```typescript
648
+ //<begin-backend-code>
649
+ //new method, wont override when regenerate code
650
+ logSomething = () => {
651
+ console.log('Access try api');
652
+ };
653
+ //<end-backend-code>
654
+ ```
655
+ step 2: modify `<backend>/src/docs/pes/pes.controller.ts`, call the new method
656
+ ```typescript
657
+ async newFindOne(@Param('id') id: string) {
658
+ this.service.logSomething(); //this.service is our service class
659
+ return this._findOne(id);
660
+ }
661
+ ```
662
+
663
+
664
+ 5. create frontend only code for `person`, such as:
665
+ `person.addHobbies('hobby1')`,`person.addAddress({})`,`person.delAddress(index:number)` edit `newFindOne`:
666
+ ```
667
+ ```
668
+ 6. create bothend code for `person`