diff --git a/docs/.gitignore b/docs/.gitignore index 8e5e8ed..845643d 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,3 +2,7 @@ .gem Gemfile.lock .ruby-version +.asciidoctor +node_modules +package-lock.json +mermaid.html diff --git a/docs/Gemfile b/docs/Gemfile index 1532e5d..5899a1d 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,3 +1,4 @@ source 'https://rubygems.org' gem 'asciidoctor-revealjs' +gem 'asciidoctor-diagram' diff --git a/docs/images/2024.1.0.openapi.png b/docs/images/2024.1.0.openapi.png new file mode 100644 index 0000000..4617ffd Binary files /dev/null and b/docs/images/2024.1.0.openapi.png differ diff --git a/docs/images/2024.1.1.openapi.png b/docs/images/2024.1.1.openapi.png new file mode 100644 index 0000000..2ffe5a2 Binary files /dev/null and b/docs/images/2024.1.1.openapi.png differ diff --git a/docs/images/20240105_matamata_qr.jpg b/docs/images/20240105_matamata_qr.jpg new file mode 100644 index 0000000..b3c1436 Binary files /dev/null and b/docs/images/20240105_matamata_qr.jpg differ diff --git a/docs/images/ADR.png b/docs/images/ADR.png new file mode 100644 index 0000000..98bf1ea Binary files /dev/null and b/docs/images/ADR.png differ diff --git a/docs/images/ADR2.png b/docs/images/ADR2.png new file mode 100644 index 0000000..6bd17f4 Binary files /dev/null and b/docs/images/ADR2.png differ diff --git a/docs/images/ADR3.png b/docs/images/ADR3.png new file mode 100644 index 0000000..138f87d Binary files /dev/null and b/docs/images/ADR3.png differ diff --git a/docs/images/ADR4.png b/docs/images/ADR4.png new file mode 100644 index 0000000..dbe8c4e Binary files /dev/null and b/docs/images/ADR4.png differ diff --git a/docs/images/ADR5.png b/docs/images/ADR5.png new file mode 100644 index 0000000..6c4f3c0 Binary files /dev/null and b/docs/images/ADR5.png differ diff --git a/docs/images/ADR6.png b/docs/images/ADR6.png new file mode 100644 index 0000000..3fabe9d Binary files /dev/null and b/docs/images/ADR6.png differ diff --git a/docs/images/ADR7.png b/docs/images/ADR7.png new file mode 100644 index 0000000..031fd42 Binary files /dev/null and b/docs/images/ADR7.png differ diff --git a/docs/images/ADR8.png b/docs/images/ADR8.png new file mode 100644 index 0000000..21f5dc5 Binary files /dev/null and b/docs/images/ADR8.png differ diff --git a/docs/images/mermaid-ciclo-vida-partida.svg b/docs/images/mermaid-ciclo-vida-partida.svg new file mode 100644 index 0000000..92a9326 --- /dev/null +++ b/docs/images/mermaid-ciclo-vida-partida.svg @@ -0,0 +1 @@ +
uma ou duas vezes
Cria Partida
Registra Competidor(es)
Inicia Partida
Define Vencedor (e Perdedor) da Partida
Ajusta Partida Seguinte
\ No newline at end of file diff --git a/docs/images/mermaid-ciclo-vida-torneio.svg b/docs/images/mermaid-ciclo-vida-torneio.svg new file mode 100644 index 0000000..955c6a7 --- /dev/null +++ b/docs/images/mermaid-ciclo-vida-torneio.svg @@ -0,0 +1 @@ +
uma ou mais vezes
uma ou mais vezes
Cria Torneio
Registra Competidor(es)
Cria Rodadas e Partidas
Define Vencedor (e Perdedor) da Partida
Define Vencedor do Torneio
\ No newline at end of file diff --git a/docs/images/mermaid-db.svg b/docs/images/mermaid-db.svg new file mode 100644 index 0000000..b89ecb9 --- /dev/null +++ b/docs/images/mermaid-db.svg @@ -0,0 +1 @@ +CompetitorintidPKuuiduuidUKtimestampcreatedtimestampupdatedstringlabelTournamentintidPKuuiduuidUKtimestampcreatedtimestampupdatedstringlabeltimestampmatchesCreationintcompetitorsintstartingRoundMatchintidPKuuiduuidUKtimestampcreatedtimestampupdatedinttournamentFKintroundintpositionintcompetitorAFKintcompetitorBFKtimestampresultRegistrationintwinnerFKintloserFKTournamentCompetitorinttournamentPK,FKintcompetitorPK,FKtimestampcreatedtimestampupdatedintnextMatchFKéregistrapossui \ No newline at end of file diff --git a/docs/images/mermaid-er.svg b/docs/images/mermaid-er.svg new file mode 100644 index 0000000..2eeb6ed --- /dev/null +++ b/docs/images/mermaid-er.svg @@ -0,0 +1 @@ +COMPETIDORTORNEIOPARTIDAcompete emé vencedor depossuipossui uma de finalpossui uma de terceiro lugarcompete emé o vencedor deé o vencedor deprecede \ No newline at end of file diff --git a/docs/images/mermaid-racional.svg b/docs/images/mermaid-racional.svg new file mode 100644 index 0000000..b3e78d0 --- /dev/null +++ b/docs/images/mermaid-racional.svg @@ -0,0 +1 @@ +
Documentação
Implementação com Testes
\ No newline at end of file diff --git a/docs/mermaid.adoc b/docs/mermaid.adoc new file mode 100644 index 0000000..284443f --- /dev/null +++ b/docs/mermaid.adoc @@ -0,0 +1,123 @@ +:mmdc: node_modules/.bin/mmdc +:imagesdir: images + + +[mermaid, "mermaid-racional", "svg"] +.... +stateDiagram-v2 +direction LR + state "Documentação" as doc + state "Implementação com Testes" as implement + [*] --> doc + doc --> implement + implement --> doc + implement --> [*] +.... + + +[mermaid, "mermaid-ciclo-vida-partida", "svg"] +.... +stateDiagram-v2 +direction LR + state "Cria Partida" as cria + state "Registra Competidor(es)" as competidores + state "Inicia Partida" as inicia + state "Define Vencedor (e Perdedor) da Partida" as resultado + state "Ajusta Partida Seguinte" as ajusta + + [*] --> cria + cria --> competidores + competidores --> competidores: uma ou duas vezes + competidores --> inicia + inicia --> resultado + resultado --> ajusta + resultado --> [*] + ajusta --> [*] +.... + + +[mermaid, "mermaid-ciclo-vida-torneio", "svg"] +.... +stateDiagram-v2 +direction LR + state "Cria Torneio" as cria + state "Registra Competidor(es)" as registra + state "Cria Rodadas e Partidas" as rodadas + state "Define Vencedor (e Perdedor) da Partida" as partidas + state "Define Vencedor do Torneio" as vencedor + + [*] --> cria + cria --> registra + registra --> registra: uma ou mais vezes + registra --> rodadas + rodadas --> partidas + partidas --> partidas: uma ou mais vezes + partidas --> vencedor + vencedor --> [*] +.... + + +[mermaid, "mermaid-er", "svg"] +.... +erDiagram + COMPETIDOR one or more -- zero or more TORNEIO : "compete em" + COMPETIDOR only one -- zero or more TORNEIO : "é vencedor de" + TORNEIO only one -- one or more PARTIDA : possui + TORNEIO only one -- only one PARTIDA : "possui uma de final" + TORNEIO only one -- zero or one PARTIDA : "possui uma de terceiro lugar" + COMPETIDOR one or more -- zero or more PARTIDA : "compete em" + COMPETIDOR only one -- zero or more PARTIDA : "é o vencedor de" + COMPETIDOR zero or one -- zero or more PARTIDA : "é o vencedor de" + PARTIDA zero or more -- zero or more PARTIDA : precede +.... + + +[mermaid, "mermaid-db", "svg"] +.... +erDiagram + Competitor { + int id PK + uuid uuid UK + timestamp created + timestamp updated + string label + } + + Tournament { + int id PK + uuid uuid UK + timestamp created + timestamp updated + string label + timestamp matchesCreation + int competitors + int startingRound + } + + Match { + int id PK + uuid uuid UK + timestamp created + timestamp updated + int tournament FK + int round + int position + int competitorA FK + int competitorB FK + timestamp resultRegistration + int winner FK + int loser FK + } + + TournamentCompetitor { + int tournament PK, FK + int competitor PK, FK + timestamp created + timestamp updated + int nextMatch FK + } + + Competitor only one -- zero or more TournamentCompetitor : "é" + Tournament only one -- one or more TournamentCompetitor : registra + Tournament only one -- one or more Match : possui +.... diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000..a42e674 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,7 @@ +{ + "name": "sobre-matamata", + "version": "2024.1.0", + "dependencies": { + "@mermaid-js/mermaid-cli": "~10.6.1" + } +} \ No newline at end of file diff --git a/docs/presentation-adr.adoc b/docs/presentation-adr.adoc new file mode 100644 index 0000000..63bc142 --- /dev/null +++ b/docs/presentation-adr.adoc @@ -0,0 +1,17 @@ +== Architecture Decision Record + +image:ADR.png[exemplo de ADR através do ADR 1 do projeto,width=800] + +=== ADR +[%step] +image:ADR2.png[título e data do ADR2,width=800] +[%step] +image:ADR3.png[título e data do ADR3,width=800] +[%step] +image:ADR4.png[título e data do ADR4,width=800] + +=== ADR +[%step] +image:ADR5.png[título e data do ADR5,width=800] +[%step] +image:ADR6.png[título e data do ADR6,width=800] diff --git a/docs/presentation-api.adoc b/docs/presentation-api.adoc new file mode 100644 index 0000000..9992c35 --- /dev/null +++ b/docs/presentation-api.adoc @@ -0,0 +1,547 @@ +== API e Endpoints + +Dividido em + +- Escrita +- Leitura + +=== API e Endpoints de Escrita + +[frame=none,cols="h,m"] +|=== +| +|Proposta inicial + +a|[.small]#Cadastro de novos torneios# +|POST /tournament + +a|[.small]#Cadastro dos competidores# +|POST /tournament//competitor + +a|[.small]#Cadastro de resultado de partida# +|POST /tournament//match/ +|=== + + +=== API e Endpoints de Leitura + +[frame=none,cols="h,m"] +|=== +| +|Proposta inicial + +a|[.small]#Listagem de partidas# +|GET /tournament//match + +a|[.small]#Exibição do TOP 4# +|GET /tournament//result +|=== + + +=== API e Endpoints de Escrita (modificado) + +[frame=none,cols=".^h,m,m"] +|=== +| +|Proposta inicial +|Proposta final + +a|[.small]#Cadastro de novos competidores# +| +|POST /competitor + +a|[.small]#Cadastro de novos torneios# +|POST /tournament +|POST /tournament + +a|[.small]#Cadastro dos competidores# +|POST /tournament//competitor +|POST /tournament//competitor +|=== + + +=== API e Endpoints de Escrita (modificado) + +[frame=none,cols=".^h,m,m"] +|=== +| +|Proposta inicial +|Proposta final + +a|[.small]#Início do torneio# +| +|POST /tournament//start + +a|[.small]#Cadastro de resultado de partida# +|POST /tournament//match/ +|POST /match/ +|=== + + +=== API e Endpoints de Leitura (modificado) + +[frame=none,cols=".^h,m,m"] +|=== +| +|Proposta inicial +|Proposta final + +a|[.small]#Listagem de partidas# +|GET /tournament//match +|GET /tournament//match + +a|[.small]#Exibição do TOP 4# +|GET /tournament//result +|GET /tournament//result +|=== + + +=== `POST /competitor` + +Status code: 201 Created + +[frame=none,cols="m,m"] +|=== +|Payload +|Response + +a| +[source,json] +---- +{ + "label": "South Korea" +} +---- +a| +[source,json] +---- +{ + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" +} +---- +|=== + + +=== `POST /tournament` + +Status code: 201 Created + +[frame=none,cols="m,m"] +|=== +|Payload +|Response + +a| +[source,json] +---- +{ + "label": "2002 FIFA World Cup" +} +---- +a| +[source,json] +---- +{ + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup" +} +---- +|=== + + +=== `POST /tournament//competitor` + +Status code: 201 Created + +[frame=none,cols="m,m"] +|=== +|Payload +|Response + +a| +[source,json] +---- +{ + "competitor_uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9" +} +---- +a| +[source,json] +---- +{ + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup" + }, + "competitor": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + } +} +---- +|=== + +=== `POST /tournament//competitor` + +Falhas + +[frame=none,cols="m,d"] +|=== +|`404 Not Found` +|Competidor inexistente + +|`404 Not Found` +|Torneio inexistente + +|`409 Conflict` +|Competidor já registrado no torneio + +|`409 Conflict` +|Torneio já iniciado não permitindo novos registros +|=== + + +=== `POST /tournament//start` + +Status code: 201 Created + +Payload: N/A + +=== `POST /tournament//start` + +Response + +[source,json] +---- +{ + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "startingRound": 1, + "numberCompetitors": 4 + }, + "competitors": [ + { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + }, + { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil" + }, + { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + } + ], + "matches": [ + { + "uuid": "1e172084-ec76-4f56-bd8e-7b3c170e1221", + "round": 1, + "position": 0, + "competitorA": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + "competitorB": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + }, + "winner": null, + "loser": null + }, + { + "uuid": "3866cad6-ba40-44fb-96c6-09f1131c5649", + "round": 1, + "position": 1, + "competitorA": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil" + }, + "competitorB": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + }, + "winner": null, + "loser": null + }, + { + "uuid": "1f1fc156-4382-427c-aefb-5ae10009b7ce", + "round": 0, + "position": 0, + "competitorA": null, + "competitorB": null, + "winner": null, + "loser": null + }, + { + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "round": 0, + "position": 1, + "competitorA": null, + "competitorB": null, + "winner": null, + "loser": null + } + ] +} +---- + +=== `POST /tournament//start` + +Falhas + +[frame=none,cols="m,d"] +|=== +|`404 Not Found` +|Torneio inexistente + +|`422 Unprocessable Content` +|Torneio não possui um competidor registrado + +|`409 Conflict` +|Torneio já criou suas partidas +|=== + + +=== `POST /match/` + +Status code: 200 OK + +Payload: +[source,json] +---- +{ + "winner_uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e" +} +---- + + +=== `POST /match/` + +Response + +[source,json] +---- +{ + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "startingRound": 1, + "numberCompetitors": 4 + }, + "round": 0, + "position": 0, + "competitorA": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + "competitorB": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil" + }, + "winner": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil" + }, + "loser": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + } +} +---- + +=== `POST /match/` + +Falhas + +[frame=none,cols="m,d"] +|=== +|`404 Not Found` +|Partida inexistente + +|`409 Conflict` +|Partida já registrou seu resultado + +|`422 Unprocessable Content` +|Partida não está pronta para registrar seu resultado devido a partidas anteriores com competidor faltante +|=== + + +=== `GET /tournament//match` + +Status code: 200 OK + +Payload: N/A + + +=== `GET /tournament//match` +Response +[source,json] +---- +{ + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "startingRound": 1, + "numberCompetitors": 4 + }, + "past": [ + { + "uuid": "1e172084-ec76-4f56-bd8e-7b3c170e1221", + "round": 1, + "position": 0, + "competitorA": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + "competitorB": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + }, + "winner": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + "loser": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + } + }, + { + "uuid": "3866cad6-ba40-44fb-96c6-09f1131c5649", + "round": 1, + "position": 1, + "competitorA": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil" + }, + "competitorB": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + }, + "winner": { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil" + }, + "loser": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + } + }, + { + "uuid": "a9367a16-3f64-408b-9596-4029f7f60e62", + "round": 0, + "position": 1, + "competitorA": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + }, + "competitorB": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + }, + "winner": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + }, + "loser": { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + } + } + ], + "upcoming": [ + { + "uuid": "1f1fc156-4382-427c-aefb-5ae10009b7ce", + "round": 0, + "position": 0, + "competitorA": { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + "competitorB": { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Brazil" + }, + "winner": null, + "loser": null + } + ] +} +---- + +=== `GET /tournament//match` + +Falhas + +[frame=none,cols="m,d"] +|=== +|`404 Not Found` +|Torneio inexistente + +|`422 Unprocessable Content` +|Torneio ainda não criou suas partidas +|=== + + +=== `GET /tournament//result` + +Status code: 200 OK + +Payload: N/A + + +=== `GET /tournament//result` +Response +[source,json] +---- +{ + "tournament": { + "uuid": "03c964f8-7f5c-4224-b848-1ab6c1413c7d", + "label": "2002 FIFA World Cup", + "startingRound": 1, + "numberCompetitors": 4 + }, + "top4": [ + { + "uuid": "7f026276-0904-4a7b-ae14-8c66b95ffc9e", + "label": "Brazil" + }, + { + "uuid": "de686e37-804b-4815-a507-d5879a240af6", + "label": "Germany" + }, + { + "uuid": "15f4fe33-f317-4c4a-96e0-3b815dc481c6", + "label": "Turkey" + }, + { + "uuid": "5d1bd1d1-2679-432a-ac11-ebfebfa1bce9", + "label": "South Korea" + } + ] +} +---- + +=== `GET /tournament//result` + +Falhas + +[frame=none,cols="m,d"] +|=== +|`404 Not Found` +|Torneio inexistente + +|`422 Unprocessable Content` +|Torneio ainda não criou suas partidas + +|`422 Unprocessable Content` +|Torneio ainda não está pronto para exibir seus Top 4 competidores +|=== diff --git a/docs/presentation-dados.adoc b/docs/presentation-dados.adoc new file mode 100644 index 0000000..f78e531 --- /dev/null +++ b/docs/presentation-dados.adoc @@ -0,0 +1,45 @@ +== Diagrama Entidade Relacionamento + +image:mermaid-er.svg[diagrama entidade relacionamento,width=640] + +=== Tabelas do Banco de Dados Relacional + +image:mermaid-db.svg[diagrama entidade relacionamento do banco relacional,width=600] + +=== Campos de identificação + +`id`:: Inteiro para indexação das instâncias +`uuid`:: Campo UUID para exposição externa da instância +`label`:: Representação textual da instância + +=== Carimbo de tempo + +`created`:: Criação da instância +`updated`:: Última atualização da instância +`Tournament.matchesCreation`:: Criação das partidas do torneio +`Matches.resultRegistration`:: Registro do resultado de partida + + +=== Dados de Torneio + +`competitors`:: Inteiro positivo representando quantidade de competidores durante o início do torneio +`startingRound`:: Inteiro não-negativo representando a rodada de início do torneio + + +=== Dados de Partida + +`round`:: Inteiro não-negativo representando quantidade de rodadas até a partida final +`position`:: Inteiro não-negativo representando a posição da partida na rodada do torneio + + +=== Dados de Partida + +`competitorA`:: Referência para um competidor, aqui chamado de Competidor A +`competitorB`:: Referência para um competidor, aqui chamado de Competidor B +`winner`:: Referência para o vencedor +`loser`:: Referência para o perdedor + + +=== Dados de Torneio e Competidor + +`nextMatch`:: Referência a próxima partida do competidor no torneio diff --git a/docs/presentation-documentacao.adoc b/docs/presentation-documentacao.adoc new file mode 100644 index 0000000..252fbdc --- /dev/null +++ b/docs/presentation-documentacao.adoc @@ -0,0 +1,7 @@ +== Documentação + +1. Método de Documentação +2. Linguagem Ubíqua +3. Regras Estabelecidas +4. Mapeamento de Dados +5. API e Endpoints diff --git a/docs/presentation-eu.adoc b/docs/presentation-eu.adoc new file mode 100644 index 0000000..fea8d2b --- /dev/null +++ b/docs/presentation-eu.adoc @@ -0,0 +1,15 @@ +== Alexandre Harano +:icons: font +:icon-set: fab + +[cols=">h,= 1 AND startingRound >= 0)` + + +=== Modelo SQLAlchemy `TournamentCompetitor` + +* UNIQUE Constraint +** `tournament_id, competitor_id` + + +=== Modelo SQLAlchemy `Match` + +* UNIQUE Constraint +** `tournament_id, round, position` +* CHECK Constraint +** `round >= 0` +** `position >= 0` +** `(round == 0 AND position < 2) OR (round > 0 AND position < pow(2, round))` + + +=== Modelo SQLAlchemy `Match` + +* CHECK Constraint +** `(competitorA_id IS NULL AND competitorB_id IS NULL) OR (competitorA_id <> competitorB_id)` +** `(resultRegistration IS NULL AND winner_id is NULL) OR (resultRegistration IS NOT NULL AND winner_id IS NOT NULL)` +** `(resultRegistration IS NULL AND loser_id is NULL) OR (resultRegistration IS NOT NULL AND loser_id is NULL) OR (resultRegistration IS NOT NULL AND loser_id IS NOT NULL)` + + +=== Modelos pydantic de Payload + +* `CompetitorPayloadSchema` (`label`) +* `TournamentPayloadSchema` (`label`) +* `TournamentCompetitorPayloadSchema` (`competitor_uuid`) +* `WinnerPayloadSchema` (`winner_uuid`) + + +=== Modelos pydantic de Response + +* `CompetitorSchema` (`label` e `uuid`) +* `TournamentSchema` (`label` e `uuid`) +* `TournamentCompetitorSchema` (`tournament` e `competitor`) +* `TournamentStartSchema` (`tournament`, `competitor` e `matches`) +* `TournamentMatchesSchema` (`tournament`, `past` e `upcoming`) +* `TournamentResultSchema` (`tournament` e `top4`) +* `MatchSchema` (`uuid`, `tournament`, `round`, `position`, `competitorA`, `competitorB`, `winner` e `loser`) + + +=== Serviços + +* `start_tournament` +* `register_match_result` + +=== Parâmetros do Torneio + +Exceto para o caso de um único competidor, + +seja stem:[C] o número de competitores registrados, + +seja stem:[R] o número da rodada inicial, e + +seja stem:[M] o número de partidas de entrada. + +Temos que + +- stem:[R = \lfloor\log_{2}(C-1)\rfloor] +- stem:[M = 2^{R}] + +=== `start_tournament` +[%step] +* Calcula parâmetros do torneio (competidores, rodada de entrada, quantidade de partidas de entrada) +* Prepara dados de partida como lista de dicionários +* Prepara sequência aleatória de competidores +* Aloca competidores nas partidas de entrada +* Calcula as partidas automaticamente ganhas e ajusta as seguintes +* Insere partidas em lote no banco de dados +* Ajusta as referências de próximas partidas + +=== `register_match_result` +[%step] +* Valida a partida para registrar o resultado +* Ajusta as próximas partidas +[%step] +** Atualiza os dados de próxima partida do vencedor +** Atualiza os dados de próxima partida do perdedor + +=== OpenAPI +image:2024.1.0.openapi.png[OpenAPI para versão de referência] + +=== pytest-cov + +``` +Name Stmts Miss Cover +------------------------------------------------------------------ +src/matamata/__init__.py 1 0 100% +src/matamata/database.py 7 2 71% +src/matamata/main.py 7 0 100% +src/matamata/models/__init__.py 5 0 100% +src/matamata/models/base.py 14 0 100% +src/matamata/models/competitor.py 13 0 100% +src/matamata/models/constants.py 10 0 100% +src/matamata/models/exceptions.py 4 0 100% +src/matamata/models/match.py 25 0 100% +src/matamata/models/tournament.py 29 0 100% +src/matamata/models/tournament_competitor.py 14 0 100% +src/matamata/routers/__init__.py 0 0 100% +src/matamata/routers/competitor.py 13 0 100% +src/matamata/routers/match.py 70 0 100% +src/matamata/routers/tournament.py 83 0 100% +src/matamata/schemas.py 62 2 97% +src/matamata/services.py 81 2 98% +src/matamata/settings.py 5 0 100% +------------------------------------------------------------------ +TOTAL 443 6 99% +``` diff --git a/docs/presentation-intro.adoc b/docs/presentation-intro.adoc new file mode 100644 index 0000000..e27353e --- /dev/null +++ b/docs/presentation-intro.adoc @@ -0,0 +1,24 @@ +== Enunciado + +* Pequeno sistema e API HTTP +* Sistema de torneio por chaves eliminatórias + +=== Regras +* Pareamento inicial +* Cada rodada +* Rodada final + +=== Pareamento inicial + +* Competidores divididos em duplas de forma aleatória +* Caso não pareie todos os competidores, alguns passam automaticamente para a segunda rodada + +=== Cada rodada + +* Competem entre si +* Vencedores para a próxima rodada e competem contra outros vencedores + +=== Rodada final + +* Vencedores da penúltima rodada: partida final com vencedor do torneio e segundo lugar +* Perdedores da penúltima rodada: partida de terceira lugar com terceiro e o quarto lugar diff --git a/docs/presentation-linguagem.adoc b/docs/presentation-linguagem.adoc new file mode 100644 index 0000000..1430545 --- /dev/null +++ b/docs/presentation-linguagem.adoc @@ -0,0 +1,35 @@ +== Linguagem Ubíqua + +Competidor (_Competitor_):: Um sujeito (indivíduo, time, etc.) que compete em zero ou mais torneios +Torneio (_Tournament_):: Usado ubiquamente como representação de torneio de eliminação única +Partida (_Match_):: Confronto de dois competidores, com um resultado de um vencedor e um perdedor. É possível casos em que possua somente um competidor e por padrão tal competidor é o vencedor + +=== Linguagem Ubíqua + +Usuário (_User_):: Um cliente que interage com o sistema de gerenciamento usando ciclos requisição-resposta de API REST + +== Regras Estabelecidas + +Foram definidas 14 regras sendo as mais importantes: + +* Um torneio deve ter ao menos um competidor para a criação de suas partidas +* O sistema é responsável pela geração aleatória inicial das partidas e das rodadas seguindo as regras +* Uma partida deve ser criada com um competidor ou duas partidas anteriores + +=== Ressalvas + +Tão importante quanto as regras são as ressalvas + +* Um competidor não pode desistir do torneio +* Não registraremos a pontuação da partida, somente o vencedor e o perdedor +* O sistema não permite empate entre os competidores + + +=== Ciclo de Vida da Partida + +image:mermaid-ciclo-vida-partida.svg[ciclo de vida da partida] + + +=== Ciclo de Vida do Torneio + +image:mermaid-ciclo-vida-torneio.svg[ciclo de vida do torneio] diff --git a/docs/presentation-melhorias.adoc b/docs/presentation-melhorias.adoc new file mode 100644 index 0000000..5963c20 --- /dev/null +++ b/docs/presentation-melhorias.adoc @@ -0,0 +1,88 @@ +== Melhorias Feitas + +* Refatoração para melhorar legibilidade + +=== Melhorias Feitas + +* Endpoints para melhorar usabilidade + +image:ADR7.png[título e data do ADR7,width=900] + +=== Endpoints para melhorar usabilidade + +[frame=none,cols="h,m"] +|=== +| +|Endpoint + +a|[.small]#Listagem de competidores# +|GET /competitor + +a|[.small]#Detalhe de competidor com torneios passados, em andamento e futuros# +|GET /competitor/ + +a|[.small]#Detalhe de partida# +|GET /match/ +|=== + +=== Endpoints para melhorar usabilidade + +[frame=none,cols="h,m"] +|=== +| +|Endpoint + +a|[.small]#Listagem de torneios# +|GET /tournament + +a|[.small]#Listagem de competidores em um torneio# +|GET /tournament//competitor + +a|[.small]#Listagem de todas as partidas de um competidor em um torneio dividido em passadas e futuras# +|GET /competitor/ +|=== + + +=== OpenAPI após Melhorias Feitas +image:2024.1.1.openapi.png[OpenAPI para versão com melhorias,width=800] + + +=== Melhorias Feitas + +* Mudança de SQLite para PostgreSQL para melhorar escalabilidade + +image:ADR8.png[título e data do ADR8,width=900] + +=== Melhorias Feitas + +* Substituição de venv local para o uso de Docker Compose com compartilhamento de arquivos locais + +=== pytest-cov após Melhorias Feitas + +``` + Name Stmts Miss Cover + -------------------------------------------------------------------- + src/matamata/__init__.py 1 0 100% + src/matamata/database.py 7 2 71% + src/matamata/main.py 7 0 100% + src/matamata/models/__init__.py 5 0 100% + src/matamata/models/base.py 14 0 100% + src/matamata/models/competitor.py 16 0 100% + src/matamata/models/constants.py 10 0 100% + src/matamata/models/exceptions.py 4 0 100% + src/matamata/models/match.py 25 0 100% + src/matamata/models/tournament.py 31 0 100% + src/matamata/models/tournament_competitor.py 15 0 100% + src/matamata/routers/__init__.py 0 0 100% + src/matamata/routers/competitor.py 34 0 100% + src/matamata/routers/match.py 32 0 100% + src/matamata/routers/tournament.py 124 0 100% + src/matamata/schemas.py 94 2 98% + src/matamata/services/__init__.py 2 0 100% + src/matamata/services/exceptions.py 10 0 100% + src/matamata/services/register_match_result.py 86 0 100% + src/matamata/services/start_tournament.py 93 2 98% + src/matamata/settings.py 5 0 100% + -------------------------------------------------------------------- + TOTAL 615 6 99% +``` diff --git a/docs/presentation-racional.adoc b/docs/presentation-racional.adoc new file mode 100644 index 0000000..af21fc8 --- /dev/null +++ b/docs/presentation-racional.adoc @@ -0,0 +1,8 @@ +== Racional do Desenvolvimento + +image:mermaid-racional.svg[máquina de estados do racional] + +=== Versão de Referência + +image:20240105_matamata_qr.jpg[versão específica de matamata,width=480] + +[.decent]#`https://bit.ly/20240105_matamata[bit.ly/20240105_matamata]`# diff --git a/docs/presentation.adoc b/docs/presentation.adoc new file mode 100644 index 0000000..bf6eed1 --- /dev/null +++ b/docs/presentation.adoc @@ -0,0 +1,43 @@ += Sobre _matamata_ +:author: Alexandre Harano @ayharano +:date: 2024-01-16 +:revealjs_theme: solarized +:revealjs_autoSlide: 5000 +:revealjs_history: true +:revealjs_fragmentInURL: true +:revealjs_viewDistance: 5 +:revealjs_width: 1408 +:revealjs_height: 792 +:revealjs_controls: true +:revealjs_controlsLayout: edges +:revealjs_controlsTutorial: true +:revealjs_slideNumber: c/t +:revealjs_showSlideNumber: speaker +:revealjs_autoPlayMedia: true +:revealjs_defaultTiming: 42 +:imagesdir: images +:source-highlighter: highlight.js +:highlightjs-languages: json, python +:highlightjs-main-theme: solarized-dark +:stem: + + +include::presentation-intro.adoc[] + +include::presentation-racional.adoc[] + +include::presentation-documentacao.adoc[] + +include::presentation-adr.adoc[] + +include::presentation-linguagem.adoc[] + +include::presentation-dados.adoc[] + +include::presentation-api.adoc[] + +include::presentation-implementacao.adoc[] + +include::presentation-melhorias.adoc[] + +include::presentation-eu.adoc[]