# Toozy Rest :::success Last update: 15 Februari 2020 ::: ###### using: `nodejs` `koa` `jwt` `sequelize` `postgresql` ## Table of Content [ToC] ## :memo: Todo ### Step 1: Fix and documentation database schema - [ ] Fix database :rocket: - [ ] Documentation it ### Step 2: Create Module #### **System** :::info :bulb: Must have `.core.js` `.presenter.js` `.validation.js` `.routes.js` `.storage.js` `index.js` and optional can using `.constant.js` for text or whatever when can dynamic changed. ::: - [ ] article - [x] auth - [x] Login - [x] Register - [x] RegisterVerification - [x] RegisterRequestVerification - [x] ForgotPassword - [x] CheckForgotPassword - [x] VerifyForgotPassword - [ ] banner - [ ] menu - [ ] notification - [ ] payment - [ ] restaurant - [x] role - [x] Create - [x] GetById - [x] GetList - [x] DeleteById - [x] UpdateById - [ ] table - [ ] upload - [ ] user - [ ] verification - [ ] voucher #### **Lib** :::info :bulb: Must stand alone or only single initializing using `attach()` and all function is accessable directly. ::: - [ ] docean (digitalocean) - [ ] mailgun - [ ] redis - [ ] sendgrid - [ ] socket.io - [ ] transalation - [ ] error.js - [ ] jwt.js - [ ] logger.js - [ ] roles.js ## :memo: Database ### users | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | email | `STRING` `NOTNULL` | :x: | :x: | | telephone | `STRING` `NULL` | :x: | :x: | | password | `STRING` `NOTNULL` | :x: | :x: | | roleId | `UUID` `NOTNULL` | `roles` `id` | :heavy_check_mark: | | vouchers | `UUID` `[]` | `vouchers` `id` | :heavy_check_mark: | | status | `STRING` `REGISTERED` | :x: | :x: | | avatar | `TEXT` `NOTNULL` | :x: | :x: | ### restaurants | Name | Type | Reference | PK / FK | | ----------- | ----------------------------------------------------------------------- | --------------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` `UNIQUE` | :x: | :x: | | address | `STRING` `NOTNULL` | :x: | :x: | | status | `BOOLEAN` `FALSE` | :x: | :x: | | image | `ARRAY(STRING)` `NOTNULL` | :x: | :x: | | tag | `ARRAY(UUID)` `NOTNULL` | `restaurantTags` `id` | :heavy_check_mark: | | location | `JSONB` `NOTNULL` `{ longitude: number, latitude: number }` | :x: | :x: | | operational | `JSONB` `NOTNULL` `Array({ day: string, open: string, close: string })` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | point | `GEOMETRY` `NOTNULL` `POINT` | :x: | :x: | ### restaurantTags | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` `UNIQUE` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### articles | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | title | `STRING` `NOTNULL` | :x: | :x: | | description | `TEXT` `NOTNULL` | :x: | :x: | | content | `STRING` `NOTNULL` | :x: | :x: | | tags | `ARRAY(STRING)` `NOTNULL` | :x: | :x: | | image | `STRING` `NOTNULL` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### banners | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | image | `STRING` `NOTNULL` | :x: | :x: | | type | `UUID` `NOTNULL` | `bannerTypes` `id` | :heavy_check_mark: | | tag | `ARRAY(UUID)` `NOTNULL` | `bannerTags` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | value | `UUID` `NOTNULL` | :x: | :x: | ### bannerTags | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` `UNIQUE` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### bannerTypes | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` `UNIQUE` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### menu | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | image | `STRING` `NOTNULL` | :x: | :x: | | type | `STRING` `NOTNULL` | :x: | :x: | | restoId | `UUID` `NOTNULL` | `restaurants` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | status | `STRING` `NOTNULL` | :x: | :x: | | price | `INTEGER` `NOTNULL` | :x: | :x: | ### menuTags | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | restoId | `UUID` `NOTNULL` | `restaurants` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | menuId | `ARRAY(UUID)` `NOTNULL` | `menu` `id` | :heavy_check_mark: | | priority | `SMALLINT` `NOTNULL` `0` | :x: | :x: | ### payments | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | amount | `STRING` `NOTNULL` | :x: | :x: | | discountCode | `STRING` `NULL` | :x: | :x: | | total | `STRING` `NOTNULL` | :x: | :x: | | method | `STRING` `NOTNULL` | :x: | :x: | | createdTo | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | status | `STRING` `NOTNULL` | :x: | :x: | | product | `JSONB` `NULL` `ARRAY({ id: uuid, name: string, image: string, qty: number, price: string, type: string, note: string })` | :x: | :x: | | data | `JSONB` `NULL` `{ name: string, uuid: uuid, type: string, tableId: uuid }` | :x: | :x: | ### roles | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | roles | `ARRAY(STRING)` `NOTNULL` | :x: | :x: | | slug | `STRING` `NOTNULL` | :x: | :x: | ### tables | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | code | `STRING` `NOTNULL` | :x: | :x: | | restoId | `UUID` `NOTNULL` | `restaurants` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### verifications | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | code | `STRING` `NOTNULL` | :x: | :x: | | expiration | `SMALLINT` `NOTNULL` | :x: | :x: | | type | `SMALLINT` `NOTNULL` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### vouchers | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | description | `STRING` `NOTNULL` | :x: | :x: | | image | `STRING` `NOTNULL` | :x: | :x: | | code | `STRING` `NOTNULL` `UNIQUE` | :x: | :x: | | value | `INTEGER` `NOTNULL` | :x: | :x: | | maxRedeem | `INTEGER` `NOTNULL` | :x: | :x: | | maxValue | `INTEGER` `NULL` | :x: | :x: | | status | `BOOLEAN` `NOTNULL` `TRUE` | :x: | :x: | | type | `STRING` `NOTNULL` | :x: | :x: | | tag | `ARRAY(UUID)` `NOTNULL` | `voucherTags` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | validAt | `DATE` `NOTNULL` | :x: | :x: | | expireAt | `DATE` `NOTNULL` | :x: | :x: | | termsCondition | `ARRAY(STRING)` `NOTNULL` | :x: | :x: | | queryCondition | `ARRAY(STRING)` `NOTNULL` `ARRAY({ value1: string, value2: string, condition: string, type: string })` | :x: | :x: | ### voucherTags | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### waiters | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | name | `STRING` `NOTNULL` | :x: | :x: | | restoId | `UUID` `NOTNULL` | `restaurants` `id` | :heavy_check_mark: | | createdBy | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | ### notifications | Name | Type | Reference | PK / FK | | --------- | --------------------- | --------------- | ------------------ | | id | `UUID` | :x: | :heavy_check_mark: | | userId | `UUID` `NOTNULL` | `users` `id` | :heavy_check_mark: | | type | `SMALLINT` `NOTNULL` | :x: | :x: | | data | `JSONB` `NOTNULL` `Object` | :x: | :x: | ## :memo: Flow ### Login :::info `Login` will check status is `ACTIVE`, if status `REGISTERED` will send new otp to user email. ::: ### Register :::info `Register` will create user with status `REGISTERED`, user must be verify email with `RegisterVerification` ::: ### Forgot Password :::info `ForgotPassword` will send verification by email, `CheckForgotPassword` use for check otp, `VerifyForgotPassword` use for check otp and change password ::: ## :memo: Changelog | Date | Description | Version | | ---------------- | ------------ | ------- | | 15 Februari 2020 | add database | - | | 17 Februari 2020 | - | - |