Skip to main content

Arquitectura GSERP

1. Introducció i objectius

1.1. Visió general dels requeriments

1.2. Objectius de qualitat

IdMetaMotivació
1

1.3. Parts interessades

RolNomObjectiu i límits
DesenvolupadorsGirosystemDesenvolupar el backend i frontend segons especificat.

2. Restriccions de l'arquitectura

2.1 Restriccions tècniques

RestriccióRerefons i motivació
RT1Desplegable en WindowsLes apps s'han de poder instal·lar en servidors Windows
RT2Base de dadesL'app ha de connectar amb la base de dades actual GSERP, SQL Server
RT3CI/CDLes actualitzacions s'han d'automatitzar amb Azure DevOps
RT4DocumentacióLa documentació es crea amb Docusaurus i Star UML
RT5UI AngularLa interfície d'usuari és una SPA web Angular.
RT6Backend .NET CoreEl backend és una API REST .NET core 8, independent de la plataforma i sistema de base de dades.

2.2 Restriccions organitzatives

RestriccióRerefons i motivació
RO1
RO2

2.3 Convencions

RestriccióRerefons i motivació
C1Documentació d'arquitecturaEstructura basada en la plantilla arc42.
C2Codi frontendEl projecte fa servir les guies d'estil d'Angular (https://angular.io/guide/styleguide) i TypeScript (https://google.github.io/styleguide/tsguide.html)
C3Codi backendEl projecte fa servir la guia d'estil de C# de Google (https://google.github.io/styleguide/csharp-style.html) i Microsoft (https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names, https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions)
C4IdiomaEl projecte es fa tot en Català.

2.3.1 Nomenclatura dels arxius del projecte Angular

En el projecte farem servir aquest format per anonenar arxius i carpetes:

nomEnCamelCase.tipus.ext

El tipus només s'aplica en els arxius segons aquesta taula:

ArxiuDescripcióCapa Tipus
moduleName.module.tsMòdulPresentationModule
componentName.component.tsComponent filePresentationView Model
componentName.component.htmlComponent templatePresentationView
componentName.component.cssComponent CSS filePresentationView
componentName.component.spec.tsComponent test specificationPresentationTest
serviceName.service.tsServei (autenticació, validacions, ...)
repositoryName.repository.tsRepository d'objectes, en aquest cas de l'API REST del backend
xxxDto.tsClasse per representar els DTO de l'API REST del backend
xxx.component.tsComponent Angular
modelName.tsModels del DominiDomain
xxx.tsClasses base (mapper, useCase)

Exemples:

badgeType.ts

export enum BadgeType {
Info = 'Info',
}

customer.ts

export class Customer {
id: number,
...
}

customerEditor.component.ts

@Component({
selector: 'appCustomerEditor',
templateUrl: './customerEditor.component.html',
styleUrls: ['./customerEditor.component.css'],
})
export class CustomerEditorComponent implements OnInit {
...
}

2.3.2 Estructura del projecte Angular

S'estructuren les carpetes seguint el model de capes del DDD (Domain Driven Design):

alt text

docs/
├── pull_request_template.md
node_modules/
├── ...
src/
├── application/
│ ├── authentication/
│ │ ├── authentication.service.ts (interface)
│ │ ├── token.service.ts (interface)
│ │ └── ...
│ ├── validators/
│ │ ├── emailValidations.service.ts (utilitzar Value Objects del domini!)
│ │ ├── nifValidations.service.ts (utilitzar Value Objects del domini!)
│ │ ├── ibanValidations.service.ts (utilitzar Value Objects del domini!)
│ │ └── ...
│ └── ...

├── common/
│ ├── mapper.ts (abstract)
│ ├── useCase.ts (interface)
│ └── ...
|
├── domain/ (Value Objects + una carpeta per cada 'agregat')
│ ├── valueObjects/
│ │ ├── email.ts
│ │ ├── nif.ts
│ │ ├── iban.ts
│ │ └── ...
│ ├── enviamentDocumentASignar/
│ │ ├── enviamentDocumentASignar.repository.ts (interface)
| | ├── professional.ts
│ │ └── enviamentDocumentASignar.ts
│ ├── professional/
│ │ ├── professional.repository.ts (interface)
│ │ ├── professional.ts
│ │ └── estatProfessional.ts
│ └── propostaDeContractacio/
│ ├── propostaDeContractacio.repository.ts (interface)
│ ├── propostaDeContractacio.ts
│ ├── estatPropostaDeContractacio.ts
│ └── useCases/
│ ├── enviarPropostaDeContractacioUseCase.ts (implementa interface)
│ └── ...
|
├── infrastructure/
│ ├── interceptors/
│ │ ├── bearerTokenRequestInterceptor.service.ts
│ │ └── ...
│ │
│ ├── fakeData/
│ │ ├── fakeProfessional.repository.ts (implements interface)
│ │ └── ...
│ │
│ ├── localData/
│ │ ├── localDataToken.service.ts (implements interface)
│ │ └── ...
│ │
│ └── remoteData/
│ ├── dto/
│ │ ├── apiResponse.ts
│ │ └── ...
│ ├── repositories/
│ │ └── professional/
│ │ ├── tests/
│ │ │ ├── remoteProfessional.repository.jest.ts
│ │ │ └── ...
│ │ ├── professionalDto.mapper.ts
│ │ ├── professionalDto.ts
│ │ └── remoteProfessional.repository.ts (implements interface)
│ ├── authentication/
│ │ ├── remoteAuthentication.service.ts (implements interface)
│ │ └── ...
│ ├── dataTables/
│ │ ├── dataTableFilters.service.ts (implements interface)
│ │ └── ...
│ └── ...

├── presentation/
│ ├── app/
│ │ ├── app.module.ts
│ │ ├── ...
│ │ ├── layouts/
│ │ │ └── footer/
│ │ │ │ ├── footer.component.html
│ │ │ │ ├── footer.component.scss
│ │ │ │ ├── footer.component.spec.ts
│ │ │ │ └── footer.component.ts
│ │ │ └── ...
│ │ │
│ │ ├── pages/
│ │ │ └── professionals/
│ │ │ │ └── llistaProfessionals/
│ │ │ │ │ ├── llistaProfessionals.component.html
│ │ │ │ │ ├── llistaProfessionals.component.scss
│ │ │ │ │ ├── llistaProfessionals.component.spec.ts
│ │ │ │ │ └── llistaProfessionals.component.ts
│ │ │ │ └── ...
│ │ │ └── ...
│ │ │
│ │ ├── routing/
│ │ │ ├── auth.guard.ts
│ │ │ ├── ...
│ │ │ └── appRouting.module.ts
│ │ │
│ │ ├── interceptors/
│ │ │ ├── spinnerRequestInterceptor.service.ts
│ │ │ └── ...
│ │ │
│ │ └── shared/
│ │ ├── tests/
│ │ │ ├── ...
│ │ │ └── ...
│ │ ├── components/
│ │ │ ├── alertsDialog/
│ │ │ │ └── ...
│ │ │ └── toggleButton/
│ │ │ ├── toggleButton.component.html
│ │ │ ├── toggleButton.component.scss
│ │ │ ├── toggleButton.component.spec.ts
│ │ │ └── toggleButton.component.ts
│ │ └── pipes/
│ │ │ ├── sort.pipe.ts
│ │ │ ├── permission.pipe.ts
│ │ │ └── ...
│ │ └── shared.module.ts
│ │
│ ├── assets/
│ │ ├── i18n/
│ │ │ ├── ca.json
│ │ │ ├── es.json
│ │ │ └── ...
│ │ ├── icons/
│ │ │ ├── info.svg
│ │ │ └── ...
│ │ └── img/
│ │ ├── profile.jpeg
│ │ └── ...
│ │
│ └── environments/
│ ├── environment.preprod.ts
│ ├── ...
│ └── environment.ts

├── favicon.ico
├── index.html
├── main.ts
├── styles.css

angular.json
karma.conf.ts
package.json
README.md
tailwind.config.js
tsconfig.app.json
tsconfig.json
...

3. Context i abast

Aquest capítol descriu l'entorn i context de l'aplicació: qui utilitza el sistema i de quins altres sistemes en depén.

3.1. Context de negoci

3.2. Context tècnic

4. Estrategia de solucions

5. Vista de blocs

5.1 Nivell 1 - Vista general

5.2 Nivell 2 - Backend.

5.3 Nivell 3 - Frontend.

6. Vista d'execució

URL API: http://192.168.20.13:8082

7. Vista de desplegament

7.1 Infraestructura nivell 1

Describe (usually in a combination of diagrams, tables, and text):

the distribution of your system to multiple locations, environments, computers, processors, .. as well as the physical connections between them important justification or motivation for this deployment structure Quality and/or performance features of the infrastructure the mapping of software artifacts (building blocks) to elements of the infrastructure For multiple environments or alternative deployments please copy that section of arc42 for all relevant environments. **

7.2 Infraestructura nivell 2

Here you can include the internal structure of (some) infrastructure elements from infrastructure level 1.

Please copy the structure from level 1 for each selected element.

8. Conceptes transversals (Cross-cutting)

8.1. Model del domini

Taula d'entitats:

NameDescription

8.2. Persistència

Les dades es guarden a la base de dades SQL Server utilitzant l'ORM EF Core 8.

8.3. Interfície d'usuari

La interfície d'usuari és una SPA feta amb Angular.

8.4. Transaccions

Totes les operacions son transaccionals a nivell d'endpoint.

8.5. Seguretat

Els usuaris s'han de loginar per que el servidor els generi un token d'accés (JWT). Aquest token te la informació de l'usuari, rol, i permisos d'aplicacio:

{
"jti": "d8fbcfbc-89b3-49f7-80fc-13d0385cd861",
"username": "02390377X",
"role": [
"SOL",
"OFI"
],
"permission": [
"professional",
"professional:create",
"professional:write",
"professional:delete",
"professional:dades"
],
"exp": 1712513915,
"iss": "GIRHWebAPI",
"aud": "GIRHWebClient"
}

8.6. Gestió d'errors

El backend retorna els codis d'error estàndard d'HTTP. En concret el grup d'errors de client (400-499) i el d'errors del servidor (500-599)

8.7. Logging

Els logs es guarden al Graylog fent servir els "sinks" de Serilog.
URL PreProd:
URL Prod:

8.8. Configuracions

Configuracions de l'API REST del Backend:

ConfiguracióDescripció
ConnectionStrings:GIRHDbCadena de connexió a la base de dades. Per exemple: server=localhost;port=3306;database=GIRH_ANON;user=root;password=xxxxx;ConvertZeroDateTime=True

8.9. Localització

El programa només suporta l'idioma Català.

8.10. Testing

Totes les aplicacions disposen de tests unitaris, i alguns d'integració.

Biblioteques utilitzades en el backend:

  • xUnit.
  • Moq.
  • FluentAssertions.
  • Bogus faker.

9. Decisions de disseny

9.1. Bases de dades compatibles

El sistema s'ha desenvolupat utilitzant MariaDB, tot i que l'API fa servir Entity Framework Core i Dapper, que admeten la connexió amb múltiples sistemes de bases de dades. Es pot canviar quin fan servir modificant la injecció de les dependències al projecte de l'API de contractació.

9.2. Sessions d'usuaris.

El usuaris tenen un temps limitat per mantenir la sessió oberta. En cas de superar-lo surt un avís informant que es tancarà.

9.3. Software de tercers utilitzats.

Biblioteques, components i sistemes de tercers que es fan servir en la solució, amb el motiu pel qual s'han triat.

NomDescripcióMotiu de decisió
GraylogSistema de gestió de logsPermet la gestió de diferents logs via web
SerilogRegistre de logsPermet crear logs estructurats i volcar-los al Graylog

10. Requeriments de qualitat

10.1. Arbre de qualitat

CategoriaQualitatDescripcióEscenari
UsabilitatTraspàs d'usuariUn usuari de l'app desktop ha de saber fer servir la web nova de forma immediataSC1
Nou usuariUn usuari nou ha de saber fer servir la web en menys de 10 minutsSC1
RendimentFacilitat d'úsEls temps de resposta de les pàgines han de ser ràpidsSC2
SeguretatDades restringidesEls usuaris no han de poder accedir a dades que no tenen permís

10.2. Escenaris de qualitat

IdEscenari
SC1
SC2Totes les pàgines tarden menys de 2 segons a carregar

11. Riscs i deute tècnic

### 11.1. Deute tècnic

### 11.2. Riscos de seguretat.

RiscDescripcióMesures
Ús indegut dels tokensUn hacker podria atacar el sistema accedint als tokens del navegadorConfigurar la durada dels tokens per que sigui breu

### 11.2. Riscos tècnics.

RiscDescripcióMesures
Navegador incompatibleUna nova versió d'algun navegador podria ser incompatibleDefinir i comprovar versions compatibles

12. Glossari

TermeDefinició
Soci
Stakeholder