Skip to content
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
422 changes: 422 additions & 0 deletions PROJECT_SUMMARY.md

Large diffs are not rendered by default.

55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ brex-interview-playground/
│ │ ├── models/ # SQLAlchemy models
│ │ └── schemas/ # Pydantic schemas
│ └── tests/ # Test files
├── backend-go/ # Go Backend (Alternative)
│ ├── cmd/
│ │ └── api/ # Application entry point
│ └── internal/
│ ├── config/ # Configuration constants
│ ├── database/ # Database initialization and seeding
│ ├── dto/ # Data transfer objects
│ ├── graphql/ # GraphQL schema and resolvers
│ ├── model/ # Domain models
│ ├── repository/ # Data access layer
│ ├── rest/ # REST API handlers
│ └── service/ # Business logic
└── frontend/ # T3 Stack Frontend
├── src/
│ ├── app/ # Next.js app router pages
Expand All @@ -46,7 +58,7 @@ brex-interview-playground/

### Backend Options

You can choose between two backend implementations:
You can choose between three backend implementations:

#### Kotlin Spring Boot Backend

Expand All @@ -63,6 +75,14 @@ The Python backend is a FastAPI application that provides:
- Strawberry GraphQL integration
- Pydantic for data validation

#### Go Backend (Alternative)

The Go backend is a Gorilla Mux-based application that provides:
- REST and GraphQL APIs for simple message operations
- GORM with SQLite database
- gqlgen for GraphQL code generation
- Clean architecture with repository and service layers

### Frontend (T3 Stack)

The frontend is built with the T3 Stack, featuring:
Expand All @@ -82,6 +102,9 @@ For Python backend:
- Python 3.8 or higher
- Poetry (for dependency management)

For Go backend:
- Go 1.21 or higher

For frontend:
- Node.js 18 or higher
- npm or yarn
Expand Down Expand Up @@ -131,6 +154,29 @@ For frontend:
- i.e. `http://localhost:8080/api/messages/latest`
- GraphQL Playground: `http://localhost:8080/graphql`

#### Option 3: Go Backend

1. **Install Dependencies**:
```bash
cd backend-go
go mod download
```

2. **Generate GraphQL Code** (first time or after schema changes):
```bash
GOPROXY=https://go-proxy-public.golang.org,direct go run github.com/99designs/gqlgen@v0.17.86 generate
```

3. **Run the Application**:
```bash
GOPROXY=https://go-proxy-public.golang.org,direct go run cmd/api/main.go
```

4. **Access the Application**:
- REST API: `http://localhost:8080/api/`
- i.e. `http://localhost:8080/api/messages/latest`
- GraphQL API: `http://localhost:8080/graphql`

### Running the Frontend

1. **Install Dependencies**:
Expand Down Expand Up @@ -159,6 +205,7 @@ For frontend:
- Access the GraphQL IDE:
- For Kotlin backend: `http://localhost:8080/graphiql`
- For Python backend: `http://localhost:8080/graphql`
- For Go backend: `http://localhost:8080/graphql`

- **Example Query**:
```graphql
Expand Down Expand Up @@ -194,4 +241,10 @@ cd backend-kotlin
```bash
cd backend-python
poetry run pytest
```

#### Go Backend Tests:
```bash
cd backend-go
go test ./...
```
34 changes: 34 additions & 0 deletions backend-go/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool
*.out

# Dependency directories
vendor/

# Go workspace file
go.work

# Database files
*.db
*.sqlite
*.sqlite3

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db
138 changes: 138 additions & 0 deletions backend-go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Brex Interview Playground Backend (Go)

This is a Go backend implementation for the Brex interview playground, providing REST and GraphQL APIs for simple message operations.

## Features

- REST API endpoints for message operations
- GraphQL API with query and mutation support
- SQLite database with GORM ORM
- CORS support for frontend integration
- Automatic database migration and seeding

## Prerequisites

- Go 1.21 or higher
- Make (optional, for convenience commands)

## Project Structure

```
backend-go/
├── cmd/
│ └── api/
│ └── main.go # Application entry point
├── internal/
│ ├── config/ # Configuration constants
│ ├── database/ # Database initialization and seeding
│ ├── dto/ # Data transfer objects
│ ├── graphql/ # GraphQL schema and resolvers
│ ├── model/ # Domain models
│ ├── repository/ # Data access layer
│ ├── rest/ # REST API handlers
│ └── service/ # Business logic
├── gqlgen.yml # GraphQL code generation config
└── go.mod # Go module dependencies
```

## Installation

1. **Install dependencies**:
```bash
cd backend-go
go mod download
```

2. **Generate GraphQL code** (if needed):
```bash
go run github.com/99designs/gqlgen generate
```

## Running the Application

### Option 1: Using Go Run

```bash
cd backend-go
go run cmd/api/main.go
```

### Option 2: Build and Run

```bash
cd backend-go
go build -o bin/api cmd/api/main.go
./bin/api
```

### Option 3: Using Make (if Makefile is available)

```bash
make run
```

## Accessing the Application

- **REST API**: `http://localhost:8080/api/`
- Get latest messages: `GET http://localhost:8080/api/messages/latest?limit=10`
- Create message: `POST http://localhost:8080/api/messages`

