Skip to content
Merged
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
49 changes: 39 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,47 @@ make clean

## Project Structure
```
.
├── cmd/
│ ├── api/ # Main API application
│ └── migrate/ # Database migrations
│ ├── api/ # Main API application (Gin server)
│ │ ├── auth.go # Authentication handlers (login, register)
│ │ ├── contex.go # Helper functions to get user from context
│ │ ├── events.go # Event CRUD handlers
│ │ ├── main.go # Entry point for API server
│ │ ├── middleware.go # Authentication & logging middleware
│ │ ├── routes.go # Route definitions
│ │ └── server.go # Server configuration & startup
│ └── migrate/ # Database migrations
│ └── migrations/
│ ├── 000001_create_user_table.up.sql
│ ├── 000001_create_user_table.down.sql
│ ├── 000002_create_events_table.up.sql
│ ├── 000002_create_events_table.down.sql
│ ├── 000003_create_attendance_table.up.sql
│ ├── 000003_create_attendance_table.down.sql
│ └── main.go
├── internals/
│ ├── database/ # Database models and queries
│ └── env/ # Environment configuration
├── server/ # Server configurations
├── Makefile # Build automation
├── data.db # SQLite database
├── .air.toml # Air configuration
└── go.mod # Go modules
│ ├── database/ # Database models and queries
│ │ ├── models.go # Model registry
│ │ ├── users.go # User model & queries
│ │ ├── event.go # Event model & queries
│ │ └── attendee.go # Attendance model & queries
│ └── env/ # Environment configuration (env variables)
│ └── env.go
├── server/ # Server-related files (local data, configs)
│ └── data.db # Local SQLite database
├── tmp/ # Temporary build and runtime files
│ ├── main # Compiled binary (generated by Air)
│ └── build-errors.log # Logs from failed builds
├── Makefile # Build & run automation commands
├── go.mod # Go module definition
├── go.sum # Dependency checksums
├── data.db # Development SQLite database
├── .air.toml # Air live-reload configuration
└── README.md # Project documentation
```

## API Endpoints
Expand Down
83 changes: 78 additions & 5 deletions cmd/api/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@ import (
"github.com/kunalkumar-1/Evently/internals/database"
)

// create event handler
// CreateEvent creates a new event
// @Summary Create a new event
// @Description Create a new event owned by the authenticated user
// @Tags Events
// @Accept json
// @Produce json
// @Param event body database.Event true "Event Data"
// @Success 201 {object} database.Event
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /events [post]
// @Security BearerAuth
func (app *application) createEvent(c *gin.Context) {

var event database.Event
Expand Down Expand Up @@ -39,7 +50,16 @@ func (app *application) createEvent(c *gin.Context) {
c.JSON(http.StatusCreated, event)
}

// get all events
// GetAllEvent returns all events
// @Summary Get all events
// @Description Retrieve a list of all available events
// @Tags Events
// @Accept json
// @Produce json
// @Success 200 {array} database.Event
// @Failure 500 {object} map[string]string "Failed to retrieve events"
// @Router /events [get]

func (app *application) getAllEvent(c *gin.Context) {
events, err := app.models.Events.GetAll()
if err != nil {
Expand All @@ -51,7 +71,17 @@ func (app *application) getAllEvent(c *gin.Context) {
c.JSON(http.StatusOK, events)
}

// get events
// GetEvent retrieves an event by ID
// @Summary Get event by ID
// @Description Retrieve details of a specific event
// @Tags Events
// @Accept json
// @Produce json
// @Param id path int true "Event ID"
// @Success 200 {object} database.Event
// @Failure 400 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Router /events/{id} [get]
func (app *application) getEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
Expand All @@ -78,7 +108,20 @@ func (app *application) getEvent(c *gin.Context) {
c.JSON(http.StatusCreated, event)
}

// update event
// UpdateEvent updates an existing event
// @Summary Update event
// @Description Update an existing event by ID (only by owner)
// @Tags Events
// @Accept json
// @Produce json
// @Param id path int true "Event ID"
// @Param event body database.Event true "Updated Event Data"
// @Success 200 {object} database.Event
// @Failure 400 {object} map[string]string
// @Failure 403 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /events/{id} [put]
// @Security BearerAuth
func (app *application) updateEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id")) // get event id from url
if err != nil {
Expand Down Expand Up @@ -137,7 +180,17 @@ func (app *application) updateEvent(c *gin.Context) {
c.JSON(http.StatusOK, updatedEvent)
}

// delete event
// DeleteEvent deletes an event by ID
// @Summary Delete event
// @Description Delete an event by ID (only by owner)
// @Tags Events
// @Param id path int true "Event ID"
// @Success 204 {object} nil
// @Failure 400 {object} map[string]string
// @Failure 403 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Router /events/{id} [delete]
// @Security BearerAuth
func (app *application) deleteEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
Expand Down Expand Up @@ -178,6 +231,18 @@ func (app *application) deleteEvent(c *gin.Context) {

}

// AddAttendeeToEvent adds a user to an event
// @Summary Add attendee to event
// @Description Adds a user as an attendee to a specific event
// @Tags Attendees
// @Param id path int true "Event ID"
// @Param userId path int true "User ID"
// @Success 201 {object} database.Attendee
// @Failure 400 {object} map[string]string
// @Failure 403 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Router /events/{id}/attendees/{userId} [post]
// @Security BearerAuth
func (app *application) addAttendeeToEvent(c *gin.Context) {
eventId, err := strconv.Atoi(c.Param("id"))
if err != nil {
Expand Down Expand Up @@ -262,6 +327,14 @@ func (app *application) addAttendeeToEvent(c *gin.Context) {
c.JSON(http.StatusCreated, attendee)
}

// GetAttendeesForEvent retrieves attendees for a given event
// @Summary Get attendees for event
// @Description Get a list of all attendees for a specific event
// @Tags Attendees
// @Param id path int true "Event ID"
// @Success 200 {array} database.Attendee
// @Failure 400 {object} map[string]string
// @Router /events/{id}/attendees [get]
func (app *application) getAttendeesForEvent(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,27 @@ import (
"log"

_ "github.com/joho/godotenv/autoload"
_ "github.com/kunalkumar-1/Evently/docs"
"github.com/kunalkumar-1/Evently/internals/database"
"github.com/kunalkumar-1/Evently/internals/env"
_ "github.com/mattn/go-sqlite3"
)

// @title Evently API
// @version 1.0
// @description Event Management REST API built with Go and Gin.

// @contact.name API Support
// @contact.url https://github.com/kunalkumar-1/Evently
// @contact.email kunaldevspro@gmail.com

// @license.name MIT
// @license.url https://opensource.org/licenses/MIT

// @host localhost:8080
// @BasePath /api/v1
// @schemes http

type application struct {
port int
jwtSecret string
Expand Down
9 changes: 9 additions & 0 deletions cmd/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"net/http"

"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)

func (app *application) routes() http.Handler {
Expand All @@ -29,5 +31,12 @@ func (app *application) routes() http.Handler {
auth.DELETE("/events/:id/attendees/:userId", app.deleteAttendeeFromEvent) // delete attendee from event
}

r.GET("/swagger/*any", func(c *gin.Context) {
if c.Request.RequestURI == "/swagger/" {
c.Redirect(302, "/swagger/index.html")
}
ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.URL("http://localhost:8080/swagger/doc.json"))(c)
})

return r
}
Loading