diff --git a/donateApp/config.go b/donateApp/config.go deleted file mode 100644 index c55690d5..00000000 --- a/donateApp/config.go +++ /dev/null @@ -1,5 +0,0 @@ -package donateapp - -type Config struct{ - -} diff --git a/donateApp/delivery/donate_server/handler.go b/donateApp/delivery/donate_server/handler.go deleted file mode 100644 index 7cc44499..00000000 --- a/donateApp/delivery/donate_server/handler.go +++ /dev/null @@ -1,8 +0,0 @@ -package donate_server - -type Handler struct { -} - -func NewHandler() Handler { - return Handler{} -} diff --git a/donateApp/repository/migrations/1774070672_add_donate_table.sql b/donateApp/repository/migrations/1774070672_add_donate_table.sql deleted file mode 100644 index 7950546f..00000000 --- a/donateApp/repository/migrations/1774070672_add_donate_table.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +migrate Up -CREATE TABLE `donates` ( - `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT, - `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) USING BTREE, - UNIQUE INDEX `id`(`id` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 84 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_persian_ci ROW_FORMAT = Dynamic; - --- +migrate Down -DROP TABLE IF EXISTS `donates`; \ No newline at end of file diff --git a/donateApp/repository/mysql/db.go b/donateApp/repository/mysql/db.go deleted file mode 100644 index b0843023..00000000 --- a/donateApp/repository/mysql/db.go +++ /dev/null @@ -1 +0,0 @@ -package mysql diff --git a/donateApp/service/entity/campiagn.go b/donateApp/service/entity/campiagn.go deleted file mode 100644 index bd914808..00000000 --- a/donateApp/service/entity/campiagn.go +++ /dev/null @@ -1,47 +0,0 @@ -package service - - -import ( - "time" -) - -// --- Type Aliases --- - -// UserID is a type alias for clarity, representing foreign keys to the User service -type UserID uint32 - -// TransactionID is a type alias for clarity, representing foreign keys to the Transaction service -type TransactionID uint32 - -// CampaignID is a type alias for clarity, representing primary keys for Campaigns -type CampaignID uint32 - -// DonationID is a type alias for clarity, representing primary keys for Donations -type DonationID uint32 - -// --- Campaign Module Entities --- - -// CampaignStatus represents the possible states of a campaign -type CampaignStatus string - -const ( - StatusActive CampaignStatus = "active" - StatusCompleted CampaignStatus = "completed" - StatusCancelled CampaignStatus = "cancelled" - StatusExpired CampaignStatus = "expired" // New status for deadlines -) - -// Campaign represents a fundraising campaign entity -type Campaign struct { - ID CampaignID `json:"id"` - Title string `json:"title"` - Description string `json:"description"` - GoalAmount float64 `json:"goal_amount"` // Using float64 for decimal, consider using a dedicated decimal type for precision - RaisedAmount float64 `json:"raised_amount"` - Status CampaignStatus `json:"status"` - CreatedAt time.Time `json:"created_at"` - DeadlineAt *time.Time `json:"deadline_at,omitempty"` // Pointer to time.Time, allows nil for no deadline. omitempty hides if nil. - AdminID UserID `json:"admin_id"` // Foreign Key to User service - InitiatedByUserID *UserID `json:"initiated_by_user_id,omitempty"` // Pointer to UserID, allows nil. omitempty hides if nil. -} - diff --git a/donateApp/service/entity/donation.go b/donateApp/service/entity/donation.go deleted file mode 100644 index 3c064929..00000000 --- a/donateApp/service/entity/donation.go +++ /dev/null @@ -1,25 +0,0 @@ -package service - - - -// DonationLevel represents the level of a donation (e.g., Bronze, Silver, Gold) -type DonationLevel string - -const ( - DonationLevelBronze DonationLevel = "Bronze" - DonationLevelSilver DonationLevel = "Silver" - DonationLevelGold DonationLevel = "Gold" -) - -// Donation represents a donation made to a campaign -type Donation struct { - ID DonationID `json:"id"` - UserID UserID `json:"user_id"` // Foreign Key to User service - CampaignID CampaignID `json:"campaign_id"` // Foreign Key to Campaign - Amount float64 `json:"amount"` // Using float64 for decimal, consider a dedicated decimal type - PointsEarned int `json:"points_earned"` // امتیازی که از این تراکنش خاص کسب شده - TransactionID TransactionID `json:"transaction_id"` // Foreign Key to Transaction service - CreatedAt time.Time `json:"created_at"` - DonationLevel *DonationLevel `json:"donation_level,omitempty"` // Pointer to DonationLevel, allows nil. omitempty hides if nil. -} - diff --git a/donateApp/app.go b/donate_app/app.go similarity index 79% rename from donateApp/app.go rename to donate_app/app.go index d762c024..d280a647 100644 --- a/donateApp/app.go +++ b/donate_app/app.go @@ -1,8 +1,10 @@ -package doanteApp +package donate_app import "net/http" type Application struct { Config Config HTTPServer *http.Server -} \ No newline at end of file +} + + diff --git a/donate_app/config.go b/donate_app/config.go new file mode 100644 index 00000000..b670aced --- /dev/null +++ b/donate_app/config.go @@ -0,0 +1,17 @@ +package donate_app + + + + +import ( + "git.gocasts.ir/ebhomengo/niki/repository/mysql" +) + +type Config struct { + Mysql mysql.Config `koanf:"mariadb"` +} + + +type Config struct{ + +} diff --git a/donate_app/delivery/donate_server/handler.go b/donate_app/delivery/donate_server/handler.go new file mode 100644 index 00000000..9f94a9c3 --- /dev/null +++ b/donate_app/delivery/donate_server/handler.go @@ -0,0 +1,5 @@ +package donate_server + +type Handler struct{} + + diff --git a/donateApp/delivery/donate_server/routes.go b/donate_app/delivery/donate_server/routes.go similarity index 100% rename from donateApp/delivery/donate_server/routes.go rename to donate_app/delivery/donate_server/routes.go diff --git a/donateApp/delivery/donate_server/server.go b/donate_app/delivery/donate_server/server.go similarity index 100% rename from donateApp/delivery/donate_server/server.go rename to donate_app/delivery/donate_server/server.go diff --git a/donate_app/pkg/types.go b/donate_app/pkg/types.go new file mode 100644 index 00000000..ad2823b5 --- /dev/null +++ b/donate_app/pkg/types.go @@ -0,0 +1,4 @@ +// --- Type Aliases --- +package pkg + +type ID uint64 diff --git a/donate_app/repository/migrations/1775633533_add_campaign_table.sql b/donate_app/repository/migrations/1775633533_add_campaign_table.sql new file mode 100644 index 00000000..65aead6e --- /dev/null +++ b/donate_app/repository/migrations/1775633533_add_campaign_table.sql @@ -0,0 +1,18 @@ +-- +migrate Up + +CREATE TABLE `campaigns` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT, + `title` VARCHAR(255) NOT NULL, + `description` TEXT, + `goal_amount` DECIMAL(15,2) NOT NULL, + `raised_amount` DECIMAL(15,2) DEFAULT 0, + `status` VARCHAR(50) NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + `deadline_at` TIMESTAMP, + `admin_id` BIGINT NOT NULL, + FOREIGN KEY (`admin_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT +); + + +-- +migrate Down +DROP TABLE `campaigns`; diff --git a/donate_app/repository/migrations/1775633805_add_campaign_participants_table.sql b/donate_app/repository/migrations/1775633805_add_campaign_participants_table.sql new file mode 100644 index 00000000..779a9bd2 --- /dev/null +++ b/donate_app/repository/migrations/1775633805_add_campaign_participants_table.sql @@ -0,0 +1,19 @@ +-- +migrate Up + +CREATE TABLE `campaign_participants` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT, + `campaign_id` BIGINT NOT NULL, + `user_id` BIGINT NOT NULL, + `amount` DECIMAL(15,2) NOT NULL, + `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`campaign_id`) + REFERENCES `campaigns`(`id`) + ON DELETE CASCADE, + FOREIGN KEY (`user_id`) + REFERENCES `users`(`id`) + ON DELETE CASCADE, + UNIQUE KEY `unique_campaign_user` (`campaign_id`, `user_id`) +); + +-- +migrate Down +DROP TABLE `campaign_participants`; diff --git a/donate_app/repository/mysql/db.go b/donate_app/repository/mysql/db.go new file mode 100644 index 00000000..6a89ad81 --- /dev/null +++ b/donate_app/repository/mysql/db.go @@ -0,0 +1,90 @@ +package mysql + +import ( + "context" + "git.gocasts.ir/ebhomengo/niki/campaign/entity" + richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" + "git.gocasts.ir/ebhomengo/niki/repository/mysql" + "git.gocasts.ir/ebhomengo/niki/types" +) + +type DB struct { + conn *mysql.DB +} + +func New(db *mysql.DB) *DB { + return &DB{conn: db} +} + +// CreateCampaign creates a new campaign +func (d *DB) CreateCampaign(ctx context.Context, campaign entity.Campaign) (types.ID, error) { + const Op = "repository.mysql.campaign.create" + + tx, err := d.conn.Conn().BeginTx(ctx, nil) + if err != nil { + return 0, richerror.New(Op).WithErr(err) + } + defer tx.Rollback() + + query := `INSERT INTO campaigns (title, description, goal_amount, raised_amount, + status, deadline_at ,admin_id , created_at ) + VALUES (?, ?, ?, ?, ?, ?, ? , NOW() )` + + result, err := tx.ExecContext(ctx, query, + campaign.Title, + campaign.Description, + campaign.GoalAmount, + campaign.RaisedAmount, + campaign.Status, + campaign.DeadlineAt, + campaign.AdminID, + campaign.CreatedAt, + + + ) + if err != nil { + return 0, richerror.New(Op).WithErr(err) + } + + campaignID, err := result.LastInsertId() + if err != nil { + return 0, richerror.New(Op).WithErr(err) + } + + if err := tx.Commit(); err != nil { + return 0, richerror.New(Op).WithErr(err) + } + + return types.ID(campaignID), nil +} + +// Create adds a new participant to a campaign +func (d *DB) CreateCampaignParticipants(ctx context.Context, participant entity.CampaignParticipant) (types.ID, error) { + const Op = "repository.mysql.campaign_participant.create" + + query := `INSERT INTO campaign_participants (id,campaign_id, user_id, amount , created_at) + VALUES (?, ?, ? , ? , NOW())` + + result, err := d.conn.ExecContext(ctx, query, + participant.ID, + participant.CampaignID, + participant.UserID, + participant.Amount, + participant.CreatedAt + ) + if err != nil { + return 0, richerror.New(Op).WithErr(err) + } + + id, err := result.LastInsertId() + if err != nil { + return 0, richerror.New(Op).WithErr(err) + } + + return types.ID(id), nil +} + + + + + diff --git a/donate_app/service/entity/campaignParticipant.go b/donate_app/service/entity/campaignParticipant.go new file mode 100644 index 00000000..fb493429 --- /dev/null +++ b/donate_app/service/entity/campaignParticipant.go @@ -0,0 +1,14 @@ +package service + + +type ID uint64 + + +type CampaignParticipant struct { + ID ID `json:"id"` + CampaignID ID `json:"campaign_id"` + UserID ID `json:"user_id"` + Amount float64 `json:"amount"` + CreatedAt time.Time `json:"created_at"` + +} \ No newline at end of file diff --git a/donate_app/service/entity/campiagn.go b/donate_app/service/entity/campiagn.go new file mode 100644 index 00000000..157ef030 --- /dev/null +++ b/donate_app/service/entity/campiagn.go @@ -0,0 +1,30 @@ +package service + +import ( + "time" +) + +// CampaignStatus represents the possible states of a campaign +type CampaignStatus string + +const ( + StatusActive CampaignStatus = "active" + StatusCompleted CampaignStatus = "completed" + StatusCancelled CampaignStatus = "cancelled" + StatusExpired CampaignStatus = "expired" // New status for deadlines +) + +type ID uint64 + +type Campaign struct { + ID ID `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + GoalAmount float64 `json:"goal_amount"` + RaisedAmount float64 `json:"raised_amount"` + Status CampaignStatus `json:"status"` + CreatedAt time.Time `json:"created_at"` + DeadlineAt *time.Time `json:"deadline_at,omitempty"` + + AdminID ID `json:"creator_id"` +} diff --git a/donateApp/service/param.go b/donate_app/service/param.go similarity index 100% rename from donateApp/service/param.go rename to donate_app/service/param.go diff --git a/donateApp/service/service.go b/donate_app/service/service.go similarity index 100% rename from donateApp/service/service.go rename to donate_app/service/service.go diff --git a/donateApp/service/validator.go b/donate_app/service/validator.go similarity index 100% rename from donateApp/service/validator.go rename to donate_app/service/validator.go