Proyecto TPV. Este proyecto es un apoyo docente de la asignatura. Es una aplicación completa realizada con un Front-end con Angular, dos Back-ends con Spring y un Back-end con Python. El Back-end-user se desarrolla con programación síncrona y Postgresql. El Back-end-core se realiza con programación reactiva y MongoDB. El Back-end-customer-support con programación síncrona y MongoDB
Java
Maven
Spring-Boot
Reactor
Python
Angular
MondoDB
JPA
SQL
GitHub
Travis-CI
Sonarcloud
Better Code Hub
Heroku
Proyecto | GitHub - CI | Sonarcloud |
---|---|---|
Front-end-angular | ||
Back-end-user | ||
Back-end-core | ||
Back-end-customer-support |
- Clonar repositorios, mediante consola:
- betca-tpv-angular
> cd <folder path>
> git clone https://github.com/miw-upm/betca-tpv-angular
> cd betca-tpv-angular
betca-tpv-angular> npm install
- betca-tpv-user
> cd <folder path>
> git clone https://github.com/miw-upm/betca-tpv-user
- betca-tpv-core
> cd <folder path>
> git clone https://github.com/miw-upm/betca-tpv-core
- betca-tpv-customer-support
> cd <folder path>
> git clone https://github.com/miw-upm/betca-tpv-customer-support
> cd betca-tpv-customer-support
> venv\Scripts\activate.bat
(venv) > pip install -r requirements.txt
- Importar el proyecto
betca-tpv-angular
mediante WebStorm- Open, y seleccionar la carpeta del proyecto.
- Importar los proyectos
betca-tpv-user
&betca-tpv-core
mediante IntelliJ- Import Project, y seleccionar la carpeta del proyecto.
- Marcar Create Project from external model, elegir Maven.
- Next … Finish.
- Importar el proyecto
betca-tpv-customer-support
mediante PyCharm- Open, y seleccionar la carpeta del proyecto.
- Ejecución
- Ejecución de test: se utiliza MongoDB embebido y H2 embebido
- Ejecución en local:
- BBDD. Se debe tener arrancado el motor de MongoDB:
mongodb://localhost:27017/tpv
&mongodb://localhost:27017/tpv2
, y el motor de Postgresql:spring.datasource.url=jdbc:postgresql://localhost:5432/tpv
- Spring. Ejecutar mediante linea de comando en ambos proyectos:
> mvn clean spring-boot:run
- Python. Ejecutar mediante linea de comando:
> uvicorn src.main:app --reload --port 8083
- Angular. Ejecutar mediante linea de comand:
> ng serve
, o ejecución de Angular con los back-end en Heroku:> ng serve --prod
- BBDD. Se debe tener arrancado el motor de MongoDB:
La practica consiste en ampliar de forma colaborativa una aplicación web: TPV.
NOTA. Todo el software deberá estar en ingles.
El enunciado se obtiene por sorteo entre los posibles existentes: https://github.com/miw-upm/betca-tpv/wiki.
La metodología se desarrolla en el proyecto: https://github.com/miw-upm/betca-tpv/projects/1, de forma centralizada para todos las historias.
La historia debe organizarse en tareas
mas pequeñas, cada una de ella asociada a un issue
. Asignar el Hito.
Justo antes de empezar una tarea, asignar la estimación de tiempo: puntos. Al finalizar una tarea, asignarle el tiempo
consumido y cerrarla.
Utilizar un flujo de trabajo ramificado, visto en IWVG: Ecosistema o APAW. Acordaros de incluir #? con el número del issue en los mensajes de los commits.
El primer issue
es realizar el Interfaz de Usuario en Angular, asociarlo al hito Evaluación: Interfaz de Usuario
,
con valores mock y sin atacar a los API.
Una vez finalizado, y antes de cerrarlo, se debe avisar al profesor mediante Slack, en un hilo privado,
hasta que el profesor de por correcto el UI.
El resto de la práctica se realizarán con los issues
que se consideren necesarios, se recomienda entre 5-10. A modo de ejemplo,
se propone una posible división:
- Tarea (2..5). Una tarea por cada parte del enunciado diferenciada.
- Tarea. Creación de entidades o modelos en BD.
- Tarea. Refactorizar, reoordenar, simplificar...
- Tarea. Bugs encontrados en la pruebas de aceptación.
- Planificar antes los cambios a realizar, y cuando se tiene claro, actualizar la rama issue#xx con develop justo antes de empezar. Realizar una estimación temporal y anotarlo en la tarea.
- Cuando nos sentamos a trabajar, comprobar que la rama issue#xx está actualizada respecto a develop.
- No es recomendable dejar de trabajar sin aportar a develop las mejoras, siempre sin romper develop.
- Realizar aportaciones frecuentes a la rama develop, del código estable, aunque este a medias. Ojo con los ficheros muy susceptibles de colisionar, como por ejemplo app.module.ts, app-routing.module.ts, home.component.ts..., en este caso, modificarlos y subirlos a develop con rapidez.
- Vigilar y pensar bien los comentarios de los commits, acordarse de añadir la referencia del issue: #xx.
- Cuando se termina una tarea o issue#xx, añadir el tiempo real utilizado y cerrarlo.
- Uso correcto del flujo de trabajo ramificado. Hasta -2 ptos. Los warning son avisos sin perdida de puntos.
- Adecuación de la temporalidad de desarrollo según el enunciado. Hasta -3 ptos.
- No se puede realizar un findAll y luego filtrar por código, se debe utilizar adecuadamente las queries. Las búsquedas, a cualquier nivel, resource, service, repository... siempre se coloca en el tipo devuelto. Hasta -2 ptos
- Cobertura total >= 80%, cobertura de end-points = 100% (>90% código) , cobertura de servicios = 100% (>90% código). Hasta -2 ptos
- Mantenimiento de calidad del código según Actions-CI y Sonar. Cuando IntelliJ subraya en naranja: OJO!!! puede ser
un indicio de un error cometido. Todos los aspectos vistos en teoría, y poniendo espeacial enfásis en:
- Formatear.
- Herramienta del IDE.
- Líneas en blanco.
- Ordenar métodos.
- Repasar nombres de clases, métodos, atributos, parámetros y variables.
- Sencillez del código.
- Simplificar el código.
- Eliminar comentarios.
- Estructuras anidadas: <3.
- Complejidad ciclomática: <8-12.
- Métricas.
- Paquete: <20 clases.
- Clases: <500-200 líneas, <20 métodos.
- Métodos: <3-4 parámetros, <15 líneas.
- Eliminar redundancias (copy & paste).
- Eliminar código muerto.
- Tratamiento de errores.
- Calidad de la arquitectura (GRASP, SOLID, patrones...).
- Formatear.
- Gestión adecuada, completa y equilibrada (estimación, tiempo real...) durante el desarrollo. Hasta -3 ptos.
- Uso del ingles. Hasta -1 pto.
Indicar como texto en la subida:
- Nombre de la história.
- Cuenta de github.
- Valor del nombre que aparece en los commits del autor.
- Número del último commit y fecha del mismo (dÍa-hora).
- Tiempo total estimado, tiempo total real utilizado.
Este proyecto es la práctica TPV desarrollada de forma colaborativa por todos los alumnos. Se parte de la versión
core
, ya implementada, y se pretende ampliar con un conjunto de mejoras. Un Terminal Punto de Venta es un sistema informático que gestiona el proceso de venta mediante una interfaz accesible para los vendedores o compradores. Permite la creación e impresión del recibo ticket o factura de venta —con los detalles de las referencias y precios— de los artículos vendidos, actualiza los cambios en el nivel de existencias de mercancías (STOCK) en la base de datos... Además tiene la parte de venta on-line.
<p><button mat-raised-button (click)=requestSync() >Sync </button> {{sync}}</p>
<p><button mat-raised-button (click)=requestAsync()>Async</button> {{asyn | async}}</p>
export class InputOverviewExample {
sync: string;
asyn: Observable<string>;
requestSync(): void {
this.serviceMock()
.subscribe(item => this.sync = item);
}
requestAsync(): void {
this.asyn = this.serviceMock();
}
serviceMock(): Observable<string> {
return of('Result');
}
}
export class ArticleService {
create(article: Article): Observable<Article> {
return of(article);
}
read(barcode: string): Observable<Article> {
return of({barcode: barcode, description: '...', retailPrice: 10, providerCompany: 'pro1'})
}
search(articleSearch: ArticleSearch): Observable<Article[]> {
return of([
{barcode: 123, description: '...', retailPrice: 10, providerCompany: 'pro1'},
{barcode: 345, description: '...', retailPrice: 10, providerCompany: 'pro2'},
{barcode: 678, description: '...', retailPrice: 10, providerCompany: 'pro1'}
])
}
my-comp.component.html
<p>Hello {{user}}! <input type="button" value="Ok" (click)="onClick()"></p>
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({ selector: 'app-my-comp', templateUrl: './my-comp.component.html' })
export class MyCompComponent {
@Input() user = 'By default';
@Output() pressed = new EventEmitter<string>();
onClick(){
this.pressed.emit(this.user)
}
}
Utilización:
<app-my-comp></app-my-comp>
<app-my-comp user="Value"></app-my-comp>
<app-my-comp [user]=user></app-my-comp>
<app-my-comp user="With event" (pressed)="onPressed($event)"></app-my-comp>
export class AppComponent {
user = "Variable";
onPressed(value:string){
alert(value);
}
}
<app-crud (create)="create()" (read)="read($event)" (update)="update($event)"
[data]="articles" [deleteAction]="false" [title]="title"></app-crud>
export class ArticlesComponent {
title = 'Articles management';
articles = of([]);
create(): void {
this.dialog.open(ArticleCreationUpdatingDialogComponent);
}
read(article: Article): void {
this.dialog.open(ReadDetailDialogComponent, {
data: {
title: 'Article Details',
object: this.articleService.read(article.barcode)
}
});
}
update(article: Article): void {
this.articleService.read(article.barcode)
.subscribe(fullArticle => this.dialog.open(ArticleCreationUpdatingDialogComponent, {data: fullArticle}));
}
}
-
Desinstalar node & borrado de carpetas, si procede:
- C:\Users*\AppData\Roaming\npm
- C:\Users*\AppData\Roaming\npm-cache
-
Instalar Node, todo estándar
- node --version ?
v14.15.0
- npm –version ?
6.14.8
- npm list ?muestra todas las dependencias instaladas
- npm list <dependence> ?muestra la dependencia especificada
- npm update –g
- node --version ?
-
Instalar Angular CLI
- npm install -g @angular/cli
- ng –-version ?
11.0.1
-
Crear una nueva aplicación
- ng new <app>
-
Ejecutar aplicación:
- cd <app>
- ng serve
- Navegador: http://localhost:4200/
-
Instalar express:
- npm i express ?i:install
- npm list express ?
4.17.1
- Crear el fichero
server.js
- ng build --prod
- node server.js ?arrancar sobre express
-
Instalar Material + Flex
- ng add @angular/material ?(Indigo/Pink, Yes & Yes)
- npm i @angular/flex-layout
- npm list @angular/material ?
11.0.0
- npm list @angular/flex-layout ?
11.0.0-beta.33
-
Instalar Jwt
- npm i @auth0/angular-jwt
- npm list @auth0/angular-jwt ?
5.0.1
Otros comandos
>ng serve
for a dev server. Navigate tohttp://localhost:4200/
. The app will automatically reload if you change any of the source files.>ng build
to build the project. The build artifacts will be stored in thedist/
directory. Use the--prod
flag for a production build.>ng test
to execute the unit tests via Karma.>ng e2e
to execute the end-to-end tests via Protractor.>ng help
or go check out the Angular CLI Overview and Command Reference page.
{
"name": "betca-tpv-angular",
"version": "4.1.0-SNAPSHOT",
}
~: versión mas cercana posible, ^: versión compatible mas alta
En el fichero tsconfig
, habilitar las opciones de compilación siguientes, esto nos permite importar valores de los ficheros *.json.
{
"compilerOptions": {
"resolveJsonModule": true
}
}
enviroments.ts
import {name, version} from '../../package.json';
export const environment = {
production: false,
NAME: name,
VERSION: version,
REST_USER: 'http://localhost:8081',
REST_CORE: 'http://localhost:8082'
};
enviroments.prod.ts
import {name, version} from '../../package.json';
export const environment = {
production: true,
NAME: name,
VERSION: version,
REST_USER: 'https://betca-tpv-user.herokuapp.com',
REST_CORE: 'https://betca-tpv-core.herokuapp.com'
En el fichero tsconfig
, habilitar las opciones de compilación:
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"@env": ["environments/environment"],
"@shared/*": ["app/shared/*"],
"@core/*": ["app/core/*"]
}
}
}
{
"scripts": {
"heroku-postbuild": "ng build --prod",
"build-prod": "ng build --prod",
"start": "node server.js"
}
}
Se establecen los workflows en la carpeta: .github/workflows/*.yml
Conexión con Sonarcloud:
-
Se debe crear el proyecto en sonarcloud:
Administration/Projects Management
, botónCreate Project
. -
Configurar la rama por defecto, renombrar
master
si esta no es la rama por defecto:Administración/Branches and Pull Requests
. Renombrar laslong living branch: (master|develop|release-).*
-
Se deben establecer la contraseña:
secrets.SONAR_TOKEN
en en proyecto de GitHub,settings/Secrets
ParaSonarcloud
, se debe crear el fichero:sonar-project.properties
.
Conexión con Heroku:
- Crear la aplicación en Heroku.
- Se deben establecer la contraseña:
secrets.HEROKU_API_KEY
en en proyecto de GitHub. - Deben existir los scripts para construcción y arranque con
express
:
{
"scripts": {
"heroku-postbuild": "ng build --prod",
"start": "node server.js"
}
}
Spring mediante Arquitectura por Capas
Spring mediante Arquitectura Hexagonal
Python mediante Arquitectura Seudo-Hexagonal