feat: fulfillment modes, MQ, admin status, docs; scrub compose secrets

Made-with: Cursor
This commit is contained in:
2026-04-03 16:26:38 +08:00
parent 1f16966174
commit b4c5103fb3
56 changed files with 4088 additions and 3742 deletions

View File

@@ -0,0 +1,71 @@
package mq
import (
"fmt"
"strings"
amqp "github.com/rabbitmq/amqp091-go"
)
const routingKeyOrderEmail = "order.email.notify"
// OrderEmailRoutingKey is the binding / publish key for order notification messages.
func OrderEmailRoutingKey() string { return routingKeyOrderEmail }
// ExchangeName returns the durable topic exchange for this app + env (isolation from other apps on same broker).
func ExchangeName(env string) string {
return fmt.Sprintf("ex.mengyastore.%s.events", sanitizeEnv(env))
}
// QueueName returns the durable order-email queue name for this env.
func QueueName(env string) string {
return fmt.Sprintf("q.mengyastore.%s.order_email", sanitizeEnv(env))
}
func sanitizeEnv(env string) string {
e := strings.TrimSpace(strings.ToLower(env))
if e == "prod" || e == "production" {
return "prod"
}
return "dev"
}
func declareTopology(ch *amqp.Channel, env string) (exchange, queue string, err error) {
exchange = ExchangeName(env)
queue = QueueName(env)
if err = ch.ExchangeDeclare(
exchange,
"topic",
true,
false,
false,
false,
nil,
); err != nil {
return "", "", fmt.Errorf("exchange declare: %w", err)
}
if _, err = ch.QueueDeclare(
queue,
true,
false,
false,
false,
nil,
); err != nil {
return "", "", fmt.Errorf("queue declare: %w", err)
}
if err = ch.QueueBind(
queue,
routingKeyOrderEmail,
exchange,
false,
nil,
); err != nil {
return "", "", fmt.Errorf("queue bind: %w", err)
}
return exchange, queue, nil
}