I am batman

This commit is contained in:
2026-06-20 11:07:01 -04:00
commit 013d01358c
52 changed files with 7615 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
FROM golang:1.24-alpine AS build
RUN apk add --no-cache git ca-certificates protobuf-dev
WORKDIR /app
# use repo-level go.mod so modules are resolvable
COPY go.mod go.sum ./
RUN go mod download
# install Go protoc plugins
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest && \
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# copy service sources and proto files
COPY services/user-service ./services/user-service
COPY proto ./proto
# generate proto files
RUN mkdir -p proto/auth proto/user proto/post && \
export PATH=/go/bin:$PATH && \
protoc --go_out=proto --go_opt=paths=source_relative \
--go-grpc_out=proto --go-grpc_opt=paths=source_relative \
--proto_path=proto \
proto/auth.proto proto/user.proto proto/post.proto && \
ls -la proto/auth/ proto/user/ proto/post/
# build static binary
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /usr/local/bin/user-service ./services/user-service/cmd
FROM alpine:3.20
RUN apk add --no-cache ca-certificates
COPY --from=build /usr/local/bin/user-service /usr/local/bin/user-service
EXPOSE 50052
ENTRYPOINT ["/usr/local/bin/user-service"]

View File

@@ -0,0 +1,39 @@
package main
import (
"fmt"
pb "go-microservices/proto/user"
"go-microservices/services/user-service/internal/database"
"go-microservices/services/user-service/internal/repository"
"go-microservices/services/user-service/internal/server"
"log"
"net"
"os"
"google.golang.org/grpc"
)
func main() {
fmt.Println("Starting User Service...")
port := os.Getenv("PORT")
if port == "" {
port = "50052"
}
lis, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
db, err := database.Init()
if err != nil {
log.Fatalf("failed to init database: %v", err)
}
repo := repository.NewRepository(db)
grpcServer := grpc.NewServer()
pb.RegisterUserServiceServer(grpcServer, server.NewUserServer(repo))
log.Printf("User Service listening on %s", port)
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}

View File

@@ -0,0 +1 @@
This is the configuration file for the User Service microservice. It defines the settings and parameters used by the service at runtime.

View File

@@ -0,0 +1,22 @@
package config
import (
"os"
"strconv"
)
type Env struct {
Port int
JWTSecret string
TokenDuration int
DatabaseURL string
RedisAddr string
RedisPassword string
RedisDB int
EmailHost string
EmailPort int
EmailUsername string
EmailPassword string
EmailFrom string
FrontendURL string
}

View File

@@ -0,0 +1,28 @@
package database
import (
"os"
"go-microservices/services/user-service/internal/models"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func Init() (*gorm.DB, error) {
dsn := os.Getenv("DATABASE_URL")
if dsn == "" {
dsn = "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable TimeZone=UTC"
}
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
if err := db.AutoMigrate(&models.User{}, &models.Client{}); err != nil {
return nil, err
}
return db, nil
}

View File

@@ -0,0 +1,27 @@
package models
import (
"gorm.io/gorm"
)
type Client struct {
gorm.Model
Name string
Email string `gorm:"uniqueIndex;not null"`
Active bool `gorm:"default:true"`
Address string
}
type User struct {
gorm.Model
Email string `gorm:"uniqueIndex;not null"`
Name string
Role string `gorm:"default:User"`
Active bool `gorm:"default:true"`
Username string `gorm:"uniqueIndex"`
Address string
PhoneNumber string
ProfilePhoto []byte `gorm:"type:bytea"`
ClientID *uint
Client *Client
}

View File

@@ -0,0 +1,7 @@
package repository
// TODO: Add database repository implementations
// Example repositories:
// - UserRepository for user data access
// - ProfileRepository for profile management
// - PreferenceRepository for user settings

View File

@@ -0,0 +1,13 @@
package repository
import (
"gorm.io/gorm"
)
type Repository struct {
DB *gorm.DB
}
func NewRepository(db *gorm.DB) *Repository {
return &Repository{DB: db}
}

View File

@@ -0,0 +1,49 @@
package server
import (
"context"
pb "go-microservices/proto/user"
"go-microservices/services/user-service/internal/repository"
"google.golang.org/protobuf/types/known/emptypb"
)
type UserServer struct {
pb.UnimplementedUserServiceServer
repo *repository.Repository
}
func NewUserServer(repo *repository.Repository) *UserServer {
return &UserServer{repo: repo}
}
func (s *UserServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
// TODO: Implement create user logic
user := &pb.User{Id: "1", Username: req.Username, Email: req.Email, Bio: req.Bio, AvatarUrl: req.AvatarUrl, CreatedAt: 0, UpdatedAt: 0}
return &pb.CreateUserResponse{User: user}, nil
}
func (s *UserServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
// TODO: Implement get user logic
user := &pb.User{Id: req.Id, Username: "user", Email: "user@example.com", Bio: "bio", AvatarUrl: "", CreatedAt: 0, UpdatedAt: 0}
return &pb.GetUserResponse{User: user}, nil
}
func (s *UserServer) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserResponse, error) {
// TODO: Implement update user logic
user := &pb.User{Id: req.Id, Username: req.Username, Email: req.Email, Bio: req.Bio, AvatarUrl: req.AvatarUrl, CreatedAt: 0, UpdatedAt: 0}
return &pb.UpdateUserResponse{User: user}, nil
}
func (s *UserServer) DeleteUser(ctx context.Context, req *pb.DeleteUserRequest) (*emptypb.Empty, error) {
// TODO: Implement delete user logic
return &emptypb.Empty{}, nil
}
func (s *UserServer) ListUsers(ctx context.Context, req *pb.ListUsersRequest) (*pb.ListUsersResponse, error) {
// TODO: Implement list users logic
users := []*pb.User{}
return &pb.ListUsersResponse{Users: users}, nil
}