Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6e36374
feat: Implement checkout system with migrations, email templates, and…
gustaavik May 23, 2025
3310acb
refactor: Remove unused imports and helper function from MultiProvide…
gustaavik May 23, 2025
72df18c
refactor: Add helper function to check if a slice contains a string u…
gustaavik May 23, 2025
6425cac
feat: Refactor checkout system to use session-based approach
gustaavik May 24, 2025
e05d0d6
Refactor order handler: remove ProcessPayment method and related rout…
gustaavik May 24, 2025
668eae8
fix: Change default MobilePay market from NOK to DKK
gustaavik May 24, 2025
ba59894
feat: Add currency filtering to available payment providers API and r…
gustaavik May 24, 2025
56c0a88
fix: Improve error message for payment processing failure in Complete…
gustaavik May 24, 2025
a7ce7a0
feat: Implement currency change functionality for checkouts and add r…
gustaavik May 24, 2025
2db6958
Refactor checkout system: Remove cart API, update documentation, and …
gustaavik May 24, 2025
b8e3580
feat: Add discount DTOs and update discount handler to use DTOs for r…
gustaavik May 24, 2025
00329af
Refactor checkout and shipping DTOs; update shipping handler to use n…
gustaavik May 24, 2025
860cce7
feat: Add currency DTOs and update currency handler to utilize new DT…
gustaavik May 24, 2025
9fc7982
Add comprehensive tests for shipping and user DTOs
gustaavik May 24, 2025
94697a9
fix: Handle error from UpdateCheckout in UpdateCheckoutItem method
gustaavik May 25, 2025
2702462
feat: Add ImageURL field to CheckoutItem and CheckoutItemDTO; update …
gustaavik May 30, 2025
3abbc3f
Merge pull request #30 from Zenfulcode/new-checkout-flow
gustaavik May 30, 2025
45f0947
Merge pull request #31 from Zenfulcode/development-refactoring
gustaavik May 30, 2025
225a3c1
refactor: Improve error handling and response structure in checkout h…
gustaavik May 31, 2025
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
27 changes: 3 additions & 24 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ Commercify follows **Clean Architecture** principles with clear separation of co
- Keep functions small and focused
- Document all exported functions, types, and constants
- Use meaningful variable and function names
- Avoid global variables
- Handle all errors explicitly

### Naming Conventions
Expand Down Expand Up @@ -81,15 +80,14 @@ if err != nil {
### Migrations

To create new migrations, run the following command in the CLI:
`migrate create -ext sql -dir migrations -seq "<name>"`
`migrate create -ext sql -dir migrations -seq "<name>"`

Note: Replace `<name>` with the desired migration name. Use quotes around the name if it contains spaces or special characters. For example: `"add_friendly_numbers"`.

### Queries

- Use prepared statements for all database queries
- Never concatenate user input into SQL strings
- Add indexes for columns used in WHERE clauses
- Use transactions for operations that affect multiple tables

## API Design
Expand Down Expand Up @@ -130,12 +128,6 @@ Note: Replace `<name>` with the desired migration name. Use quotes around the na
- Use table-driven tests for testing multiple cases
- Use mocks for external dependencies

### Integration Tests

- Set up test databases for integration testing
- Clean up test data after tests run
- Use test fixtures or factories for test data

## Documentation

### Code Documentation
Expand All @@ -146,7 +138,7 @@ Note: Replace `<name>` with the desired migration name. Use quotes around the na

### API Documentation

- Keep RESTAPI.md updated with all endpoint changes
- Keep /docs/<filename>.md up to date
- Include request/response examples
- Document authentication requirements

Expand Down Expand Up @@ -242,7 +234,6 @@ POST /api/discounts
- `403 Forbidden`: Not authorized (not an admin)
- `409 Conflict`: Discount code already exists

```

## Commit Messages

Expand All @@ -251,22 +242,10 @@ POST /api/discounts
- Optionally provide more detailed description after summary
- Reference issue numbers if applicable

## Deployment

- Use environment variables for configuration
- Never commit sensitive information to the repository
- Use semantic versioning for releases

## Identifier Standards

- **Order Numbers**: Use format `ORD-YYYYMMDD-000001`
- **Product Numbers**: Use format `PROD-000001`

## Email Templates

- Keep HTML email templates responsive
- Test emails on multiple email clients
- Provide both HTML and plain text versions

By following these guidelines, we'll maintain a high-quality, consistent codebase that is easy to understand, extend, and maintain.
```
90 changes: 90 additions & 0 deletions cmd/recover/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"database/sql"
"flag"
"fmt"
"log"
"os"
"path/filepath"

_ "github.com/lib/pq"
"github.com/zenfulcode/commercify/config"
"github.com/zenfulcode/commercify/internal/application/usecase"
"github.com/zenfulcode/commercify/internal/infrastructure/repository/postgres"
"github.com/zenfulcode/commercify/internal/infrastructure/service"
)

func main() {
// Parse command line flags
flag.Parse()

// Load configuration from environment variables
cfg, err := config.LoadConfig()
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}

// Initialize database connection
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
cfg.Database.Host, cfg.Database.Port, cfg.Database.User,
cfg.Database.Password, cfg.Database.DBName, cfg.Database.SSLMode)

db, err := sql.Open("postgres", dsn)
if err != nil {
log.Fatalf("Failed to connect to database: %v", err)
}
defer db.Close()

// Initialize repositories
checkoutRepo := postgres.NewCheckoutRepository(db)

// Initialize email service
emailService := service.NewEmailServiceFromEnv()

// Determine template path
templatePath := "templates"
if val := os.Getenv("TEMPLATE_PATH"); val != "" {
templatePath = val
}

// Store configuration
storeName := os.Getenv("STORE_NAME")
if storeName == "" {
storeName = "Commercify"
}

storeLogoURL := os.Getenv("STORE_LOGO_URL")
if storeLogoURL == "" {
storeLogoURL = "https://example.com/logo.png"
}

storeURL := os.Getenv("STORE_URL")
if storeURL == "" {
storeURL = "https://example.com"
}

privacyPolicyURL := os.Getenv("PRIVACY_POLICY_URL")
if privacyPolicyURL == "" {
privacyPolicyURL = "https://example.com/privacy"
}

// Initialize checkout recovery use case
recoveryUseCase := usecase.NewCheckoutRecoveryUseCase(
checkoutRepo,
emailService,
filepath.Join(templatePath, "emails"),
storeName,
storeLogoURL,
storeURL,
privacyPolicyURL,
)

// Process abandoned checkouts
count, err := recoveryUseCase.ProcessAbandonedCheckouts()
if err != nil {
log.Fatalf("Failed to process abandoned checkouts: %v", err)
}

fmt.Printf("Successfully processed %d abandoned checkouts\n", count)
}
Loading