feat: scaffold Antonym fashion store
Anonymous Bitcoin-only fashion e-commerce with: - Vue 3 + Tailwind 4 frontend with glassmorphism dark/light design system - Express 5 + SQLite backend with BTCPay Server integration - Nostr identity (NIP-07/keypair) for anonymous purchase tracking - ChaCha20-Poly1305 encrypted shipping addresses - Admin panel with order/product/stock management - SVG logo splash animation with clip-path reveal - 5 seeded products across 4 categories Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
27
server/routes/products.ts
Normal file
27
server/routes/products.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Router } from 'express'
|
||||
import { getDb } from '../db/connection.js'
|
||||
import type { Product, SizeStock } from '../../shared/types.js'
|
||||
|
||||
export const productsRouter = Router()
|
||||
|
||||
interface ProductRow { id: string; name: string; slug: string; description: string; price_sats: number; images: string; sizes: string; category: string; is_active: number; created_at: string; updated_at: string }
|
||||
|
||||
export function rowToProduct(row: ProductRow): Product {
|
||||
return { id: row.id, name: row.name, slug: row.slug, description: row.description, priceSats: row.price_sats, images: JSON.parse(row.images) as string[], sizes: JSON.parse(row.sizes) as SizeStock[], category: row.category, isActive: row.is_active === 1, createdAt: row.created_at, updatedAt: row.updated_at }
|
||||
}
|
||||
|
||||
productsRouter.get('/', (req, res) => {
|
||||
const db = getDb()
|
||||
const category = req.query.category as string | undefined
|
||||
let rows: ProductRow[]
|
||||
if (category) { rows = db.prepare('SELECT * FROM products WHERE is_active = 1 AND category = ? ORDER BY created_at DESC').all(category) as ProductRow[] }
|
||||
else { rows = db.prepare('SELECT * FROM products WHERE is_active = 1 ORDER BY created_at DESC').all() as ProductRow[] }
|
||||
res.json(rows.map(rowToProduct))
|
||||
})
|
||||
|
||||
productsRouter.get('/:slug', (req, res) => {
|
||||
const db = getDb()
|
||||
const row = db.prepare('SELECT * FROM products WHERE slug = ? AND is_active = 1').get(req.params.slug) as ProductRow | undefined
|
||||
if (!row) { res.status(404).json({ error: { code: 'NOT_FOUND', message: 'Product not found' } }); return }
|
||||
res.json(rowToProduct(row))
|
||||
})
|
||||
Reference in New Issue
Block a user