Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions
143
api/src/routes/discounts.ts
Normal file
143
api/src/routes/discounts.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import { Router } from "express";
|
||||
import { pool } from "../db.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
interface DiscountCode {
|
||||
id: number;
|
||||
code: string;
|
||||
description: string | null;
|
||||
discount_type: "percent" | "flat";
|
||||
discount_value: number;
|
||||
applies_to: string | null;
|
||||
referral_partner: string | null;
|
||||
max_uses: number | null;
|
||||
max_uses_per_email: number;
|
||||
current_uses: number;
|
||||
active: boolean;
|
||||
starts_at: string;
|
||||
expires_at: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a discount code and return its details + calculated discount.
|
||||
*
|
||||
* GET /api/v1/discount/:code?service=formation&email=user@example.com&amount=59900
|
||||
*
|
||||
* Query params:
|
||||
* service — service slug to check scope (optional)
|
||||
* email — customer email to check per-email limits (optional)
|
||||
* amount — amount in cents to calculate discount against (optional)
|
||||
*/
|
||||
router.get("/api/v1/discount/:code", async (req, res) => {
|
||||
try {
|
||||
const code = req.params.code.toUpperCase().trim();
|
||||
const service = (req.query.service as string) || "";
|
||||
const email = (req.query.email as string) || "";
|
||||
const amount = parseInt(req.query.amount as string, 10) || 0;
|
||||
|
||||
if (!code || code.length < 2) {
|
||||
res.status(400).json({ error: "Invalid discount code." });
|
||||
return;
|
||||
}
|
||||
|
||||
// Look up the code
|
||||
const result = await pool.query(
|
||||
"SELECT * FROM discount_codes WHERE code = $1",
|
||||
[code],
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
res.status(404).json({
|
||||
valid: false,
|
||||
error: "Discount code not found.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const dc = result.rows[0] as DiscountCode;
|
||||
|
||||
// Check if active
|
||||
if (!dc.active) {
|
||||
res.status(410).json({ valid: false, error: "This discount code is no longer active." });
|
||||
return;
|
||||
}
|
||||
|
||||
// Check expiration
|
||||
if (dc.expires_at && new Date(dc.expires_at) < new Date()) {
|
||||
res.status(410).json({ valid: false, error: "This discount code has expired." });
|
||||
return;
|
||||
}
|
||||
|
||||
// Check start date
|
||||
if (new Date(dc.starts_at) > new Date()) {
|
||||
res.status(410).json({ valid: false, error: "This discount code is not yet active." });
|
||||
return;
|
||||
}
|
||||
|
||||
// Check global usage limit
|
||||
if (dc.max_uses !== null && dc.current_uses >= dc.max_uses) {
|
||||
res.status(410).json({ valid: false, error: "This discount code has reached its usage limit." });
|
||||
return;
|
||||
}
|
||||
|
||||
// Check per-email limit
|
||||
if (email && dc.max_uses_per_email > 0) {
|
||||
const emailUsage = await pool.query(
|
||||
"SELECT COUNT(*) as cnt FROM discount_usage WHERE code = $1 AND customer_email = $2",
|
||||
[code, email.toLowerCase().trim()],
|
||||
);
|
||||
const usedByEmail = parseInt(emailUsage.rows[0]?.cnt || "0", 10);
|
||||
if (usedByEmail >= dc.max_uses_per_email) {
|
||||
res.status(410).json({
|
||||
valid: false,
|
||||
error: "You have already used this discount code.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check service scope
|
||||
if (dc.applies_to && service) {
|
||||
const allowedServices = dc.applies_to.split(",").map((s) => s.trim().toLowerCase());
|
||||
if (!allowedServices.includes(service.toLowerCase())) {
|
||||
res.status(400).json({
|
||||
valid: false,
|
||||
error: `This code does not apply to ${service} services.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate discount amount — applies ONLY to service fees.
|
||||
// State filing fees, expedited fees, and attorney review are NEVER discountable.
|
||||
// The `amount` param should be the service fee only, not the total with state fees.
|
||||
let discountCents = 0;
|
||||
if (amount > 0) {
|
||||
if (dc.discount_type === "percent") {
|
||||
discountCents = Math.round((amount * dc.discount_value) / 100);
|
||||
} else {
|
||||
discountCents = Math.min(dc.discount_value, amount);
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
valid: true,
|
||||
code: dc.code,
|
||||
discount_type: dc.discount_type,
|
||||
discount_value: dc.discount_value,
|
||||
discount_cents: discountCents,
|
||||
description: dc.discount_type === "percent"
|
||||
? `${dc.discount_value}% off service fees`
|
||||
: `$${(dc.discount_value / 100).toFixed(2)} off service fees`,
|
||||
applies_to: dc.applies_to || "all services",
|
||||
referral_partner: dc.referral_partner || null,
|
||||
note: "Discount applies to service fees only. State filing fees, expedited processing, and attorney review fees are not discountable.",
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("[discounts] Error:", err);
|
||||
res.status(500).json({ error: "Could not validate discount code." });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Loading…
Add table
Add a link
Reference in a new issue