- **GraphQL API**: `http://localhost:8080/graphql`
- GraphQL Playground: `http://localhost:8080/graphql` (if enabled)

## GraphQL Examples

### Query Latest Messages

```graphql
query {
latestMessages(limit: 10) {
id
content
createdAt
}
}
```

### Mutation Create Message

```graphql
mutation {
createMessage {
id
content
createdAt
}
}
```

## Environment Variables

- `PORT`: Server port (default: 8080)

## Database

The application uses SQLite with the database file `dummy.db` in the project root. The database is automatically migrated and seeded on startup.

## Development

### Code Generation

To regenerate GraphQL code after schema changes:

```bash
go run github.com/99designs/gqlgen generate
```

### Testing

```bash
go test ./...
```

## Dependencies

- **Gorilla Mux**: HTTP router and URL matcher
- **GORM**: ORM for database operations
- **gqlgen**: GraphQL code generation
- **SQLite**: Database driver
55 changes: 55 additions & 0 deletions backend-go/cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import (
"log"
"net/http"
"os"

"brex/interview/internal/database"
"brex/interview/internal/graphql"
"brex/interview/internal/middleware"
"brex/interview/internal/rest"
"brex/interview/internal/service"

"github.com/gorilla/mux"
)

func main() {
// Initialize database
db, err := database.Initialize()
if err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}

// Seed database
if err := database.Seed(db); err != nil {
log.Fatalf("Failed to seed database: %v", err)
}

// Initialize services
messageService := service.NewMessageService(db)

// Setup Gorilla Mux router
r := mux.NewRouter()

// Apply CORS middleware
r.Use(middleware.CORS)

// Setup REST routes
rest.SetupRoutes(r, messageService)

// Setup GraphQL
graphqlHandler := graphql.NewHandler(messageService)
r.Handle("/graphql", graphqlHandler).Methods("POST", "OPTIONS")

// Get port from environment or use default
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

log.Printf("Server starting on port %s", port)
if err := http.ListenAndServe(":"+port, r); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}
39 changes: 39 additions & 0 deletions backend-go/cmd/query/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"fmt"
"log"

"brex/interview/internal/config"
"brex/interview/internal/database"
"brex/interview/internal/model"
)

func main() {
// Initialize database
db, err := database.Initialize()
if err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}

// Query all messages
var messages []model.Message
if err := db.Order("created_at DESC").Find(&messages).Error; err != nil {
log.Fatalf("Failed to query messages: %v", err)
}

// Print results
fmt.Printf("\n=== Mensagens no banco de dados (%s) ===\n\n", config.DatabasePath)
if len(messages) == 0 {
fmt.Println("Nenhuma mensagem encontrada.")
} else {
for i, msg := range messages {
fmt.Printf("Mensagem %d:\n", i+1)
fmt.Printf(" ID: %s\n", msg.ID)
fmt.Printf(" Content: %s\n", msg.Content)
fmt.Printf(" CreatedAt: %s\n", msg.CreatedAt.Format("2006-01-02 15:04:05"))
fmt.Println()
}
}
fmt.Printf("Total: %d mensagem(ns)\n\n", len(messages))
}
Loading