Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ doc/api/
*.js_
*.js.deps
*.js.map


**/backend/ven/
backend/ven/

**/backend/venv/
backend/venv/

backend/pgdata/
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# startata
A arte de atar
# :spiral_notepad: Startata: A Arte de atar

Aplicação idealizada para a elaboração de [Atas](https://pt.wikipedia.org/wiki/Ata_de_reuni%C3%A3o), mais especificamente atas diárias que realizamos na Skwiz Labs.


## Funcionalidades - FrontEnd

:black_square_button: fazer login <br />
:black_square_button: criar uma nova ata <br />
:black_square_button: inserir/editar um report de um usuário <br />
:black_square_button: salvar a ata <br />
:black_square_button: converter para um documento (.pdf) <br />
:black_square_button: enviar a ata para um e-mail listado <br />
<br />
<br />
:black_square_button: fazer download da ata em pdf <br />
<br />

done :white_check_mark: todo :black_square_button:

## Features

*** V1 ***
- Confirmação de email para iniciar a ata
- Lista com todos os usuário em ordem alfabética e separados por time
- Ao chegar no ultimo usuário,
- Quem fez a ata também deve aparecer no template da Ata
*** V2 ***
- Se ao final da ata, não estão registrados todos os usuário o software deve agendar o envio da ata e enviar um email para os usuários que não estão presentes dando a possibilidade de adicionar seu registro a ata até o tempo agendado
- No final da ata, o usuário deve informar para qual email a ata deve ser enviada
- Botãozinho de download

## Telas

![Wireframe](imgs/Startata.png)
102 changes: 102 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Startata Backend API

Web API in Python using FastAPI.

## Overview

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.

## Features

:black_square_button: fazer login com e-mail e senha <br />
:black_square_button: listar todos os usuários <br />
:black_square_button: inserir vários reports a vários usuários de uma vez <br />
:black_square_button: gerar um arquivo com a ata (.pdf) <br />
:black_square_button: realizar o download desse arquivo <br />
:black_square_button: listar receivers e-mails <br />
:black_square_button: enviar um arquivo a um e-mail específico <br />
<br />

:black_square_button: adicionar um receiver e-mail <br />
:black_square_button: obter reports de um usuário em uma data em específico <br />
:black_square_button: inserir um report a um usuário em específico <br />
:black_square_button: editar report passado de um usuário <br />
<br />
done :white_check_mark: todo :black_square_button:
## Preconditions:

- Python 3.8+

## Clone the project

```
git clone <link>
```

## Run local


### Install VirtualEnv

```
virtualenv -p python3 venv
```
### Active VirtualEnv

```
. venv/bin/activate
```
### Install dependencies

```
pip install -r requirements.txt
```

### Run server

```
uvicorn src.server:app --port 8080 --reload --reload-dir=src
```

## Run with docker

### Run server

```
docker-compose up -d --build
```

## API documentation (provided by Swagger UI)

```
http://127.0.0.1:8080/docs
```

### Run server

```
docker-compose exec db psql --username=fastapi --dbname=fastapi_dev
```


## Project structure

Files related to application are in the ``app`` or ``tests`` directories.
Application parts are:


app
├── api - web related stuff.
│ ├── dependencies - dependencies for routes definition.
│ ├── errors - definition of error handlers.
│ └── routes - web routes.
├── core - application configuration, startup events, logging.
├── db - db related stuff.
│ ├── migrations - manually written alembic migrations.
│ └── repositories - all crud stuff.
├── models - pydantic models for this application.
│ ├── domain - main models that are used almost everywhere.
│ └── schemas - schemas for using in web routes.
├── resources - strings that are used in web responses.
├── services - logic that is not just crud related.
└── main.py - FastAPI application creation and configuration.
Binary file added backend/database.db
Binary file not shown.
9 changes: 9 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
anyio==3.4.0
fastapi==0.70.1
greenlet==1.1.2
idna==3.3
pydantic==1.8.2
sniffio==1.2.0
SQLAlchemy==1.4.29
starlette==0.16.0
typing_extensions==4.0.1
Binary file added backend/src/__pycache__/server.cpython-38.pyc
Binary file not shown.
Binary file not shown.
25 changes: 25 additions & 0 deletions backend/src/infra/sqlalchemy/config/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./database.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"

engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()


def criar_bd():
Base.metadata.create_all(bind=engine)


def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Binary file not shown.
62 changes: 62 additions & 0 deletions backend/src/infra/sqlalchemy/models/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'''
from enum import auto
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from src.infra.sqlalchemy.config.database import Base


class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String)
email = Column(String)
photo_url = Column(String)
teams = relationship('Team', back_populates='person')


class Team(Base):
__tablename__ = 'team'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
index = Column(Integer)
label = Column(String)
person_id = Column(Integer, ForeignKey('person.id', name='fk_person'))

person = relationship('Person', back_populates='teams')

'''

from enum import auto
from sqlalchemy import Column, Integer, String, ForeignKey, Table
from sqlalchemy.orm import backref, relationship
from src.infra.sqlalchemy.config.database import Base

associate_table = Table('association', Base.metadata,
Column('team_id', Integer, ForeignKey('team.id')),
Column('person_id', Integer, ForeignKey('person.id'))
)

class User(Base):

__tablename__ = 'person'

id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String)
email = Column(String)
photo_url = Column(String)
teams = relationship('Team', secondary=associate_table)

