fix: Static file paths and crawl_enabled API filters
- Fix static file paths for local development (./public/* instead of /app/public/*) - Add crawl_enabled and dutchie_verified filters to /api/stores and /api/dispensaries - Default API to return only enabled stores (crawl_enabled=true) - Add ?crawl_enabled=false to show disabled, ?crawl_enabled=all to show all 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,11 +17,13 @@ app.use(cors());
|
|||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
// Serve static images when MinIO is not configured
|
// Serve static images when MinIO is not configured
|
||||||
const LOCAL_IMAGES_PATH = process.env.LOCAL_IMAGES_PATH || '/app/public/images';
|
// Uses ./public/images relative to working directory (works for both Docker and local dev)
|
||||||
|
const LOCAL_IMAGES_PATH = process.env.LOCAL_IMAGES_PATH || './public/images';
|
||||||
app.use('/images', express.static(LOCAL_IMAGES_PATH));
|
app.use('/images', express.static(LOCAL_IMAGES_PATH));
|
||||||
|
|
||||||
// Serve static downloads (plugin files, etc.)
|
// Serve static downloads (plugin files, etc.)
|
||||||
const LOCAL_DOWNLOADS_PATH = process.env.LOCAL_DOWNLOADS_PATH || '/app/public/downloads';
|
// Uses ./public/downloads relative to working directory (works for both Docker and local dev)
|
||||||
|
const LOCAL_DOWNLOADS_PATH = process.env.LOCAL_DOWNLOADS_PATH || './public/downloads';
|
||||||
app.use('/downloads', express.static(LOCAL_DOWNLOADS_PATH));
|
app.use('/downloads', express.static(LOCAL_DOWNLOADS_PATH));
|
||||||
|
|
||||||
// Simple health check for load balancers/K8s probes
|
// Simple health check for load balancers/K8s probes
|
||||||
|
|||||||
@@ -11,29 +11,46 @@ const VALID_MENU_TYPES = ['dutchie', 'treez', 'jane', 'weedmaps', 'leafly', 'mea
|
|||||||
// Get all dispensaries
|
// Get all dispensaries
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { menu_type, city, state } = req.query;
|
const { menu_type, city, state, crawl_enabled, dutchie_verified } = req.query;
|
||||||
|
|
||||||
let query = `
|
let query = `
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
company_name,
|
|
||||||
slug,
|
slug,
|
||||||
address,
|
address1,
|
||||||
|
address2,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
zip,
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
dba_name,
|
dba_name,
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
product_count,
|
product_count,
|
||||||
last_crawl_at,
|
last_crawl_at,
|
||||||
|
crawl_enabled,
|
||||||
|
dutchie_verified,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM dispensaries
|
FROM dispensaries
|
||||||
@@ -48,10 +65,10 @@ router.get('/', async (req, res) => {
|
|||||||
params.push(menu_type);
|
params.push(menu_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter by city if provided
|
// Filter by city if provided (supports partial match)
|
||||||
if (city) {
|
if (city) {
|
||||||
conditions.push(`city ILIKE $${params.length + 1}`);
|
conditions.push(`city ILIKE $${params.length + 1}`);
|
||||||
params.push(city);
|
params.push(`%${city}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter by state if provided
|
// Filter by state if provided
|
||||||
@@ -60,6 +77,27 @@ router.get('/', async (req, res) => {
|
|||||||
params.push(state);
|
params.push(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter by crawl_enabled - defaults to showing only enabled
|
||||||
|
if (crawl_enabled === 'false' || crawl_enabled === '0') {
|
||||||
|
// Explicitly show disabled only
|
||||||
|
conditions.push(`(crawl_enabled = false OR crawl_enabled IS NULL)`);
|
||||||
|
} else if (crawl_enabled === 'all') {
|
||||||
|
// Show all (no filter)
|
||||||
|
} else {
|
||||||
|
// Default: show only enabled
|
||||||
|
conditions.push(`crawl_enabled = true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by dutchie_verified if provided
|
||||||
|
if (dutchie_verified !== undefined) {
|
||||||
|
const verified = dutchie_verified === 'true' || dutchie_verified === '1';
|
||||||
|
if (verified) {
|
||||||
|
conditions.push(`dutchie_verified = true`);
|
||||||
|
} else {
|
||||||
|
conditions.push(`(dutchie_verified = false OR dutchie_verified IS NULL)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (conditions.length > 0) {
|
if (conditions.length > 0) {
|
||||||
query += ` WHERE ${conditions.join(' AND ')}`;
|
query += ` WHERE ${conditions.join(' AND ')}`;
|
||||||
}
|
}
|
||||||
@@ -68,7 +106,7 @@ router.get('/', async (req, res) => {
|
|||||||
|
|
||||||
const result = await pool.query(query, params);
|
const result = await pool.query(query, params);
|
||||||
|
|
||||||
res.json({ dispensaries: result.rows });
|
res.json({ dispensaries: result.rows, total: result.rowCount });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching dispensaries:', error);
|
console.error('Error fetching dispensaries:', error);
|
||||||
res.status(500).json({ error: 'Failed to fetch dispensaries' });
|
res.status(500).json({ error: 'Failed to fetch dispensaries' });
|
||||||
@@ -91,6 +129,46 @@ router.get('/stats/menu-types', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get crawl status stats
|
||||||
|
router.get('/stats/crawl-status', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { state, city } = req.query;
|
||||||
|
|
||||||
|
let query = `
|
||||||
|
SELECT
|
||||||
|
COUNT(*) FILTER (WHERE crawl_enabled = true) as enabled_count,
|
||||||
|
COUNT(*) FILTER (WHERE crawl_enabled = false OR crawl_enabled IS NULL) as disabled_count,
|
||||||
|
COUNT(*) FILTER (WHERE dutchie_verified = true) as verified_count,
|
||||||
|
COUNT(*) FILTER (WHERE dutchie_verified = false OR dutchie_verified IS NULL) as unverified_count,
|
||||||
|
COUNT(*) as total_count
|
||||||
|
FROM dispensaries
|
||||||
|
`;
|
||||||
|
|
||||||
|
const params: any[] = [];
|
||||||
|
const conditions: string[] = [];
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
conditions.push(`state = $${params.length + 1}`);
|
||||||
|
params.push(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (city) {
|
||||||
|
conditions.push(`city ILIKE $${params.length + 1}`);
|
||||||
|
params.push(`%${city}%`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conditions.length > 0) {
|
||||||
|
query += ` WHERE ${conditions.join(' AND ')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await pool.query(query, params);
|
||||||
|
res.json(result.rows[0]);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching crawl status stats:', error);
|
||||||
|
res.status(500).json({ error: 'Failed to fetch crawl status stats' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Get single dispensary by slug or ID
|
// Get single dispensary by slug or ID
|
||||||
router.get('/:slugOrId', async (req, res) => {
|
router.get('/:slugOrId', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@@ -101,21 +179,36 @@ router.get('/:slugOrId', async (req, res) => {
|
|||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
company_name,
|
|
||||||
slug,
|
slug,
|
||||||
address,
|
address1,
|
||||||
|
address2,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
zip,
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
dba_name,
|
dba_name,
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
product_count,
|
product_count,
|
||||||
last_crawl_at,
|
last_crawl_at,
|
||||||
raw_metadata,
|
raw_metadata,
|
||||||
@@ -143,19 +236,34 @@ router.put('/:id', async (req, res) => {
|
|||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
dba_name,
|
dba_name,
|
||||||
company_name,
|
|
||||||
website,
|
website,
|
||||||
phone,
|
phone,
|
||||||
address,
|
email,
|
||||||
|
address1,
|
||||||
|
address2,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
zip,
|
zipcode,
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
slug,
|
slug,
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
@@ -171,39 +279,69 @@ router.put('/:id', async (req, res) => {
|
|||||||
SET
|
SET
|
||||||
name = COALESCE($1, name),
|
name = COALESCE($1, name),
|
||||||
dba_name = COALESCE($2, dba_name),
|
dba_name = COALESCE($2, dba_name),
|
||||||
company_name = COALESCE($3, company_name),
|
website = COALESCE($3, website),
|
||||||
website = COALESCE($4, website),
|
phone = COALESCE($4, phone),
|
||||||
phone = COALESCE($5, phone),
|
email = COALESCE($5, email),
|
||||||
address = COALESCE($6, address),
|
address1 = COALESCE($6, address1),
|
||||||
city = COALESCE($7, city),
|
address2 = COALESCE($7, address2),
|
||||||
state = COALESCE($8, state),
|
city = COALESCE($8, city),
|
||||||
zip = COALESCE($9, zip),
|
state = COALESCE($9, state),
|
||||||
latitude = COALESCE($10, latitude),
|
zipcode = COALESCE($10, zipcode),
|
||||||
longitude = COALESCE($11, longitude),
|
latitude = COALESCE($11, latitude),
|
||||||
menu_url = COALESCE($12, menu_url),
|
longitude = COALESCE($12, longitude),
|
||||||
menu_type = COALESCE($13, menu_type),
|
timezone = COALESCE($13, timezone),
|
||||||
platform = COALESCE($14, platform),
|
menu_url = COALESCE($14, menu_url),
|
||||||
platform_dispensary_id = COALESCE($15, platform_dispensary_id),
|
menu_type = COALESCE($15, menu_type),
|
||||||
slug = COALESCE($16, slug),
|
platform = COALESCE($16, platform),
|
||||||
|
platform_dispensary_id = COALESCE($17, platform_dispensary_id),
|
||||||
|
c_name = COALESCE($18, c_name),
|
||||||
|
chain_slug = COALESCE($19, chain_slug),
|
||||||
|
enterprise_id = COALESCE($20, enterprise_id),
|
||||||
|
description = COALESCE($21, description),
|
||||||
|
logo_image = COALESCE($22, logo_image),
|
||||||
|
banner_image = COALESCE($23, banner_image),
|
||||||
|
offer_pickup = COALESCE($24, offer_pickup),
|
||||||
|
offer_delivery = COALESCE($25, offer_delivery),
|
||||||
|
offer_curbside_pickup = COALESCE($26, offer_curbside_pickup),
|
||||||
|
is_medical = COALESCE($27, is_medical),
|
||||||
|
is_recreational = COALESCE($28, is_recreational),
|
||||||
|
status = COALESCE($29, status),
|
||||||
|
country = COALESCE($30, country),
|
||||||
|
slug = COALESCE($31, slug),
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $17
|
WHERE id = $32
|
||||||
RETURNING *
|
RETURNING *
|
||||||
`, [
|
`, [
|
||||||
name,
|
name,
|
||||||
dba_name,
|
dba_name,
|
||||||
company_name,
|
|
||||||
website,
|
website,
|
||||||
phone,
|
phone,
|
||||||
address,
|
email,
|
||||||
|
address1,
|
||||||
|
address2,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
zip,
|
zipcode,
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
slug,
|
slug,
|
||||||
id
|
id
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ function detectProvider(menuUrl: string | null): string {
|
|||||||
// Get all stores (from dispensaries table)
|
// Get all stores (from dispensaries table)
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { city, state, menu_type } = req.query;
|
const { city, state, menu_type, crawl_enabled, dutchie_verified } = req.query;
|
||||||
|
|
||||||
let query = `
|
let query = `
|
||||||
SELECT
|
SELECT
|
||||||
@@ -79,18 +79,36 @@ router.get('/', async (req, res) => {
|
|||||||
slug,
|
slug,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
address,
|
address1,
|
||||||
zip,
|
address2,
|
||||||
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
product_count,
|
product_count,
|
||||||
last_crawl_at,
|
last_crawl_at,
|
||||||
|
crawl_enabled,
|
||||||
|
dutchie_verified,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM dispensaries
|
FROM dispensaries
|
||||||
@@ -99,21 +117,45 @@ router.get('/', async (req, res) => {
|
|||||||
const params: any[] = [];
|
const params: any[] = [];
|
||||||
const conditions: string[] = [];
|
const conditions: string[] = [];
|
||||||
|
|
||||||
|
// Filter by city (partial match)
|
||||||
if (city) {
|
if (city) {
|
||||||
conditions.push(`city ILIKE $${params.length + 1}`);
|
conditions.push(`city ILIKE $${params.length + 1}`);
|
||||||
params.push(city);
|
params.push(`%${city}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter by state
|
||||||
if (state) {
|
if (state) {
|
||||||
conditions.push(`state = $${params.length + 1}`);
|
conditions.push(`state = $${params.length + 1}`);
|
||||||
params.push(state);
|
params.push(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter by menu_type
|
||||||
if (menu_type) {
|
if (menu_type) {
|
||||||
conditions.push(`menu_type = $${params.length + 1}`);
|
conditions.push(`menu_type = $${params.length + 1}`);
|
||||||
params.push(menu_type);
|
params.push(menu_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter by crawl_enabled - defaults to showing only enabled
|
||||||
|
if (crawl_enabled === 'false' || crawl_enabled === '0') {
|
||||||
|
// Explicitly show disabled only
|
||||||
|
conditions.push(`(crawl_enabled = false OR crawl_enabled IS NULL)`);
|
||||||
|
} else if (crawl_enabled === 'all') {
|
||||||
|
// Show all (no filter)
|
||||||
|
} else {
|
||||||
|
// Default: show only enabled
|
||||||
|
conditions.push(`crawl_enabled = true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by dutchie_verified
|
||||||
|
if (dutchie_verified !== undefined) {
|
||||||
|
const verified = dutchie_verified === 'true' || dutchie_verified === '1';
|
||||||
|
if (verified) {
|
||||||
|
conditions.push(`dutchie_verified = true`);
|
||||||
|
} else {
|
||||||
|
conditions.push(`(dutchie_verified = false OR dutchie_verified IS NULL)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (conditions.length > 0) {
|
if (conditions.length > 0) {
|
||||||
query += ` WHERE ${conditions.join(' AND ')}`;
|
query += ` WHERE ${conditions.join(' AND ')}`;
|
||||||
}
|
}
|
||||||
@@ -129,7 +171,7 @@ router.get('/', async (req, res) => {
|
|||||||
...calculateFreshness(row.last_crawl_at)
|
...calculateFreshness(row.last_crawl_at)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
res.json({ stores });
|
res.json({ stores, total: result.rowCount });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching stores:', error);
|
console.error('Error fetching stores:', error);
|
||||||
res.status(500).json({ error: 'Failed to fetch stores' });
|
res.status(500).json({ error: 'Failed to fetch stores' });
|
||||||
@@ -148,18 +190,33 @@ router.get('/:id', async (req, res) => {
|
|||||||
slug,
|
slug,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
address,
|
address1,
|
||||||
zip,
|
address2,
|
||||||
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
dba_name,
|
dba_name,
|
||||||
company_name,
|
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
|
timezone,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country,
|
||||||
product_count,
|
product_count,
|
||||||
last_crawl_at,
|
last_crawl_at,
|
||||||
raw_metadata,
|
raw_metadata,
|
||||||
@@ -203,16 +260,32 @@ router.post('/', requireRole('superadmin', 'admin'), async (req, res) => {
|
|||||||
slug,
|
slug,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
address,
|
address1,
|
||||||
zip,
|
address2,
|
||||||
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
latitude,
|
latitude,
|
||||||
longitude
|
longitude,
|
||||||
|
timezone,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
if (!name || !slug || !city || !state) {
|
if (!name || !slug || !city || !state) {
|
||||||
@@ -221,16 +294,19 @@ router.post('/', requireRole('superadmin', 'admin'), async (req, res) => {
|
|||||||
|
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
INSERT INTO dispensaries (
|
INSERT INTO dispensaries (
|
||||||
name, slug, city, state, address, zip, phone, website,
|
name, slug, city, state, address1, address2, zipcode, phone, website, email,
|
||||||
menu_url, menu_type, platform, platform_dispensary_id,
|
menu_url, menu_type, platform, platform_dispensary_id, c_name, chain_slug, enterprise_id,
|
||||||
latitude, longitude, created_at, updated_at
|
latitude, longitude, timezone, description, logo_image, banner_image,
|
||||||
|
offer_pickup, offer_delivery, offer_curbside_pickup, is_medical, is_recreational, status, country,
|
||||||
|
created_at, updated_at
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
RETURNING *
|
RETURNING *
|
||||||
`, [
|
`, [
|
||||||
name, slug, city, state, address, zip, phone, website,
|
name, slug, city, state, address1, address2, zipcode, phone, website, email,
|
||||||
menu_url, menu_type, platform || 'dutchie', platform_dispensary_id,
|
menu_url, menu_type, platform || 'dutchie', platform_dispensary_id, c_name, chain_slug, enterprise_id,
|
||||||
latitude, longitude
|
latitude, longitude, timezone, description, logo_image, banner_image,
|
||||||
|
offer_pickup, offer_delivery, offer_curbside_pickup, is_medical, is_recreational, status, country || 'United States'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
res.status(201).json(result.rows[0]);
|
res.status(201).json(result.rows[0]);
|
||||||
@@ -253,16 +329,32 @@ router.put('/:id', requireRole('superadmin', 'admin'), async (req, res) => {
|
|||||||
slug,
|
slug,
|
||||||
city,
|
city,
|
||||||
state,
|
state,
|
||||||
address,
|
address1,
|
||||||
zip,
|
address2,
|
||||||
|
zipcode,
|
||||||
phone,
|
phone,
|
||||||
website,
|
website,
|
||||||
|
email,
|
||||||
menu_url,
|
menu_url,
|
||||||
menu_type,
|
menu_type,
|
||||||
platform,
|
platform,
|
||||||
platform_dispensary_id,
|
platform_dispensary_id,
|
||||||
|
c_name,
|
||||||
|
chain_slug,
|
||||||
|
enterprise_id,
|
||||||
latitude,
|
latitude,
|
||||||
longitude
|
longitude,
|
||||||
|
timezone,
|
||||||
|
description,
|
||||||
|
logo_image,
|
||||||
|
banner_image,
|
||||||
|
offer_pickup,
|
||||||
|
offer_delivery,
|
||||||
|
offer_curbside_pickup,
|
||||||
|
is_medical,
|
||||||
|
is_recreational,
|
||||||
|
status,
|
||||||
|
country
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
@@ -272,23 +364,40 @@ router.put('/:id', requireRole('superadmin', 'admin'), async (req, res) => {
|
|||||||
slug = COALESCE($2, slug),
|
slug = COALESCE($2, slug),
|
||||||
city = COALESCE($3, city),
|
city = COALESCE($3, city),
|
||||||
state = COALESCE($4, state),
|
state = COALESCE($4, state),
|
||||||
address = COALESCE($5, address),
|
address1 = COALESCE($5, address1),
|
||||||
zip = COALESCE($6, zip),
|
address2 = COALESCE($6, address2),
|
||||||
phone = COALESCE($7, phone),
|
zipcode = COALESCE($7, zipcode),
|
||||||
website = COALESCE($8, website),
|
phone = COALESCE($8, phone),
|
||||||
menu_url = COALESCE($9, menu_url),
|
website = COALESCE($9, website),
|
||||||
menu_type = COALESCE($10, menu_type),
|
email = COALESCE($10, email),
|
||||||
platform = COALESCE($11, platform),
|
menu_url = COALESCE($11, menu_url),
|
||||||
platform_dispensary_id = COALESCE($12, platform_dispensary_id),
|
menu_type = COALESCE($12, menu_type),
|
||||||
latitude = COALESCE($13, latitude),
|
platform = COALESCE($13, platform),
|
||||||
longitude = COALESCE($14, longitude),
|
platform_dispensary_id = COALESCE($14, platform_dispensary_id),
|
||||||
|
c_name = COALESCE($15, c_name),
|
||||||
|
chain_slug = COALESCE($16, chain_slug),
|
||||||
|
enterprise_id = COALESCE($17, enterprise_id),
|
||||||
|
latitude = COALESCE($18, latitude),
|
||||||
|
longitude = COALESCE($19, longitude),
|
||||||
|
timezone = COALESCE($20, timezone),
|
||||||
|
description = COALESCE($21, description),
|
||||||
|
logo_image = COALESCE($22, logo_image),
|
||||||
|
banner_image = COALESCE($23, banner_image),
|
||||||
|
offer_pickup = COALESCE($24, offer_pickup),
|
||||||
|
offer_delivery = COALESCE($25, offer_delivery),
|
||||||
|
offer_curbside_pickup = COALESCE($26, offer_curbside_pickup),
|
||||||
|
is_medical = COALESCE($27, is_medical),
|
||||||
|
is_recreational = COALESCE($28, is_recreational),
|
||||||
|
status = COALESCE($29, status),
|
||||||
|
country = COALESCE($30, country),
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $15
|
WHERE id = $31
|
||||||
RETURNING *
|
RETURNING *
|
||||||
`, [
|
`, [
|
||||||
name, slug, city, state, address, zip, phone, website,
|
name, slug, city, state, address1, address2, zipcode, phone, website, email,
|
||||||
menu_url, menu_type, platform, platform_dispensary_id,
|
menu_url, menu_type, platform, platform_dispensary_id, c_name, chain_slug, enterprise_id,
|
||||||
latitude, longitude, id
|
latitude, longitude, timezone, description, logo_image, banner_image,
|
||||||
|
offer_pickup, offer_delivery, offer_curbside_pickup, is_medical, is_recreational, status, country, id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (result.rows.length === 0) {
|
if (result.rows.length === 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user