Mise à jour de 'Devrules'

philc 2023-03-27 08:53:43 +00:00
parent 32aafedfe9
commit e1a05c7fb6

@ -1,268 +1,274 @@
# Developers
This page is about to save time to a dev to quickly onboard to add a features or debug any issues. This is also a good start if you want just dev a plugin for a tribe.
Visual studio theme @id:ms-vscode.cpptools-themes
## git management
**Relations between git branches and environment**
Those branches are corresponding to various environment:
- **branch `main` is used for the production only** and needs a pull request to allow developers changes;
- **branch `staging` is used for testing** and needs a pull request to allow developers changes;
- **branch `develop` is the current last working version under development of the application .** Writing changes is allowed for developers on this branch.
Initialize a developer branch, each developer must create and checkout a new branch named `devel/${USERNAME}` to work.
**Git process for developers**
1. Select a feature to develop or a bug to fix. ideally work on different files and isolated from other work done in parallel by other developers. This will avoid or limit problems when merging branches.
2. Before any change on your local repository, please previously :
- run a `git pull`;
- merge your branch with the last commit of the `devel` branch :
```shell
git checkout devel/${USERNAME}
git merge devel
```
- fix conflicts on your local repository if necessary.
3. Program your changes.
4. **Don't forget to test!** Check if your changes are working locally.
5. Commit local changes on your named branch: `git commit -am "[comment]`
6. Push on your named branch: `git push -u origin devel/${USERNAME}`
7. Merge your modifications on the `devel` branch : `git checkout devel && git merge devel/${USERNAME}`
- Fix conflict if needed.
8. Push on the reference `devel` branch your changes: `git push -u origin devel`
9. Return to your local git branch to avoid errors directly on the `devel` reference branch
**Git process for product owner** (aka P.O.)
1. The P.O. can merge `testing` branch with latest commit of the `develop` branch **only if application is working and functional**.
2. Add a git tag on commit according [SemVer](semver.org/) standards: `git tag v[SEMVER_VERSION] -m "[comment]" "&& git push --tags`
- *This tag is essential to correctly track application versions and to integrate it into a CI/CD process that is standardized and compliant!**
3. Test the application on the related environment.
4. Then the P.O. can merge `main` branch with latest commit of the `testing` branch **only if application is working and functional**.
## Common rules
### Security
- **Never store any password, API keys or any another sensible information in the Git repository!**
- **Think twice before adding a package in your project, get answer about licence, audited or not,**
### Performance
- **use require function by loading only what you need**
- **be a bootleneck hunter, use async when it is possible but keep your code readable and simple**
## apXtrib Key points
* this is a npm/yarn classical organization (package.json give you 1st info)
* **Entry point** ./apxtrib.js
* apXtrib is organize around an express.js api and respect the restFULL concept on an object.
* An **object** has:
- a unique objectName
- a schema definition that describe each character to qualify an object
- a route named ./routes/objectName.js from the api /objectName/ parameters to request acting on items of this objectName
- a model named ./models/ObjectName.js that act on items
- a language info in infolg/ObjectName.js
* **Access control** is done by 3 middlewares:
- checkHeaders.js that check ./tribes/townconf.json.exposedHeaders are presents
- isAuthenticated.js check the token (header.xauth ) for header.xpaganid is valid
- hasAccessrighton.js check accessright of pagan to act (CRUD) on an object into a tribe (xworkon)
* A **request** is send with specific header to be accepted.
```
{
xauth: 'jwt token 24hours valid or 1 if not authenticated',
xpaganid: 'uuid of the connected user'
xlang:' lang international notification 2 letters of the request',
xtribe: 'name of the tribe, xpaganId belongs to',
xworkon: 'name of tribe user want to act if accessrights are properly set up',
xapp: 'name of app requesting action "tribename:nappname" if accessrights are set up'
}
```
* A **response** is structured as
```
{
status: mandatory Integer,(web status code)[https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml]
info: optional string,
data: optional object
}
```
* **Multilanguage management** depending of header.xlang request
- info:"|model|key" starting by | mean a file is available in ./nationchains/static/info/model_lg.json to match {key:"information in language lg}
## apXtrib Coding Convention
Standard: Eslint 6 with a .eslintrc.js
lib used for:
- file json manipulation: fs-extra.js
- templating szysteme: mustache.js
- encryption with simple hash : bcrypt that is more efficient than crypto-js that is use inside a browser or node for cypher and uncipher
- time management use luxon and no more moment
- cross domain management: cors.js
- to generate unique id use lib uuid.v4()
- stripe to allow payment in $,€,... any device
In general try to not install other lib in your dev. An apXtrib town mayor have to globaly valid to add a new lib into apxtrib so if you do then you can only use your town to provide your service and cannot use other town to deal wwith.
## CORS and global
global variable into node:
* ${__base} is the current dir where project are install in case you need absolute path.
* config is set from ./tribes/townconf.json where:
- system data are available to sync town and nation (linux user, url, nation and town name)
- express set up parameter appset allow to set any key:val parameter of express
-
* const app is an express instance that is set into apixtrib.js
## route template
A route analyse (data structure and user accesrights) a http request to act a model action
## model template
A model is a logical to apply onto an object. It is indepedant of the interface
export model to make it importable into route or any other app
## Object organization
Object properties are strongly inspire of https://schema.org/docs/schemas.html <br>
Fom https://json-schema.org/learn/<br>
https://json-schema.org/understanding-json-schema/index.html<br>
https://json-schema.org/draft/2020-12/release-notes.html<br>
Warning: stay in those specification much as it is possible, try to use existing object like person, organisation, ....
As it is still on draft, a Odmdb.js (Objectdatamodeldatabase) is managing any CRUD on json object
Any apxtrib key word is **prefix by apx** to inform that it does not exist in JSON schema protocole. This can be change in the futur if json schema will be stable enough.
An **object is defined by a schema** store into ./nationchains/socialworld/schema/objectName.json or tribe/tribeId/plugins/pluginName/schema/objectName.json
It lists key definition of an item's object.
In basic configuration Items object are store into ./nationchains/socialworld/objects/objectName/objectNameid.json or tribe/tribeId/objects/objectName/objectNameid.json.
If an **item have a language** properties:lang that describe in with language is used by this item. If the object item cannot be translate this means that it is a different object.
apXtrib **convention to manage language** to get a schema in a language:lg :
|objectName|keyword => file ./nationchains/socialworld/objects_lang/objectName_lg.json = {keyword:description in lg}
or tribe/tribeId/objects_lang/objectName_lg.json
If any string start with | mean it exist a file translation
A models/objectName.js manage all items of an objectName:
- CRUD action on any items depind of pagan accessright
- index builder that are store into /objectName/searchindex/
a searchindex file is named as objectname_idfield1_idfiled2_lg.json
and contain: { value1idfiled1:[ value1idfield2 ] }
Depending of volume, it is possible to have objectName_UUID_UUID_lg.json this contain
{ valueuuid: { key:value of object} }
### Object key description
Main properties key:
* **description** a short description that can be use in GUI
* **desclong** a long description
* **info** a long or short html description
* **default** value by default if not set when object is save, this can be a function
example: UUID.v4() or moment(new Date()).format('YYYY-MM-DD')
* **format** usefull for date or any text structured example:"YYYY-MM-DD"
* **type** string / int /
* **enum** list of valid data
* **$apxenumkey** if "data" then properties status.data has to be set as a {key:value}
else a web link (absolute http:/... or relative ./...) to a {key:value}
mean the value have to be one of the key of this json file if it is required
*
En prevision de smatchit :
person shema
{
"idfield": "telephone",
"desc": "|Pagans|telephonedesc",
"check": ["phone"]
"tpl": "input",
"type": "text"
},
{
"idfield": "familyName",
"desc": "|Pagans|familyNamedesc",
"tpl": "input",
"type": "text"
},
{
"idfield": "givenName",
"desc": "|Pagans|givenNamedesc",
"tpl": "input",
"type": "text"
},
{
"idfield": "additionalName",
"desc": "|Pagans|additionalNamedesc",
"tpl": "input",
"type": "text",
"info": "|Pagans|additionalNameinfo"
},
**searchindex** array of index to generate
keyword "all" => generate objectname/searchinndex/objectname_UUID_UUID.json = {uuid:{full key:value}}
* **nouserupdate** user cannot modify this field from a request (only internal process can change this)
* **check** array of keyword required, unique, ...
a checkdata lib (./natonchains/socialworld/contracts/checkdata.js) can be used
into a browser : <script src="https://townName.nationName.dns/socialworld/contracts/checkdata.js"></script>
or into a node.js : const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
Some test function need context (ctx ) for example to check a value is unique
example: @TODO key example
checkdata.evaluate = (contexte (list ), metaobject (definition of object metaobject/name.json), data (item object set to evaluate))
In case of unconsistency(ies) a new field call invalidfor array of list of unconsitencies is returned
### Object Nationschains
This model manage the socialworld based on nations and towns to run a blockchain where a node is a town and a nation is a blockchain rules that any town respect.
Rules are manage in Contracts.
.models/Setup.js is the interface of this model, to create a node/town for dev that is an unchain town or for production that is a chain town (real node) [process of setup] (https://gitea.ndda.fr/apxtrib/apxtrib/wiki/Setup)
A pagan have an uuid + public key + private key and belong to only one tribe at a time optionaly an email + login + psw to recover his login/psw into his tribe. His private key is the only way to prove a user his the owner of an uuid account. No one else than the pagan knows his private key.
At a time:
* A pagan belong to only 1 tribe.
* A tribe belong to only 1 town.
* A town belong to only 1 nation.
The blockchain register only data about pagan (uuid/publickey)
Each town is fully decentralized manage by a pagan with mayor role.
**A mayor knows** pagans informations from all tribes (uuid, publickey and optionaly: login/hash password and any information store).
**A Druid rent** a space to the mayor of the town in exchange of anything (fiat currency, services, ...).
**Druid knows** all about his user he can ask and store any data (cipher it or not) about pagans hosted in his tribe space.
With a contract a druid can generate token currency that are valuate by stacking the equivalent of crypto's nation into the mayor wallet. Druid then can distribute as he wants those token to his community of pagan to value Pagans activities.
A pagan can at any time convert a token in his equivalent in the crypto's nation. Then token's druid are destoyed.
A pagan owns data store into the blockchain and can request to move from tribe A to tribe B. By doing this all token owns will be convert to crypto's nation and all specific data will stay the properties of Druid or not(can be removed by him or not but Pagan will have no more access to it).
### Object Contracts
A contract is a script js that is apply into the blockchain to register important transaction into the social world.
### Object Tribes
Tribes are localy manage, by a pagan that have mayor role that can Create Delete a ./tribes/tribeId
### Object Pagans
# Developers
This page is about to save time to a dev to quickly onboard to add a features or debug any issues. This is also a good start if you want just dev a plugin for a tribe.
Visual studio theme @id:ms-vscode.cpptools-themes
## git management
**Relations between git branches and environment**
Those branches are corresponding to various environment:
- **branch `main` is used for the production only** and needs a pull request to allow developers changes;
- **branch `staging` is used for testing** and needs a pull request to allow developers changes;
- **branch `develop` is the current last working version under development of the application .** Writing changes is allowed for developers on this branch.
Initialize a developer branch, each developer must create and checkout a new branch named `devel/${USERNAME}` to work.
**Git process for developers**
1. Select a feature to develop or a bug to fix. ideally work on different files and isolated from other work done in parallel by other developers. This will avoid or limit problems when merging branches.
2. Before any change on your local repository, please previously :
- run a `git pull`;
- merge your branch with the last commit of the `devel` branch :
```shell
git checkout devel/${USERNAME}
git merge devel
```
- fix conflicts on your local repository if necessary.
3. Program your changes.
4. **Don't forget to test!** Check if your changes are working locally.
5. Commit local changes on your named branch: `git commit -am "[comment]`
6. Push on your named branch: `git push -u origin devel/${USERNAME}`
7. Merge your modifications on the `devel` branch : `git checkout devel && git merge devel/${USERNAME}`
- Fix conflict if needed.
8. Push on the reference `devel` branch your changes: `git push -u origin devel`
9. Return to your local git branch to avoid errors directly on the `devel` reference branch
**Git process for product owner** (aka P.O.)
1. The P.O. can merge `testing` branch with latest commit of the `develop` branch **only if application is working and functional**.
2. Add a git tag on commit according [SemVer](semver.org/) standards: `git tag v[SEMVER_VERSION] -m "[comment]" "&& git push --tags`
- *This tag is essential to correctly track application versions and to integrate it into a CI/CD process that is standardized and compliant!**
3. Test the application on the related environment.
4. Then the P.O. can merge `main` branch with latest commit of the `testing` branch **only if application is working and functional**.
## Common rules
### Security
- **Never store any password, API keys or any another sensible information in the Git repository!**
- **Think twice before adding a package in your project, get answer about licence, audited or not,**
### Performance
- **use require function by loading only what you need**
- **be a bootleneck hunter, use async when it is possible but keep your code readable and simple**
## apXtrib Key points
* this is a npm/yarn classical organization (package.json give you 1st info)
* **Entry point** ./apxtrib.js
* apXtrib is organize around an express.js api and respect the restFULL concept on an object.
* An **object** has:
- a unique objectName
- a schema definition that describe each character to qualify an object
- a route named ./routes/objectName.js from the api /objectName/ parameters to request acting on items of this objectName
- a model named ./models/ObjectName.js that act on items
- a language info in infolg/ObjectName.js
* **Access control** is done by 3 middlewares:
- checkHeaders.js that check ./tribes/townconf.json.exposedHeaders are presents
- isAuthenticated.js check the token (header.xauth ) for header.xpaganid is valid
- hasAccessrighton.js check accessright of pagan to act (CRUD) on an object into a tribe (xworkon)
* A **request** is send with specific header to be accepted.
```
{
xauth: 'jwt token 24hours valid or 1 if not authenticated',
xpaganid: 'uuid of the connected user'
xlang:' lang international notification 2 letters of the request',
xtribe: 'name of the tribe, xpaganId belongs to',
xworkon: 'name of tribe user want to act if accessrights are properly set up',
xapp: 'name of app requesting action "tribename:nappname" if accessrights are set up'
}
```
* A **response** is structured as
```
{
status: mandatory Integer,(web status code)[https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml]
info: optional string,
data: optional object
}
```
* **Multilanguage management** depending of header.xlang request
- info:"|model|key" starting by | mean a file is available in ./nationchains/static/info/model_lg.json to match {key:"information in language lg}
### apXtrib Coding Convention
Standard: Eslint 6 with a .eslintrc.js
lib used for:
- file json manipulation: fs-extra.js
- templating szysteme: mustache.js
- encryption with simple hash : bcrypt that is more efficient than crypto-js that is use inside a browser or node for cypher and uncipher
- time management use luxon and no more moment
- cross domain management: cors.js
- to generate unique id use lib uuid.v4()
- stripe to allow payment in $,€,... any device
In general try to not install other lib in your dev. An apXtrib town mayor have to globaly valid to add a new lib into apxtrib so if you do then you can only use your town to provide your service and cannot use other town to deal wwith.
### apiDoc
We use apidoc to generate the apXtrib documentation in nationscjains/apidoc/
Each route has to respect https://apidocjs.com/
Before a push please run yarn apidoc to update the documentation.
### CORS and global
global variable into node:
* ${__base} is the current dir where project are install in case you need absolute path.
* config is set from ./tribes/townconf.json where:
- system data are available to sync town and nation (linux user, url, nation and town name)
- express set up parameter appset allow to set any key:val parameter of express
-
* const app is an express instance that is set into apixtrib.js
### route template
A route analyse (data structure and user accesrights) a http request to act a model action
### model template
A model is a logical to apply onto an object. It is indepedant of the interface
export model to make it importable into route or any other app
## Object organization
Object properties are strongly inspire of https://schema.org/docs/schemas.html <br>
Fom https://json-schema.org/learn/<br>
https://json-schema.org/understanding-json-schema/index.html<br>
https://json-schema.org/draft/2020-12/release-notes.html<br>
Warning: stay in those specification much as it is possible, try to use existing object like person, organisation, ....
As it is still on draft, a Odmdb.js (Objectdatamodeldatabase) is managing any CRUD on json object
Any apxtrib key word is **prefix by apx** to inform that it does not exist in JSON schema protocole. This can be change in the futur if json schema will be stable enough.
An **object is defined by a schema** store into ./nationchains/socialworld/schema/objectName.json or tribe/tribeId/plugins/pluginName/schema/objectName.json
It lists key definition of an item's object.
In basic configuration Items object are store into ./nationchains/socialworld/objects/objectName/objectNameid.json or tribe/tribeId/objects/objectName/objectNameid.json.
If an **item have a language** properties:lang that describe in with language is used by this item. If the object item cannot be translate this means that it is a different object.
apXtrib **convention to manage language** to get a schema in a language:lg :
|objectName|keyword => file ./nationchains/socialworld/objects_lang/objectName_lg.json = {keyword:description in lg}
or tribe/tribeId/objects_lang/objectName_lg.json
If any string start with | mean it exist a file translation
A models/objectName.js manage all items of an objectName:
- CRUD action on any items depind of pagan accessright
- index builder that are store into /objectName/searchindex/
a searchindex file is named as objectname_idfield1_idfiled2_lg.json
and contain: { value1idfiled1:[ value1idfield2 ] }
Depending of volume, it is possible to have objectName_UUID_UUID_lg.json this contain
{ valueuuid: { key:value of object} }
### Object key description
Main properties key:
* **description** a short description that can be use in GUI
* **desclong** a long description
* **info** a long or short html description
* **default** value by default if not set when object is save, this can be a function
example: UUID.v4() or moment(new Date()).format('YYYY-MM-DD')
* **format** usefull for date or any text structured example:"YYYY-MM-DD"
* **type** string / int /
* **enum** list of valid data
* **$apxenumkey** if "data" then properties status.data has to be set as a {key:value}
else a web link (absolute http:/... or relative ./...) to a {key:value}
mean the value have to be one of the key of this json file if it is required
*
En prevision de smatchit :
person shema
{
"idfield": "telephone",
"desc": "|Pagans|telephonedesc",
"check": ["phone"]
"tpl": "input",
"type": "text"
},
{
"idfield": "familyName",
"desc": "|Pagans|familyNamedesc",
"tpl": "input",
"type": "text"
},
{
"idfield": "givenName",
"desc": "|Pagans|givenNamedesc",
"tpl": "input",
"type": "text"
},
{
"idfield": "additionalName",
"desc": "|Pagans|additionalNamedesc",
"tpl": "input",
"type": "text",
"info": "|Pagans|additionalNameinfo"
},
**searchindex** array of index to generate
keyword "all" => generate objectname/searchinndex/objectname_UUID_UUID.json = {uuid:{full key:value}}
* **nouserupdate** user cannot modify this field from a request (only internal process can change this)
* **check** array of keyword required, unique, ...
a checkdata lib (./natonchains/socialworld/contracts/checkdata.js) can be used
into a browser : <script src="https://townName.nationName.dns/socialworld/contracts/checkdata.js"></script>
or into a node.js : const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
Some test function need context (ctx ) for example to check a value is unique
example: @TODO key example
checkdata.evaluate = (contexte (list ), metaobject (definition of object metaobject/name.json), data (item object set to evaluate))
In case of unconsistency(ies) a new field call invalidfor array of list of unconsitencies is returned
### Object Nationschains
This model manage the socialworld based on nations and towns to run a blockchain where a node is a town and a nation is a blockchain rules that any town respect.
Rules are manage in Contracts.
.models/Setup.js is the interface of this model, to create a node/town for dev that is an unchain town or for production that is a chain town (real node) [process of setup] (https://gitea.ndda.fr/apxtrib/apxtrib/wiki/Setup)
A pagan have an uuid + public key + private key and belong to only one tribe at a time optionaly an email + login + psw to recover his login/psw into his tribe. His private key is the only way to prove a user his the owner of an uuid account. No one else than the pagan knows his private key.
At a time:
* A pagan belong to only 1 tribe.
* A tribe belong to only 1 town.
* A town belong to only 1 nation.
The blockchain register only data about pagan (uuid/publickey)
Each town is fully decentralized manage by a pagan with mayor role.
**A mayor knows** pagans informations from all tribes (uuid, publickey and optionaly: login/hash password and any information store).
**A Druid rent** a space to the mayor of the town in exchange of anything (fiat currency, services, ...).
**Druid knows** all about his user he can ask and store any data (cipher it or not) about pagans hosted in his tribe space.
With a contract a druid can generate token currency that are valuate by stacking the equivalent of crypto's nation into the mayor wallet. Druid then can distribute as he wants those token to his community of pagan to value Pagans activities.
A pagan can at any time convert a token in his equivalent in the crypto's nation. Then token's druid are destoyed.
A pagan owns data store into the blockchain and can request to move from tribe A to tribe B. By doing this all token owns will be convert to crypto's nation and all specific data will stay the properties of Druid or not(can be removed by him or not but Pagan will have no more access to it).
### Object Contracts
A contract is a script js that is apply into the blockchain to register important transaction into the social world.
### Object Tribes
Tribes are localy manage, by a pagan that have mayor role that can Create Delete a ./tribes/tribeId
### Object Pagans
Pagans is managed by a pagan that have druid role for his tribe. He can host any other pagan. A pagan can only belong to one tribe