def __repr__(self):
return "<Person {}>".format(self.id)


class Team(Base):

__tablename__ = 'team'

id = Column(Integer, primary_key=True, index=True, autoincrement=True)
index = Column(Integer)
label = Column(String)

def __repr__(self):
return "<Team {}>".format(self.id)

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
24 changes: 24 additions & 0 deletions backend/src/infra/sqlalchemy/repositories/team_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from sqlalchemy import select, delete
from sqlalchemy.orm import Session
from src.infra.sqlalchemy.models import models
from src.schemas import schemas


class TeamRepository:

def __init__(self, db: Session):
self.session = db

def criar(self, team: schemas.Team):
db_team = models.Team(index=team.index,
label=team.label)
self.session.add(db_team)
self.session.commit()
self.session.refresh(db_team)

return db_team

def listar(self):
teams = self.session.query(models.Team).all()
return teams

39 changes: 39 additions & 0 deletions backend/src/infra/sqlalchemy/repositories/user_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from sqlalchemy import select, delete
from sqlalchemy.orm import Session
from src.infra.sqlalchemy.models import models
from src.schemas import schemas


class UserRepository:

def __init__(self, db: Session):
self.session = db

def criar(self, user: schemas.User):
db_user = models.User(name=user.name,
email=user.email,
photo_url=user.photo_url,
# teams=user.teams
)
self.session.add(db_user)
self.session.commit()
self.session.refresh(db_user)

return db_user

def listar(self):
users = self.session.query(models.User).all()
return users

def obter(self, user_id: int):
stmt = select(models.User).filter_by(id=user_id)
user = self.session.execute(stmt).one()

return user

def remover(self, user_id: int):
stmt = delete(models.User).where(models.User.id == user_id)

self.session.execute(stmt)
self.session.commit()

Binary file not shown.
23 changes: 23 additions & 0 deletions backend/src/schemas/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pydantic import BaseModel
from typing import Optional, List


class Team(BaseModel):
id: Optional[int] = None
index: int
label: str

class Config:
orm_mode = True


class User(BaseModel):
id: Optional[int] = None
name: str
email: str
photo_url: str
teams: Optional[List[Team]] = []

class Config:
orm_mode = True

46 changes: 46 additions & 0 deletions backend/src/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from sqlalchemy.orm import Session
from fastapi import FastAPI, Depends, status
from src.infra.sqlalchemy.config.database import criar_bd, get_db
from src.schemas import schemas
from src.infra.sqlalchemy.repositories.user_repository import UserRepository
from src.infra.sqlalchemy.repositories.team_repository import TeamRepository

# Criar a base de dados
criar_bd()


app = FastAPI()


# userS

@app.post('/users', status_code=status.HTTP_201_CREATED)
def create_user(user: schemas.User, db: Session = Depends(get_db)):
created_user = UserRepository(db).criar(user)
return created_user

@app.get('/users')
def list_users(db: Session = Depends(get_db)):
return UserRepository(db).listar()

@app.get('/users/{user_id}')
def get_user(user_id: int, db: Session = Depends(get_db)):
user = UserRepository(db).obter(user_id)
return user

@app.delete('/users/{user_id}')
def delete_user(user_id: int, db: Session = Depends(get_db)):
UserRepository(db).remover(user_id)
return {"msg": "Removido com sucesso"}


# TEAMS

@app.post('/teams', status_code=status.HTTP_201_CREATED)
def create_team(team: schemas.Team, session: Session = Depends(get_db)):
created_team = TeamRepository(session).criar(team)
return created_team

@app.get('/teams')
def list_teams(db: Session = Depends(get_db)):
return TeamRepository(db).listar()
File renamed without changes.
Loading