forked from ebhomengo/niki
features:(db config & tables migrations & improve entities)
This commit is contained in:
parent
bd58162f3e
commit
e96553be9c
|
|
@ -1,5 +0,0 @@
|
|||
package donateapp
|
||||
|
||||
type Config struct{
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package donate_server
|
||||
|
||||
type Handler struct {
|
||||
}
|
||||
|
||||
func NewHandler() Handler {
|
||||
return Handler{}
|
||||
}
|
||||
|
|
@ -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`;
|
||||
|
|
@ -1 +0,0 @@
|
|||
package mysql
|
||||
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
package doanteApp
|
||||
package donate_app
|
||||
|
||||
import "net/http"
|
||||
|
||||
type Application struct {
|
||||
Config Config
|
||||
HTTPServer *http.Server
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package donate_server
|
||||
|
||||
type Handler struct{}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// --- Type Aliases ---
|
||||
package pkg
|
||||
|
||||
type ID uint64
|
||||
|
|
@ -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`;
|
||||
|
|
@ -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`;
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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"`
|
||||
|
||||
}
|
||||
|
|
@ -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"`
|
||||
}
|
||||
Loading…
Reference in New Issue